[llvm-commits] [LLD] Patch to tie Atoms in a section together

Shankar Easwaran shankare at codeaurora.org
Tue Oct 23 20:21:51 PDT 2012


+ Nick, Michael

On 10/23/2012 9:49 PM, Shankar Easwaran wrote:
> Hi,
>
> This is a LLD patch for the ELF linker so that Atoms in a section are 
> tied together preventing atoms within a section not garbage collected
>
> * Changes to ReaderELF to add a 'NONE' relocation from the current 
> atom to the previous atom
> * Changes to ELF.h to add a function to retrieve the symbol index for 
> a particular symbol table entry
> * TestCase
>
> Ok to submit ?
>
> Thanks
>
> Shankar Easwaran
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by the Linux Foundation

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20121023/82f3e1b2/attachment.html>
-------------- next part --------------
diff --git a/test/elf/Inputs/relocs-test-bss.c b/test/elf/Inputs/relocs-test-bss.c
new file mode 100644
index 0000000..b380b51
--- /dev/null
+++ b/test/elf/Inputs/relocs-test-bss.c
@@ -0,0 +1,2 @@
+int a = 0;
+int b = 0;
diff --git a/test/elf/Inputs/relocs-test-data.c b/test/elf/Inputs/relocs-test-data.c
new file mode 100644
index 0000000..6437dff
--- /dev/null
+++ b/test/elf/Inputs/relocs-test-data.c
@@ -0,0 +1,2 @@
+int a = 1;
+int b = 2;
diff --git a/test/elf/Inputs/relocs-test-text.c b/test/elf/Inputs/relocs-test-text.c
new file mode 100644
index 0000000..a52cb77
--- /dev/null
+++ b/test/elf/Inputs/relocs-test-text.c
@@ -0,0 +1,10 @@
+int fn()
+{
+	return 0;
+}
+
+
+int fn1()
+{
+	return 0;
+}
diff --git a/test/elf/section-relocs.objtxt b/test/elf/section-relocs.objtxt
new file mode 100644
index 0000000..dbffe87
--- /dev/null
+++ b/test/elf/section-relocs.objtxt
@@ -0,0 +1,171 @@
+RUN: gcc -c %p/Inputs/relocs-test-text.c -o %t1
+RUN: lld-core -reader ELF %t1 | FileCheck -check-prefix=YAMLTEXT %s 
+RUN: gcc -c %p/Inputs/relocs-test-data.c -o %t3
+RUN: lld-core -reader ELF %t3 | FileCheck -check-prefix=YAMLDATA %s 
+RUN: gcc -c %p/Inputs/relocs-test-bss.c -o %t3
+RUN: lld-core -reader ELF %t3 | FileCheck -check-prefix=YAMLBSS %s 
+
+YAMLTEXT: ---
+YAMLTEXT: atoms:
+YAMLTEXT:     - name:              .text
+YAMLTEXT:       type:              code
+YAMLTEXT:       section-choice:    custom-required
+YAMLTEXT:       section-name:      .text
+YAMLTEXT:     - name:              fn
+YAMLTEXT:       scope:             global
+YAMLTEXT:       type:              code
+YAMLTEXT:       section-choice:    custom-required
+YAMLTEXT:       section-name:      .text
+YAMLTEXT:       content:           [ 55, 89, E5, B8, 00, 00, 00, 00, 5D, C3 ]
+YAMLTEXT:       fixups:
+YAMLTEXT:       - offset:            0
+YAMLTEXT:         kind:              none
+YAMLTEXT:         target:            .text
+YAMLTEXT:     - name:              fn1
+YAMLTEXT:       scope:             global
+YAMLTEXT:       type:              code
+YAMLTEXT:       section-choice:    custom-required
+YAMLTEXT:       section-name:      .text
+YAMLTEXT:       content:           [ 55, 89, E5, B8, 00, 00, 00, 00, 5D, C3 ]
+YAMLTEXT:       fixups:
+YAMLTEXT:       - offset:            0
+YAMLTEXT:         kind:              none
+YAMLTEXT:         target:            fn
+YAMLTEXT:     - name:              .data
+YAMLTEXT:       section-choice:    custom-required
+YAMLTEXT:       section-name:      .data
+YAMLTEXT:     - name:              .bss
+YAMLTEXT:       type:              zero-fill
+YAMLTEXT:       section-choice:    custom-required
+YAMLTEXT:       section-name:      .bss
+YAMLTEXT:     - name:              .comment
+YAMLTEXT:       type:              unknown
+YAMLTEXT:       section-choice:    custom-required
+YAMLTEXT:       section-name:      .comment
+YAMLTEXT:       content:           [ 00, 47, 43, 43, 3A, 20, 28, 55, 62, 75, 6E, 74, 
+YAMLTEXT:                            75, 2F, 4C, 69, 6E, 61, 72, 6F, 20, 34, 2E, 37, 
+YAMLTEXT:                            2E, 32, 2D, 32, 75, 62, 75, 6E, 74, 75, 31, 29, 
+YAMLTEXT:                            20, 34, 2E, 37, 2E, 32, 00 ]
+YAMLTEXT:     - name:              .note.GNU-stack
+YAMLTEXT:       type:              unknown
+YAMLTEXT:       section-choice:    custom-required
+YAMLTEXT:       section-name:      .note.GNU-stack
+YAMLTEXT:     - name:              .eh_frame
+YAMLTEXT:       type:              constant
+YAMLTEXT:       section-choice:    custom-required
+YAMLTEXT:       section-name:      .eh_frame
+YAMLTEXT:       content:           [ 14, 00, 00, 00, 00, 00, 00, 00, 01, 7A, 52, 00, 
+YAMLTEXT:                            01, 7C, 08, 01, 1B, 0C, 04, 04, 88, 01, 00, 00, 
+YAMLTEXT:                            1C, 00, 00, 00, 1C, 00, 00, 00, 00, 00, 00, 00, 
+YAMLTEXT:                            0A, 00, 00, 00, 00, 41, 0E, 08, 85, 02, 42, 0D, 
+YAMLTEXT:                            05, 46, C5, 0C, 04, 04, 00, 00, 1C, 00, 00, 00, 
+YAMLTEXT:                            3C, 00, 00, 00, 0A, 00, 00, 00, 0A, 00, 00, 00, 
+YAMLTEXT:                            00, 41, 0E, 08, 85, 02, 42, 0D, 05, 46, C5, 0C, 
+YAMLTEXT:                            04, 04, 00, 00 ]
+YAMLTEXT:       fixups:
+YAMLTEXT:       - offset:            32
+YAMLTEXT:         kind:              call32
+YAMLTEXT:         target:            .text
+YAMLTEXT:       - offset:            64
+YAMLTEXT:         kind:              call32
+YAMLTEXT:         target:            .text
+YAMLTEXT:     - name:              relocs-test-text.c
+YAMLTEXT:       definition:        absolute
+YAMLTEXT:       value:             0x0
+YAMLTEXT: ...
+
+YAMLDATA: ---
+YAMLDATA: atoms:
+YAMLDATA:     - name:              .text
+YAMLDATA:       type:              code
+YAMLDATA:       section-choice:    custom-required
+YAMLDATA:       section-name:      .text
+YAMLDATA:     - name:              .data
+YAMLDATA:       section-choice:    custom-required
+YAMLDATA:       section-name:      .data
+YAMLDATA:     - name:              a
+YAMLDATA:       scope:             global
+YAMLDATA:       section-choice:    custom-required
+YAMLDATA:       section-name:      .data
+YAMLDATA:       content:           [ 01, 00, 00, 00 ]
+YAMLDATA:       fixups:
+YAMLDATA:       - offset:            0
+YAMLDATA:         kind:              none
+YAMLDATA:         target:            .data
+YAMLDATA:     - name:              b
+YAMLDATA:       scope:             global
+YAMLDATA:       section-choice:    custom-required
+YAMLDATA:       section-name:      .data
+YAMLDATA:       content:           [ 02, 00, 00, 00 ]
+YAMLDATA:       fixups:
+YAMLDATA:       - offset:            0
+YAMLDATA:         kind:              none
+YAMLDATA:         target:            a
+YAMLDATA:     - name:              .bss
+YAMLDATA:       type:              zero-fill
+YAMLDATA:       section-choice:    custom-required
+YAMLDATA:       section-name:      .bss
+YAMLDATA:     - name:              .comment
+YAMLDATA:       type:              unknown
+YAMLDATA:       section-choice:    custom-required
+YAMLDATA:       section-name:      .comment
+YAMLDATA:       content:           [ 00, 47, 43, 43, 3A, 20, 28, 55, 62, 75, 6E, 74, 
+YAMLDATA:                            75, 2F, 4C, 69, 6E, 61, 72, 6F, 20, 34, 2E, 37, 
+YAMLDATA:                            2E, 32, 2D, 32, 75, 62, 75, 6E, 74, 75, 31, 29, 
+YAMLDATA:                            20, 34, 2E, 37, 2E, 32, 00 ]
+YAMLDATA:     - name:              .note.GNU-stack
+YAMLDATA:       type:              unknown
+YAMLDATA:       section-choice:    custom-required
+YAMLDATA:       section-name:      .note.GNU-stack
+YAMLDATA:     - name:              relocs-test-data.c
+YAMLDATA:       definition:        absolute
+YAMLDATA:       value:             0x0
+YAMLDATA: ...
+
+YAMLBSS: ---
+YAMLBSS: atoms:
+YAMLBSS:     - name:              .text
+YAMLBSS:       type:              code
+YAMLBSS:       section-choice:    custom-required
+YAMLBSS:       section-name:      .text
+YAMLBSS:     - name:              .data
+YAMLBSS:       section-choice:    custom-required
+YAMLBSS:       section-name:      .data
+YAMLBSS:     - name:              .bss
+YAMLBSS:       type:              zero-fill
+YAMLBSS:       section-choice:    custom-required
+YAMLBSS:       section-name:      .bss
+YAMLBSS:     - name:              a
+YAMLBSS:       scope:             global
+YAMLBSS:       type:              zero-fill
+YAMLBSS:       section-choice:    custom-required
+YAMLBSS:       section-name:      .bss
+YAMLBSS:       fixups:
+YAMLBSS:       - offset:            0
+YAMLBSS:         kind:              none
+YAMLBSS:         target:            .bss
+YAMLBSS:     - name:              b
+YAMLBSS:       scope:             global
+YAMLBSS:       type:              zero-fill
+YAMLBSS:       section-choice:    custom-required
+YAMLBSS:       section-name:      .bss
+YAMLBSS:       fixups:
+YAMLBSS:       - offset:            0
+YAMLBSS:         kind:              none
+YAMLBSS:         target:            a
+YAMLBSS:     - name:              .comment
+YAMLBSS:       type:              unknown
+YAMLBSS:       section-choice:    custom-required
+YAMLBSS:       section-name:      .comment
+YAMLBSS:       content:           [ 00, 47, 43, 43, 3A, 20, 28, 55, 62, 75, 6E, 74, 
+YAMLBSS:                            75, 2F, 4C, 69, 6E, 61, 72, 6F, 20, 34, 2E, 37, 
+YAMLBSS:                            2E, 32, 2D, 32, 75, 62, 75, 6E, 74, 75, 31, 29, 
+YAMLBSS:                            20, 34, 2E, 37, 2E, 32, 00 ]
+YAMLBSS:     - name:              .note.GNU-stack
+YAMLBSS:       type:              unknown
+YAMLBSS:       section-choice:    custom-required
+YAMLBSS:       section-name:      .note.GNU-stack
+YAMLBSS:     - name:              relocs-test-bss.c
+YAMLBSS:       definition:        absolute
+YAMLBSS:       value:             0x0
+YAMLBSS: ...
-------------- next part --------------
Index: include/llvm/Object/ELF.h
===================================================================
--- include/llvm/Object/ELF.h	(revision 165886)
+++ include/llvm/Object/ELF.h	(working copy)
@@ -169,6 +169,7 @@
   Elf_Half      st_shndx; // Which section (header table index) it's defined in
   Elf_Addr      st_value; // Value or address associated with the symbol
   Elf_Xword     st_size;  // Size of the symbol
