parent
7bdeab592d
commit
c44bc347cb
|
@ -154,11 +154,20 @@ void LayoutPass::buildFollowOnTable(MutableFile::DefinedAtomRange &range) {
|
|||
} 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(MutableFile::DefinedAtomRange &range) {
|
|||
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(MutableFile::DefinedAtomRange &range) {
|
|||
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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#include <stdio.h>
|
||||
void f(void)
|
||||
{
|
||||
printf("overridden f!\n");
|
||||
}
|
||||
|
||||
void g(void)
|
||||
{
|
||||
printf("overridden g!\n");
|
||||
}
|
Binary file not shown.
|
@ -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;
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,6 @@
|
|||
#include <stdio.h>
|
||||
void f(void)
|
||||
{
|
||||
printf("overridden f!\n");
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,14 @@
|
|||
int fn()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __attribute__((weak)) f()
|
||||
{
|
||||
printf("original f..\n");
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
f();
|
||||
return 0;
|
||||
}
|
Binary file not shown.
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue