Verify that macho-o delta64 relocs have the same offset.

The delta64 relocation is represented as the pair ARM64_RELOC_SUBTRACTOR and ARM64_RELOC_UNSIGNED.

Those should always have the same offset, so this adds a check and tests to ensure this is the case.

Also updated the error printing in this case to shows both relocs when erroring on pair.

llvm-svn: 255274
This commit is contained in:
Pete Cooper 2015-12-10 18:48:52 +00:00
parent 8aa0b80ec7
commit 5cd12580fd
3 changed files with 115 additions and 21 deletions

View File

@ -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 |

View File

@ -598,10 +598,37 @@ std::error_code convertRelocs(const Section &section,
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 &section,
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();

View File

@ -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