mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 07:31:28 +00:00
[lld-macho] Don't emit rebase opcodes for subtractor minuend relocs
Also add a few asserts to verify that we are indeed handling an UNSIGNED relocation as the minued. I haven't made it an actual user-facing error since I don't think llvm-mc is capable of generating SUBTRACTOR relocations without an associated UNSIGNED. Reviewed By: #lld-macho, smeenai Differential Revision: https://reviews.llvm.org/D97103
This commit is contained in:
parent
cc5c03e109
commit
541390131e
@ -47,7 +47,6 @@ struct ARM64 : TargetInfo {
|
||||
|
||||
// Random notes on reloc types:
|
||||
// ADDEND always pairs with BRANCH26, PAGE21, or PAGEOFF12
|
||||
// SUBTRACTOR always pairs with UNSIGNED (a delta between two sections)
|
||||
// POINTER_TO_GOT: ld64 supports a 4-byte pc-relative form as well as an 8-byte
|
||||
// absolute version of this relocation. The semantics of the absolute relocation
|
||||
// are weird -- it results in the value of the GOT slot being written, instead
|
||||
|
@ -287,6 +287,10 @@ void ObjFile::parseRelocations(const section_64 &sec,
|
||||
p.type = relInfo.r_type;
|
||||
p.referent = symbols[relInfo.r_symbolnum];
|
||||
relInfo = relInfos[++i];
|
||||
// SUBTRACTOR relocations should always be followed by an UNSIGNED one
|
||||
// indicating the minuend symbol.
|
||||
assert(target->hasAttr(relInfo.r_type, RelocAttrBits::UNSIGNED) &&
|
||||
relInfo.r_extern);
|
||||
}
|
||||
Reloc r;
|
||||
r.type = relInfo.r_type;
|
||||
@ -317,8 +321,7 @@ void ObjFile::parseRelocations(const section_64 &sec,
|
||||
}
|
||||
|
||||
InputSection *subsec = findContainingSubsection(subsecMap, &r.offset);
|
||||
if (p.type != GENERIC_RELOC_INVALID &&
|
||||
target->hasAttr(p.type, RelocAttrBits::SUBTRAHEND))
|
||||
if (p.type != GENERIC_RELOC_INVALID)
|
||||
subsec->relocs.push_back(p);
|
||||
subsec->relocs.push_back(r);
|
||||
}
|
||||
|
@ -59,13 +59,13 @@ void InputSection::writeTo(uint8_t *buf) {
|
||||
|
||||
for (size_t i = 0; i < relocs.size(); i++) {
|
||||
auto *fromSym = target->hasAttr(relocs[i].type, RelocAttrBits::SUBTRAHEND)
|
||||
? relocs[i++].referent.dyn_cast<Symbol *>()
|
||||
? relocs[i++].referent.get<Symbol *>()
|
||||
: nullptr;
|
||||
const Reloc &r = relocs[i];
|
||||
uint8_t *loc = buf + r.offset;
|
||||
uint64_t referentVA = 0;
|
||||
if (fromSym) {
|
||||
auto *toSym = r.referent.dyn_cast<Symbol *>();
|
||||
auto *toSym = r.referent.get<Symbol *>();
|
||||
referentVA = toSym->getVA() - fromSym->getVA();
|
||||
} else if (auto *referentSym = r.referent.dyn_cast<Symbol *>()) {
|
||||
if (target->hasAttr(r.type, RelocAttrBits::LOAD) &&
|
||||
|
@ -52,6 +52,7 @@ enum class RelocAttrBits {
|
||||
UNSIGNED = 1 << 14, // *_UNSIGNED relocs
|
||||
LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ (1 << 15) - 1),
|
||||
};
|
||||
// Note: SUBTRACTOR always pairs with UNSIGNED (a delta between two symbols).
|
||||
|
||||
class TargetInfo {
|
||||
public:
|
||||
|
@ -449,9 +449,16 @@ void Writer::scanRelocations() {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Reloc &r : isec->relocs) {
|
||||
if (target->hasAttr(r.type, RelocAttrBits::SUBTRAHEND))
|
||||
for (auto it = isec->relocs.begin(); it != isec->relocs.end(); ++it) {
|
||||
Reloc &r = *it;
|
||||
if (target->hasAttr(r.type, RelocAttrBits::SUBTRAHEND)) {
|
||||
// Skip over the following UNSIGNED relocation -- it's just there as the
|
||||
// minuend, and doesn't have the usual UNSIGNED semantics. We don't want
|
||||
// to emit rebase opcodes for it.
|
||||
it = std::next(it);
|
||||
assert(isa<Defined>(it->referent.dyn_cast<lld::macho::Symbol *>()));
|
||||
continue;
|
||||
}
|
||||
if (auto *sym = r.referent.dyn_cast<lld::macho::Symbol *>()) {
|
||||
if (auto *undefined = dyn_cast<Undefined>(sym))
|
||||
treatUndefinedSymbol(*undefined);
|
||||
|
@ -3,9 +3,9 @@
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/x86_64.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %s -o %t/arm64.o
|
||||
# RUN: %lld -lSystem %t/x86_64.o -o %t/x86_64
|
||||
# RUN: llvm-objdump --syms --full-contents %t/x86_64 | FileCheck %s
|
||||
# RUN: llvm-objdump --syms --full-contents --rebase %t/x86_64 | FileCheck %s
|
||||
# RUN: %lld -arch arm64 -lSystem %t/arm64.o -o %t/arm64
|
||||
# RUN: llvm-objdump --syms --full-contents %t/arm64 | FileCheck %s
|
||||
# RUN: llvm-objdump --syms --full-contents --rebase %t/arm64 | FileCheck %s
|
||||
|
||||
# CHECK-LABEL: SYMBOL TABLE:
|
||||
# CHECK: {{0*}}[[#%x, SUB1ADDR:]] l {{.*}} __DATA,__data _sub1
|
||||
@ -17,6 +17,9 @@
|
||||
# CHECK-NEXT: [[#SUB2ADDR]] f0ffffff
|
||||
# CHECK-NEXT: [[#SUB3ADDR]] 10000000 00000000
|
||||
# CHECK-NEXT: [[#SUB4ADDR]] f0ffffff ffffffff
|
||||
# CHECK: Rebase table:
|
||||
# CHECK-NEXT: segment section address type
|
||||
# CHECK-EMPTY:
|
||||
|
||||
.globl _main, _subtrahend_1, _subtrahend_2, _minued1, _minued2
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user