blob: 9c2f81e596f6444cf758e0d309199280f9d0c5f1 [file] [log] [blame]
Rafael Espindola09044592011-12-22 03:03:17 +00001//===-- 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
18using namespace llvm;
19
20namespace {
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
39MipsELFObjectWriter::MipsELFObjectWriter(uint8_t OSABI)
40 : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, ELF::EM_MIPS,
41 /*HasRelocationAddend*/ false) {}
42
43MipsELFObjectWriter::~MipsELFObjectWriter() {}
44
45// FIXME: get the real EABI Version from the Triple.
46unsigned MipsELFObjectWriter::getEFlags() const {
47 return ELF::EF_MIPS_NOREORDER | ELF::EF_MIPS_ARCH_32R2;
48}
49
50const 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
65unsigned 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
132MCObjectWriter *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}