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; @@ -679,6 +680,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. @@ -692,8 +695,25 @@ auto *ESym = reinterpret_cast(Buf); 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()); + ErrorOr SymHOrErr = + File.getObj()->getSection(Sym.st_shndx); + error(SymHOrErr, Twine("can't get section header")); + for (SectionChunk *C : File.getChunks()) { + if (!C) + continue; + const Elf_Shdr *H = C->getSectionHdr(); + if (H == *SymHOrErr) { + Section = C; + Out = C->getOutputSection(); + break; + } + } + assert(Section != nullptr && Out != nullptr); + ESym->st_shndx = Out->getSectionIndex(); + ESym->st_value = + Out->getVA() + Section->getOutputSectionOff() + Sym.st_value; Buf += sizeof(Elf_Sym); } } @@ -710,8 +730,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