authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-01 12:11:55-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-01 12:11:55-05:00
loga206ef34bbbc46017e471063a4a1832c1ddafb0a
tree43cd4beb078306f2f202e47d9d38c55be102e5e6
parentddca67a2b94f68985789fc8254fd1326e26269f6

LLD patch: Fix the ASM code generated for __stub_helpers section

This applies 93ca847862af07632197dcf2d8a68b9b27a26d7a from the llvm-project git monorepo to the embedded LLD.

7 files changed, 79 insertions(+), 2 deletions(-)

deps/lld/lib/ReaderWriter/MachO/ArchHandler.h+4
...@@ -112,6 +112,10 @@ public:...@@ -112,6 +112,10 @@ public:
112 /// info in final executables.112 /// info in final executables.
113 virtual bool isLazyPointer(const Reference &);113 virtual bool isLazyPointer(const Reference &);
114114
115 /// Reference from an __stub_helper entry to the required offset of the
116 /// lazy bind commands.
117 virtual Reference::KindValue lazyImmediateLocationKind() = 0;
118
115 /// Returns true if the specified relocation is paired to the next relocation.119 /// Returns true if the specified relocation is paired to the next relocation.
116 virtual bool isPairedReloc(const normalized::Relocation &) = 0;120 virtual bool isPairedReloc(const normalized::Relocation &) = 0;
117121
deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp+4
...@@ -67,6 +67,10 @@ public:...@@ -67,6 +67,10 @@ public:
67 return invalid;67 return invalid;
68 }68 }
6969
70 Reference::KindValue lazyImmediateLocationKind() override {
71 return lazyImmediateLocation;
72 }
73
70 Reference::KindValue pointerKind() override {74 Reference::KindValue pointerKind() override {
71 return invalid;75 return invalid;
72 }76 }
deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp+4
...@@ -127,6 +127,10 @@ public:...@@ -127,6 +127,10 @@ public:
127 return pointer64;127 return pointer64;
128 }128 }
129129
130 Reference::KindValue lazyImmediateLocationKind() override {
131 return lazyImmediateLocation;
132 }
133
130 uint32_t dwarfCompactUnwindType() override {134 uint32_t dwarfCompactUnwindType() override {
131 return 0x03000000;135 return 0x03000000;
132 }136 }
deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp+4
...@@ -70,6 +70,10 @@ public:...@@ -70,6 +70,10 @@ public:
70 return delta32;70 return delta32;
71 }71 }
7272
73 Reference::KindValue lazyImmediateLocationKind() override {
74 return lazyImmediateLocation;
75 }
76
73 Reference::KindValue unwindRefToEhFrameKind() override {77 Reference::KindValue unwindRefToEhFrameKind() override {
74 return invalid;78 return invalid;
75 }79 }
deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp+4
...@@ -116,6 +116,10 @@ public:...@@ -116,6 +116,10 @@ public:
116 return unwindFDEToFunction;116 return unwindFDEToFunction;
117 }117 }
118118
119 Reference::KindValue lazyImmediateLocationKind() override {
120 return lazyImmediateLocation;
121 }
122
119 Reference::KindValue unwindRefToEhFrameKind() override {123 Reference::KindValue unwindRefToEhFrameKind() override {
120 return unwindInfoToEhFrame;124 return unwindInfoToEhFrame;
121 }125 }
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp+57
...@@ -172,6 +172,8 @@ private:...@@ -172,6 +172,8 @@ private:
172 SymbolScope &symbolScope);172 SymbolScope &symbolScope);
173 void appendSection(SectionInfo *si, NormalizedFile &file);173 void appendSection(SectionInfo *si, NormalizedFile &file);
174 uint32_t sectionIndexForAtom(const Atom *atom);174 uint32_t sectionIndexForAtom(const Atom *atom);
175 void fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset,
176 NormalizedFile &file);
175177
176 typedef llvm::DenseMap<const Atom*, uint32_t> AtomToIndex;178 typedef llvm::DenseMap<const Atom*, uint32_t> AtomToIndex;
177 struct AtomAndIndex { const Atom *atom; uint32_t index; SymbolScope scope; };179 struct AtomAndIndex { const Atom *atom; uint32_t index; SymbolScope scope; };
...@@ -1423,6 +1425,8 @@ void Util::addRebaseAndBindingInfo(const lld::File &atomFile,...@@ -1423,6 +1425,8 @@ void Util::addRebaseAndBindingInfo(const lld::File &atomFile,
14231425
1424 uint8_t segmentIndex;1426 uint8_t segmentIndex;
1425 uint64_t segmentStartAddr;1427 uint64_t segmentStartAddr;
1428 uint32_t offsetInBindInfo = 0;
1429
1426 for (SectionInfo *sect : _sectionInfos) {1430 for (SectionInfo *sect : _sectionInfos) {
1427 segIndexForSection(sect, segmentIndex, segmentStartAddr);1431 segIndexForSection(sect, segmentIndex, segmentStartAddr);
1428 for (const AtomInfo &info : sect->atomsAndOffsets) {1432 for (const AtomInfo &info : sect->atomsAndOffsets) {
...@@ -1467,6 +1471,59 @@ void Util::addRebaseAndBindingInfo(const lld::File &atomFile,...@@ -1467,6 +1471,59 @@ void Util::addRebaseAndBindingInfo(const lld::File &atomFile,
1467 bind.symbolName = targ->name();1471 bind.symbolName = targ->name();
1468 bind.addend = ref->addend();1472 bind.addend = ref->addend();
1469 nFile.lazyBindingInfo.push_back(bind);1473 nFile.lazyBindingInfo.push_back(bind);
1474
1475 // Now that we know the segmentOffset and the ordinal attribute,
1476 // we can fix the helper's code
1477
1478 fixLazyReferenceImm(atom, offsetInBindInfo, nFile);
1479
1480 // 5 bytes for opcodes + variable sizes (target name + \0 and offset
1481 // encode's size)
1482 offsetInBindInfo +=
1483 6 + targ->name().size() + llvm::getULEB128Size(bind.segOffset);
1484 if (bind.ordinal > BIND_IMMEDIATE_MASK)
1485 offsetInBindInfo += llvm::getULEB128Size(bind.ordinal);
1486 }
1487 }
1488 }
1489 }
1490}
1491
1492void Util::fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset,
1493 NormalizedFile &file) {
1494 for (const auto &ref : *atom) {
1495 const DefinedAtom *da = dyn_cast<DefinedAtom>(ref->target());
1496 if (da == nullptr)
1497 return;
1498
1499 const Reference *helperRef = nullptr;
1500 for (const Reference *hr : *da) {
1501 if (hr->kindValue() == _archHandler.lazyImmediateLocationKind()) {
1502 helperRef = hr;
1503 break;
1504 }
1505 }
1506 if (helperRef == nullptr)
1507 continue;
1508
1509 // TODO: maybe get the fixed atom content from _archHandler ?
1510 for (SectionInfo *sectInfo : _sectionInfos) {
1511 for (const AtomInfo &atomInfo : sectInfo->atomsAndOffsets) {
1512 if (atomInfo.atom == helperRef->target()) {
1513 auto sectionContent =
1514 file.sections[sectInfo->normalizedSectionIndex].content;
1515 uint8_t *rawb =
1516 file.ownedAllocations.Allocate<uint8_t>(sectionContent.size());
1517 llvm::MutableArrayRef<uint8_t> newContent{rawb,
1518 sectionContent.size()};
1519 std::copy(sectionContent.begin(), sectionContent.end(),
1520 newContent.begin());
1521 llvm::support::ulittle32_t *loc =
1522 reinterpret_cast<llvm::support::ulittle32_t *>(
1523 &newContent[atomInfo.offsetInSection +
1524 helperRef->offsetInAtom()]);
1525 *loc = offset;
1526 file.sections[sectInfo->normalizedSectionIndex].content = newContent;
1470 }1527 }
1471 }1528 }
1472 }1529 }
deps/lld/test/mach-o/lazy-bind-x86_64.yaml+2-2
...@@ -80,8 +80,8 @@ undefined-symbols:...@@ -80,8 +80,8 @@ undefined-symbols:
8080
81# CHECK-HELPERS:Disassembly of section __TEXT,__stub_helper:81# CHECK-HELPERS:Disassembly of section __TEXT,__stub_helper:
82# CHECK-HELPERS: 68 00 00 00 00 pushq $082# CHECK-HELPERS: 68 00 00 00 00 pushq $0
83# CHECK-HELPERS: 68 10 00 00 00 pushq $1683# CHECK-HELPERS: 68 0b 00 00 00 pushq $11
84# CHECK-HELPERS: 68 20 00 00 00 pushq $3284# CHECK-HELPERS: 68 16 00 00 00 pushq $22
8585
86# Make sure the stub helper is correctly aligned86# Make sure the stub helper is correctly aligned
87# CHECK-DYLIBS: sectname __stub_helper87# CHECK-DYLIBS: sectname __stub_helper