From dfc7200b1808433f60e02cb6773a2c4f6b699df1 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 28 Sep 2015 18:29:47 +0000 Subject: [PATCH] Add support for local absolute symbols. llvm-svn: 248726 --- lld/ELF/OutputSections.cpp | 27 +++++++++++++++------------ lld/test/elf2/local.s | 12 +++++++++++- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 07e79b1adf18..6e1359e5f6cf 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -403,24 +403,27 @@ template void SymbolTableSection::writeTo(uint8_t *Buf) { 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()); if (SymName && !shouldKeepInSymtab(*SymName)) continue; ESym->st_name = (SymName) ? StrTabSec.getFileOff(*SymName) : 0; 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 *> Sections = File.getSections(); - const InputSection *Section = Sections[SecIndex]; - assert(Section != nullptr); - const OutputSection *Out = Section->getOutputSection(); - assert(Out != nullptr); - ESym->st_shndx = Out->getSectionIndex(); - ESym->st_value = - Out->getVA() + Section->getOutputSectionOff() + Sym.st_value; + uint32_t SecIndex = Sym.st_shndx; + uintX_t VA = Sym.st_value; + if (SecIndex == SHN_ABS) { + ESym->st_shndx = SHN_ABS; + } else { + if (SecIndex == SHN_XINDEX) + SecIndex = File.getObj().getExtendedSymbolTableIndex( + &Sym, File.getSymbolTable(), File.getSymbolTableShndx()); + ArrayRef *> Sections = File.getSections(); + const InputSection *Section = Sections[SecIndex]; + const OutputSection *Out = Section->getOutputSection(); + ESym->st_shndx = Out->getSectionIndex(); + VA += Out->getVA() + Section->getOutputSectionOff(); + } + ESym->st_value = VA; Buf += sizeof(Elf_Sym); } } diff --git a/lld/test/elf2/local.s b/lld/test/elf2/local.s index 3aa9642c21a2..8c09264ff765 100644 --- a/lld/test/elf2/local.s +++ b/lld/test/elf2/local.s @@ -14,7 +14,7 @@ // CHECK-NEXT: Offset: // CHECK-NEXT: Size: // CHECK-NEXT: Link: -// CHECK-NEXT: Info: 4 +// CHECK-NEXT: Info: 5 // CHECK: Symbols [ // CHECK-NEXT: Symbol { @@ -27,6 +27,15 @@ // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } // CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: abs +// CHECK-NEXT: Value: 0x2A +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Absolute +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { // CHECK-NEXT: Name: blah // CHECK-NEXT: Value: 0x11000 // CHECK-NEXT: Size: 0 @@ -70,3 +79,4 @@ _start: blah: foo: goo: +abs = 42