29 bool recordScatteredRelocation(MachObjectWriter *Writer,
30 const MCAssembler &Asm,
31 const MCFragment *Fragment,
35 uint64_t &FixedValue);
36 void recordTLVPRelocation(MachObjectWriter *Writer,
37 const MCAssembler &Asm,
38 const MCFragment *Fragment,
41 uint64_t &FixedValue);
43 void RecordX86Relocation(MachObjectWriter *Writer,
44 const MCAssembler &Asm,
45 const MCFragment *Fragment,
48 uint64_t &FixedValue);
49 void RecordX86_64Relocation(MachObjectWriter *Writer, MCAssembler &Asm,
50 const MCFragment *Fragment,
const MCFixup &
Fixup,
51 MCValue Target, uint64_t &FixedValue);
54 X86MachObjectWriter(
bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype)
55 : MCMachObjectTargetWriter(Is64Bit,
CPUType, CPUSubtype) {}
57 void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
58 const MCFragment *Fragment,
const MCFixup &
Fixup,
59 MCValue Target, uint64_t &FixedValue)
override {
61 RecordX86_64Relocation(Writer, Asm, Fragment,
Fixup, Target, FixedValue);
63 RecordX86Relocation(Writer, Asm, Fragment,
Fixup, Target, FixedValue);
100void X86MachObjectWriter::RecordX86_64Relocation(
103 unsigned IsPCRel =
Fixup.isPCRel();
108 uint32_t FixupOffset =
Asm.getFragmentOffset(*Fragment) +
Fixup.getOffset();
109 uint32_t FixupAddress =
113 unsigned IsExtern = 0;
115 const MCSymbol *RelSymbol =
nullptr;
125 Value += 1LL << Log2Size;
128 if (
Target.isAbsolute()) {
140 }
else if (
Target.getSubSym()) {
142 if (
A->isTemporary())
147 if (
B->isTemporary())
152 if (
Target.getSpecifier()) {
161 "unsupported pc-relative relocation of difference");
175 if (A_Base == B_Base && A_Base) {
182 if (
A->isUndefined() ||
B->isUndefined()) {
183 StringRef
Name =
A->isUndefined() ?
A->getName() :
B->getName();
186 "unsupported relocation with subtraction expression, symbol '" +
187 Name +
"' can not be undefined in a subtraction expression");
197 Index =
A->getFragment()->getParent()->getOrdinal() + 1;
200 MachO::any_relocation_info MRE;
203 (
Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (
Type << 28);
209 Index =
B->getFragment()->getParent()->getOrdinal() + 1;
214 const MCSection &Sec =
Symbol->getSection();
218 RelSymbol = Writer->
getAtom(*Symbol);
224 if (
Symbol->isInSection()) {
225 const MCSectionMachO &
Section =
226 static_cast<const MCSectionMachO &
>(*Fragment->
getParent());
236 if (RelSymbol != Symbol)
237 Value +=
Asm.getSymbolOffset(*Symbol) -
Asm.getSymbolOffset(*RelSymbol);
238 }
else if (
Symbol->isInSection() && !
Symbol->isVariable()) {
240 Index =
Symbol->getFragment()->getParent()->getOrdinal() + 1;
244 Value -= FixupAddress + (1 << Log2Size);
245 }
else if (
Symbol->isVariable()) {
250 "unsupported relocation of undefined symbol '" +
268 }
else if (Specifier) {
270 "unsupported symbol modifier in relocation");
289 switch (-(
Target.getConstant() + (1LL << Log2Size))) {
298 "unsupported symbol modifier in branch relocation");
316 "TLVP symbol modifier should have been rip-rel");
318 }
else if (Specifier) {
320 "unsupported symbol modifier in relocation");
327 "32-bit absolute addressing is not supported in 64-bit mode");
338 MachO::any_relocation_info MRE;
340 MRE.
r_word1 = (
Index << 0) | (IsPCRel << 24) | (Log2Size << 25) |
341 (IsExtern << 27) | (
Type << 28);
345bool X86MachObjectWriter::recordScatteredRelocation(MachObjectWriter *Writer,
346 const MCAssembler &Asm,
347 const MCFragment *Fragment,
348 const MCFixup &
Fixup,
351 uint64_t &FixedValue) {
352 uint64_t OriginalFixedValue = FixedValue;
353 uint32_t FixupOffset =
Asm.getFragmentOffset(*Fragment) +
Fixup.getOffset();
354 unsigned IsPCRel =
Fixup.isPCRel();
358 auto *
A =
static_cast<const MCSymbolMachO *
>(
Target.getAddSym());
359 if (!
A->getFragment()) {
361 "symbol '" +
A->getName() +
362 "' can not be undefined in a subtraction expression");
368 FixedValue += SecAddr;
371 if (
const MCSymbol *SB =
Target.getSubSym()) {
372 if (!SB->getFragment()) {
374 "symbol '" + SB->getName() +
375 "' can not be undefined in a subtraction expression");
395 if (FixupOffset > 0xffffff) {
397 format(
"0x%x", FixupOffset).print(Buffer,
sizeof(Buffer));
401 ") into 24 bits of scattered "
402 "relocation entry.");
406 MachO::any_relocation_info MRE;
422 if (FixupOffset > 0xffffff) {
423 FixedValue = OriginalFixedValue;
428 MachO::any_relocation_info MRE;
429 MRE.
r_word0 = ((FixupOffset << 0) |
439void X86MachObjectWriter::recordTLVPRelocation(MachObjectWriter *Writer,
440 const MCAssembler &Asm,
441 const MCFragment *Fragment,
442 const MCFixup &
Fixup,
444 uint64_t &FixedValue) {
447 "Should only be called with a 32-bit TLVP relocation!");
450 uint32_t
Value =
Asm.getFragmentOffset(*Fragment) +
Fixup.getOffset();
451 unsigned IsPCRel = 0;
457 if (
auto *SymB =
Target.getSubSym()) {
459 uint32_t FixupAddress =
464 FixedValue += 1ULL << Log2Size;
470 MachO::any_relocation_info MRE;
477void X86MachObjectWriter::RecordX86Relocation(MachObjectWriter *Writer,
478 const MCAssembler &Asm,
479 const MCFragment *Fragment,
480 const MCFixup &
Fixup,
482 uint64_t &FixedValue) {
483 unsigned IsPCRel =
Fixup.isPCRel();
489 recordTLVPRelocation(Writer, Asm, Fragment,
Fixup, Target, FixedValue);
497 recordScatteredRelocation(Writer, Asm, Fragment,
Fixup, Target, Log2Size,
512 recordScatteredRelocation(Writer, Asm, Fragment,
Fixup, Target, Log2Size,
517 uint32_t FixupOffset =
Asm.getFragmentOffset(*Fragment) +
Fixup.getOffset();
520 const MCSymbol *RelSymbol =
nullptr;
522 if (
Target.isAbsolute()) {
529 assert(
A &&
"Unknown symbol data");
532 if (
A->isVariable()) {
535 A->getVariableValue()->evaluateAsRelocatable(Val, &Asm);
555 if (!
A->isUndefined())
556 FixedValue -=
Asm.getSymbolOffset(*
A);
559 const MCSection &Sec =
A->getSection();
570 MachO::any_relocation_info MRE;
573 (
Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (
Type << 28);
577std::unique_ptr<MCObjectTargetWriter>
580 return std::make_unique<X86MachObjectWriter>(Is64Bit, CPUType, CPUSubtype);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static Error reportError(StringRef Message)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
PowerPC TLS Dynamic Call Fixup
static bool is64Bit(const char *name)
static bool isFixupKindRIPRel(unsigned Kind)
static bool isSectionAtomizableBySymbols(const MCSection &Section)
True if the section is atomized using the symbols in it.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
MCSection * getParent() const
unsigned getOrdinal() const
const MCSymbol * getAddSym() const
int64_t getConstant() const
const MCSymbol * getSubSym() const
bool isAbsolute() const
Is this an absolute (as opposed to relocatable) value.
bool doesSymbolRequireExternRelocation(const MCSymbol &S)
uint64_t getFragmentAddress(const MCAssembler &Asm, const MCFragment *Fragment) const
uint64_t getSectionAddress(const MCSection *Sec) const
void addRelocation(const MCSymbol *RelSymbol, const MCSection *Sec, MachO::any_relocation_info &MRE)
const MCSymbol & findAliasedSymbol(const MCSymbol &Sym) const
const MCSymbol * getAtom(const MCSymbol &S) const
uint64_t getSymbolAddress(const MCSymbol &S) const
Target - Wrapper for Target specific information.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ GENERIC_RELOC_LOCAL_SECTDIFF
@ X86_64_RELOC_SUBTRACTOR
@ S_ATTR_DEBUG
S_ATTR_DEBUG - A debug section.
@ reloc_riprel_4byte_movq_load_rex2
@ reloc_signed_4byte_relax
@ reloc_branch_4byte_pcrel
@ reloc_riprel_4byte_relax
@ reloc_riprel_4byte_relax_evex
@ reloc_riprel_4byte_relax_rex
@ reloc_riprel_4byte_movq_load
@ reloc_riprel_4byte_relax_rex2
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
static unsigned getFixupKindLog2Size(unsigned Kind)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
@ FK_Data_8
A eight-byte fixup.
@ FK_Data_1
A one-byte fixup.
@ FK_Data_4
A four-byte fixup.
@ FK_Data_2
A two-byte fixup.
std::unique_ptr< MCObjectTargetWriter > createX86MachObjectWriter(bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype)
Construct an X86 Mach-O object writer.