1edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola//===-- X86ELFObjectWriter.cpp - X86 ELF Writer ---------------------------===//
2edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola//
3edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola//                     The LLVM Compiler Infrastructure
4edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola//
5edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola// This file is distributed under the University of Illinois Open Source
6edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola// License. See LICENSE.TXT for details.
7edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola//
8edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola//===----------------------------------------------------------------------===//
9edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
10edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola#include "MCTargetDesc/X86FixupKinds.h"
11edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola#include "MCTargetDesc/X86MCTargetDesc.h"
12edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola#include "llvm/MC/MCELFObjectWriter.h"
13edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola#include "llvm/MC/MCExpr.h"
14edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola#include "llvm/MC/MCValue.h"
15edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola#include "llvm/Support/ELF.h"
16edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola#include "llvm/Support/ErrorHandling.h"
17edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
18edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindolausing namespace llvm;
19edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
20edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindolanamespace {
21edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola  class X86ELFObjectWriter : public MCELFObjectTargetWriter {
22edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola  public:
23678c35c3861df3d5882553da45e79a89dae20294Michael Liao    X86ELFObjectWriter(bool IsELF64, uint8_t OSABI, uint16_t EMachine);
24edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
25edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola    virtual ~X86ELFObjectWriter();
26edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola  protected:
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          bool IsPCRel) const override;
29edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola  };
30edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola}
31edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
32678c35c3861df3d5882553da45e79a89dae20294Michael LiaoX86ELFObjectWriter::X86ELFObjectWriter(bool IsELF64, uint8_t OSABI,
33678c35c3861df3d5882553da45e79a89dae20294Michael Liao                                       uint16_t EMachine)
34678c35c3861df3d5882553da45e79a89dae20294Michael Liao  : MCELFObjectTargetWriter(IsELF64, OSABI, EMachine,
35678c35c3861df3d5882553da45e79a89dae20294Michael Liao                            // Only i386 uses Rel instead of RelA.
36678c35c3861df3d5882553da45e79a89dae20294Michael Liao                            /*HasRelocationAddend*/ EMachine != ELF::EM_386) {}
37edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
38edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael EspindolaX86ELFObjectWriter::~X86ELFObjectWriter()
39edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola{}
40edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
41edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindolaunsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
42edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola                                          const MCFixup &Fixup,
4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                          bool IsPCRel) const {
44edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola  // determine the type of the relocation
45edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
47edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola  unsigned Type;
48678c35c3861df3d5882553da45e79a89dae20294Michael Liao  if (getEMachine() == ELF::EM_X86_64) {
49edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola    if (IsPCRel) {
50edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      switch ((unsigned)Fixup.getKind()) {
51edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      default: llvm_unreachable("invalid fixup kind!");
52edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
53edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_Data_8: Type = ELF::R_X86_64_PC64; break;
54edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_Data_4: Type = ELF::R_X86_64_PC32; break;
55edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_Data_2: Type = ELF::R_X86_64_PC16; break;
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      case FK_Data_1: Type = ELF::R_X86_64_PC8; break;
57edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
58edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_PCRel_8:
59edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        assert(Modifier == MCSymbolRefExpr::VK_None);
60edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        Type = ELF::R_X86_64_PC64;
61edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        break;
62edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case X86::reloc_signed_4byte:
63edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case X86::reloc_riprel_4byte_movq_load:
64edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case X86::reloc_riprel_4byte:
65edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_PCRel_4:
66edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        switch (Modifier) {
67edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        default:
68edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          llvm_unreachable("Unimplemented");
69edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_None:
70edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_X86_64_PC32;
71edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
72edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_PLT:
73edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_X86_64_PLT32;
74edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
75edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_GOTPCREL:
76edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_X86_64_GOTPCREL;
77edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
78edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_GOTTPOFF:
79edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_X86_64_GOTTPOFF;
80edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        break;
81edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_TLSGD:
82edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_X86_64_TLSGD;
83edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
84edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_TLSLD:
85edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_X86_64_TLSLD;
86edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
87edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        }
88edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        break;
89edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_PCRel_2:
90edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        assert(Modifier == MCSymbolRefExpr::VK_None);
91edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        Type = ELF::R_X86_64_PC16;
92edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        break;
93edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_PCRel_1:
94edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        assert(Modifier == MCSymbolRefExpr::VK_None);
95edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        Type = ELF::R_X86_64_PC8;
96edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        break;
97edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      }
98edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola    } else {
99edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      switch ((unsigned)Fixup.getKind()) {
100edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      default: llvm_unreachable("invalid fixup kind!");
101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case X86::reloc_global_offset_table8:
102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Type = ELF::R_X86_64_GOTPC64;
103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case X86::reloc_global_offset_table:
105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Type = ELF::R_X86_64_GOTPC32;
106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
107c084c0945b0530180e8969f5e2017d02d06db130David Blaikie      case FK_Data_8:
108c084c0945b0530180e8969f5e2017d02d06db130David Blaikie        switch (Modifier) {
109c084c0945b0530180e8969f5e2017d02d06db130David Blaikie        default:
110c084c0945b0530180e8969f5e2017d02d06db130David Blaikie          llvm_unreachable("Unimplemented");
111c084c0945b0530180e8969f5e2017d02d06db130David Blaikie        case MCSymbolRefExpr::VK_None:
112c084c0945b0530180e8969f5e2017d02d06db130David Blaikie          Type = ELF::R_X86_64_64;
113c084c0945b0530180e8969f5e2017d02d06db130David Blaikie          break;
1144ca9a2a0adf01ae1aaad2c7fa499501b58183991Tom Roeder        case MCSymbolRefExpr::VK_GOT:
1154ca9a2a0adf01ae1aaad2c7fa499501b58183991Tom Roeder          Type = ELF::R_X86_64_GOT64;
1164ca9a2a0adf01ae1aaad2c7fa499501b58183991Tom Roeder          break;
1174ca9a2a0adf01ae1aaad2c7fa499501b58183991Tom Roeder        case MCSymbolRefExpr::VK_GOTOFF:
1184ca9a2a0adf01ae1aaad2c7fa499501b58183991Tom Roeder          Type = ELF::R_X86_64_GOTOFF64;
1194ca9a2a0adf01ae1aaad2c7fa499501b58183991Tom Roeder          break;
1207d7db75a55319f1d21f0d8336744f90a81b87ac7David Majnemer        case MCSymbolRefExpr::VK_TPOFF:
1217d7db75a55319f1d21f0d8336744f90a81b87ac7David Majnemer          Type = ELF::R_X86_64_TPOFF64;
1227d7db75a55319f1d21f0d8336744f90a81b87ac7David Majnemer          break;
123c084c0945b0530180e8969f5e2017d02d06db130David Blaikie        case MCSymbolRefExpr::VK_DTPOFF:
124c084c0945b0530180e8969f5e2017d02d06db130David Blaikie          Type = ELF::R_X86_64_DTPOFF64;
125c084c0945b0530180e8969f5e2017d02d06db130David Blaikie          break;
126c084c0945b0530180e8969f5e2017d02d06db130David Blaikie        }
127c084c0945b0530180e8969f5e2017d02d06db130David Blaikie        break;
128edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case X86::reloc_signed_4byte:
129edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        switch (Modifier) {
130edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        default:
131edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          llvm_unreachable("Unimplemented");
132edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_None:
133edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_X86_64_32S;
134edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
135edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_GOT:
136edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_X86_64_GOT32;
137edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
138edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_GOTPCREL:
139edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_X86_64_GOTPCREL;
140edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
141edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_TPOFF:
142edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_X86_64_TPOFF32;
143edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
144edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_DTPOFF:
145edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_X86_64_DTPOFF32;
146edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
147edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        }
148edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        break;
149edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_Data_4:
150edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        Type = ELF::R_X86_64_32;
151edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        break;
152edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_Data_2: Type = ELF::R_X86_64_16; break;
153edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_PCRel_1:
154edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_Data_1: Type = ELF::R_X86_64_8; break;
155edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      }
156edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola    }
157678c35c3861df3d5882553da45e79a89dae20294Michael Liao  } else if (getEMachine() == ELF::EM_386) {
158edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola    if (IsPCRel) {
159edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      switch ((unsigned)Fixup.getKind()) {
160edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      default: llvm_unreachable("invalid fixup kind!");
161edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
162edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case X86::reloc_global_offset_table:
163edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        Type = ELF::R_386_GOTPC;
164edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        break;
165edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      case FK_PCRel_1:
16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      case FK_Data_1:
16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        switch (Modifier) {
16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        default:
17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          llvm_unreachable("Unimplemented");
17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        case MCSymbolRefExpr::VK_None:
17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          Type = ELF::R_386_PC8;
17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          break;
17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break;
17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      case FK_PCRel_2:
17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      case FK_Data_2:
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        switch (Modifier) {
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        default:
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          llvm_unreachable("Unimplemented");
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        case MCSymbolRefExpr::VK_None:
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          Type = ELF::R_386_PC16;
18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          break;
18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break;
18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
188edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case X86::reloc_signed_4byte:
189edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_PCRel_4:
190edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_Data_4:
191edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        switch (Modifier) {
192edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        default:
193edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          llvm_unreachable("Unimplemented");
194edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_None:
195edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_386_PC32;
196edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
197edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_PLT:
198edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_386_PLT32;
199edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
200edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        }
201edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        break;
202edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      }
203edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola    } else {
204edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      switch ((unsigned)Fixup.getKind()) {
205edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      default: llvm_unreachable("invalid fixup kind!");
206edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
207edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case X86::reloc_global_offset_table:
208edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        Type = ELF::R_386_GOTPC;
209edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        break;
210edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
211edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
212edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      // instead?
213edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case X86::reloc_signed_4byte:
214edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_PCRel_4:
215edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_Data_4:
216edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        switch (Modifier) {
217edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        default:
218edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          llvm_unreachable("Unimplemented");
219edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_None:
220edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_386_32;
221edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
222edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_GOT:
223edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_386_GOT32;
224edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
225edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_GOTOFF:
226edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_386_GOTOFF;
227edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
228edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_TLSGD:
229edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_386_TLS_GD;
230edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
231edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_TPOFF:
232edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_386_TLS_LE_32;
233edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
234edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_INDNTPOFF:
235edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_386_TLS_IE;
236edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
237edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_NTPOFF:
238edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_386_TLS_LE;
239edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
240edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_GOTNTPOFF:
241edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_386_TLS_GOTIE;
242edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
243edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_TLSLDM:
244edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_386_TLS_LDM;
245edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
246edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_DTPOFF:
247edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_386_TLS_LDO_32;
248edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
249edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        case MCSymbolRefExpr::VK_GOTTPOFF:
250edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          Type = ELF::R_386_TLS_IE_32;
251edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola          break;
252edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        }
253edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola        break;
254edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_Data_2: Type = ELF::R_386_16; break;
255edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_PCRel_1:
256edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      case FK_Data_1: Type = ELF::R_386_8; break;
257edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola      }
258edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola    }
259678c35c3861df3d5882553da45e79a89dae20294Michael Liao  } else
260678c35c3861df3d5882553da45e79a89dae20294Michael Liao    llvm_unreachable("Unsupported ELF machine type.");
261edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
262edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola  return Type;
263edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola}
264edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola
265edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael EspindolaMCObjectWriter *llvm::createX86ELFObjectWriter(raw_ostream &OS,
266678c35c3861df3d5882553da45e79a89dae20294Michael Liao                                               bool IsELF64,
267678c35c3861df3d5882553da45e79a89dae20294Michael Liao                                               uint8_t OSABI,
268678c35c3861df3d5882553da45e79a89dae20294Michael Liao                                               uint16_t EMachine) {
269edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola  MCELFObjectTargetWriter *MOTW =
270678c35c3861df3d5882553da45e79a89dae20294Michael Liao    new X86ELFObjectWriter(IsELF64, OSABI, EMachine);
271edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola  return createELFObjectWriter(MOTW, OS,  /*IsLittleEndian=*/true);
272edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola}
273