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:
112112 /// info in final executables.
113113 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
115119 /// Returns true if the specified relocation is paired to the next relocation.
116120 virtual bool isPairedReloc(const normalized::Relocation &) = 0;
117121
deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp+4
......@@ -67,6 +67,10 @@ public:
6767 return invalid;
6868 }
6969
70 Reference::KindValue lazyImmediateLocationKind() override {
71 return lazyImmediateLocation;
72 }
73
7074 Reference::KindValue pointerKind() override {
7175 return invalid;
7276 }
deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp+4
......@@ -127,6 +127,10 @@ public:
127127 return pointer64;
128128 }
129129
130 Reference::KindValue lazyImmediateLocationKind() override {
131 return lazyImmediateLocation;
132 }
133
130134 uint32_t dwarfCompactUnwindType() override {
131135 return 0x03000000;
132136 }
deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp+4
......@@ -70,6 +70,10 @@ public:
7070 return delta32;
7171 }
7272
73 Reference::KindValue lazyImmediateLocationKind() override {
74 return lazyImmediateLocation;
75 }
76
7377 Reference::KindValue unwindRefToEhFrameKind() override {
7478 return invalid;
7579 }
deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp+4
......@@ -116,6 +116,10 @@ public:
116116 return unwindFDEToFunction;
117117 }
118118
119 Reference::KindValue lazyImmediateLocationKind() override {
120 return lazyImmediateLocation;
121 }
122
119123 Reference::KindValue unwindRefToEhFrameKind() override {
120124 return unwindInfoToEhFrame;
121125 }
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp+57
......@@ -172,6 +172,8 @@ private:
172172 SymbolScope &symbolScope);
173173 void appendSection(SectionInfo *si, NormalizedFile &file);
174174 uint32_t sectionIndexForAtom(const Atom *atom);
175 void fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset,
176 NormalizedFile &file);
175177
176178 typedef llvm::DenseMap<const Atom*, uint32_t> AtomToIndex;
177179 struct AtomAndIndex { const Atom *atom; uint32_t index; SymbolScope scope; };
......@@ -1423,6 +1425,8 @@ void Util::addRebaseAndBindingInfo(const lld::File &atomFile,
14231425
14241426 uint8_t segmentIndex;
14251427 uint64_t segmentStartAddr;
1428 uint32_t offsetInBindInfo = 0;
1429
14261430 for (SectionInfo *sect : _sectionInfos) {
14271431 segIndexForSection(sect, segmentIndex, segmentStartAddr);
14281432 for (const AtomInfo &info : sect->atomsAndOffsets) {
......@@ -1467,6 +1471,59 @@ void Util::addRebaseAndBindingInfo(const lld::File &atomFile,
14671471 bind.symbolName = targ->name();
14681472 bind.addend = ref->addend();
14691473 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;
14701527 }
14711528 }
14721529 }
deps/lld/test/mach-o/lazy-bind-x86_64.yaml+2-2
......@@ -80,8 +80,8 @@ undefined-symbols:
8080
8181# CHECK-HELPERS:Disassembly of section __TEXT,__stub_helper:
8282# CHECK-HELPERS: 68 00 00 00 00 pushq $0
83# CHECK-HELPERS: 68 10 00 00 00 pushq $16
84# CHECK-HELPERS: 68 20 00 00 00 pushq $32
83# CHECK-HELPERS: 68 0b 00 00 00 pushq $11
84# CHECK-HELPERS: 68 16 00 00 00 pushq $22
8585
8686# Make sure the stub helper is correctly aligned
8787# CHECK-DYLIBS: sectname __stub_helper