[lld] r176583 - [ELF] Order weak symbols properly
Shankar Easwaran
shankare at codeaurora.org
Wed Mar 6 13:59:28 PST 2013
Author: shankare
Date: Wed Mar 6 15:59:27 2013
New Revision: 176583
URL: http://llvm.org/viewvc/llvm-project?rev=176583&view=rev
Log:
[ELF] Order weak symbols properly
Added:
lld/trunk/test/elf/X86_64/
lld/trunk/test/elf/X86_64/Inputs/
lld/trunk/test/elf/X86_64/Inputs/multi-ovrd.c
lld/trunk/test/elf/X86_64/Inputs/multi-ovrd.o (with props)
lld/trunk/test/elf/X86_64/Inputs/multi-weak.c
lld/trunk/test/elf/X86_64/Inputs/multi-weak.o (with props)
lld/trunk/test/elf/X86_64/Inputs/ovrd.c
lld/trunk/test/elf/X86_64/Inputs/ovrd.o (with props)
lld/trunk/test/elf/X86_64/Inputs/weak-zero-sized.o (with props)
lld/trunk/test/elf/X86_64/Inputs/weak.c
lld/trunk/test/elf/X86_64/Inputs/weak.o (with props)
lld/trunk/test/elf/X86_64/multi-weak-override.test
lld/trunk/test/elf/X86_64/multi-weak-syms-order.test
lld/trunk/test/elf/X86_64/weak-override.test
lld/trunk/test/elf/X86_64/weak-zero-sized.test
Modified:
lld/trunk/lib/Passes/LayoutPass.cpp
lld/trunk/lib/ReaderWriter/ELF/File.h
Modified: lld/trunk/lib/Passes/LayoutPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Passes/LayoutPass.cpp?rev=176583&r1=176582&r2=176583&view=diff
==============================================================================
--- lld/trunk/lib/Passes/LayoutPass.cpp (original)
+++ lld/trunk/lib/Passes/LayoutPass.cpp Wed Mar 6 15:59:27 2013
@@ -154,11 +154,20 @@ void LayoutPass::buildFollowOnTable(Muta
} else { // the atom could be part of chain already
// Get to the root of the chain
const DefinedAtom *a = _followOnRoots[targetAtom];
+ const DefinedAtom *targetPrevAtom = nullptr;
+
+ // If the size of the atom is 0, and the target
+ // is already part of a chain, lets bring the current
+ // atom into the chain
+ size_t currentAtomSize = (*ai).size();
+
// Lets add to the chain only if the atoms that
// appear before the targetAtom in the chain
// are of size 0
bool foundNonZeroSizeAtom = false;
while (true) {
+ targetPrevAtom = a;
+
// Set all the follow on's for the targetAtom to be
// the current root
AtomToAtomT::iterator targetFollowOnAtomsIter =
@@ -169,12 +178,14 @@ void LayoutPass::buildFollowOnTable(Muta
else
break;
- if (a->size() != 0) {
+ if ((a->size() != 0) && (currentAtomSize != 0)) {
foundNonZeroSizeAtom = true;
break;
}
+
if (a == targetAtom)
break;
+
} // while true
if (foundNonZeroSizeAtom) {
// TODO: print warning that an impossible layout
@@ -183,20 +194,29 @@ void LayoutPass::buildFollowOnTable(Muta
break;
}
- _followOnNexts[ai] = _followOnRoots[targetAtom];
- // Set the root of all atoms in the
- a = _followOnRoots[targetAtom];
- while (true) {
- _followOnRoots[a] = _followOnRoots[ai];
- // Set all the follow on's for the targetAtom to be
- // the current root
- AtomToAtomT::iterator targetFollowOnAtomsIter =
- _followOnNexts.find(a);
- if (targetFollowOnAtomsIter != _followOnNexts.end())
- a = targetFollowOnAtomsIter->second;
- else
- break;
- } // while true
+ // If the atom is a zero sized atom, then make the target
+ // follow the zero sized atom, as the zero sized atom may be
+ // a weak symbol
+ if ((currentAtomSize == 0) && (targetPrevAtom)) {
+ _followOnNexts[targetPrevAtom] = ai;
+ _followOnRoots[ai] = _followOnRoots[targetPrevAtom];
+ _followOnNexts[ai] = targetAtom;
+ } else {
+ _followOnNexts[ai] = _followOnRoots[targetAtom];
+ // Set the root of all atoms in the
+ a = _followOnRoots[targetAtom];
+ while (true) {
+ _followOnRoots[a] = _followOnRoots[ai];
+ // Set all the follow on's for the targetAtom to be
+ // the current root
+ AtomToAtomT::iterator targetFollowOnAtomsIter =
+ _followOnNexts.find(a);
+ if (targetFollowOnAtomsIter != _followOnNexts.end())
+ a = targetFollowOnAtomsIter->second;
+ else
+ break;
+ } // while true
+ } // end else (currentAtomSize != 0)
} // end else
} // else
} // kindLayoutAfter
Modified: lld/trunk/lib/ReaderWriter/ELF/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/File.h?rev=176583&r1=176582&r2=176583&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/File.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/File.h Wed Mar 6 15:59:27 2013
@@ -346,6 +346,11 @@ public:
}
ELFDefinedAtom<ELFT> *previous_atom = nullptr;
+ // Don't allocate content to a weak symbol, as they may be merged away.
+ // Create an anonymous atom to hold the data.
+ ELFDefinedAtom<ELFT> *anonAtom = nullptr;
+ ELFReference<ELFT> *anonPrecededBy = nullptr;
+ ELFReference<ELFT> *anonFollowedBy = nullptr;
// i.first is the section the symbol lives in
for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
@@ -380,9 +385,29 @@ public:
contentSize = isCommon ? 0 : (*(si + 1))->st_value - (*si)->st_value;
}
+ // Check to see if we need to add the FollowOn Reference
+ // We dont want to do for symbols that are
+ // a) common symbols
+ ELFReference<ELFT> *followOn = nullptr;
+ if (!isCommon && previous_atom) {
+ // Replace the followon atom with the anonymous
+ // atom that we created, so that the next symbol
+ // that we create is a followon from the anonymous
+ // atom
+ if (!anonFollowedBy) {
+ followOn = new (_readerStorage)
+ ELFReference<ELFT>(lld::Reference::kindLayoutAfter);
+ previous_atom->addReference(followOn);
+ }
+ else
+ followOn = anonFollowedBy;
+ }
+
// Don't allocate content to a weak symbol, as they may be merged away.
// Create an anonymous atom to hold the data.
- ELFDefinedAtom<ELFT> *anonAtom = nullptr;
+ anonAtom = nullptr;
+ anonPrecededBy = nullptr;
+ anonFollowedBy = nullptr;
if ((*si)->getBinding() == llvm::ELF::STB_WEAK && contentSize != 0) {
// Create a new non-weak ELF symbol.
auto sym = new (_readerStorage) Elf_Sym;
@@ -392,26 +417,26 @@ public:
"", sectionName, sym, i.first,
ArrayRef<uint8_t>((uint8_t *)sectionContents.data() +
(*si)->st_value, contentSize));
+
+ // If this is the last atom, lets not create a followon
+ // reference
+ if ((si + 1) != se)
+ anonFollowedBy = new (_readerStorage)
+ ELFReference<ELFT>(lld::Reference::kindLayoutAfter);
+ anonPrecededBy = new (_readerStorage)
+ ELFReference<ELFT>(lld::Reference::kindLayoutBefore);
+ // Add the references to the anonymous atom that we created
+ if (anonFollowedBy)
+ anonAtom->addReference(anonFollowedBy);
+ anonAtom->addReference(anonPrecededBy);
+ if (previous_atom)
+ anonPrecededBy->setTarget(previous_atom);
contentSize = 0;
}
ArrayRef<uint8_t> symbolData = ArrayRef<uint8_t>(
(uint8_t *)sectionContents.data() + (*si)->st_value, contentSize);
- // Check to see if we need to add the FollowOn Reference
- // We dont want to do for symbols that are
- // a) common symbols
- // so, lets add a follow-on reference from the previous atom to the
- // current atom as well as lets add a preceded-by reference from the
- // current atom to the previous atom, so that the previous atom
- // is not removed in any case
- ELFReference<ELFT> *followOn = nullptr;
- if (!isCommon && previous_atom) {
- followOn = new (_readerStorage)
- ELFReference<ELFT>(lld::Reference::kindLayoutAfter);
- previous_atom->addReference(followOn);
- }
-
// If the linker finds that a section has global atoms that are in a
// mergeable section, treat them as defined atoms as they shouldnt be
// merged away as well as these symbols have to be part of symbol
@@ -434,11 +459,24 @@ public:
auto newAtom = createDefinedAtomAndAssignRelocations(
symbolName, sectionName, *si, i.first, symbolData);
- // If we are inserting a followOn reference, lets add a precededBy
- // reference too
+ // If the atom was a weak symbol, lets create a followon
+ // reference to the anonymous atom that we created
+ if ((*si)->getBinding() == llvm::ELF::STB_WEAK && anonAtom) {
+ ELFReference<ELFT> *wFollowedBy = new (_readerStorage)
+ ELFReference<ELFT>(lld::Reference::kindLayoutAfter);
+ wFollowedBy->setTarget(anonAtom);
+ newAtom->addReference(wFollowedBy);
+ }
+
if (followOn) {
ELFReference<ELFT> *precededby = nullptr;
- followOn->setTarget(newAtom);
+ // Set the followon atom to the weak atom
+ // that we have created, so that they would
+ // alias when the file gets written
+ if (anonAtom)
+ followOn->setTarget(anonAtom);
+ else
+ followOn->setTarget(newAtom);
// Add a preceded by reference only if the current atom is not a
// weak atom
if ((*si)->getBinding() != llvm::ELF::STB_WEAK) {
@@ -451,7 +489,9 @@ public:
// The previous atom is always the atom created before unless
// the atom is a weak atom
- if ((*si)->getBinding() != llvm::ELF::STB_WEAK)
+ if (anonAtom)
+ previous_atom = anonAtom;
+ else
previous_atom = newAtom;
_definedAtoms._atoms.push_back(newAtom);
Added: lld/trunk/test/elf/X86_64/Inputs/multi-ovrd.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/multi-ovrd.c?rev=176583&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/Inputs/multi-ovrd.c (added)
+++ lld/trunk/test/elf/X86_64/Inputs/multi-ovrd.c Wed Mar 6 15:59:27 2013
@@ -0,0 +1,10 @@
+#include <stdio.h>
+void f(void)
+{
+ printf("overridden f!\n");
+}
+
+void g(void)
+{
+ printf("overridden g!\n");
+}
Added: lld/trunk/test/elf/X86_64/Inputs/multi-ovrd.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/multi-ovrd.o?rev=176583&view=auto
==============================================================================
Binary file - no diff available.
Propchange: lld/trunk/test/elf/X86_64/Inputs/multi-ovrd.o
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: lld/trunk/test/elf/X86_64/Inputs/multi-weak.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/multi-weak.c?rev=176583&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/Inputs/multi-weak.c (added)
+++ lld/trunk/test/elf/X86_64/Inputs/multi-weak.c Wed Mar 6 15:59:27 2013
@@ -0,0 +1,20 @@
+int fn()
+{
+ return 0;
+}
+
+void __attribute__((weak)) f()
+{
+ printf("original f..\n");
+}
+
+void __attribute__((weak)) g()
+{
+ printf("original f..\n");
+}
+
+int main(void)
+{
+ f();
+ return 0;
+}
Added: lld/trunk/test/elf/X86_64/Inputs/multi-weak.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/multi-weak.o?rev=176583&view=auto
==============================================================================
Binary file - no diff available.
Propchange: lld/trunk/test/elf/X86_64/Inputs/multi-weak.o
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: lld/trunk/test/elf/X86_64/Inputs/ovrd.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/ovrd.c?rev=176583&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/Inputs/ovrd.c (added)
+++ lld/trunk/test/elf/X86_64/Inputs/ovrd.c Wed Mar 6 15:59:27 2013
@@ -0,0 +1,6 @@
+#include <stdio.h>
+void f(void)
+{
+ printf("overridden f!\n");
+}
+
Added: lld/trunk/test/elf/X86_64/Inputs/ovrd.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/ovrd.o?rev=176583&view=auto
==============================================================================
Binary file - no diff available.
Propchange: lld/trunk/test/elf/X86_64/Inputs/ovrd.o
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: lld/trunk/test/elf/X86_64/Inputs/weak-zero-sized.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/weak-zero-sized.o?rev=176583&view=auto
==============================================================================
Binary file - no diff available.
Propchange: lld/trunk/test/elf/X86_64/Inputs/weak-zero-sized.o
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: lld/trunk/test/elf/X86_64/Inputs/weak.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/weak.c?rev=176583&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/Inputs/weak.c (added)
+++ lld/trunk/test/elf/X86_64/Inputs/weak.c Wed Mar 6 15:59:27 2013
@@ -0,0 +1,14 @@
+int fn()
+{
+ return 0;
+}
+
+void __attribute__((weak)) f()
+{
+ printf("original f..\n");
+}
+int main(void)
+{
+ f();
+ return 0;
+}
Added: lld/trunk/test/elf/X86_64/Inputs/weak.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/weak.o?rev=176583&view=auto
==============================================================================
Binary file - no diff available.
Propchange: lld/trunk/test/elf/X86_64/Inputs/weak.o
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: lld/trunk/test/elf/X86_64/multi-weak-override.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/multi-weak-override.test?rev=176583&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/multi-weak-override.test (added)
+++ lld/trunk/test/elf/X86_64/multi-weak-override.test Wed Mar 6 15:59:27 2013
@@ -0,0 +1,15 @@
+# Test for weak symbol getting overridden
+RUN: lld-core -reader ELF -writer ELF -arch x86_64 %p/Inputs/multi-weak.o \
+RUN: %p/Inputs/multi-ovrd.o -o %t
+RUN: llvm-nm -n %t | FileCheck -check-prefix=WEAKORDER %s
+RUN: lld-core -reader ELF -arch x86_64 %p/Inputs/multi-weak.o \
+RUN: %p/Inputs/multi-ovrd.o -layout-pass=true -o %t2
+RUN: FileCheck -check-prefix=WEAKATOMSORDER %s < %t2
+
+WEAKORDER: 0040011c T f
+WEAKORDER: 0040012c T g
+
+WEAKATOMSORDER: - ref-name: L002
+WEAKATOMSORDER: - ref-name: L003
+WEAKATOMSORDER: - name: f
+WEAKATOMSORDER: - name: g
Added: lld/trunk/test/elf/X86_64/multi-weak-syms-order.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/multi-weak-syms-order.test?rev=176583&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/multi-weak-syms-order.test (added)
+++ lld/trunk/test/elf/X86_64/multi-weak-syms-order.test Wed Mar 6 15:59:27 2013
@@ -0,0 +1,19 @@
+# Test for weak symbol getting overridden
+RUN: lld-core -reader ELF -writer ELF -arch x86_64 %p/Inputs/multi-weak.o \
+RUN: -o %t
+RUN: llvm-nm -n %t | FileCheck -check-prefix=WEAKORDER %s
+RUN: lld-core -reader ELF -arch x86_64 %p/Inputs/multi-weak.o \
+RUN: -layout-pass=true -o %t2
+RUN: FileCheck -check-prefix=WEAKATOMSORDER %s < %t2
+
+WEAKORDER: 004000c0 T fn
+WEAKORDER: 004000cb T .text
+WEAKORDER: 004000cb T f
+WEAKORDER: 004000db T .text
+WEAKORDER: 004000db T g
+WEAKORDER: 004000eb T main
+
+WEAKATOMSORDER: - name: f
+WEAKATOMSORDER: - ref-name: L004
+WEAKATOMSORDER: - name: g
+WEAKATOMSORDER: - ref-name: L005
Added: lld/trunk/test/elf/X86_64/weak-override.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/weak-override.test?rev=176583&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/weak-override.test (added)
+++ lld/trunk/test/elf/X86_64/weak-override.test Wed Mar 6 15:59:27 2013
@@ -0,0 +1,56 @@
+# Test for weak symbol getting overridden
+RUN: lld-core -reader ELF -writer ELF -arch x86_64 %p/Inputs/weak.o \
+RUN: %p/Inputs/ovrd.o -o %t
+RUN: llvm-nm %t | FileCheck -check-prefix=WEAKORDER %s
+RUN: lld-core -reader ELF -arch x86_64 %p/Inputs/weak.o \
+RUN: %p/Inputs/ovrd.o -layout-pass=true -o %t2
+RUN: FileCheck -check-prefix=WEAKATOMSORDER %s < %t2
+
+WEAKORDER: 004000fc T f
+
+WEAKATOMSORDER: - name: .text
+WEAKATOMSORDER: references:
+WEAKATOMSORDER: - kind: layout-after
+WEAKATOMSORDER: offset: 0
+WEAKATOMSORDER: target: fn
+WEAKATOMSORDER: - name: fn
+WEAKATOMSORDER: references:
+WEAKATOMSORDER: - kind: layout-after
+WEAKATOMSORDER: offset: 0
+WEAKATOMSORDER: target: L001
+WEAKATOMSORDER: - ref-name: L001
+WEAKATOMSORDER: scope: global
+WEAKATOMSORDER: content: [ 55, 48, 89, E5, BF, 00, 00, 00, 00, E8, 00, 00,
+WEAKATOMSORDER: 00, 00, 5D, C3 ]
+WEAKATOMSORDER: references:
+WEAKATOMSORDER: - kind: layout-after
+WEAKATOMSORDER: offset: 0
+WEAKATOMSORDER: target: main
+WEAKATOMSORDER: - kind: layout-before
+WEAKATOMSORDER: offset: 0
+WEAKATOMSORDER: target: fn
+WEAKATOMSORDER: - name: main
+WEAKATOMSORDER: scope: global
+WEAKATOMSORDER: content: [ 55, 48, 89, E5, B8, 00, 00, 00, 00, E8, 00, 00,
+WEAKATOMSORDER: 00, 00, B8, 00, 00, 00, 00, 5D, C3 ]
+WEAKATOMSORDER: references:
+WEAKATOMSORDER: - kind: call32
+WEAKATOMSORDER: offset: 10
+WEAKATOMSORDER: target: f
+WEAKATOMSORDER: addend: -4
+WEAKATOMSORDER: - kind: layout-before
+WEAKATOMSORDER: offset: 0
+WEAKATOMSORDER: target: L001
+WEAKATOMSORDER: - name: .text
+WEAKATOMSORDER: section-name: .text
+WEAKATOMSORDER: references:
+WEAKATOMSORDER: - kind: layout-after
+WEAKATOMSORDER: offset: 0
+WEAKATOMSORDER: target: f
+WEAKATOMSORDER: - name: f
+WEAKATOMSORDER: scope: global
+WEAKATOMSORDER: content: [ 55, 48, 89, E5, BF, 00, 00, 00, 00, E8, 00, 00,
+WEAKATOMSORDER: 00, 00, 5D, C3 ]
+WEAKATOMSORDER: references:
+WEAKATOMSORDER: - kind: layout-before
+WEAKATOMSORDER: offset: 0
Added: lld/trunk/test/elf/X86_64/weak-zero-sized.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/weak-zero-sized.test?rev=176583&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/weak-zero-sized.test (added)
+++ lld/trunk/test/elf/X86_64/weak-zero-sized.test Wed Mar 6 15:59:27 2013
@@ -0,0 +1,34 @@
+# Test for zero sized weak atoms, there is only a single weak atom
+RUN: lld-core -reader ELF -writer ELF -arch x86_64 %p/Inputs/weak-zero-sized.o \
+RUN: -o %t
+RUN: llvm-nm %t | FileCheck -check-prefix=WEAKORDER %s
+RUN: lld-core -reader ELF -arch x86_64 %p/Inputs/weak-zero-sized.o \
+RUN: -layout-pass=true -o %t2
+RUN: FileCheck -check-prefix=WEAKATOMSORDER %s < %t2
+
+WEAKORDER: 004000b0 T _start
+
+WEAKATOMSORDER: - name: .text
+WEAKATOMSORDER: alignment: 2^2
+WEAKATOMSORDER: section-name: .text
+WEAKATOMSORDER: - kind: layout-after
+WEAKATOMSORDER: offset: 0
+WEAKATOMSORDER: target: L001
+WEAKATOMSORDER: - name: _start
+WEAKATOMSORDER: scope: global
+WEAKATOMSORDER: merge: as-weak
+WEAKATOMSORDER: alignment: 2^2
+WEAKATOMSORDER: section-name: .text
+WEAKATOMSORDER: references:
+WEAKATOMSORDER: - kind: layout-after
+WEAKATOMSORDER: offset: 0
+WEAKATOMSORDER: target: L001
+WEAKATOMSORDER: - ref-name: L001
+WEAKATOMSORDER: scope: global
+WEAKATOMSORDER: content: [ C3 ]
+WEAKATOMSORDER: alignment: 2^2
+WEAKATOMSORDER: section-name: .text
+WEAKATOMSORDER: references:
+WEAKATOMSORDER: - kind: layout-before
+WEAKATOMSORDER: offset: 0
+WEAKATOMSORDER: target: .text
More information about the llvm-commits
mailing list