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 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 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 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 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 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 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 3260b57cec5SDimitry 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> 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