28 struct MipsRelocationEntry {
30 : R(R), SortOffset(R.Offset), HasMatchingHi(
false) {}
42 MipsELFObjectWriter(
bool _is64Bit, uint8_t OSABI,
43 bool _isN64,
bool IsLittleEndian);
45 ~MipsELFObjectWriter()
override;
48 bool IsPCRel)
const override;
49 bool needsRelocateWithSymbol(
const MCSymbol &Sym,
50 unsigned Type)
const override;
52 std::vector<ELFRelocationEntry> &Relocs)
override;
56 MipsELFObjectWriter::MipsELFObjectWriter(
bool _is64Bit, uint8_t OSABI,
57 bool _isN64,
bool IsLittleEndian)
62 MipsELFObjectWriter::~MipsELFObjectWriter() {}
64 unsigned MipsELFObjectWriter::GetRelocType(
const MCValue &
Target,
73 return IsPCRel ? ELF::R_MIPS_PC16 : ELF::R_MIPS_16;
76 return IsPCRel ? ELF::R_MIPS_PC32 : ELF::R_MIPS_32;
83 return ELF::R_MIPS_PC16;
85 return ELF::R_MICROMIPS_PC7_S1;
87 return ELF::R_MICROMIPS_PC10_S1;
89 return ELF::R_MICROMIPS_PC16_S1;
91 return ELF::R_MIPS_PC19_S2;
93 return ELF::R_MIPS_PC18_S3;
95 return ELF::R_MIPS_PC21_S2;
97 return ELF::R_MIPS_PC26_S2;
99 return ELF::R_MIPS_PCHI16;
101 return ELF::R_MIPS_PCLO16;
110 return ELF::R_MIPS_64;
114 Type = setRType((
unsigned)ELF::R_MIPS_GPREL32, Type);
115 Type = setRType2((
unsigned)ELF::R_MIPS_64, Type);
116 Type = setRType3((
unsigned)ELF::R_MIPS_NONE, Type);
119 return ELF::R_MIPS_GPREL32;
121 return ELF::R_MIPS_GPREL16;
123 return ELF::R_MIPS_26;
125 return ELF::R_MIPS_CALL16;
128 return ELF::R_MIPS_GOT16;
130 return ELF::R_MIPS_HI16;
132 return ELF::R_MIPS_LO16;
134 return ELF::R_MIPS_TLS_GD;
136 return ELF::R_MIPS_TLS_GOTTPREL;
138 return ELF::R_MIPS_TLS_TPREL_HI16;
140 return ELF::R_MIPS_TLS_TPREL_LO16;
142 return ELF::R_MIPS_TLS_LDM;
144 return ELF::R_MIPS_TLS_DTPREL_HI16;
146 return ELF::R_MIPS_TLS_DTPREL_LO16;
148 return ELF::R_MIPS_GOT_PAGE;
150 return ELF::R_MIPS_GOT_OFST;
152 return ELF::R_MIPS_GOT_DISP;
154 unsigned Type = (
unsigned)ELF::R_MIPS_NONE;
155 Type = setRType((
unsigned)ELF::R_MIPS_GPREL16, Type);
156 Type = setRType2((
unsigned)ELF::R_MIPS_SUB, Type);
157 Type = setRType3((
unsigned)ELF::R_MIPS_HI16, Type);
161 unsigned Type = (
unsigned)ELF::R_MIPS_NONE;
162 Type = setRType((
unsigned)ELF::R_MIPS_GPREL16, Type);
163 Type = setRType2((
unsigned)ELF::R_MIPS_SUB, Type);
164 Type = setRType3((
unsigned)ELF::R_MIPS_LO16, Type);
168 return ELF::R_MIPS_HIGHER;
170 return ELF::R_MIPS_HIGHEST;
172 return ELF::R_MIPS_GOT_HI16;
174 return ELF::R_MIPS_GOT_LO16;
176 return ELF::R_MIPS_CALL_HI16;
178 return ELF::R_MIPS_CALL_LO16;
180 return ELF::R_MICROMIPS_26_S1;
182 return ELF::R_MICROMIPS_HI16;
184 return ELF::R_MICROMIPS_LO16;
186 return ELF::R_MICROMIPS_GOT16;
188 return ELF::R_MICROMIPS_CALL16;
190 return ELF::R_MICROMIPS_GOT_DISP;
192 return ELF::R_MICROMIPS_GOT_PAGE;
194 return ELF::R_MICROMIPS_GOT_OFST;
196 return ELF::R_MICROMIPS_TLS_GD;
198 return ELF::R_MICROMIPS_TLS_LDM;
200 return ELF::R_MICROMIPS_TLS_DTPREL_HI16;
202 return ELF::R_MICROMIPS_TLS_DTPREL_LO16;
204 return ELF::R_MICROMIPS_TLS_TPREL_HI16;
206 return ELF::R_MICROMIPS_TLS_TPREL_LO16;
216 const MipsRelocationEntry *BP) {
217 const MipsRelocationEntry &
A = *AP;
218 const MipsRelocationEntry &B = *BP;
219 if (A.SortOffset != B.SortOffset)
220 return B.SortOffset - A.SortOffset;
221 if (A.R.Offset != B.R.Offset)
222 return A.R.Offset - B.R.Offset;
223 if (B.R.Type != A.R.Type)
224 return B.R.Type - A.R.Type;
233 unsigned Type = Reloc.
Type;
234 if (Type == ELF::R_MIPS_HI16)
235 return ELF::R_MIPS_LO16;
236 if (Type == ELF::R_MICROMIPS_HI16)
237 return ELF::R_MICROMIPS_LO16;
238 if (Type == ELF::R_MIPS16_HI16)
239 return ELF::R_MIPS16_LO16;
242 return ELF::R_MIPS_NONE;
244 if (Type == ELF::R_MIPS_GOT16)
245 return ELF::R_MIPS_LO16;
246 if (Type == ELF::R_MICROMIPS_GOT16)
247 return ELF::R_MICROMIPS_LO16;
248 if (Type == ELF::R_MIPS16_GOT16)
249 return ELF::R_MIPS16_LO16;
251 return ELF::R_MIPS_NONE;
267 std::vector<MipsRelocationEntry> &MipsRelocs) {
268 return Index < MipsRelocs.size() - 1 &&
275 std::vector<MipsRelocationEntry> &MipsRelocs) {
276 return Index < MipsRelocs.size() && !MipsRelocs[Index].HasMatchingHi &&
284 static void setMatch(MipsRelocationEntry &
Hi, MipsRelocationEntry &
Lo) {
285 Lo.HasMatchingHi =
true;
286 Hi.SortOffset = Lo.R.Offset - 1;
329 std::vector<ELFRelocationEntry> &Relocs) {
330 if (Relocs.size() < 2)
334 MCELFObjectTargetWriter::sortRelocs(Asm, Relocs);
337 std::vector<MipsRelocationEntry> MipsRelocs;
338 for (
unsigned I = 0, E = Relocs.size();
I != E; ++
I)
339 MipsRelocs.push_back(MipsRelocationEntry(Relocs[
I]));
342 for (int32_t I = 0, E = MipsRelocs.size(); I != E; ++
I) {
347 int32_t MatchedLoIndex = -1;
350 for (int32_t J = MipsRelocs.size() - 1,
N = -1; J !=
N; --J) {
353 (MatchedLoIndex == -1 ||
356 (MatchedLoIndex > J &&
isFreeLo(Asm, J, MipsRelocs))))
360 if (MatchedLoIndex != -1)
362 setMatch(MipsRelocs[I], MipsRelocs[MatchedLoIndex]);
369 for (
unsigned I = 0, E = MipsRelocs.size(); I != E; ++
I)
370 Relocs[I] = MipsRelocs[I].R;
373 bool MipsELFObjectWriter::needsRelocateWithSymbol(
const MCSymbol &Sym,
374 unsigned Type)
const {
382 case ELF::R_MIPS_GOT16:
383 case ELF::R_MIPS16_GOT16:
384 case ELF::R_MICROMIPS_GOT16:
392 case ELF::R_MIPS_HI16:
393 case ELF::R_MIPS16_HI16:
394 case ELF::R_MICROMIPS_HI16:
395 case ELF::R_MIPS_LO16:
396 case ELF::R_MIPS16_LO16:
397 case ELF::R_MICROMIPS_LO16:
406 case ELF::R_MIPS_GPREL16:
416 new MipsELFObjectWriter(Is64Bit, OSABI, Is64Bit, IsLittleEndian);
static bool areMatchingHiAndLo(const MCAssembler &Asm, const ELFRelocationEntry &First, const ELFRelocationEntry &Second)
This represents an "assembler immediate".
static void setMatch(MipsRelocationEntry &Hi, MipsRelocationEntry &Lo)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Defines the object file and target independent interfaces used by the assembler backend to write nati...
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A four-byte gp relative fixup.
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
static bool isFreeLo(const MCAssembler &Asm, uint32_t Index, std::vector< MipsRelocationEntry > &MipsRelocs)
The instances of the Type class are immutable: once they are created, they are never changed...
static bool isPrecededByMatchingHi(const MCAssembler &Asm, uint32_t Index, std::vector< MipsRelocationEntry > &MipsRelocs)
static int cmpRelMips(const MipsRelocationEntry *AP, const MipsRelocationEntry *BP)
unsigned getBinding() const
MCFixupKind getKind() const
MCObjectWriter * createMipsELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI, bool IsLittleEndian, bool Is64Bit)
PowerPC TLS Dynamic Call Fixup
static unsigned getMatchingLoType(const MCAssembler &Asm, const ELFRelocationEntry &Reloc)
Target - Wrapper for Target specific information.
MCObjectWriter * createELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_pwrite_stream &OS, bool IsLittleEndian)
Construct a new ELF writer instance.
An abstract base class for streams implementations that also support a pwrite operation.
const ARM::ArchExtKind Kind
const MCSymbolELF * Symbol