diff options
-rw-r--r-- | lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp | 3 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp | 68 | ||||
-rw-r--r-- | lld/test/mach-o/arm64-relocs-errors-delta64-offset.yaml | 65 |
3 files changed, 115 insertions, 21 deletions
diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp index f3a171ea0d6..d6a4926f293 100644 --- a/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp +++ b/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp @@ -482,6 +482,9 @@ std::error_code ArchHandler_arm64::getPairReferenceInfo( *kind = delta64; if (auto ec = atomFromSymbolIndex(reloc2.symbol, target)) return ec; + // The offsets of the 2 relocations must match + if (reloc1.offset != reloc2.offset) + return make_dynamic_error_code("paired relocs must have the same offset"); *addend = (int64_t)*(const little64_t *)fixupContent + offsetInAtom; return std::error_code(); case ((ARM64_RELOC_SUBTRACTOR | rExtern | rLength4) << 16 | diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp index 971c44eba95..649bd542415 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp @@ -598,10 +598,37 @@ std::error_code convertRelocs(const Section §ion, Reference::KindValue kind; std::error_code relocErr; if (handler.isPairedReloc(reloc)) { - // Handle paired relocations together. + // Handle paired relocations together. + const Relocation &reloc2 = *++it; relocErr = handler.getPairReferenceInfo( - reloc, *++it, inAtom, offsetInAtom, fixupAddress, isBig, scatterable, + reloc, reloc2, inAtom, offsetInAtom, fixupAddress, isBig, scatterable, atomByAddr, atomBySymbol, &kind, &target, &addend); + if (relocErr) { + return make_dynamic_error_code( + Twine("bad relocation (") + relocErr.message() + + ") in section " + + section.segmentName + "/" + section.sectionName + + " (r1_address=" + Twine::utohexstr(reloc.offset) + + ", r1_type=" + Twine(reloc.type) + + ", r1_extern=" + Twine(reloc.isExtern) + + ", r1_length=" + Twine((int)reloc.length) + + ", r1_pcrel=" + Twine(reloc.pcRel) + + (!reloc.scattered ? (Twine(", r1_symbolnum=") + + Twine(reloc.symbol)) + : (Twine(", r1_scattered=1, r1_value=") + + Twine(reloc.value))) + + ")" + + ", (r2_address=" + Twine::utohexstr(reloc2.offset) + + ", r2_type=" + Twine(reloc2.type) + + ", r2_extern=" + Twine(reloc2.isExtern) + + ", r2_length=" + Twine((int)reloc2.length) + + ", r2_pcrel=" + Twine(reloc2.pcRel) + + (!reloc2.scattered ? (Twine(", r2_symbolnum=") + + Twine(reloc2.symbol)) + : (Twine(", r2_scattered=1, r2_value=") + + Twine(reloc2.value))) + + ")" ); + } } else { // Use ArchHandler to convert relocation record into information @@ -609,26 +636,25 @@ std::error_code convertRelocs(const Section §ion, relocErr = handler.getReferenceInfo( reloc, inAtom, offsetInAtom, fixupAddress, isBig, atomByAddr, atomBySymbol, &kind, &target, &addend); + if (relocErr) { + return make_dynamic_error_code( + Twine("bad relocation (") + relocErr.message() + + ") in section " + + section.segmentName + "/" + section.sectionName + + " (r_address=" + Twine::utohexstr(reloc.offset) + + ", r_type=" + Twine(reloc.type) + + ", r_extern=" + Twine(reloc.isExtern) + + ", r_length=" + Twine((int)reloc.length) + + ", r_pcrel=" + Twine(reloc.pcRel) + + (!reloc.scattered ? (Twine(", r_symbolnum=") + Twine(reloc.symbol)) + : (Twine(", r_scattered=1, r_value=") + + Twine(reloc.value))) + + ")" ); + } } - if (relocErr) { - return make_dynamic_error_code( - Twine("bad relocation (") + relocErr.message() - + ") in section " - + section.segmentName + "/" + section.sectionName - + " (r_address=" + Twine::utohexstr(reloc.offset) - + ", r_type=" + Twine(reloc.type) - + ", r_extern=" + Twine(reloc.isExtern) - + ", r_length=" + Twine((int)reloc.length) - + ", r_pcrel=" + Twine(reloc.pcRel) - + (!reloc.scattered ? (Twine(", r_symbolnum=") + Twine(reloc.symbol)) - : (Twine(", r_scattered=1, r_value=") - + Twine(reloc.value))) - + ")" ); - } else { - // Instantiate an lld::Reference object and add to its atom. - inAtom->addReference(offsetInAtom, kind, target, addend, - handler.kindArch()); - } + // Instantiate an lld::Reference object and add to its atom. + inAtom->addReference(offsetInAtom, kind, target, addend, + handler.kindArch()); } return std::error_code(); diff --git a/lld/test/mach-o/arm64-relocs-errors-delta64-offset.yaml b/lld/test/mach-o/arm64-relocs-errors-delta64-offset.yaml new file mode 100644 index 00000000000..09c59612489 --- /dev/null +++ b/lld/test/mach-o/arm64-relocs-errors-delta64-offset.yaml @@ -0,0 +1,65 @@ +# RUN: not lld -flavor darwin -arch arm64 %s -r \ +# RUN: 2> %t.err +# RUN: FileCheck %s < %t.err + + +--- !mach-o +arch: arm64 +file-type: MH_OBJECT +flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ] +sections: + - segment: __TEXT + section: __text + type: S_REGULAR + attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ] + alignment: 4 + address: 0x0000000000000000 + content: [ 0xFF, 0x83, 0x00, 0xD1, 0xE0, 0x0B, 0x00, 0xF9, + 0x08, 0x00, 0x40, 0xB9, 0x08, 0x0D, 0x00, 0x71, + 0x08, 0x09, 0x00, 0x71, 0xE8, 0x0F, 0x00, 0xB9, + 0xC8, 0x00, 0x00, 0x54, 0x01, 0x00, 0x00, 0x14, + 0xE8, 0x03, 0x00, 0x32, 0x08, 0x01, 0x00, 0x12, + 0xE8, 0x7F, 0x00, 0x39, 0x02, 0x00, 0x00, 0x14 ] + - segment: __DATA + section: __data + type: S_REGULAR + attributes: [ ] + alignment: 3 + address: 0x000000000001C348 + content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ] + relocations: + +# Make sure that the offsets of the subtractor and unsigned both match. +# CHECK: bad relocation (paired relocs must have the same offset) in section __DATA/__data (r1_address=1, r1_type=1, r1_extern=1, r1_length=3, r1_pcrel=0, r1_symbolnum=1), (r2_address=0, r2_type=0, r2_extern=1, r2_length=3, r2_pcrel=0, r2_symbolnum=1) + - offset: 0x00000001 + type: ARM64_RELOC_SUBTRACTOR + length: 3 + pc-rel: false + extern: true + symbol: 1 + - offset: 0x00000000 + type: ARM64_RELOC_UNSIGNED + length: 3 + pc-rel: false + extern: true + symbol: 1 +global-symbols: + - name: _f1 + type: N_SECT + sect: 2 + value: 0x000000000001C348 + - name: _f2 + type: N_SECT + sect: 1 + value: 0x0000000000000010 + - name: _f3 + type: N_SECT + sect: 1 + value: 0x0000000000000020 |