172062f5744557e270a38192554c3126ea5f97434Tim Northover//===-- AArch64ELFObjectWriter.cpp - AArch64 ELF Writer -------------------===//
272062f5744557e270a38192554c3126ea5f97434Tim Northover//
372062f5744557e270a38192554c3126ea5f97434Tim Northover//                     The LLVM Compiler Infrastructure
472062f5744557e270a38192554c3126ea5f97434Tim Northover//
572062f5744557e270a38192554c3126ea5f97434Tim Northover// This file is distributed under the University of Illinois Open Source
672062f5744557e270a38192554c3126ea5f97434Tim Northover// License. See LICENSE.TXT for details.
772062f5744557e270a38192554c3126ea5f97434Tim Northover//
872062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===//
95bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover//
105bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover// This file handles ELF-specific object emission, converting LLVM's internal
115bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover// fixups into the appropriate relocations.
125bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover//
135bd6cb2dabf3fea9cb9fa0b275fbc7ceb85ba970Tim Northover//===----------------------------------------------------------------------===//
1472062f5744557e270a38192554c3126ea5f97434Tim Northover
1572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "MCTargetDesc/AArch64FixupKinds.h"
16dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "MCTargetDesc/AArch64MCExpr.h"
1772062f5744557e270a38192554c3126ea5f97434Tim Northover#include "MCTargetDesc/AArch64MCTargetDesc.h"
18de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/MC/MCContext.h"
1972062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCELFObjectWriter.h"
2072062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCValue.h"
2172062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/ErrorHandling.h"
2272062f5744557e270a38192554c3126ea5f97434Tim Northover
2372062f5744557e270a38192554c3126ea5f97434Tim Northoverusing namespace llvm;
2472062f5744557e270a38192554c3126ea5f97434Tim Northover
2572062f5744557e270a38192554c3126ea5f97434Tim Northovernamespace {
2672062f5744557e270a38192554c3126ea5f97434Tim Northoverclass AArch64ELFObjectWriter : public MCELFObjectTargetWriter {
2772062f5744557e270a38192554c3126ea5f97434Tim Northoverpublic:
2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  AArch64ELFObjectWriter(uint8_t OSABI, bool IsLittleEndian);
2972062f5744557e270a38192554c3126ea5f97434Tim Northover
300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  ~AArch64ELFObjectWriter() override;
3172062f5744557e270a38192554c3126ea5f97434Tim Northover
3272062f5744557e270a38192554c3126ea5f97434Tim Northoverprotected:
33de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
34de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                        const MCFixup &Fixup, bool IsPCRel) const override;
3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3672062f5744557e270a38192554c3126ea5f97434Tim Northoverprivate:
3772062f5744557e270a38192554c3126ea5f97434Tim Northover};
3872062f5744557e270a38192554c3126ea5f97434Tim Northover}
3972062f5744557e270a38192554c3126ea5f97434Tim Northover
40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64ELFObjectWriter::AArch64ELFObjectWriter(uint8_t OSABI,
41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                               bool IsLittleEndian)
42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    : MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, ELF::EM_AARCH64,
43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                              /*HasRelocationAddend*/ true) {}
4472062f5744557e270a38192554c3126ea5f97434Tim Northover
45dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAArch64ELFObjectWriter::~AArch64ELFObjectWriter() {}
4672062f5744557e270a38192554c3126ea5f97434Tim Northover
47de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarunsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
48de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                              const MCValue &Target,
49de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                              const MCFixup &Fixup,
50de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                              bool IsPCRel) const {
51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64MCExpr::VariantKind RefKind =
52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind);
54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool IsNC = AArch64MCExpr::isNotChecked(RefKind);
55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert((!Target.getSymA() ||
57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None) &&
58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         "Should only be expression-level modifiers here");
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert((!Target.getSymB() ||
61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None) &&
62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         "Should only be expression-level modifiers here");
63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
6472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (IsPCRel) {
6572062f5744557e270a38192554c3126ea5f97434Tim Northover    switch ((unsigned)Fixup.getKind()) {
66de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    case FK_Data_1:
67de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
68de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return ELF::R_AARCH64_NONE;
6972062f5744557e270a38192554c3126ea5f97434Tim Northover    case FK_Data_2:
7072062f5744557e270a38192554c3126ea5f97434Tim Northover      return ELF::R_AARCH64_PREL16;
71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case FK_Data_4:
72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return ELF::R_AARCH64_PREL32;
73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case FK_Data_8:
74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return ELF::R_AARCH64_PREL64;
75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::fixup_aarch64_pcrel_adr_imm21:
76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(SymLoc == AArch64MCExpr::VK_NONE && "unexpected ADR relocation");
77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return ELF::R_AARCH64_ADR_PREL_LO21;
78dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::fixup_aarch64_pcrel_adrp_imm21:
79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_ABS && !IsNC)
80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_ADR_PREL_PG_HI21;
81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC)
82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_ADR_GOT_PAGE;
83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC)
84dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21;
85dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC)
86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        return ELF::R_AARCH64_TLSDESC_ADR_PAGE21;
87de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Ctx.reportError(Fixup.getLoc(),
88de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                      "invalid symbol kind for ADRP relocation");
89de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return ELF::R_AARCH64_NONE;
90dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::fixup_aarch64_pcrel_branch26:
91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return ELF::R_AARCH64_JUMP26;
92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::fixup_aarch64_pcrel_call26:
93dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return ELF::R_AARCH64_CALL26;
94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::fixup_aarch64_ldr_pcrel_imm19:
95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_GOTTPREL)
96dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSIE_LD_GOTTPREL_PREL19;
97dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return ELF::R_AARCH64_LD_PREL_LO19;
98dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::fixup_aarch64_pcrel_branch14:
99dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return ELF::R_AARCH64_TSTBR14;
100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::fixup_aarch64_pcrel_branch19:
101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return ELF::R_AARCH64_CONDBR19;
102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    default:
103de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Ctx.reportError(Fixup.getLoc(), "Unsupported pc-relative fixup kind");
104de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return ELF::R_AARCH64_NONE;
10572062f5744557e270a38192554c3126ea5f97434Tim Northover    }
10672062f5744557e270a38192554c3126ea5f97434Tim Northover  } else {
10772062f5744557e270a38192554c3126ea5f97434Tim Northover    switch ((unsigned)Fixup.getKind()) {
108de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    case FK_Data_1:
109de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
110de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return ELF::R_AARCH64_NONE;
11172062f5744557e270a38192554c3126ea5f97434Tim Northover    case FK_Data_2:
11272062f5744557e270a38192554c3126ea5f97434Tim Northover      return ELF::R_AARCH64_ABS16;
113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case FK_Data_4:
114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return ELF::R_AARCH64_ABS32;
115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case FK_Data_8:
116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return ELF::R_AARCH64_ABS64;
117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::fixup_aarch64_add_imm12:
118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_DTPREL_HI12)
119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_ADD_DTPREL_HI12;
120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_TPREL_HI12)
121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12;
122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_DTPREL_LO12_NC)
123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC;
124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_DTPREL_LO12)
125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_ADD_DTPREL_LO12;
126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_TPREL_LO12_NC)
127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC;
128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_TPREL_LO12)
129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12;
130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12)
131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSDESC_ADD_LO12_NC;
132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_ADD_ABS_LO12_NC;
13472062f5744557e270a38192554c3126ea5f97434Tim Northover
135de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Ctx.reportError(Fixup.getLoc(),
136de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                      "invalid fixup for add (uimm12) instruction");
137de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return ELF::R_AARCH64_NONE;
138dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::fixup_aarch64_ldst_imm12_scale1:
139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_LDST8_ABS_LO12_NC;
141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_LDST8_DTPREL_LO12;
143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC;
145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
146dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12;
147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC;
14972062f5744557e270a38192554c3126ea5f97434Tim Northover
150de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Ctx.reportError(Fixup.getLoc(),
151de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                      "invalid fixup for 8-bit load/store instruction");
152de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return ELF::R_AARCH64_NONE;
153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::fixup_aarch64_ldst_imm12_scale2:
154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_LDST16_ABS_LO12_NC;
156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_LDST16_DTPREL_LO12;
158dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC;
160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
161dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12;
162dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC;
16472062f5744557e270a38192554c3126ea5f97434Tim Northover
165de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Ctx.reportError(Fixup.getLoc(),
166de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                      "invalid fixup for 16-bit load/store instruction");
167de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return ELF::R_AARCH64_NONE;
168dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::fixup_aarch64_ldst_imm12_scale4:
169dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
170dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_LDST32_ABS_LO12_NC;
171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_LDST32_DTPREL_LO12;
173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC;
175dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
176dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12;
177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
178dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC;
17972062f5744557e270a38192554c3126ea5f97434Tim Northover
180de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Ctx.reportError(Fixup.getLoc(),
181de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                      "invalid fixup for 32-bit load/store instruction");
182de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return ELF::R_AARCH64_NONE;
183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::fixup_aarch64_ldst_imm12_scale8:
184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_LDST64_ABS_LO12_NC;
186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_GOT && IsNC)
187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_LD64_GOT_LO12_NC;
188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_LDST64_DTPREL_LO12;
190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC;
192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12;
194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC;
196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC)
197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_TLSDESC && IsNC)
199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSDESC_LD64_LO12_NC;
200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
201de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Ctx.reportError(Fixup.getLoc(),
202de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                      "invalid fixup for 64-bit load/store instruction");
203de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return ELF::R_AARCH64_NONE;
204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::fixup_aarch64_ldst_imm12_scale16:
205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_LDST128_ABS_LO12_NC;
207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
208de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Ctx.reportError(Fixup.getLoc(),
209de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                      "invalid fixup for 128-bit load/store instruction");
210de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return ELF::R_AARCH64_NONE;
211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::fixup_aarch64_movw:
212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_ABS_G3)
213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_MOVW_UABS_G3;
214dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_ABS_G2)
215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_MOVW_UABS_G2;
216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_ABS_G2_S)
217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_MOVW_SABS_G2;
218dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_ABS_G2_NC)
219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_MOVW_UABS_G2_NC;
220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_ABS_G1)
221dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_MOVW_UABS_G1;
222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_ABS_G1_S)
223dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_MOVW_SABS_G1;
224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_ABS_G1_NC)
225dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_MOVW_UABS_G1_NC;
226dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_ABS_G0)
227dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_MOVW_UABS_G0;
228dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_ABS_G0_S)
229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_MOVW_SABS_G0;
230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_ABS_G0_NC)
231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_MOVW_UABS_G0_NC;
232dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_DTPREL_G2)
233dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2;
234dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_DTPREL_G1)
235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1;
236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_DTPREL_G1_NC)
237dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC;
238dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_DTPREL_G0)
239dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G0;
240dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_DTPREL_G0_NC)
241dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC;
242dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_TPREL_G2)
243dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G2;
244dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_TPREL_G1)
245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1;
246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_TPREL_G1_NC)
247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC;
248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_TPREL_G0)
249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0;
250dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_TPREL_G0_NC)
251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC;
252dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_GOTTPREL_G1)
253dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1;
254dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (RefKind == AArch64MCExpr::VK_GOTTPREL_G0_NC)
255dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC;
256de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Ctx.reportError(Fixup.getLoc(),
257de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                      "invalid fixup for movz/movk instruction");
258de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return ELF::R_AARCH64_NONE;
259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case AArch64::fixup_aarch64_tlsdesc_call:
260dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return ELF::R_AARCH64_TLSDESC_CALL;
261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    default:
262de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type");
263de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return ELF::R_AARCH64_NONE;
26472062f5744557e270a38192554c3126ea5f97434Tim Northover    }
26572062f5744557e270a38192554c3126ea5f97434Tim Northover  }
26672062f5744557e270a38192554c3126ea5f97434Tim Northover
267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  llvm_unreachable("Unimplemented fixup -> relocation");
26872062f5744557e270a38192554c3126ea5f97434Tim Northover}
26972062f5744557e270a38192554c3126ea5f97434Tim Northover
2700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga NainarMCObjectWriter *llvm::createAArch64ELFObjectWriter(raw_pwrite_stream &OS,
2710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                                   uint8_t OSABI,
2720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                                   bool IsLittleEndian) {
273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCELFObjectTargetWriter *MOTW =
274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      new AArch64ELFObjectWriter(OSABI, IsLittleEndian);
275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return createELFObjectWriter(MOTW, OS, IsLittleEndian);
27672062f5744557e270a38192554c3126ea5f97434Tim Northover}
277