diff options
| -rw-r--r-- | lld/ELF/InputFiles.cpp | 3 | ||||
| -rw-r--r-- | lld/ELF/Symbols.cpp | 1 | ||||
| -rw-r--r-- | lld/ELF/Symbols.h | 46 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 7 | ||||
| -rw-r--r-- | lld/test/elf2/symbols.s | 12 |
5 files changed, 56 insertions, 13 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 14566dccd32..457a78dbf2b 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -90,6 +90,9 @@ SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable, StringRef Name = *NameOrErr; uint32_t SecIndex = Sym->st_shndx; + if (SecIndex == SHN_ABS) + return new (Alloc) DefinedAbsolute<ELFT>(Name, *Sym); + if (SecIndex == SHN_XINDEX) SecIndex = ELFObj->getExtendedSymbolTableIndex(Sym, Symtab, SymtabSHNDX); diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 095940c284c..359632fec47 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -33,6 +33,7 @@ int SymbolBody::compare(SymbolBody *Other) { // Now handle the case where the kinds are the same. switch (LK) { + case DefinedAbsoluteKind: case DefinedRegularKind: return 0; case DefinedWeakKind: diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index 296fd40a6ab..309c34f1810 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -39,11 +39,12 @@ public: enum Kind { DefinedFirst = 0, DefinedRegularKind = 0, - DefinedWeakKind = 1, - DefinedLast = 1, - UndefinedWeakKind = 2, - UndefinedKind = 3, - UndefinedSyntheticKind = 4 + DefinedAbsoluteKind = 1, + DefinedWeakKind = 2, + DefinedLast = 2, + UndefinedWeakKind = 3, + UndefinedKind = 4, + UndefinedSyntheticKind = 5 }; Kind kind() const { return static_cast<Kind>(SymbolKind); } @@ -103,14 +104,35 @@ public: // etc. template <class ELFT> class Defined : public ELFSymbolBody<ELFT> { typedef ELFSymbolBody<ELFT> Base; + +protected: + typedef typename Base::Kind Kind; + typedef typename Base::Elf_Sym Elf_Sym; + +public: + explicit Defined(Kind K, StringRef N, const Elf_Sym &Sym) + : ELFSymbolBody<ELFT>(K, N, Sym) {} +}; + +template <class ELFT> class DefinedAbsolute : public Defined<ELFT> { + typedef ELFSymbolBody<ELFT> Base; + typedef typename Base::Elf_Sym Elf_Sym; + +public: + explicit DefinedAbsolute(StringRef N, const Elf_Sym &Sym) + : Defined<ELFT>(Base::DefinedAbsoluteKind, N, Sym) {} +}; + +template <class ELFT> class DefinedInSection : public Defined<ELFT> { + typedef ELFSymbolBody<ELFT> Base; typedef typename Base::Kind Kind; public: typedef typename Base::Elf_Sym Elf_Sym; - explicit Defined(Kind K, StringRef N, const Elf_Sym &Sym, - SectionChunk<ELFT> &Section) - : ELFSymbolBody<ELFT>(K, N, Sym), Section(Section) {} + explicit DefinedInSection(Kind K, StringRef N, const Elf_Sym &Sym, + SectionChunk<ELFT> &Section) + : Defined<ELFT>(K, N, Sym), Section(Section) {} static bool classof(const SymbolBody *S) { Kind K = S->kind(); @@ -121,28 +143,28 @@ public: }; // Regular defined symbols read from object file symbol tables. -template <class ELFT> class DefinedRegular : public Defined<ELFT> { +template <class ELFT> class DefinedRegular : public DefinedInSection<ELFT> { typedef Defined<ELFT> Base; typedef typename Base::Elf_Sym Elf_Sym; public: explicit DefinedRegular(StringRef N, const Elf_Sym &Sym, SectionChunk<ELFT> &Section) - : Defined<ELFT>(Base::DefinedRegularKind, N, Sym, Section) {} + : DefinedInSection<ELFT>(Base::DefinedRegularKind, N, Sym, Section) {} static bool classof(const SymbolBody *S) { return S->kind() == Base::DefinedRegularKind; } }; -template <class ELFT> class DefinedWeak : public Defined<ELFT> { +template <class ELFT> class DefinedWeak : public DefinedInSection<ELFT> { typedef Defined<ELFT> Base; typedef typename Base::Elf_Sym Elf_Sym; public: explicit DefinedWeak(StringRef N, const Elf_Sym &Sym, SectionChunk<ELFT> &Section) - : Defined<ELFT>(Base::DefinedWeakKind, N, Sym, Section) {} + : DefinedInSection<ELFT>(Base::DefinedWeakKind, N, Sym, Section) {} static bool classof(const SymbolBody *S) { return S->kind() == Base::DefinedWeakKind; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index bde48972b01..38616f8ae09 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -246,11 +246,12 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { llvm_unreachable("Should be defined by now"); case SymbolBody::DefinedWeakKind: case SymbolBody::DefinedRegularKind: { - auto *Def = cast<Defined<ELFT>>(Body); + auto *Def = cast<DefinedInSection<ELFT>>(Body); InputSym = &Def->Sym; Section = &Def->Section; break; } + case SymbolBody::DefinedAbsoluteKind: case SymbolBody::UndefinedWeakKind: InputSym = &cast<ELFSymbolBody<ELFT>>(Body)->Sym; break; @@ -261,6 +262,10 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { uint8_t Binding = InputSym->getBinding(); ESym->setBindingAndType(Binding, Type); ESym->st_size = InputSym->st_size; + if (InputSym->isAbsolute()) { + ESym->st_shndx = SHN_ABS; + ESym->st_value = InputSym->st_value; + } } if (Section) { diff --git a/lld/test/elf2/symbols.s b/lld/test/elf2/symbols.s index be0661d7413..44a478757e8 100644 --- a/lld/test/elf2/symbols.s +++ b/lld/test/elf2/symbols.s @@ -28,6 +28,9 @@ zed2: .size zed3, 4 zed3: +.globl abs +abs = 0x123 + // CHECK: Name: .text // CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ @@ -90,6 +93,15 @@ zed3: // CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: } // CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: abs +// CHECK-NEXT: Value: 0x123 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Absolute +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { // CHECK-NEXT: Name: foo // CHECK-NEXT: Value: 0x1000 // CHECK-NEXT: Size: 0 |