+
 };
 
 template<support::endianness target_endianness, bool is64Bits>
@@ -184,6 +185,17 @@
   void setBindingAndType(unsigned char b, unsigned char t) {
     st_info = (b << 4) + (t & 0x0f);
   }
+
+  bool operator ==(const Elf_Sym_Impl<target_endianness, is64Bits> &rhs) const {
+	if ((this->st_name == rhs.st_name) &&
+            (this->st_info == rhs.st_info) &&
+            (this->st_other == rhs.st_other) &&
+            (this->st_shndx == rhs.st_shndx) &&
+            (this->st_value == rhs.st_value) &&
+            (this->st_size == rhs.st_size))
+          return true;	
+	return false;
+  }
 };
 
 /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
@@ -604,6 +616,8 @@
   error_code      getSymbolName(const Elf_Shdr *section,
                                 const Elf_Sym *Symb,
                                 StringRef &Res) const;
+  error_code      getSymbolIndex(const Elf_Sym *sym,
+				 uint64_t &symbol_index);
   error_code      getSectionName(const Elf_Shdr *section,
                                  StringRef &Res) const;
   const Elf_Dyn  *getDyn(DataRefImpl DynData) const;
@@ -2083,7 +2097,31 @@
   }
 }
 
+// Get the symbol table index in the symtab section given a symbol
+// returns an error code if the symbol is not found
 template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>::getSymbolIndex(const Elf_Sym *sym, uint64_t &sym_index) 
