Move the Mips only bits of the ELF writer to lib/Target/Mips.
[oota-llvm.git] / lib / Target / Mips / MCTargetDesc / MipsELFObjectWriter.cpp
1 //===-- MipsELFObjectWriter.cpp - Mips ELF Writer ---------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "MCTargetDesc/MipsFixupKinds.h"
11 #include "MCTargetDesc/MipsMCTargetDesc.h"
12 #include "llvm/MC/MCELFObjectWriter.h"
13 #include "llvm/MC/MCExpr.h"
14 #include "llvm/MC/MCSection.h"
15 #include "llvm/MC/MCValue.h"
16 #include "llvm/Support/ErrorHandling.h"
17
18 using namespace llvm;
19
20 namespace {
21   class MipsELFObjectWriter : public MCELFObjectTargetWriter {
22   public:
23     MipsELFObjectWriter(uint8_t OSABI);
24
25     virtual ~MipsELFObjectWriter();
26
27     virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
28                                   bool IsPCRel, bool IsRelocWithSymbol,
29                                   int64_t Addend) const;
30     virtual unsigned getEFlags() const;
31     virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
32                                            const MCValue &Target,
33                                            const MCFragment &F,
34                                            const MCFixup &Fixup,
35                                            bool IsPCRel) const;
36   };
37 }
38
39 MipsELFObjectWriter::MipsELFObjectWriter(uint8_t OSABI)
40   : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, ELF::EM_MIPS,
41                             /*HasRelocationAddend*/ false) {}
42
43 MipsELFObjectWriter::~MipsELFObjectWriter() {}
44
45 // FIXME: get the real EABI Version from the Triple.
46 unsigned MipsELFObjectWriter::getEFlags() const {
47   return ELF::EF_MIPS_NOREORDER | ELF::EF_MIPS_ARCH_32R2;
48 }
49
50 const MCSymbol *MipsELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
51                                                     const MCValue &Target,
52                                                     const MCFragment &F,
53                                                     const MCFixup &Fixup,
54                                                     bool IsPCRel) const {
55   assert(Target.getSymA() && "SymA cannot be 0.");
56   const MCSymbol &Sym = Target.getSymA()->getSymbol();
57
58   if (Sym.getSection().getKind().isMergeableCString() ||
59       Sym.getSection().getKind().isMergeableConst())
60     return &Sym;
61
62   return NULL;
63 }
64
65 unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
66                                            const MCFixup &Fixup,
67                                            bool IsPCRel,
68                                            bool IsRelocWithSymbol,
69                                            int64_t Addend) const {
70   // determine the type of the relocation
71   unsigned Type = (unsigned)ELF::R_MIPS_NONE;
72   unsigned Kind = (unsigned)Fixup.getKind();
73
74   switch (Kind) {
75   default:
76     llvm_unreachable("invalid fixup kind!");
77   case FK_Data_4:
78     Type = ELF::R_MIPS_32;
79     break;
80   case FK_GPRel_4:
81     Type = ELF::R_MIPS_GPREL32;
82     break;
83   case Mips::fixup_Mips_GPREL16:
84     Type = ELF::R_MIPS_GPREL16;
85     break;
86   case Mips::fixup_Mips_26:
87     Type = ELF::R_MIPS_26;
88     break;
89   case Mips::fixup_Mips_CALL16:
90     Type = ELF::R_MIPS_CALL16;
91     break;
92   case Mips::fixup_Mips_GOT_Global:
93   case Mips::fixup_Mips_GOT_Local:
94     Type = ELF::R_MIPS_GOT16;
95     break;
96   case Mips::fixup_Mips_HI16:
97     Type = ELF::R_MIPS_HI16;
98     break;
99   case Mips::fixup_Mips_LO16:
100     Type = ELF::R_MIPS_LO16;
101     break;
102   case Mips::fixup_Mips_TLSGD:
103     Type = ELF::R_MIPS_TLS_GD;
104     break;
105   case Mips::fixup_Mips_GOTTPREL:
106     Type = ELF::R_MIPS_TLS_GOTTPREL;
107     break;
108   case Mips::fixup_Mips_TPREL_HI:
109     Type = ELF::R_MIPS_TLS_TPREL_HI16;
110     break;
111   case Mips::fixup_Mips_TPREL_LO:
112     Type = ELF::R_MIPS_TLS_TPREL_LO16;
113     break;
114   case Mips::fixup_Mips_TLSLDM:
115     Type = ELF::R_MIPS_TLS_LDM;
116     break;
117   case Mips::fixup_Mips_DTPREL_HI:
118     Type = ELF::R_MIPS_TLS_DTPREL_HI16;
119     break;
120   case Mips::fixup_Mips_DTPREL_LO:
121     Type = ELF::R_MIPS_TLS_DTPREL_LO16;
122     break;
123   case Mips::fixup_Mips_Branch_PCRel:
124   case Mips::fixup_Mips_PC16:
125     Type = ELF::R_MIPS_PC16;
126     break;
127   }
128
129   return Type;
130 }
131
132 MCObjectWriter *llvm::createMipsELFObjectWriter(raw_ostream &OS,
133                                                bool IsLittleEndian,
134                                                uint8_t OSABI) {
135   MCELFObjectTargetWriter *MOTW = new MipsELFObjectWriter(OSABI);
136   return createELFObjectWriter(MOTW, OS, IsLittleEndian);
137 }