1//===-- AArch64MachObjectWriter.cpp - ARM Mach Object Writer --------------===// 
  3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
  4// See https://llvm.org/LICENSE.txt for license information. 
  5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
  7//===----------------------------------------------------------------------===// 
  35 bool getAArch64FixupKindMachOInfo(
const MCFixup &
Fixup, 
unsigned &RelocType,
 
  37 const MCAssembler &Asm);
 
  40 AArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype, 
bool IsILP32)
 
  41 : MCMachObjectTargetWriter(!IsILP32 
/* is64Bit */, 
CPUType, CPUSubtype) {}
 
  43 void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
 
  44 const MCFragment *Fragment, 
const MCFixup &
Fixup,
 
  45 MCValue Target, uint64_t &FixedValue) 
override;
 
  48} 
// end anonymous namespace 
  50bool AArch64MachObjectWriter::getAArch64FixupKindMachOInfo(
 
  56 switch (
Fixup.getKind()) {
 
  98 // This encompasses the relocation for the whole 21-bit value. 
  123 const MCSymbol &Symbol, 
unsigned Log2Size) {
 
  124 // Debug info sections can use local relocations. 
  128 // Otherwise, only pointer sized relocations are supported. 
  132 // But only if they don't point to a few forbidden sections. 
  133 if (!Symbol.isInSection())
 
  141 (RefSec.
getName() == 
"__cfstring" ||
 
  142 RefSec.
getName() == 
"__objc_classrefs"))
 
 
  148void AArch64MachObjectWriter::recordRelocation(
 
  149 MachObjectWriter *Writer, MCAssembler &Asm, 
const MCFragment *Fragment,
 
  150 const MCFixup &
Fixup, MCValue Target, uint64_t &FixedValue) {
 
  151 unsigned IsPCRel = 
Fixup.isPCRel();
 
  154 uint32_t FixupOffset = 
Asm.getFragmentOffset(*Fragment);
 
  155 unsigned Log2Size = 0;
 
  160 const MCSymbol *RelSymbol = 
nullptr;
 
  162 FixupOffset += 
Fixup.getOffset();
 
  164 // AArch64 pcrel relocation addends do not include the section offset. 
  166 FixedValue += FixupOffset;
 
  168 // ADRP fixups use relocations for the whole symbol value and only 
  169 // put the addend in the instruction itself. Clear out any value the 
  170 // generic code figured out from the sybmol definition. 
  174 // imm19 relocations are for conditional branches, which require 
  175 // assembler local symbols. If we got here, that's not what we have, 
  176 // so complain loudly. 
  180 Target.getAddSym()->getName() +
 
  185 // 14-bit branch relocations should only target internal labels, and so 
  186 // should never get here. 
  200 if (
Target.isAbsolute()) { 
// constant 
  201 // FIXME: Should this always be extern? 
  202 // SymbolNum of 0 indicates the absolute section. 
  209 // FIXME: x86_64 sets the type to a branch reloc here. Should we do 
  210 // something similar? 
  212 } 
else if (
auto *
B = 
Target.getSubSym()) { 
// A - B + constant 
  217 // Check for "_foo@got - .", which comes through here as: 
  219 // ... _foo@got - Ltmp0 
  221 Asm.getSymbolOffset(*
B) ==
 
  222 Asm.getFragmentOffset(*Fragment) + 
Fixup.getOffset()) {
 
  223 // SymB is the PC, so use a PC-rel pointer-to-GOT relocation. 
  226 MachO::any_relocation_info MRE;
 
  228 MRE.
r_word1 = (IsPCRel << 24) | (Log2Size << 25) | (
Type << 28);
 
  232 // Otherwise, neither symbol can be modified. 
  237 // We don't support PCrel relocations of differences. 
  244 // AArch64 always uses external relocations. If there is no symbol to use as 
  245 // a base address (a local symbol with no preceding non-local symbol), 
  248 // FIXME: We should probably just synthesize an external symbol and use 
  252 "unsupported relocation of local symbol '" + 
A->getName() +
 
  253 "'. Must have non-local symbol earlier in section.");
 
  258 "unsupported relocation of local symbol '" + 
B->getName() +
 
  259 "'. Must have non-local symbol earlier in section.");
 
  263 if (A_Base == B_Base && A_Base) {
 
  279 MachO::any_relocation_info MRE;
 
  281 MRE.
r_word1 = (IsPCRel << 24) | (Log2Size << 25) | (
Type << 28);
 
  286 } 
else { 
// A + constant 
  288 const MCSectionMachO &
Section =
 
  289 static_cast<const MCSectionMachO &
>(*Fragment->
getParent());
 
  291 bool CanUseLocalRelocation =
 
  293 if (
Symbol->isTemporary() && (
Value || !CanUseLocalRelocation)) {
 
  294 // Make sure that the symbol is actually in a section here. If it isn't, 
  295 // emit an error and exit. 
  296 if (!
Symbol->isInSection()) {
 
  298 "unsupported relocation of local symbol '" +
 
  300 "'. Must have non-local symbol earlier in section.");
 
  303 const MCSection &Sec = 
Symbol->getSection();
 
  310 // If the symbol is a variable it can either be in a section and 
  311 // we have a base or it is absolute and should have been expanded. 
  314 // Relocations inside debug sections always use local relocations when 
  315 // possible. This seems to be done because the debugger doesn't fully 
  316 // understand relocation entries and expects to find values that 
  317 // have already been fixed up. 
  318 if (
Symbol->isInSection()) {
 
  323 // AArch64 uses external relocations as much as possible. For debug 
  324 // sections, and for pointer-sized relocations (.quad), we allow section 
  325 // relocations. It's code sections that run into trouble. 
  329 // Add the local offset, if needed. 
  332 } 
else if (
Symbol->isInSection()) {
 
  333 if (!CanUseLocalRelocation) {
 
  335 "unsupported relocation of local symbol '" +
 
  337 "'. Must have non-local symbol earlier in section.");
 
  340 // Adjust the relocation to be section-relative. 
  341 // The index is the section ordinal (1-based). 
  342 const MCSection &Sec = 
Symbol->getSection();
 
  351 "This constant variable should have been expanded during evaluation");
 
  355 // If the relocation kind is Branch26, Page21, or Pageoff12, any addend 
  356 // is represented via an Addend relocation, not encoded directly into 
  367 MachO::any_relocation_info MRE;
 
  370 (
Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (
Type << 28);
 
  373 // Now set up the Addend relocation. 
  380 // Put zero into the instruction itself. The addend is in the relocation. 
  397 "invalid auth relocation size, must be 8 bytes");
 
  403 "invalid auth relocation, can't reference two symbols");
 
  416 Value = (uint32_t(
Value)) | (uint64_t(Discriminator) << 32) |
 
  417 (uint64_t(Expr->hasAddressDiversity()) << 48) |
 
  418 (uint64_t(
Key) << 49) | (1ULL << 63);
 
  421 // If there's any addend left to handle, encode it in the instruction. 
  424 // struct relocation_info (8 bytes) 
  425 MachO::any_relocation_info MRE;
 
  428 (
Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (
Type << 28);
 
  432std::unique_ptr<MCObjectTargetWriter>
 
  435 return std::make_unique<AArch64MachObjectWriter>(CPUType, CPUSubtype,
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool canUseLocalRelocation(const MCSectionMachO &Section, const MCSymbol &Symbol, unsigned Log2Size)
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 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
This represents a section on a Mach-O system (used by Mac OS X).
MachO::SectionType getType() const
StringRef getSegmentName() const
unsigned getOrdinal() const
StringRef getName() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCFragment * getFragment() const
uint64_t getFragmentAddress(const MCAssembler &Asm, const MCFragment *Fragment) const
void addRelocation(const MCSymbol *RelSymbol, const MCSection *Sec, MachO::any_relocation_info &MRE)
const MCSymbol * getAtom(const MCSymbol &S) const
uint64_t getSymbolAddress(const MCSymbol &S) const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ fixup_aarch64_ldst_imm12_scale4
@ fixup_aarch64_pcrel_call26
@ fixup_aarch64_pcrel_branch26
@ fixup_aarch64_pcrel_branch19
@ fixup_aarch64_pcrel_branch14
@ fixup_aarch64_ldst_imm12_scale2
@ fixup_aarch64_ldst_imm12_scale16
@ fixup_aarch64_pcrel_adrp_imm21
@ fixup_aarch64_add_imm12
@ fixup_aarch64_ldst_imm12_scale8
@ fixup_aarch64_ldst_imm12_scale1
@ S_CSTRING_LITERALS
S_CSTRING_LITERALS - Section with literal C strings.
@ ARM64_RELOC_POINTER_TO_GOT
@ ARM64_RELOC_AUTHENTICATED_POINTER
@ ARM64_RELOC_GOT_LOAD_PAGE21
@ ARM64_RELOC_TLVP_LOAD_PAGEOFF12
@ ARM64_RELOC_GOT_LOAD_PAGEOFF12
@ ARM64_RELOC_TLVP_LOAD_PAGE21
@ S_ATTR_DEBUG
S_ATTR_DEBUG - A debug section.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ 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.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
std::unique_ptr< MCObjectTargetWriter > createAArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype, bool IsILP32)