+{
+    error_code ec;
+    for (symbol_iterator si = begin_symbols(),
+                         se = end_symbols(); si != se; si.increment(ec)) {
+        if (ec)
+          report_fatal_error("Cannot find symbols in the symbol table!");
+
+  	DataRefImpl CSym = si->getRawDataRefImpl();
+
+  	const Elf_Sym *current_sym = getSymbol(CSym);
+
+        if (*current_sym == *sym) {
+            sym_index = CSym.d.a;
+            return object_error::success;
+        }
+    }
+    return object_error::parse_failed;
+}
+
+
+template<support::endianness target_endianness, bool is64Bits>
 symbol_iterator ELFObjectFile<target_endianness, is64Bits>
                              ::begin_symbols() const {
   DataRefImpl SymbolData;
-------------- next part --------------
diff --git a/lib/ReaderWriter/ELF/ReaderELF.cpp b/lib/ReaderWriter/ELF/ReaderELF.cpp
index 6fa3025..e463285 100644
--- a/lib/ReaderWriter/ELF/ReaderELF.cpp
+++ b/lib/ReaderWriter/ELF/ReaderELF.cpp
@@ -578,9 +578,9 @@ public:
             || symbol->getType() == llvm::ELF::STT_FUNC
             || symbol->getType() == llvm::ELF::STT_SECTION
             || symbol->getType() == llvm::ELF::STT_FILE
-            || symbol->getType() == llvm::ELF::STT_TLS
             || symbol->getType() == llvm::ELF::STT_COMMON
             || symbol->st_shndx == llvm::ELF::SHN_COMMON) {
+
           sectionSymbols[section].push_back(symbol);
         }
         else {
@@ -606,6 +606,8 @@ public:
         return A->st_value < B->st_value;
       }));
 
