35 bool getRISCVFixupKindMachOInfo(
const MCFixup &
Fixup,
unsigned &RelocType,
36 const MCValue Sym,
unsigned &Log2Size,
37 const MCAssembler &Asm);
40 RISCVMachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype)
41 : MCMachObjectTargetWriter(
false,
CPUType, CPUSubtype) {}
43 void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
44 const MCFragment *Fragment,
const MCFixup &
Fixup,
45 MCValue Target,
uint64_t &FixedValue)
override;
50bool RISCVMachObjectWriter::getRISCVFixupKindMachOInfo(
const MCFixup &
Fixup,
64 switch (
Fixup.getKind()) {
91 Asm.getContext().reportError(
Fixup.getLoc(),
92 "unknown AUIPC relocation kind");
111 const MCSymbol &Symbol,
unsigned Log2Size) {
121 if (!Symbol.isInSection())
129 RefSec.
getName() ==
"__objc_classrefs")
137 unsigned Index,
bool IsPCRel,
unsigned Log2Size,
146 (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (
Type << 28);
147 Writer->
addRelocation(RelSymbol, Fragment->getParent(), MRE);
153 Asm.getContext().reportError(
155 "unsupported relocation of local symbol '" + Symbol->getName() +
156 "'. Must have non-local symbol earlier in section.");
162template <
unsigned Bits>
167 Asm.getContext().reportError(
Loc,
Msg);
172 const MCFragment **DFOut);
174void RISCVMachObjectWriter::recordRelocation(
175 MachObjectWriter *Writer, MCAssembler &Asm,
const MCFragment *Fragment,
176 const MCFixup &
Fixup, MCValue Target,
uint64_t &FixedValue) {
181 uint32_t FixupOffset =
Asm.getFragmentOffset(*Fragment);
182 unsigned Log2Size = 0;
187 const MCSymbol *RelSymbol =
nullptr;
188 bool RequireExtraAddend =
false;
191 FixupOffset +=
Fixup.getOffset();
195 FixedValue += FixupOffset;
208 const MCFragment *AUIPCDF;
209 const MCFixup *AUIPCFixup =
216 Asm.getFragmentOffset(*AUIPCDF) + AUIPCFixup->
getOffset() - FixupOffset;
218 RequireExtraAddend =
true;
219 ExtraAddendValue = FixedValue;
222 "AUIPC out of range of corresponding %pcrel_lo instruction", Asm,
230 Asm.getContext().reportError(AUIPCFixup->
getLoc(),
231 "cannot understand AUIPC target");
235 Asm.getContext().reportError(AUIPCFixup->
getLoc(),
236 "AUIPC target with symbol difference");
247 }
else if (!getRISCVFixupKindMachOInfo(
Fixup,
Type, Target, Log2Size, Asm)) {
248 Asm.getContext().reportError(
Fixup.getLoc(),
"unknown RISC-V fixup kind");
258 Asm.getContext().reportError(
259 Fixup.getLoc(),
"conditional branch requires assembler-local"
261 Target.getAddSym()->getName() +
"' is external.");
278 if (
Target.isAbsolute()) {
282 Asm.getContext().reportError(
Fixup.getLoc(),
283 "PC relative absolute relocation!");
293 if (
const MCSymbol *
B =
Target.getSubSym()) {
300 Asm.getContext().reportError(
Fixup.getLoc(),
301 "unsupported pc-relative relocation of "
311 if (A_Base && A_Base == B_Base) {
312 Asm.getContext().reportError(
313 Fixup.getLoc(),
"unsupported relocation with identical base");
331 "AUIPC out of range of corresponding %pcrel_lo instruction", Asm,
344 if (
const MCSymbol *Symbol =
Target.getAddSym()) {
346 const MCSectionMachO &
Section =
347 static_cast<const MCSectionMachO &
>(*Fragment->
getParent());
349 const bool CanUseLocalRelocation =
351 if (
Symbol->isTemporary() && (
Value || !CanUseLocalRelocation)) {
352 if (!
Symbol->isInSection()) {
356 const MCSection &Sec =
Symbol->getSection();
370 if (
Symbol->isInSection()) {
384 }
else if (
Symbol->isInSection()) {
385 if (!CanUseLocalRelocation) {
391 const MCSection &Sec =
Symbol->getSection();
399 "This constant variable should have been expanded during evaluation");
417 emitRelocation(Writer, Fragment, FixupOffset, RelSymbol, Index, IsPCRel,
421 Value & 0xffffff,
false, 2,
426 emitRelocation(Writer, Fragment, FixupOffset, RelSymbol, Index, IsPCRel,
430 if (RequireExtraAddend) {
432 ExtraAddendValue & 0xffffff,
false,
437std::unique_ptr<MCObjectTargetWriter>
439 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.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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.