Index: ELF/InputFiles.h =================================================================== --- ELF/InputFiles.h +++ 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: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -226,6 +226,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; @@ -736,6 +737,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. @@ -747,10 +750,21 @@ 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]; + Out = Section->getOutputSection(); + assert(Section != nullptr && Out != nullptr); + ESym->st_shndx = Out->getSectionIndex(); + ESym->st_value = + Out->getVA() + Section->getOutputSectionOff() + Sym.st_value; Buf += sizeof(Elf_Sym); } } @@ -767,8 +781,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: test/elf2/local-dynamic.s =================================================================== --- test/elf2/local-dynamic.s +++ 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: test/elf2/local.s =================================================================== --- test/elf2/local.s +++ 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