[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