Add the type of the symbols to the symbol table.

For now only defined symbols are covered. I will add undefined ones in the
next patch.

llvm-svn: 245057
This commit is contained in:
Rafael Espindola
2015-08-14 15:10:49 +00:00
parent 457c940835
commit c44d17ad45
4 changed files with 34 additions and 15 deletions

View File

@@ -87,11 +87,11 @@ SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
case STB_GLOBAL:
if (Sym->isUndefined())
return new (Alloc) Undefined(Name);
return new (Alloc) DefinedRegular(Name);
return new (Alloc) DefinedRegular<ELFT>(Name, *Sym);
case STB_WEAK:
if (Sym->isUndefined())
return new (Alloc) UndefinedWeak(Name);
return new (Alloc) DefinedWeak(Name);
return new (Alloc) DefinedWeak<ELFT>(Name, *Sym);
}
}

View File

@@ -72,9 +72,13 @@ protected:
// The base class for any defined symbols, including absolute symbols,
// etc.
class Defined : public SymbolBody {
template <class ELFT> class Defined : public SymbolBody {
public:
explicit Defined(Kind K, StringRef N) : SymbolBody(K, N) {}
typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
const Elf_Sym &Sym;
explicit Defined(Kind K, StringRef N, const Elf_Sym &Sym)
: SymbolBody(K, N), Sym(Sym) {}
static bool classof(const SymbolBody *S) {
Kind K = S->kind();
@@ -83,21 +87,29 @@ public:
};
// Regular defined symbols read from object file symbol tables.
class DefinedRegular : public Defined {
template <class ELFT> class DefinedRegular : public Defined<ELFT> {
typedef Defined<ELFT> Base;
typedef typename Base::Elf_Sym Elf_Sym;
public:
explicit DefinedRegular(StringRef N) : Defined(DefinedRegularKind, N) {}
explicit DefinedRegular(StringRef N, const Elf_Sym &Sym)
: Defined<ELFT>(Base::DefinedRegularKind, N, Sym) {}
static bool classof(const SymbolBody *S) {
return S->kind() == DefinedRegularKind;
return S->kind() == Base::DefinedRegularKind;
}
};
class DefinedWeak : public Defined {
template <class ELFT> class DefinedWeak : public Defined<ELFT> {
typedef Defined<ELFT> Base;
typedef typename Base::Elf_Sym Elf_Sym;
public:
explicit DefinedWeak(StringRef N) : Defined(DefinedWeakKind, N) {}
explicit DefinedWeak(StringRef N, const Elf_Sym &Sym)
: Defined<ELFT>(Base::DefinedWeakKind, N, Sym) {}
static bool classof(const SymbolBody *S) {
return S->kind() == DefinedWeakKind;
return S->kind() == Base::DefinedWeakKind;
}
};

View File

@@ -220,18 +220,23 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
ESym->st_name = Builder.getOffset(Name);
uint8_t Binding;
switch (Sym->Body->kind()) {
SymbolBody *Body = Sym->Body;
uint8_t Type = 0;
switch (Body->kind()) {
case SymbolBody::UndefinedKind:
llvm_unreachable("Should be defined by now");
case SymbolBody::DefinedRegularKind:
Binding = STB_GLOBAL;
Type = cast<DefinedRegular<ELFT>>(Body)->Sym.getType();
break;
case SymbolBody::UndefinedWeakKind:
case SymbolBody::DefinedWeakKind:
Type = cast<DefinedWeak<ELFT>>(Body)->Sym.getType();
// Fallthrough
case SymbolBody::UndefinedWeakKind:
Binding = STB_WEAK;
break;
}
ESym->setBindingAndType(Binding, 0);
ESym->setBindingAndType(Binding, Type);
Buf += sizeof(Elf_Sym);
}

View File

@@ -3,9 +3,11 @@
// RUN: llvm-readobj -symbols %t2 | FileCheck %s
// REQUIRES: x86
.type _start, @function
.globl _start
_start:
.type foo, @object
.weak foo
foo:
@@ -24,7 +26,7 @@ foo:
// CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global (0x1)
// CHECK-NEXT: Type: None (0x0)
// CHECK-NEXT: Type: Function
// CHECK-NEXT: Other: 0
// CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: }
@@ -33,7 +35,7 @@ foo:
// CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Weak (0x2)
// CHECK-NEXT: Type: None (0x0)
// CHECK-NEXT: Type: Object
// CHECK-NEXT: Other: 0
// CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: }