]> granicus.if.org Git - llvm/commitdiff
[yaml2obj] - Lookup relocation symbols in dynamic symbol when .dynsym referenced.
authorGeorge Rimar <grimar@accesssoftek.com>
Thu, 22 Aug 2019 12:39:56 +0000 (12:39 +0000)
committerGeorge Rimar <grimar@accesssoftek.com>
Thu, 22 Aug 2019 12:39:56 +0000 (12:39 +0000)
This fixes https://bugs.llvm.org/show_bug.cgi?id=40337.

Previously, it was always assumed that relocations referenced symbols in the static symbol table.
Now, if the Link field references a section called ".dynsym" it will look up these symbols
in the dynamic symbol table.

This patch is heavily based on D59097 by James Henderson

Differential revision: https://reviews.llvm.org/D66532

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@369645 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ObjectYAML/ELFEmitter.cpp
test/tools/llvm-readobj/demangle.test
test/tools/yaml2obj/dynamic-relocations.yaml [new file with mode: 0644]
test/tools/yaml2obj/dynamic-symbols.yaml

index 5e53baf5fa4e788fc3a9417e8787ed08811f50a1..6a2d28e16e2fe45038ab6d0374244d0f7db7a1b7 100644 (file)
@@ -111,10 +111,11 @@ template <class ELFT> class ELFState {
 
   NameToIdxMap SN2I;
   NameToIdxMap SymN2I;
+  NameToIdxMap DynSymN2I;
   ELFYAML::Object &Doc;
 
   bool buildSectionIndex();
-  bool buildSymbolIndex(ArrayRef<ELFYAML::Symbol> Symbols);
+  bool buildSymbolIndexes();
   void initELFHeader(Elf_Ehdr &Header);
   void initProgramHeaders(std::vector<Elf_Phdr> &PHeaders);
   bool initImplicitHeader(ELFState<ELFT> &State, ContiguousBlobAccumulator &CBA,
@@ -717,11 +718,12 @@ bool ELFState<ELFT>::writeSectionContent(
 
   auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
 
+  const NameToIdxMap &SymMap = Section.Link == ".dynsym" ? DynSymN2I : SymN2I;
   for (const auto &Rel : Section.Relocations) {
     unsigned SymIdx = 0;
     // If a relocation references a symbol, try to look one up in the symbol
     // table. If it is not there, treat the value as a symbol index.
-    if (Rel.Symbol && !SymN2I.lookup(*Rel.Symbol, SymIdx) &&
+    if (Rel.Symbol && !SymMap.lookup(*Rel.Symbol, SymIdx) &&
         !to_integer(*Rel.Symbol, SymIdx)) {
       WithColor::error() << "Unknown symbol referenced: '" << *Rel.Symbol
                          << "' at YAML section '" << Section.Name << "'.\n";
@@ -987,11 +989,10 @@ template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {
   return true;
 }
 
-template <class ELFT>
-bool ELFState<ELFT>::buildSymbolIndex(ArrayRef<ELFYAML::Symbol> Symbols) {
+static bool buildSymbolsMap(ArrayRef<ELFYAML::Symbol> V, NameToIdxMap &Map) {
   bool GlobalSymbolSeen = false;
   std::size_t I = 0;
-  for (const auto &Sym : Symbols) {
+  for (const ELFYAML::Symbol &Sym : V) {
     ++I;
 
     StringRef Name = Sym.Name;
@@ -1003,7 +1004,7 @@ bool ELFState<ELFT>::buildSymbolIndex(ArrayRef<ELFYAML::Symbol> Symbols) {
     if (Sym.Binding.value != ELF::STB_LOCAL)
       GlobalSymbolSeen = true;
 
-    if (!Name.empty() && !SymN2I.addName(Name, I)) {
+    if (!Name.empty() && !Map.addName(Name, I)) {
       WithColor::error() << "Repeated symbol name: '" << Name << "'.\n";
       return false;
     }
@@ -1011,6 +1012,11 @@ bool ELFState<ELFT>::buildSymbolIndex(ArrayRef<ELFYAML::Symbol> Symbols) {
   return true;
 }
 
+template <class ELFT> bool ELFState<ELFT>::buildSymbolIndexes() {
+  return buildSymbolsMap(Doc.Symbols, SymN2I) &&
+         buildSymbolsMap(Doc.DynamicSymbols, DynSymN2I);
+}
+
 template <class ELFT> void ELFState<ELFT>::finalizeStrings() {
   // Add the regular symbol names to .strtab section.
   for (const ELFYAML::Symbol &Sym : Doc.Symbols)
@@ -1049,10 +1055,7 @@ int ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc) {
   // sections that might want to use them.
   State.finalizeStrings();
 
-  if (!State.buildSectionIndex())
-    return 1;
-
-  if (!State.buildSymbolIndex(Doc.Symbols))
+  if (!State.buildSectionIndex() || !State.buildSymbolIndexes())
     return 1;
 
   Elf_Ehdr Header;
index a1a881e6436d2ef7ded5ed69995b117aee303199..29181cf1b4cd5237010e9324eb6e0035853ec58b 100644 (file)
@@ -139,9 +139,7 @@ Sections:
     EntSize:      0x18
     Relocations:
       - Offset: 0x10
-        ## FIXME: This should be a lookup in the corresponding symbol table, not necessarily the static symbol table.
-        ## See https://bugs.llvm.org/show_bug.cgi?id=40337.
-        Symbol: _Z3fooc
+        Symbol: _Z3fooi
         Type:   R_X86_64_PC32
         Addend: 0x4
   - Name:            .dynamic
diff --git a/test/tools/yaml2obj/dynamic-relocations.yaml b/test/tools/yaml2obj/dynamic-relocations.yaml
new file mode 100644 (file)
index 0000000..2e2d380
--- /dev/null
@@ -0,0 +1,65 @@
+## Show that yaml2obj uses the correct set of symbols for relocation sections
+## referencing the dynamic symbol table.
+
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-readelf -r %t | FileCheck %s
+
+# CHECK:      Relocation section '.rela.dyn' at offset {{.*}} contains 2 entries:
+# CHECK-NEXT:     Offset             Info             Type      Symbol's Value  Symbol's Name
+# CHECK-NEXT: 0000000000000000  0000000100000000 R_X86_64_NONE 0000000012345678 dynamic
+# CHECK-NEXT: 0000000000000008  0000000200000000 R_X86_64_NONE 0000000087654321 both
+# CHECK-EMPTY:
+# CHECK-NEXT: Relocation section '.rela.data' at offset {{.*}} contains 2 entries:
+# CHECK-NEXT:     Offset             Info             Type      Symbol's Value  Symbol's Name
+# CHECK-NEXT: 0000000000000010  0000000200000000 R_X86_64_NONE 0000000011223344 static
+# CHECK-NEXT: 0000000000000018  0000000100000000 R_X86_64_NONE 0000000088776655 both
+
+!ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_DYN
+  Machine: EM_X86_64
+Sections:
+  - Name: .data
+    Type: SHT_PROGBITS
+  - Name: .rela.dyn
+    Type: SHT_REL
+    Link: .dynsym
+    Info: .data
+    Relocations:
+      - Offset: 0
+        Type: R_X86_64_NONE
+        Symbol: dynamic
+      - Offset: 8
+        Type: R_X86_64_NONE
+        Symbol: both
+  - Name: .rela.data
+    Type: SHT_REL
+    Link: .symtab
+    Info: .data
+    Relocations:
+      - Offset: 16
+        Type: R_X86_64_NONE
+        Symbol: static
+      - Offset: 24
+        Type: R_X86_64_NONE
+        Symbol: both
+Symbols:
+    - Name: both
+      Section: .data
+      Value: 0x88776655
+      Binding: STB_GLOBAL
+    - Name: static
+      Section: .data
+      Value: 0x11223344
+      Binding: STB_GLOBAL
+DynamicSymbols:
+    - Name: dynamic
+      Section: .data
+      Value: 0x12345678
+      Binding: STB_GLOBAL
+    - Name: both
+      Section: .data
+      Value: 0x87654321
+      Binding: STB_GLOBAL
index 47527a3a7ac348d2d58358718400a3273ec71a39..44000add88966b58f9f15fee092bf2cf5a3dac4f 100644 (file)
@@ -14,6 +14,10 @@ Sections:
     Type: SHT_PROGBITS
     Flags: [ SHF_ALLOC, SHF_WRITE ]
 DynamicSymbols:
+  - Name: dynlocal
+    Type: STT_OBJECT
+    Section: .data
+    Binding: STB_LOCAL
   - Name: dynglobal
     Type: STT_OBJECT
     Section: .data
@@ -22,10 +26,6 @@ DynamicSymbols:
     Type: STT_OBJECT
     Section: .data
     Binding: STB_WEAK
-  - Name: dynlocal
-    Type: STT_OBJECT
-    Section: .data
-    Binding: STB_LOCAL
 
 # SECTION: Name: .dynsym
 # SECTION-NEXT: Type: SHT_DYNSYM
@@ -36,6 +36,6 @@ DynamicSymbols:
 # SECTION-NEXT: Flags
 # SECTION-NEXT: SHF_ALLOC
 
+# SYMBOL-DAG: d dynlocal
 # SYMBOL-DAG: D dynglobal
 # SYMBOL-DAG: V dynweak
-# SYMBOL-DAG: d dynlocal