Index: lld/trunk/ELF/InputFiles.h =================================================================== --- lld/trunk/ELF/InputFiles.h +++ lld/trunk/ELF/InputFiles.h @@ -143,6 +143,9 @@ Elf_Sym_Range getLocalSymbols(); + const Elf_Shdr *getSymbolTable() { return this->Symtab; }; + ArrayRef getSymbolTableShndx() { return SymtabSHNDX; }; + private: void initializeChunks(); void initializeSymbols(); Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -223,6 +223,7 @@ template class SymbolTableSection final : public OutputSectionBase { public: + typedef typename ELFFile::Elf_Shdr Elf_Shdr; typedef typename ELFFile::Elf_Sym Elf_Sym; typedef typename ELFFile::Elf_Sym_Range Elf_Sym_Range; typedef typename OutputSectionBase::uintX_t uintX_t; @@ -733,6 +734,8 @@ } template void SymbolTableSection::writeTo(uint8_t *Buf) { + const OutputSection *Out = nullptr; + const SectionChunk *Section = nullptr; Buf += sizeof(Elf_Sym); // All symbols with STB_LOCAL binding precede the weak and global symbols. @@ -744,10 +747,22 @@ Elf_Sym_Range Syms = File.getLocalSymbols(); for (const Elf_Sym &Sym : Syms) { auto *ESym = reinterpret_cast(Buf); + uint32_t SecIndex = Sym.st_shndx; ErrorOr SymName = Sym.getName(File.getStringTable()); ESym->st_name = (SymName) ? StrTabSec.getFileOff(*SymName) : 0; - ESym->st_value = Sym.st_value; ESym->st_size = Sym.st_size; + ESym->setBindingAndType(Sym.getBinding(), Sym.getType()); + if (SecIndex == SHN_XINDEX) + SecIndex = File.getObj()->getExtendedSymbolTableIndex( + &Sym, File.getSymbolTable(), File.getSymbolTableShndx()); + ArrayRef *> Chunks = File.getChunks(); + Section = Chunks[SecIndex]; + assert(Section != nullptr); + Out = Section->getOutputSection(); + assert(Out != nullptr); + ESym->st_shndx = Out->getSectionIndex(); + ESym->st_value = + Out->getVA() + Section->getOutputSectionOff() + Sym.st_value; Buf += sizeof(Elf_Sym); } } @@ -764,8 +779,8 @@ auto *ESym = reinterpret_cast(Buf); ESym->st_name = StrTabSec.getFileOff(Name); - const SectionChunk *Section = nullptr; - const OutputSection *Out = nullptr; + Out = nullptr; + Section = nullptr; switch (Body->kind()) { case SymbolBody::DefinedRegularKind: Index: lld/trunk/test/elf2/local-dynamic.s =================================================================== --- lld/trunk/test/elf2/local-dynamic.s +++ lld/trunk/test/elf2/local-dynamic.s @@ -16,30 +16,30 @@ // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: blah -// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Value: 0x1000 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None // CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: Undefined +// CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: foo -// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Value: 0x1000 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None // CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: Undefined +// CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: goo -// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Value: 0x1000 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None // CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: Undefined +// CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: _start Index: lld/trunk/test/elf2/local.s =================================================================== --- lld/trunk/test/elf2/local.s +++ lld/trunk/test/elf2/local.s @@ -28,30 +28,30 @@ // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: blah -// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Value: 0x11000 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None // CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: Undefined +// CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: foo -// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Value: 0x11000 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None // CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: Undefined +// CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: goo -// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Value: 0x11000 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None // CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: Undefined +// CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: _start