10b57cec5SDimitry Andric //===-- X86ELFObjectWriter.cpp - X86 ELF Writer ---------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "MCTargetDesc/X86FixupKinds.h"
100b57cec5SDimitry Andric #include "MCTargetDesc/X86MCTargetDesc.h"
110b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
120b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
130b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
140b57cec5SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h"
150b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCValue.h"
190b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
200b57cec5SDimitry Andric #include <cassert>
210b57cec5SDimitry Andric #include <cstdint>
220b57cec5SDimitry Andric
230b57cec5SDimitry Andric using namespace llvm;
240b57cec5SDimitry Andric
250b57cec5SDimitry Andric namespace {
260b57cec5SDimitry Andric
270b57cec5SDimitry Andric class X86ELFObjectWriter : public MCELFObjectTargetWriter {
280b57cec5SDimitry Andric public:
290b57cec5SDimitry Andric X86ELFObjectWriter(bool IsELF64, uint8_t OSABI, uint16_t EMachine);
300b57cec5SDimitry Andric ~X86ELFObjectWriter() override = default;
310b57cec5SDimitry Andric
320b57cec5SDimitry Andric protected:
330b57cec5SDimitry Andric unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
340b57cec5SDimitry Andric const MCFixup &Fixup, bool IsPCRel) const override;
350b57cec5SDimitry Andric };
360b57cec5SDimitry Andric
370b57cec5SDimitry Andric } // end anonymous namespace
380b57cec5SDimitry Andric
X86ELFObjectWriter(bool IsELF64,uint8_t OSABI,uint16_t EMachine)390b57cec5SDimitry Andric X86ELFObjectWriter::X86ELFObjectWriter(bool IsELF64, uint8_t OSABI,
400b57cec5SDimitry Andric uint16_t EMachine)
410b57cec5SDimitry Andric : MCELFObjectTargetWriter(IsELF64, OSABI, EMachine,
420b57cec5SDimitry Andric // Only i386 and IAMCU use Rel instead of RelA.
430b57cec5SDimitry Andric /*HasRelocationAddend*/
440b57cec5SDimitry Andric (EMachine != ELF::EM_386) &&
450b57cec5SDimitry Andric (EMachine != ELF::EM_IAMCU)) {}
460b57cec5SDimitry Andric
470b57cec5SDimitry Andric enum X86_64RelType { RT64_NONE, RT64_64, RT64_32, RT64_32S, RT64_16, RT64_8 };
480b57cec5SDimitry Andric
getType64(MCFixupKind Kind,MCSymbolRefExpr::VariantKind & Modifier,bool & IsPCRel)498bcb0991SDimitry Andric static X86_64RelType getType64(MCFixupKind Kind,
500b57cec5SDimitry Andric MCSymbolRefExpr::VariantKind &Modifier,
510b57cec5SDimitry Andric bool &IsPCRel) {
528bcb0991SDimitry Andric switch (unsigned(Kind)) {
530b57cec5SDimitry Andric default:
540b57cec5SDimitry Andric llvm_unreachable("Unimplemented");
550b57cec5SDimitry Andric case FK_NONE:
560b57cec5SDimitry Andric return RT64_NONE;
570b57cec5SDimitry Andric case X86::reloc_global_offset_table8:
580b57cec5SDimitry Andric Modifier = MCSymbolRefExpr::VK_GOT;
590b57cec5SDimitry Andric IsPCRel = true;
600b57cec5SDimitry Andric return RT64_64;
610b57cec5SDimitry Andric case FK_Data_8:
620b57cec5SDimitry Andric return RT64_64;
630b57cec5SDimitry Andric case X86::reloc_signed_4byte:
640b57cec5SDimitry Andric case X86::reloc_signed_4byte_relax:
650b57cec5SDimitry Andric if (Modifier == MCSymbolRefExpr::VK_None && !IsPCRel)
660b57cec5SDimitry Andric return RT64_32S;
670b57cec5SDimitry Andric return RT64_32;
680b57cec5SDimitry Andric case X86::reloc_global_offset_table:
690b57cec5SDimitry Andric Modifier = MCSymbolRefExpr::VK_GOT;
700b57cec5SDimitry Andric IsPCRel = true;
710b57cec5SDimitry Andric return RT64_32;
720b57cec5SDimitry Andric case FK_Data_4:
730b57cec5SDimitry Andric case FK_PCRel_4:
740b57cec5SDimitry Andric case X86::reloc_riprel_4byte:
750b57cec5SDimitry Andric case X86::reloc_riprel_4byte_relax:
760b57cec5SDimitry Andric case X86::reloc_riprel_4byte_relax_rex:
770b57cec5SDimitry Andric case X86::reloc_riprel_4byte_movq_load:
780b57cec5SDimitry Andric return RT64_32;
790b57cec5SDimitry Andric case X86::reloc_branch_4byte_pcrel:
800b57cec5SDimitry Andric Modifier = MCSymbolRefExpr::VK_PLT;
810b57cec5SDimitry Andric return RT64_32;
820b57cec5SDimitry Andric case FK_PCRel_2:
830b57cec5SDimitry Andric case FK_Data_2:
840b57cec5SDimitry Andric return RT64_16;
850b57cec5SDimitry Andric case FK_PCRel_1:
860b57cec5SDimitry Andric case FK_Data_1:
870b57cec5SDimitry Andric return RT64_8;
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric
checkIs32(MCContext & Ctx,SMLoc Loc,X86_64RelType Type)910b57cec5SDimitry Andric static void checkIs32(MCContext &Ctx, SMLoc Loc, X86_64RelType Type) {
920b57cec5SDimitry Andric if (Type != RT64_32)
930b57cec5SDimitry Andric Ctx.reportError(Loc,
940b57cec5SDimitry Andric "32 bit reloc applied to a field with a different size");
950b57cec5SDimitry Andric }
960b57cec5SDimitry Andric
checkIs64(MCContext & Ctx,SMLoc Loc,X86_64RelType Type)97e8d8bef9SDimitry Andric static void checkIs64(MCContext &Ctx, SMLoc Loc, X86_64RelType Type) {
98e8d8bef9SDimitry Andric if (Type != RT64_64)
99e8d8bef9SDimitry Andric Ctx.reportError(Loc,
100e8d8bef9SDimitry Andric "64 bit reloc applied to a field with a different size");
101e8d8bef9SDimitry Andric }
102e8d8bef9SDimitry Andric
getRelocType64(MCContext & Ctx,SMLoc Loc,MCSymbolRefExpr::VariantKind Modifier,X86_64RelType Type,bool IsPCRel,MCFixupKind Kind)1030b57cec5SDimitry Andric static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
1040b57cec5SDimitry Andric MCSymbolRefExpr::VariantKind Modifier,
1050b57cec5SDimitry Andric X86_64RelType Type, bool IsPCRel,
1068bcb0991SDimitry Andric MCFixupKind Kind) {
1070b57cec5SDimitry Andric switch (Modifier) {
1080b57cec5SDimitry Andric default:
1090b57cec5SDimitry Andric llvm_unreachable("Unimplemented");
1100b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None:
1110b57cec5SDimitry Andric case MCSymbolRefExpr::VK_X86_ABS8:
1120b57cec5SDimitry Andric switch (Type) {
1130b57cec5SDimitry Andric case RT64_NONE:
1140b57cec5SDimitry Andric if (Modifier == MCSymbolRefExpr::VK_None)
1150b57cec5SDimitry Andric return ELF::R_X86_64_NONE;
1160b57cec5SDimitry Andric llvm_unreachable("Unimplemented");
1170b57cec5SDimitry Andric case RT64_64:
1180b57cec5SDimitry Andric return IsPCRel ? ELF::R_X86_64_PC64 : ELF::R_X86_64_64;
1190b57cec5SDimitry Andric case RT64_32:
1200b57cec5SDimitry Andric return IsPCRel ? ELF::R_X86_64_PC32 : ELF::R_X86_64_32;
1210b57cec5SDimitry Andric case RT64_32S:
1220b57cec5SDimitry Andric return ELF::R_X86_64_32S;
1230b57cec5SDimitry Andric case RT64_16:
1240b57cec5SDimitry Andric return IsPCRel ? ELF::R_X86_64_PC16 : ELF::R_X86_64_16;
1250b57cec5SDimitry Andric case RT64_8:
1260b57cec5SDimitry Andric return IsPCRel ? ELF::R_X86_64_PC8 : ELF::R_X86_64_8;
1270b57cec5SDimitry Andric }
1280b57cec5SDimitry Andric llvm_unreachable("unexpected relocation type!");
1290b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOT:
1300b57cec5SDimitry Andric switch (Type) {
1310b57cec5SDimitry Andric case RT64_64:
1320b57cec5SDimitry Andric return IsPCRel ? ELF::R_X86_64_GOTPC64 : ELF::R_X86_64_GOT64;
1330b57cec5SDimitry Andric case RT64_32:
1340b57cec5SDimitry Andric return IsPCRel ? ELF::R_X86_64_GOTPC32 : ELF::R_X86_64_GOT32;
1350b57cec5SDimitry Andric case RT64_32S:
1360b57cec5SDimitry Andric case RT64_16:
1370b57cec5SDimitry Andric case RT64_8:
1380b57cec5SDimitry Andric case RT64_NONE:
1390b57cec5SDimitry Andric llvm_unreachable("Unimplemented");
1400b57cec5SDimitry Andric }
1410b57cec5SDimitry Andric llvm_unreachable("unexpected relocation type!");
1420b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOTOFF:
1430b57cec5SDimitry Andric assert(!IsPCRel);
1445f757f3fSDimitry Andric if (Type != RT64_64)
1455f757f3fSDimitry Andric Ctx.reportError(Loc, "unsupported relocation type");
1460b57cec5SDimitry Andric return ELF::R_X86_64_GOTOFF64;
1470b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TPOFF:
1480b57cec5SDimitry Andric assert(!IsPCRel);
1490b57cec5SDimitry Andric switch (Type) {
1500b57cec5SDimitry Andric case RT64_64:
1510b57cec5SDimitry Andric return ELF::R_X86_64_TPOFF64;
1520b57cec5SDimitry Andric case RT64_32:
1530b57cec5SDimitry Andric return ELF::R_X86_64_TPOFF32;
1540b57cec5SDimitry Andric case RT64_32S:
1550b57cec5SDimitry Andric case RT64_16:
1560b57cec5SDimitry Andric case RT64_8:
1570b57cec5SDimitry Andric case RT64_NONE:
1580b57cec5SDimitry Andric llvm_unreachable("Unimplemented");
1590b57cec5SDimitry Andric }
1600b57cec5SDimitry Andric llvm_unreachable("unexpected relocation type!");
1610b57cec5SDimitry Andric case MCSymbolRefExpr::VK_DTPOFF:
1620b57cec5SDimitry Andric assert(!IsPCRel);
1630b57cec5SDimitry Andric switch (Type) {
1640b57cec5SDimitry Andric case RT64_64:
1650b57cec5SDimitry Andric return ELF::R_X86_64_DTPOFF64;
1660b57cec5SDimitry Andric case RT64_32:
1670b57cec5SDimitry Andric return ELF::R_X86_64_DTPOFF32;
1680b57cec5SDimitry Andric case RT64_32S:
1690b57cec5SDimitry Andric case RT64_16:
1700b57cec5SDimitry Andric case RT64_8:
1710b57cec5SDimitry Andric case RT64_NONE:
1720b57cec5SDimitry Andric llvm_unreachable("Unimplemented");
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric llvm_unreachable("unexpected relocation type!");
1750b57cec5SDimitry Andric case MCSymbolRefExpr::VK_SIZE:
1760b57cec5SDimitry Andric assert(!IsPCRel);
1770b57cec5SDimitry Andric switch (Type) {
1780b57cec5SDimitry Andric case RT64_64:
1790b57cec5SDimitry Andric return ELF::R_X86_64_SIZE64;
1800b57cec5SDimitry Andric case RT64_32:
1810b57cec5SDimitry Andric return ELF::R_X86_64_SIZE32;
1820b57cec5SDimitry Andric case RT64_32S:
1830b57cec5SDimitry Andric case RT64_16:
1840b57cec5SDimitry Andric case RT64_8:
1850b57cec5SDimitry Andric case RT64_NONE:
1860b57cec5SDimitry Andric llvm_unreachable("Unimplemented");
1870b57cec5SDimitry Andric }
1880b57cec5SDimitry Andric llvm_unreachable("unexpected relocation type!");
1890b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSCALL:
1900b57cec5SDimitry Andric return ELF::R_X86_64_TLSDESC_CALL;
1910b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSDESC:
1920b57cec5SDimitry Andric return ELF::R_X86_64_GOTPC32_TLSDESC;
1930b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSGD:
1940b57cec5SDimitry Andric checkIs32(Ctx, Loc, Type);
1950b57cec5SDimitry Andric return ELF::R_X86_64_TLSGD;
1960b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOTTPOFF:
1970b57cec5SDimitry Andric checkIs32(Ctx, Loc, Type);
1980b57cec5SDimitry Andric return ELF::R_X86_64_GOTTPOFF;
1990b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSLD:
2000b57cec5SDimitry Andric checkIs32(Ctx, Loc, Type);
2010b57cec5SDimitry Andric return ELF::R_X86_64_TLSLD;
2020b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PLT:
2030b57cec5SDimitry Andric checkIs32(Ctx, Loc, Type);
2040b57cec5SDimitry Andric return ELF::R_X86_64_PLT32;
2050b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOTPCREL:
2060b57cec5SDimitry Andric checkIs32(Ctx, Loc, Type);
2070b57cec5SDimitry Andric // Older versions of ld.bfd/ld.gold/lld
2080b57cec5SDimitry Andric // do not support GOTPCRELX/REX_GOTPCRELX,
2090b57cec5SDimitry Andric // and we want to keep back-compatibility.
210*0fca6ea1SDimitry Andric if (!Ctx.getTargetOptions()->X86RelaxRelocations)
2110b57cec5SDimitry Andric return ELF::R_X86_64_GOTPCREL;
2128bcb0991SDimitry Andric switch (unsigned(Kind)) {
2130b57cec5SDimitry Andric default:
2140b57cec5SDimitry Andric return ELF::R_X86_64_GOTPCREL;
2150b57cec5SDimitry Andric case X86::reloc_riprel_4byte_relax:
2160b57cec5SDimitry Andric return ELF::R_X86_64_GOTPCRELX;
2170b57cec5SDimitry Andric case X86::reloc_riprel_4byte_relax_rex:
2180b57cec5SDimitry Andric case X86::reloc_riprel_4byte_movq_load:
2190b57cec5SDimitry Andric return ELF::R_X86_64_REX_GOTPCRELX;
2200b57cec5SDimitry Andric }
2210b57cec5SDimitry Andric llvm_unreachable("unexpected relocation type!");
222349cc55cSDimitry Andric case MCSymbolRefExpr::VK_GOTPCREL_NORELAX:
223349cc55cSDimitry Andric checkIs32(Ctx, Loc, Type);
224349cc55cSDimitry Andric return ELF::R_X86_64_GOTPCREL;
225e8d8bef9SDimitry Andric case MCSymbolRefExpr::VK_X86_PLTOFF:
226e8d8bef9SDimitry Andric checkIs64(Ctx, Loc, Type);
227e8d8bef9SDimitry Andric return ELF::R_X86_64_PLTOFF64;
2280b57cec5SDimitry Andric }
2290b57cec5SDimitry Andric }
2300b57cec5SDimitry Andric
2310b57cec5SDimitry Andric enum X86_32RelType { RT32_NONE, RT32_32, RT32_16, RT32_8 };
2320b57cec5SDimitry Andric
getRelocType32(MCContext & Ctx,SMLoc Loc,MCSymbolRefExpr::VariantKind Modifier,X86_32RelType Type,bool IsPCRel,MCFixupKind Kind)2335f757f3fSDimitry Andric static unsigned getRelocType32(MCContext &Ctx, SMLoc Loc,
2340b57cec5SDimitry Andric MCSymbolRefExpr::VariantKind Modifier,
2350b57cec5SDimitry Andric X86_32RelType Type, bool IsPCRel,
2368bcb0991SDimitry Andric MCFixupKind Kind) {
2370b57cec5SDimitry Andric switch (Modifier) {
2380b57cec5SDimitry Andric default:
2390b57cec5SDimitry Andric llvm_unreachable("Unimplemented");
2400b57cec5SDimitry Andric case MCSymbolRefExpr::VK_None:
2410b57cec5SDimitry Andric case MCSymbolRefExpr::VK_X86_ABS8:
2420b57cec5SDimitry Andric switch (Type) {
2430b57cec5SDimitry Andric case RT32_NONE:
2440b57cec5SDimitry Andric if (Modifier == MCSymbolRefExpr::VK_None)
2450b57cec5SDimitry Andric return ELF::R_386_NONE;
2460b57cec5SDimitry Andric llvm_unreachable("Unimplemented");
2470b57cec5SDimitry Andric case RT32_32:
2480b57cec5SDimitry Andric return IsPCRel ? ELF::R_386_PC32 : ELF::R_386_32;
2490b57cec5SDimitry Andric case RT32_16:
2500b57cec5SDimitry Andric return IsPCRel ? ELF::R_386_PC16 : ELF::R_386_16;
2510b57cec5SDimitry Andric case RT32_8:
2520b57cec5SDimitry Andric return IsPCRel ? ELF::R_386_PC8 : ELF::R_386_8;
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric llvm_unreachable("unexpected relocation type!");
2550b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOT:
2565f757f3fSDimitry Andric if (Type != RT32_32)
2575f757f3fSDimitry Andric break;
2580b57cec5SDimitry Andric if (IsPCRel)
2590b57cec5SDimitry Andric return ELF::R_386_GOTPC;
2600b57cec5SDimitry Andric // Older versions of ld.bfd/ld.gold/lld do not support R_386_GOT32X and we
2610b57cec5SDimitry Andric // want to maintain compatibility.
262*0fca6ea1SDimitry Andric if (!Ctx.getTargetOptions()->X86RelaxRelocations)
2630b57cec5SDimitry Andric return ELF::R_386_GOT32;
2640b57cec5SDimitry Andric
2658bcb0991SDimitry Andric return Kind == MCFixupKind(X86::reloc_signed_4byte_relax)
2668bcb0991SDimitry Andric ? ELF::R_386_GOT32X
2670b57cec5SDimitry Andric : ELF::R_386_GOT32;
2680b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOTOFF:
2690b57cec5SDimitry Andric assert(!IsPCRel);
2705f757f3fSDimitry Andric if (Type != RT32_32)
2715f757f3fSDimitry Andric break;
2720b57cec5SDimitry Andric return ELF::R_386_GOTOFF;
2730b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSCALL:
2740b57cec5SDimitry Andric return ELF::R_386_TLS_DESC_CALL;
2750b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSDESC:
2760b57cec5SDimitry Andric return ELF::R_386_TLS_GOTDESC;
2770b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TPOFF:
2785f757f3fSDimitry Andric if (Type != RT32_32)
2795f757f3fSDimitry Andric break;
2800b57cec5SDimitry Andric assert(!IsPCRel);
2810b57cec5SDimitry Andric return ELF::R_386_TLS_LE_32;
2820b57cec5SDimitry Andric case MCSymbolRefExpr::VK_DTPOFF:
2835f757f3fSDimitry Andric if (Type != RT32_32)
2845f757f3fSDimitry Andric break;
2850b57cec5SDimitry Andric assert(!IsPCRel);
2860b57cec5SDimitry Andric return ELF::R_386_TLS_LDO_32;
2870b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSGD:
2885f757f3fSDimitry Andric if (Type != RT32_32)
2895f757f3fSDimitry Andric break;
2900b57cec5SDimitry Andric assert(!IsPCRel);
2910b57cec5SDimitry Andric return ELF::R_386_TLS_GD;
2920b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOTTPOFF:
2935f757f3fSDimitry Andric if (Type != RT32_32)
2945f757f3fSDimitry Andric break;
2950b57cec5SDimitry Andric assert(!IsPCRel);
2960b57cec5SDimitry Andric return ELF::R_386_TLS_IE_32;
2970b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PLT:
2985f757f3fSDimitry Andric if (Type != RT32_32)
2995f757f3fSDimitry Andric break;
3000b57cec5SDimitry Andric return ELF::R_386_PLT32;
3010b57cec5SDimitry Andric case MCSymbolRefExpr::VK_INDNTPOFF:
3025f757f3fSDimitry Andric if (Type != RT32_32)
3035f757f3fSDimitry Andric break;
3040b57cec5SDimitry Andric assert(!IsPCRel);
3050b57cec5SDimitry Andric return ELF::R_386_TLS_IE;
3060b57cec5SDimitry Andric case MCSymbolRefExpr::VK_NTPOFF:
3075f757f3fSDimitry Andric if (Type != RT32_32)
3085f757f3fSDimitry Andric break;
3090b57cec5SDimitry Andric assert(!IsPCRel);
3100b57cec5SDimitry Andric return ELF::R_386_TLS_LE;
3110b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOTNTPOFF:
3125f757f3fSDimitry Andric if (Type != RT32_32)
3135f757f3fSDimitry Andric break;
3140b57cec5SDimitry Andric assert(!IsPCRel);
3150b57cec5SDimitry Andric return ELF::R_386_TLS_GOTIE;
3160b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSLDM:
3175f757f3fSDimitry Andric if (Type != RT32_32)
3185f757f3fSDimitry Andric break;
3190b57cec5SDimitry Andric assert(!IsPCRel);
3200b57cec5SDimitry Andric return ELF::R_386_TLS_LDM;
3210b57cec5SDimitry Andric }
3225f757f3fSDimitry Andric Ctx.reportError(Loc, "unsupported relocation type");
3235f757f3fSDimitry Andric return ELF::R_386_NONE;
3240b57cec5SDimitry Andric }
3250b57cec5SDimitry Andric
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const3260b57cec5SDimitry Andric unsigned X86ELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
3270b57cec5SDimitry Andric const MCFixup &Fixup,
3280b57cec5SDimitry Andric bool IsPCRel) const {
3298bcb0991SDimitry Andric MCFixupKind Kind = Fixup.getKind();
3305ffd83dbSDimitry Andric if (Kind >= FirstLiteralRelocationKind)
3315ffd83dbSDimitry Andric return Kind - FirstLiteralRelocationKind;
3325ffd83dbSDimitry Andric MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
3330b57cec5SDimitry Andric X86_64RelType Type = getType64(Kind, Modifier, IsPCRel);
3340b57cec5SDimitry Andric if (getEMachine() == ELF::EM_X86_64)
3350b57cec5SDimitry Andric return getRelocType64(Ctx, Fixup.getLoc(), Modifier, Type, IsPCRel, Kind);
3360b57cec5SDimitry Andric
3370b57cec5SDimitry Andric assert((getEMachine() == ELF::EM_386 || getEMachine() == ELF::EM_IAMCU) &&
3380b57cec5SDimitry Andric "Unsupported ELF machine type.");
33906c3fb27SDimitry Andric
34006c3fb27SDimitry Andric X86_32RelType RelType = RT32_NONE;
34106c3fb27SDimitry Andric switch (Type) {
34206c3fb27SDimitry Andric case RT64_NONE:
34306c3fb27SDimitry Andric break;
34406c3fb27SDimitry Andric case RT64_64:
34506c3fb27SDimitry Andric Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
3465f757f3fSDimitry Andric return ELF::R_386_NONE;
34706c3fb27SDimitry Andric case RT64_32:
34806c3fb27SDimitry Andric case RT64_32S:
34906c3fb27SDimitry Andric RelType = RT32_32;
35006c3fb27SDimitry Andric break;
35106c3fb27SDimitry Andric case RT64_16:
35206c3fb27SDimitry Andric RelType = RT32_16;
35306c3fb27SDimitry Andric break;
35406c3fb27SDimitry Andric case RT64_8:
35506c3fb27SDimitry Andric RelType = RT32_8;
35606c3fb27SDimitry Andric break;
35706c3fb27SDimitry Andric }
3585f757f3fSDimitry Andric return getRelocType32(Ctx, Fixup.getLoc(), Modifier, RelType, IsPCRel, Kind);
3590b57cec5SDimitry Andric }
3600b57cec5SDimitry Andric
3610b57cec5SDimitry Andric std::unique_ptr<MCObjectTargetWriter>
createX86ELFObjectWriter(bool IsELF64,uint8_t OSABI,uint16_t EMachine)3620b57cec5SDimitry Andric llvm::createX86ELFObjectWriter(bool IsELF64, uint8_t OSABI, uint16_t EMachine) {
3638bcb0991SDimitry Andric return std::make_unique<X86ELFObjectWriter>(IsELF64, OSABI, EMachine);
3640b57cec5SDimitry Andric }
365