LLVM: lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

27#include

28#include

29

30using namespace llvm;

31

32namespace {

33

35 bool getAArch64FixupKindMachOInfo(const MCFixup &Fixup, unsigned &RelocType,

37 const MCAssembler &Asm);

38

39public:

40 AArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype, bool IsILP32)

41 : MCMachObjectTargetWriter(!IsILP32 , CPUType, CPUSubtype) {}

42

43 void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,

44 const MCFragment *Fragment, const MCFixup &Fixup,

45 MCValue Target, uint64_t &FixedValue) override;

46};

47

48}

49

50bool AArch64MachObjectWriter::getAArch64FixupKindMachOInfo(

52 unsigned &Log2Size, const MCAssembler &Asm) {

54 Log2Size = ~0U;

55

56 switch (Fixup.getKind()) {

57 default:

58 return false;

59

62 return true;

65 return true;

70 return true;

75 return true;

83 switch (Spec) {

84 default:

85 return false;

88 return true;

91 return true;

94 return true;

95 }

98

99 switch (Spec) {

100 default:

101 reportError(Fixup.getLoc(), "ADR/ADRP relocations must be GOT relative");

102 return false;

105 return true;

108 return true;

111 return true;

112 }

113 return true;

118 return true;

119 }

120}

121

123 const MCSymbol &Symbol, unsigned Log2Size) {

124

126 return true;

127

128

129 if (Log2Size != 3)

130 return false;

131

132

133 if (!Symbol.isInSection())

134 return true;

138 return false;

139

141 (RefSec.getName() == "__cfstring" ||

142 RefSec.getName() == "__objc_classrefs"))

143 return false;

144

145 return true;

146}

147

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();

152

153

154 uint32_t FixupOffset = Asm.getFragmentOffset(*Fragment);

155 unsigned Log2Size = 0;

156 int64_t Value = 0;

157 unsigned Index = 0;

158 unsigned Type = 0;

160 const MCSymbol *RelSymbol = nullptr;

161

162 FixupOffset += Fixup.getOffset();

163

164

165 if (IsPCRel)

166 FixedValue += FixupOffset;

167

168

169

170

172 FixedValue = 0;

173

174

175

176

178 reportError(Fixup.getLoc(), "conditional branch requires assembler-local"

179 " label. '" +

180 Target.getAddSym()->getName() +

181 "' is external.");

182 return;

183 }

184

185

186

188 reportError(Fixup.getLoc(), "Invalid relocation on conditional branch!");

189 return;

190 }

191

192 if (!getAArch64FixupKindMachOInfo(Fixup, Type, Target.getSpecifier(),

193 Log2Size, Asm)) {

195 return;

196 }

197

199

200 if (Target.isAbsolute()) {

201

202

204

205 if (IsPCRel) {

206 reportError(Fixup.getLoc(), "PC relative absolute relocation!");

207 return;

208

209

210

211 }

212 } else if (auto *B = Target.getSubSym()) {

216

217

218

219

221 Asm.getSymbolOffset(*B) ==

222 Asm.getFragmentOffset(*Fragment) + Fixup.getOffset()) {

223

225 IsPCRel = 1;

226 MachO::any_relocation_info MRE;

227 MRE.r_word0 = FixupOffset;

228 MRE.r_word1 = (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);

230 return;

232

233 reportError(Fixup.getLoc(), "unsupported relocation of modified symbol");

234 return;

235 }

236

237

238 if (IsPCRel) {

239 reportError(Fixup.getLoc(), "unsupported pc-relative relocation of "

240 "difference");

241 return;

242 }

243

244

245

246

247

248

249

250 if (!A_Base) {

252 "unsupported relocation of local symbol '" + A->getName() +

253 "'. Must have non-local symbol earlier in section.");

254 return;

255 }

256 if (!B_Base) {

258 "unsupported relocation of local symbol '" + B->getName() +

259 "'. Must have non-local symbol earlier in section.");

260 return;

261 }

262

263 if (A_Base == B_Base && A_Base) {

264 reportError(Fixup.getLoc(), "unsupported relocation with identical base");

265 return;

266 }

267

276

278

279 MachO::any_relocation_info MRE;

280 MRE.r_word0 = FixupOffset;

281 MRE.r_word1 = (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);

283

284 RelSymbol = B_Base;

286 } else {

288 const MCSectionMachO &Section =

289 static_cast<const MCSectionMachO &>(*Fragment->getParent());

290

291 bool CanUseLocalRelocation =

293 if (Symbol->isTemporary() && (Value || !CanUseLocalRelocation)) {

294

295

296 if (Symbol->isInSection()) {

298 "unsupported relocation of local symbol '" +

300 "'. Must have non-local symbol earlier in section.");

301 return;

302 }

303 const MCSection &Sec = Symbol->getSection();

305 Symbol->setUsedInReloc();

306 }

307

309

310

311

313

314

315

316

317

318 if (Symbol->isInSection()) {

320 Base = nullptr;

321 }

322

323

324

325

327 RelSymbol = Base;

328

329

330 if (Base != Symbol)

331 Value += Asm.getSymbolOffset(*Symbol) - Asm.getSymbolOffset(*Base);

332 } else if (Symbol->isInSection()) {

333 if (!CanUseLocalRelocation) {

335 "unsupported relocation of local symbol '" +

337 "'. Must have non-local symbol earlier in section.");

338 return;

339 }

340

341

342 const MCSection &Sec = Symbol->getSection();

345

346 if (IsPCRel)

348 (1ULL << Log2Size);

349 } else {

351 "This constant variable should have been expanded during evaluation");

352 }

353 }

354

355

356

357

363 reportError(Fixup.getLoc(), "addend too big for relocation");

364 return;

365 }

366

367 MachO::any_relocation_info MRE;

368 MRE.r_word0 = FixupOffset;

370 (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);

372

373

376 RelSymbol = nullptr;

377 IsPCRel = 0;

378 Log2Size = 2;

379

380

382 }

383

387

389

390 if (IsPCRel) {

391 reportError(Fixup.getLoc(), "invalid PC relative auth relocation");

392 return;

393 }

394

395 if (Log2Size != 3) {

397 "invalid auth relocation size, must be 8 bytes");

398 return;

399 }

400

401 if (Target.getSubSym()) {

403 "invalid auth relocation, can't reference two symbols");

404 return;

405 }

406

407 uint16_t Discriminator = Expr->getDiscriminator();

409

411 reportError(Fixup.getLoc(), "addend too big for relocation");

412 return;

413 }

414

416 Value = (uint32_t(Value)) | (uint64_t(Discriminator) << 32) |

417 (uint64_t(Expr->hasAddressDiversity()) << 48) |

418 (uint64_t(Key) << 49) | (1ULL << 63);

419 }

420

421

422 FixedValue = Value;

423

424

425 MachO::any_relocation_info MRE;

426 MRE.r_word0 = FixupOffset;

428 (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);

430}

431

432std::unique_ptr

434 bool IsILP32) {

435 return std::make_unique(CPUType, CPUSubtype,

436 IsILP32);

437}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static bool canUseLocalRelocation(const MCSectionMachO &Section, const MCSymbol &Symbol, unsigned Log2Size)

Definition AArch64MachObjectWriter.cpp:122

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 - Return the argument parameter cast to the specified type.

std::unique_ptr< MCObjectTargetWriter > createAArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype, bool IsILP32)

Definition AArch64MachObjectWriter.cpp:433