+      const Elf_Sym *prev_symbol = NULL;
+
       // i.first is the section the symbol lives in
       for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
 
@@ -643,6 +645,10 @@ public:
 
         unsigned int referenceStart = _references.size();
 
+
+	// maps a symbol index to the relocation map
+	std::map<int64_t, bool> reloc_symmap;
+
         // Only relocations that are inside the domain of the atom are 
         // added.
 
@@ -657,6 +663,10 @@ public:
                           rai, rai->r_offset-(*si)->st_value, nullptr);
 
             _references.push_back(ERef);
+
+            // Insert the target symbol to the map	   
+	    reloc_symmap.insert(std::make_pair(rai->r_info >> 32, true));
+
           }
         }
 
@@ -671,9 +681,36 @@ public:
                          (ri), (ri)->r_offset-(*si)->st_value, nullptr);
 
             _references.push_back(ERef);
+
+            // Insert the target symbol to the map	   
+	    reloc_symmap.insert(std::make_pair(ri->r_info >> 8, true));
           }
         }
 
+        // Add a reference from the current atom to the previous atom
+        if (prev_symbol) {
+           Elf_Rel reference;
+           uint64_t sym_index = -1;
+
+           if ((EC = _objFile->getSymbolIndex(prev_symbol, sym_index)))
+		return;
+
+           reference.r_offset = 0;
+           reference.r_info = 0 | sym_index << 8;
+
+           // Only add the relocation if the symbol is not already part of 
+           // the relocation list
+           if (reloc_symmap.find(sym_index) == reloc_symmap.end()) {
+               auto *ERef = new (_readerStorage.Allocate
+                            <ELFReference<target_endianness, is64Bits> > ())
+                             ELFReference<target_endianness, is64Bits> (
+                            (&reference), 0, nullptr);
+               _references.push_back(ERef);
+           }
+        }
+
+ 	prev_symbol = (*si); 
+
         // Create the DefinedAtom and add it to the list of DefinedAtoms.
         auto *newAtom = new (_readerStorage.Allocate
                        <ELFDefinedAtom<target_endianness, is64Bits> > ()) 
-------------- next part --------------
diff --git a/tools/lld-core/TestingHelpers.hpp b/tools/lld-core/TestingHelpers.hpp
index f6abb4f..b4f81b8 100644
--- a/tools/lld-core/TestingHelpers.hpp
+++ b/tools/lld-core/TestingHelpers.hpp
@@ -271,6 +271,7 @@ struct TestingKindMapping {
 // Table of fixup kinds in YAML documents used for testing
 //
 const TestingKindMapping sKinds[] = {
+    { "none",           0,    true,  false, false},
     { "call32",         2,    true,  false, false},
     { "pcrel32",        3,    false, false, false },
     { "gotLoad32",      7,    false, true,  true },


More information about the llvm-commits mailing list