36 bool getRISCVFixupKindMachOInfo(
const MCFixup &
Fixup,
unsigned &RelocType,
37 const MCValue Sym,
unsigned &Log2Size,
38 const MCAssembler &Asm);
41 RISCVMachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype)
42 : MCMachObjectTargetWriter(
false,
CPUType, CPUSubtype) {}
44 void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
45 const MCFragment *Fragment,
const MCFixup &
Fixup,
46 MCValue Target, uint64_t &FixedValue)
override;
51bool RISCVMachObjectWriter::getRISCVFixupKindMachOInfo(
const MCFixup &
Fixup,
65 switch (
Fixup.getKind()) {
92 Asm.getContext().reportError(
Fixup.getLoc(),
93 "unknown AUIPC relocation kind");
112 const MCSymbol &Symbol,
unsigned Log2Size) {
122 if (!Symbol.isInSection())
130 RefSec.
getName() ==
"__objc_classrefs")
138 unsigned Index,
bool IsPCRel,
unsigned Log2Size,
147 (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (
Type << 28);
148 Writer->
addRelocation(RelSymbol, Fragment->getParent(), MRE);
154 Asm.getContext().reportError(
156 "unsupported relocation of local symbol '" + Symbol->getName() +
157 "'. Must have non-local symbol earlier in section.");
163template <
unsigned Bits>
168 Asm.getContext().reportError(
Loc, Msg);
173 const MCFragment **DFOut);
175void RISCVMachObjectWriter::recordRelocation(
176 MachObjectWriter *Writer, MCAssembler &Asm,
const MCFragment *Fragment,
177 const MCFixup &
Fixup, MCValue Target, uint64_t &FixedValue) {
182 uint32_t FixupOffset =
Asm.getFragmentOffset(*Fragment);
183 unsigned Log2Size = 0;
188 const MCSymbol *RelSymbol =
nullptr;
190 FixupOffset +=
Fixup.getOffset();
194 FixedValue += FixupOffset;
207 const MCFragment *AUIPCDF;
208 const MCFixup *AUIPCFixup =
215 Asm.getFragmentOffset(*AUIPCDF) + AUIPCFixup->
getOffset() - FixupOffset;
218 "AUIPC out of range of corresponding %pcrel_lo instruction", Asm,
225 Asm.getContext().reportError(AUIPCFixup->
getLoc(),
226 "cannot understand AUIPC target");
230 Asm.getContext().reportError(AUIPCFixup->
getLoc(),
231 "AUIPC target with symbol difference");
242 }
else if (!getRISCVFixupKindMachOInfo(
Fixup,
Type, Target, Log2Size, Asm)) {
243 Asm.getContext().reportError(
Fixup.getLoc(),
"unknown RISC-V fixup kind");
253 Asm.getContext().reportError(
254 Fixup.getLoc(),
"conditional branch requires assembler-local"
256 Target.getAddSym()->getName() +
"' is external.");
271 if (
Target.isAbsolute()) {
275 Asm.getContext().reportError(
Fixup.getLoc(),
276 "PC relative absolute relocation!");
286 if (
const MCSymbol *
B =
Target.getSubSym()) {
293 Asm.getContext().reportError(
Fixup.getLoc(),
294 "unsupported pc-relative relocation of "
304 if (A_Base && A_Base == B_Base) {
305 Asm.getContext().reportError(
306 Fixup.getLoc(),
"unsupported relocation with identical base");
324 "AUIPC out of range of corresponding %pcrel_lo instruction", Asm,
337 if (
const MCSymbol *Symbol =
Target.getAddSym()) {
339 const MCSectionMachO &
Section =
340 static_cast<const MCSectionMachO &
>(*Fragment->
getParent());
342 const bool CanUseLocalRelocation =
344 if (
Symbol->isTemporary() && (
Value || !CanUseLocalRelocation)) {
345 if (!
Symbol->isInSection()) {
349 const MCSection &Sec =
Symbol->getSection();
363 if (
Symbol->isInSection()) {
377 }
else if (
Symbol->isInSection()) {
378 if (!CanUseLocalRelocation) {
384 const MCSection &Sec =
Symbol->getSection();
392 "This constant variable should have been expanded during evaluation");
410 emitRelocation(Writer, Fragment, FixupOffset, RelSymbol, Index, IsPCRel,
414 Value & 0xffffff,
false, 2,
419 emitRelocation(Writer, Fragment, FixupOffset, RelSymbol, Index, IsPCRel,
424std::unique_ptr<MCObjectTargetWriter>
426 return std::make_unique<RISCVMachObjectWriter>(CPUType, CPUSubtype);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool canUseLocalRelocation(const MCSectionMachO &Section, const MCSymbol &Symbol, unsigned Log2Size)
Function Alias Analysis false
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
const MCFixup * getPCRelHiFixup(const MCSpecifierExpr &Expr, const MCFragment **DFOut)
static bool checkSymbolBase(const MCSymbol *Base, const MCSymbol *Symbol, const MCFixup &Fixup, MCAssembler &Asm)
static bool isValidInt(const uint64_t &FixedValue, const char *Msg, MCAssembler &Asm, const SMLoc Loc)
static void emitRelocation(MachObjectWriter *Writer, const MCFragment *Fragment, uint32_t FixupOffset, const MCSymbol *RelSymbol, unsigned Index, bool IsPCRel, unsigned Log2Size, unsigned Type)
static bool isSectionAtomizableBySymbols(const MCSection &Section)
True if the section is atomized using the symbols in it.
LLVM_ABI bool evaluateAsValue(MCValue &Res, const MCAssembler &Asm) const
Try to evaluate the expression to the form (a - b + constant) where neither a nor b are variables.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
const MCExpr * getValue() const
LLVM_ABI SMLoc getLoc() const
uint32_t getOffset() const
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
static MCValue get(const MCSymbol *SymA, const MCSymbol *SymB=nullptr, int64_t Val=0, uint32_t Specifier=0)
const MCSymbol * getAddSym() const
int64_t getConstant() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() 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
Represents a location in source code.
The instances of the Type class are immutable: once they are created, they are never changed.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ S_CSTRING_LITERALS
S_CSTRING_LITERALS - Section with literal C strings.
@ S_ATTR_DEBUG
S_ATTR_DEBUG - A debug section.
@ fixup_riscv_pcrel_lo12_i
@ fixup_riscv_pcrel_lo12_s
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.
std::unique_ptr< MCObjectTargetWriter > createRISCVMachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype)
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
@ 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.