233 lines · c
1//=====-- AArch64MCAsmInfo.h - AArch64 asm properties ---------*- C++ -*--====//2//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the declaration of the AArch64MCAsmInfo class.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64MCASMINFO_H14#define LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64MCASMINFO_H15 16#include "Utils/AArch64BaseInfo.h"17#include "llvm/MC/MCAsmInfoCOFF.h"18#include "llvm/MC/MCAsmInfoDarwin.h"19#include "llvm/MC/MCAsmInfoELF.h"20#include "llvm/MC/MCExpr.h"21#include "llvm/Support/Casting.h"22 23namespace llvm {24class MCStreamer;25class MCValue;26class Triple;27 28struct AArch64MCAsmInfoDarwin : public MCAsmInfoDarwin {29 explicit AArch64MCAsmInfoDarwin(bool IsILP32);30 const MCExpr *31 getExprForPersonalitySymbol(const MCSymbol *Sym, unsigned Encoding,32 MCStreamer &Streamer) const override;33 void printSpecifierExpr(raw_ostream &OS,34 const MCSpecifierExpr &Expr) const override;35 bool evaluateAsRelocatableImpl(const MCSpecifierExpr &Expr, MCValue &Res,36 const MCAssembler *Asm) const override;37};38 39struct AArch64MCAsmInfoELF : public MCAsmInfoELF {40 explicit AArch64MCAsmInfoELF(const Triple &T);41 void printSpecifierExpr(raw_ostream &OS,42 const MCSpecifierExpr &Expr) const override;43 bool evaluateAsRelocatableImpl(const MCSpecifierExpr &Expr, MCValue &Res,44 const MCAssembler *Asm) const override;45};46 47struct AArch64MCAsmInfoMicrosoftCOFF : public MCAsmInfoMicrosoft {48 explicit AArch64MCAsmInfoMicrosoftCOFF();49 void printSpecifierExpr(raw_ostream &OS,50 const MCSpecifierExpr &Expr) const override;51 bool evaluateAsRelocatableImpl(const MCSpecifierExpr &Expr, MCValue &Res,52 const MCAssembler *Asm) const override;53};54 55struct AArch64MCAsmInfoGNUCOFF : public MCAsmInfoGNUCOFF {56 explicit AArch64MCAsmInfoGNUCOFF();57 void printSpecifierExpr(raw_ostream &OS,58 const MCSpecifierExpr &Expr) const override;59 bool evaluateAsRelocatableImpl(const MCSpecifierExpr &Expr, MCValue &Res,60 const MCAssembler *Asm) const override;61};62 63namespace AArch64 {64using Specifier = uint16_t;65 66enum {67 // clang-format off68 S_None = 0,69 // Symbol locations specifying (roughly speaking) what calculation should be70 // performed to construct the final address for the relocated71 // symbol. E.g. direct, via the GOT, ...72 S_ABS = 0x001,73 S_SABS = 0x002,74 S_PREL = 0x003,75 S_GOT = 0x004,76 S_DTPREL = 0x005,77 S_GOTTPREL = 0x006,78 S_TPREL = 0x007,79 S_TLSDESC = 0x008,80 S_SECREL = 0x009,81 S_AUTH = 0x00a,82 S_AUTHADDR = 0x00b,83 S_GOT_AUTH = 0x00c,84 S_TLSDESC_AUTH = 0x00d,85 S_SymLocBits = 0x00f,86 87 // Variants specifying which part of the final address calculation is88 // used. E.g. the low 12 bits for an ADD/LDR, the middle 16 bits for a89 // MOVZ/MOVK.90 S_PAGE = 0x010,91 S_PAGEOFF = 0x020,92 S_HI12 = 0x030,93 S_G0 = 0x040,94 S_G1 = 0x050,95 S_G2 = 0x060,96 S_G3 = 0x070,97 S_LO15 = 0x080,98 S_AddressFragBits = 0x0f0,99 100 // Whether the final relocation is a checked one (where a linker should101 // perform a range-check on the final address) or not. Note that this field102 // is unfortunately sometimes omitted from the assembly syntax. E.g. :lo12:103 // on its own is a non-checked relocation. We side with ELF on being104 // explicit about this!105 S_NC = 0x100,106 107 // Convenience definitions for referring to specific textual representations108 // of relocation specifiers. Note that this means the "_NC" is sometimes109 // omitted in line with assembly syntax here (S_LO12 rather than VK_LO12_NC110 // since a user would write ":lo12:").111 S_CALL = S_ABS,112 S_ABS_PAGE = S_ABS | S_PAGE,113 S_ABS_PAGE_NC = S_ABS | S_PAGE | S_NC,114 S_ABS_G3 = S_ABS | S_G3,115 S_ABS_G2 = S_ABS | S_G2,116 S_ABS_G2_S = S_SABS | S_G2,117 S_ABS_G2_NC = S_ABS | S_G2 | S_NC,118 S_ABS_G1 = S_ABS | S_G1,119 S_ABS_G1_S = S_SABS | S_G1,120 S_ABS_G1_NC = S_ABS | S_G1 | S_NC,121 S_ABS_G0 = S_ABS | S_G0,122 S_ABS_G0_S = S_SABS | S_G0,123 S_ABS_G0_NC = S_ABS | S_G0 | S_NC,124 S_LO12 = S_ABS | S_PAGEOFF | S_NC,125 S_PREL_G3 = S_PREL | S_G3,126 S_PREL_G2 = S_PREL | S_G2,127 S_PREL_G2_NC = S_PREL | S_G2 | S_NC,128 S_PREL_G1 = S_PREL | S_G1,129 S_PREL_G1_NC = S_PREL | S_G1 | S_NC,130 S_PREL_G0 = S_PREL | S_G0,131 S_PREL_G0_NC = S_PREL | S_G0 | S_NC,132 S_GOT_LO12 = S_GOT | S_PAGEOFF | S_NC,133 S_GOT_PAGE = S_GOT | S_PAGE,134 S_GOT_PAGE_LO15 = S_GOT | S_LO15 | S_NC,135 S_GOT_AUTH_LO12 = S_GOT_AUTH | S_PAGEOFF | S_NC,136 S_GOT_AUTH_PAGE = S_GOT_AUTH | S_PAGE,137 S_DTPREL_G2 = S_DTPREL | S_G2,138 S_DTPREL_G1 = S_DTPREL | S_G1,139 S_DTPREL_G1_NC = S_DTPREL | S_G1 | S_NC,140 S_DTPREL_G0 = S_DTPREL | S_G0,141 S_DTPREL_G0_NC = S_DTPREL | S_G0 | S_NC,142 S_DTPREL_HI12 = S_DTPREL | S_HI12,143 S_DTPREL_LO12 = S_DTPREL | S_PAGEOFF,144 S_DTPREL_LO12_NC = S_DTPREL | S_PAGEOFF | S_NC,145 S_GOTTPREL_PAGE = S_GOTTPREL | S_PAGE,146 S_GOTTPREL_LO12_NC = S_GOTTPREL | S_PAGEOFF | S_NC,147 S_GOTTPREL_G1 = S_GOTTPREL | S_G1,148 S_GOTTPREL_G0_NC = S_GOTTPREL | S_G0 | S_NC,149 S_TPREL_G2 = S_TPREL | S_G2,150 S_TPREL_G1 = S_TPREL | S_G1,151 S_TPREL_G1_NC = S_TPREL | S_G1 | S_NC,152 S_TPREL_G0 = S_TPREL | S_G0,153 S_TPREL_G0_NC = S_TPREL | S_G0 | S_NC,154 S_TPREL_HI12 = S_TPREL | S_HI12,155 S_TPREL_LO12 = S_TPREL | S_PAGEOFF,156 S_TPREL_LO12_NC = S_TPREL | S_PAGEOFF | S_NC,157 S_TLSDESC_LO12 = S_TLSDESC | S_PAGEOFF,158 S_TLSDESC_PAGE = S_TLSDESC | S_PAGE,159 S_TLSDESC_AUTH_LO12 = S_TLSDESC_AUTH | S_PAGEOFF,160 S_TLSDESC_AUTH_PAGE = S_TLSDESC_AUTH | S_PAGE,161 S_SECREL_LO12 = S_SECREL | S_PAGEOFF,162 S_SECREL_HI12 = S_SECREL | S_HI12,163 164 // ELF relocation specifiers in data directives:165 S_PLT = 0x400,166 S_GOTPCREL,167 S_FUNCINIT,168 169 // Mach-O @ relocation specifiers:170 S_MACHO_GOT,171 S_MACHO_GOTPAGE,172 S_MACHO_GOTPAGEOFF,173 S_MACHO_PAGE,174 S_MACHO_PAGEOFF,175 S_MACHO_TLVP,176 S_MACHO_TLVPPAGE,177 S_MACHO_TLVPPAGEOFF,178 179 S_INVALID = 0xfff180 // clang-format on181};182 183/// Return the string representation of the ELF relocation specifier184/// (e.g. ":got:", ":lo12:").185StringRef getSpecifierName(Specifier S);186 187inline Specifier getSymbolLoc(Specifier S) {188 return static_cast<Specifier>(S & AArch64::S_SymLocBits);189}190 191inline Specifier getAddressFrag(Specifier S) {192 return static_cast<Specifier>(S & AArch64::S_AddressFragBits);193}194 195inline bool isNotChecked(Specifier S) { return S & AArch64::S_NC; }196} // namespace AArch64197 198class AArch64AuthMCExpr final : public MCSpecifierExpr {199 uint16_t Discriminator;200 AArch64PACKey::ID Key;201 202 explicit AArch64AuthMCExpr(const MCExpr *Expr, uint16_t Discriminator,203 AArch64PACKey::ID Key, bool HasAddressDiversity,204 SMLoc Loc)205 : MCSpecifierExpr(206 Expr, HasAddressDiversity ? AArch64::S_AUTHADDR : AArch64::S_AUTH,207 Loc),208 Discriminator(Discriminator), Key(Key) {}209 210public:211 static const AArch64AuthMCExpr *212 create(const MCExpr *Expr, uint16_t Discriminator, AArch64PACKey::ID Key,213 bool HasAddressDiversity, MCContext &Ctx, SMLoc Loc = SMLoc());214 215 AArch64PACKey::ID getKey() const { return Key; }216 uint16_t getDiscriminator() const { return Discriminator; }217 bool hasAddressDiversity() const {218 return getSpecifier() == AArch64::S_AUTHADDR;219 }220 221 void print(raw_ostream &OS, const MCAsmInfo *MAI) const;222 223 static bool classof(const MCExpr *E) {224 auto *SE = dyn_cast<MCSpecifierExpr>(E);225 return SE && (SE->getSpecifier() == AArch64::S_AUTH ||226 SE->getSpecifier() == AArch64::S_AUTHADDR);227 }228};229 230} // namespace llvm231 232#endif233