1c5707112e7635d1dd2f2cc9c4f42e79a51302ccaJia Liu//===-- MipsELFObjectWriter.cpp - Mips ELF Writer -------------------------===//
2090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola//
3090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola//                     The LLVM Compiler Infrastructure
4090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola//
5090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola// This file is distributed under the University of Illinois Open Source
6090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola// License. See LICENSE.TXT for details.
7090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola//
8090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola//===----------------------------------------------------------------------===//
9090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola
1037ac18ef2f13a8060b745e6d3c4622bafdd4f47bAkira Hatanaka#include "MCTargetDesc/MipsBaseInfo.h"
11090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola#include "MCTargetDesc/MipsFixupKinds.h"
12090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola#include "MCTargetDesc/MipsMCTargetDesc.h"
1337ac18ef2f13a8060b745e6d3c4622bafdd4f47bAkira Hatanaka#include "llvm/MC/MCAssembler.h"
14090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola#include "llvm/MC/MCELFObjectWriter.h"
15090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola#include "llvm/MC/MCExpr.h"
16090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola#include "llvm/MC/MCSection.h"
17090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola#include "llvm/MC/MCValue.h"
18090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola#include "llvm/Support/ErrorHandling.h"
1937ac18ef2f13a8060b745e6d3c4622bafdd4f47bAkira Hatanaka#include <list>
20090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola
21090445967f0b5988446faffefd1d0722f982bc7aRafael Espindolausing namespace llvm;
22090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola
23090445967f0b5988446faffefd1d0722f982bc7aRafael Espindolanamespace {
24090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  class MipsELFObjectWriter : public MCELFObjectTargetWriter {
25090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  public:
26b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka    MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI,
27b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka                        bool _isN64, bool IsLittleEndian);
28090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola
29090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    virtual ~MipsELFObjectWriter();
30090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola
3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          bool IsPCRel) const override;
3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool needsRelocateWithSymbol(unsigned Type) const override;
34090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  };
35090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola}
36090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola
3793ee286e8d949147f8df7f093c9bd8529a99102dJack CarterMipsELFObjectWriter::MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI,
38b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka                                         bool _isN64, bool IsLittleEndian)
39a551a48402385cf3f4b754dc72264b2f0974b1a6Akira Hatanaka  : MCELFObjectTargetWriter(_is64Bit, OSABI, ELF::EM_MIPS,
40101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter                            /*HasRelocationAddend*/ (_isN64) ? true : false,
4193ee286e8d949147f8df7f093c9bd8529a99102dJack Carter                            /*IsN64*/ _isN64) {}
42090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola
43090445967f0b5988446faffefd1d0722f982bc7aRafael EspindolaMipsELFObjectWriter::~MipsELFObjectWriter() {}
44090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola
45090445967f0b5988446faffefd1d0722f982bc7aRafael Espindolaunsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
46090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola                                           const MCFixup &Fixup,
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                           bool IsPCRel) const {
48090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  // determine the type of the relocation
49090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  unsigned Type = (unsigned)ELF::R_MIPS_NONE;
50090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  unsigned Kind = (unsigned)Fixup.getKind();
51090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola
52090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  switch (Kind) {
53090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  default:
54090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    llvm_unreachable("invalid fixup kind!");
55090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case FK_Data_4:
56090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    Type = ELF::R_MIPS_32;
57090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
58e2245bab3ca29dc2142d8f254005f4ae7c40cde2Jack Carter  case FK_Data_8:
59e2245bab3ca29dc2142d8f254005f4ae7c40cde2Jack Carter    Type = ELF::R_MIPS_64;
60e2245bab3ca29dc2142d8f254005f4ae7c40cde2Jack Carter    break;
61090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case FK_GPRel_4:
62096d617796228293810cb0443c6617b33c5afdc5Jack Carter    if (isN64()) {
63096d617796228293810cb0443c6617b33c5afdc5Jack Carter      Type = setRType((unsigned)ELF::R_MIPS_GPREL32, Type);
64096d617796228293810cb0443c6617b33c5afdc5Jack Carter      Type = setRType2((unsigned)ELF::R_MIPS_64, Type);
65096d617796228293810cb0443c6617b33c5afdc5Jack Carter      Type = setRType3((unsigned)ELF::R_MIPS_NONE, Type);
66096d617796228293810cb0443c6617b33c5afdc5Jack Carter    }
67096d617796228293810cb0443c6617b33c5afdc5Jack Carter    else
68096d617796228293810cb0443c6617b33c5afdc5Jack Carter      Type = ELF::R_MIPS_GPREL32;
69090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
70090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_GPREL16:
71090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    Type = ELF::R_MIPS_GPREL16;
72090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
73090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_26:
74090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    Type = ELF::R_MIPS_26;
75090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
76090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_CALL16:
77090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    Type = ELF::R_MIPS_CALL16;
78090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
79090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_GOT_Global:
80090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_GOT_Local:
81090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    Type = ELF::R_MIPS_GOT16;
82090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
83090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_HI16:
84090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    Type = ELF::R_MIPS_HI16;
85090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
86090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_LO16:
87090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    Type = ELF::R_MIPS_LO16;
88090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
89090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_TLSGD:
90090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    Type = ELF::R_MIPS_TLS_GD;
91090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
92090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_GOTTPREL:
93090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    Type = ELF::R_MIPS_TLS_GOTTPREL;
94090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
95090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_TPREL_HI:
96090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    Type = ELF::R_MIPS_TLS_TPREL_HI16;
97090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
98090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_TPREL_LO:
99090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    Type = ELF::R_MIPS_TLS_TPREL_LO16;
100090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
101090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_TLSLDM:
102090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    Type = ELF::R_MIPS_TLS_LDM;
103090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
104090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_DTPREL_HI:
105090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    Type = ELF::R_MIPS_TLS_DTPREL_HI16;
106090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
107090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_DTPREL_LO:
108090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    Type = ELF::R_MIPS_TLS_DTPREL_LO16;
109090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
110090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_Branch_PCRel:
111090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  case Mips::fixup_Mips_PC16:
112090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    Type = ELF::R_MIPS_PC16;
113090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola    break;
1140140e55393c4403ab240c386501cdc5e438dcc0eJack Carter  case Mips::fixup_Mips_GOT_PAGE:
1150140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    Type = ELF::R_MIPS_GOT_PAGE;
1160140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    break;
1170140e55393c4403ab240c386501cdc5e438dcc0eJack Carter  case Mips::fixup_Mips_GOT_OFST:
1180140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    Type = ELF::R_MIPS_GOT_OFST;
1190140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    break;
120fd506efec628819f7e6fad8016a9dbb5d8612b8bJack Carter  case Mips::fixup_Mips_GOT_DISP:
121fd506efec628819f7e6fad8016a9dbb5d8612b8bJack Carter    Type = ELF::R_MIPS_GOT_DISP;
122fd506efec628819f7e6fad8016a9dbb5d8612b8bJack Carter    break;
1230140e55393c4403ab240c386501cdc5e438dcc0eJack Carter  case Mips::fixup_Mips_GPOFF_HI:
1240140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    Type = setRType((unsigned)ELF::R_MIPS_GPREL16, Type);
1250140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    Type = setRType2((unsigned)ELF::R_MIPS_SUB, Type);
1260140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    Type = setRType3((unsigned)ELF::R_MIPS_HI16, Type);
1270140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    break;
1280140e55393c4403ab240c386501cdc5e438dcc0eJack Carter  case Mips::fixup_Mips_GPOFF_LO:
1290140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    Type = setRType((unsigned)ELF::R_MIPS_GPREL16, Type);
1300140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    Type = setRType2((unsigned)ELF::R_MIPS_SUB, Type);
1310140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    Type = setRType3((unsigned)ELF::R_MIPS_LO16, Type);
1320140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    break;
133fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter  case Mips::fixup_Mips_HIGHER:
134fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter    Type = ELF::R_MIPS_HIGHER;
135fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter    break;
136fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter  case Mips::fixup_Mips_HIGHEST:
137fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter    Type = ELF::R_MIPS_HIGHEST;
138fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter    break;
139198ad916d736047f8a439f19dee25cee917df8a9Jack Carter  case Mips::fixup_Mips_GOT_HI16:
140198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    Type = ELF::R_MIPS_GOT_HI16;
141198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    break;
142198ad916d736047f8a439f19dee25cee917df8a9Jack Carter  case Mips::fixup_Mips_GOT_LO16:
143198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    Type = ELF::R_MIPS_GOT_LO16;
144198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    break;
145198ad916d736047f8a439f19dee25cee917df8a9Jack Carter  case Mips::fixup_Mips_CALL_HI16:
146198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    Type = ELF::R_MIPS_CALL_HI16;
147198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    break;
148198ad916d736047f8a439f19dee25cee917df8a9Jack Carter  case Mips::fixup_Mips_CALL_LO16:
149198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    Type = ELF::R_MIPS_CALL_LO16;
150198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    break;
1511aaf43c2a2ec0fd4c8dbfe56558237219c5f8af7Zoran Jovanovic  case Mips::fixup_MICROMIPS_26_S1:
1521aaf43c2a2ec0fd4c8dbfe56558237219c5f8af7Zoran Jovanovic    Type = ELF::R_MICROMIPS_26_S1;
1531aaf43c2a2ec0fd4c8dbfe56558237219c5f8af7Zoran Jovanovic    break;
1540082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_HI16:
1550082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    Type = ELF::R_MICROMIPS_HI16;
1560082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    break;
1570082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_LO16:
1580082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    Type = ELF::R_MICROMIPS_LO16;
1590082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    break;
1600082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_GOT16:
1610082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    Type = ELF::R_MICROMIPS_GOT16;
1620082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    break;
1635c042162beb3c2dd556e00aab84c4278a69cd5b1Zoran Jovanovic  case Mips::fixup_MICROMIPS_PC16_S1:
1645c042162beb3c2dd556e00aab84c4278a69cd5b1Zoran Jovanovic    Type = ELF::R_MICROMIPS_PC16_S1;
1655c042162beb3c2dd556e00aab84c4278a69cd5b1Zoran Jovanovic    break;
1660082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_CALL16:
1670082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    Type = ELF::R_MICROMIPS_CALL16;
1680082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    break;
1690082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_GOT_DISP:
1700082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    Type = ELF::R_MICROMIPS_GOT_DISP;
1710082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    break;
1720082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_GOT_PAGE:
1730082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    Type = ELF::R_MICROMIPS_GOT_PAGE;
1740082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    break;
1750082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_GOT_OFST:
1760082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    Type = ELF::R_MICROMIPS_GOT_OFST;
1770082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    break;
17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Mips::fixup_MICROMIPS_TLS_GD:
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Type = ELF::R_MICROMIPS_TLS_GD;
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Mips::fixup_MICROMIPS_TLS_LDM:
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Type = ELF::R_MICROMIPS_TLS_LDM;
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
1840082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_TLS_DTPREL_HI16:
1850082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    Type = ELF::R_MICROMIPS_TLS_DTPREL_HI16;
1860082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    break;
1870082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_TLS_DTPREL_LO16:
1880082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    Type = ELF::R_MICROMIPS_TLS_DTPREL_LO16;
1890082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    break;
1900082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_TLS_TPREL_HI16:
1910082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    Type = ELF::R_MICROMIPS_TLS_TPREL_HI16;
1920082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    break;
1930082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic  case Mips::fixup_MICROMIPS_TLS_TPREL_LO16:
1940082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    Type = ELF::R_MICROMIPS_TLS_TPREL_LO16;
1950082717cb537e2d1424f755a49510fa9f9e67071Zoran Jovanovic    break;
196cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  case Mips::fixup_MIPS_PC19_S2:
197cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Type = ELF::R_MIPS_PC19_S2;
198cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    break;
199cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  case Mips::fixup_MIPS_PC18_S3:
200cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Type = ELF::R_MIPS_PC18_S3;
201cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    break;
202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::fixup_MIPS_PC21_S2:
203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Type = ELF::R_MIPS_PC21_S2;
204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::fixup_MIPS_PC26_S2:
206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Type = ELF::R_MIPS_PC26_S2;
207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::fixup_MIPS_PCHI16:
209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Type = ELF::R_MIPS_PCHI16;
210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::fixup_MIPS_PCLO16:
212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Type = ELF::R_MIPS_PCLO16;
213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
214090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  }
215090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  return Type;
216090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola}
217090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola
21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool
21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesMipsELFObjectWriter::needsRelocateWithSymbol(unsigned Type) const {
22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: This is extremelly conservative. This really needs to use a
22136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // whitelist with a clear explanation for why each realocation needs to
22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // point to the symbol, not to the section.
22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (Type) {
22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_MIPS_GOT16:
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_MIPS16_GOT16:
22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_MICROMIPS_GOT16:
23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    llvm_unreachable("Should have been handled already");
23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // These relocations might be paired with another relocation. The pairing is
23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // done by the static linker by matching the symbol. Since we only see one
23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // relocation at a time, we have to force them to relocate with a symbol to
23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // avoid ending up with a pair where one points to a section and another
23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // points to a symbol.
23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_MIPS_HI16:
23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_MIPS16_HI16:
23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_MICROMIPS_HI16:
24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_MIPS_LO16:
24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_MIPS16_LO16:
24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_MICROMIPS_LO16:
24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
24436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_MIPS_26:
24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_MIPS_32:
24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_MIPS_64:
24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ELF::R_MIPS_GPREL16:
24937ac18ef2f13a8060b745e6d3c4622bafdd4f47bAkira Hatanaka    return false;
25037ac18ef2f13a8060b745e6d3c4622bafdd4f47bAkira Hatanaka  }
25137ac18ef2f13a8060b745e6d3c4622bafdd4f47bAkira Hatanaka}
25237ac18ef2f13a8060b745e6d3c4622bafdd4f47bAkira Hatanaka
253a551a48402385cf3f4b754dc72264b2f0974b1a6Akira HatanakaMCObjectWriter *llvm::createMipsELFObjectWriter(raw_ostream &OS,
254a551a48402385cf3f4b754dc72264b2f0974b1a6Akira Hatanaka                                                uint8_t OSABI,
255a551a48402385cf3f4b754dc72264b2f0974b1a6Akira Hatanaka                                                bool IsLittleEndian,
256a551a48402385cf3f4b754dc72264b2f0974b1a6Akira Hatanaka                                                bool Is64Bit) {
25793ee286e8d949147f8df7f093c9bd8529a99102dJack Carter  MCELFObjectTargetWriter *MOTW = new MipsELFObjectWriter(Is64Bit, OSABI,
258b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka                                                (Is64Bit) ? true : false,
259b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka                                                IsLittleEndian);
260090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola  return createELFObjectWriter(MOTW, OS, IsLittleEndian);
261090445967f0b5988446faffefd1d0722f982bc7aRafael Espindola}
262