LLVM 22.0.0git
SparcELFObjectWriter.cpp
Go to the documentation of this file.
1//===-- SparcELFObjectWriter.cpp - Sparc ELF Writer -----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "llvm/MC/MCContext.h"
13#include "llvm/MC/MCExpr.h"
16#include "llvm/MC/MCValue.h"
18
19using namespace llvm;
20
21namespace {
22 class SparcELFObjectWriter : public MCELFObjectTargetWriter {
23 public:
24 SparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, uint8_t OSABI)
26 Is64Bit, OSABI,
27 Is64Bit ? ELF::EM_SPARCV9
28 : (IsV8Plus ? ELF::EM_SPARC32PLUS : ELF::EM_SPARC),
29 /*HasRelocationAddend*/ true) {}
30
31 ~SparcELFObjectWriter() override = default;
32
33 protected:
34 unsigned getRelocType(const MCFixup &Fixup, const MCValue &Target,
35 bool IsPCRel) const override;
36
37 bool needsRelocateWithSymbol(const MCValue &, unsigned Type) const override;
38 };
39}
40
41unsigned SparcELFObjectWriter::getRelocType(const MCFixup &Fixup,
42 const MCValue &Target,
43 bool IsPCRel) const {
44 switch (Target.getSpecifier()) {
45 case ELF::R_SPARC_TLS_GD_HI22:
46 case ELF::R_SPARC_TLS_GD_LO10:
47 case ELF::R_SPARC_TLS_GD_ADD:
48 case ELF::R_SPARC_TLS_LDM_HI22:
49 case ELF::R_SPARC_TLS_LDM_LO10:
50 case ELF::R_SPARC_TLS_LDM_ADD:
51 case ELF::R_SPARC_TLS_LDO_HIX22:
52 case ELF::R_SPARC_TLS_LDO_LOX10:
53 case ELF::R_SPARC_TLS_LDO_ADD:
54 case ELF::R_SPARC_TLS_IE_HI22:
55 case ELF::R_SPARC_TLS_IE_LO10:
56 case ELF::R_SPARC_TLS_IE_LD:
57 case ELF::R_SPARC_TLS_IE_LDX:
58 case ELF::R_SPARC_TLS_IE_ADD:
59 case ELF::R_SPARC_TLS_LE_HIX22:
60 case ELF::R_SPARC_TLS_LE_LOX10:
61 if (auto *SA = const_cast<MCSymbol *>(Target.getAddSym()))
62 static_cast<MCSymbolELF *>(SA)->setType(ELF::STT_TLS);
63 break;
64 default:
65 break;
66 }
67
68 // Extract the relocation type from the fixup kind, after applying STT_TLS as
69 // needed.
70 auto Kind = Fixup.getKind();
71 if (mc::isRelocation(Fixup.getKind()))
72 return Kind;
73
74 if (const auto *SExpr = dyn_cast<MCSpecifierExpr>(Fixup.getValue())) {
75 if (SExpr->getSpecifier() == ELF::R_SPARC_DISP32)
76 return ELF::R_SPARC_DISP32;
77 }
78
79 if (IsPCRel) {
80 switch (Kind) {
81 default:
82 llvm_unreachable("Unimplemented fixup -> relocation");
83 case FK_Data_1: return ELF::R_SPARC_DISP8;
84 case FK_Data_2: return ELF::R_SPARC_DISP16;
85 case FK_Data_4: return ELF::R_SPARC_DISP32;
86 case FK_Data_8: return ELF::R_SPARC_DISP64;
88 if (getContext().getObjectFileInfo()->isPositionIndependent())
89 return ELF::R_SPARC_WPLT30;
90 return ELF::R_SPARC_WDISP30;
91 }
92 }
93
94 // clang-format off
95 switch(Fixup.getKind()) {
96 default:
97 llvm_unreachable("Unimplemented fixup -> relocation");
98 case FK_NONE: return ELF::R_SPARC_NONE;
99 case FK_Data_1: return ELF::R_SPARC_8;
100 case FK_Data_2: return ((Fixup.getOffset() % 2)
101 ? ELF::R_SPARC_UA16
102 : ELF::R_SPARC_16);
103 case FK_Data_4: return ((Fixup.getOffset() % 4)
104 ? ELF::R_SPARC_UA32
105 : ELF::R_SPARC_32);
106 case FK_Data_8: return ((Fixup.getOffset() % 8)
107 ? ELF::R_SPARC_UA64
108 : ELF::R_SPARC_64);
110 if (getContext().getObjectFileInfo()->isPositionIndependent())
111 return ELF::R_SPARC_GOT13;
112 return ELF::R_SPARC_13;
113 }
114 // clang-format on
115
116 return ELF::R_SPARC_NONE;
117}
118
119bool SparcELFObjectWriter::needsRelocateWithSymbol(const MCValue &,
120 unsigned Type) const {
121 switch (Type) {
122 default:
123 return false;
124
125 // All relocations that use a GOT need a symbol, not an offset, as
126 // the offset of the symbol within the section is irrelevant to
127 // where the GOT entry is. Don't need to list all the TLS entries,
128 // as they're all marked as requiring a symbol anyways.
129 case ELF::R_SPARC_GOT10:
130 case ELF::R_SPARC_GOT13:
131 case ELF::R_SPARC_GOT22:
132 case ELF::R_SPARC_GOTDATA_HIX22:
133 case ELF::R_SPARC_GOTDATA_LOX10:
134 case ELF::R_SPARC_GOTDATA_OP_HIX22:
135 case ELF::R_SPARC_GOTDATA_OP_LOX10:
136 return true;
137 }
138}
139
140std::unique_ptr<MCObjectTargetWriter>
141llvm::createSparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, uint8_t OSABI) {
142 return std::make_unique<SparcELFObjectWriter>(Is64Bit, IsV8Plus, OSABI);
143}
PowerPC TLS Dynamic Call Fixup
virtual unsigned getRelocType(const MCFixup &Fixup, const MCValue &Target, bool IsPCRel) const =0
virtual bool needsRelocateWithSymbol(const MCValue &, unsigned Type) const
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:61
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ EM_SPARC
Definition: ELF.h:140
@ EM_SPARC32PLUS
Definition: ELF.h:151
@ EM_SPARCV9
Definition: ELF.h:164
@ STT_TLS
Definition: ELF.h:1414
@ fixup_sparc_13
fixup_sparc_13 - 13-bit fixup
bool isRelocation(MCFixupKind FixupKind)
Definition: MCFixup.h:130
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ FK_Data_8
A eight-byte fixup.
Definition: MCFixup.h:37
@ FK_Data_1
A one-byte fixup.
Definition: MCFixup.h:34
@ FK_Data_4
A four-byte fixup.
Definition: MCFixup.h:36
@ FK_NONE
A no-op fixup.
Definition: MCFixup.h:33
@ FK_Data_2
A two-byte fixup.
Definition: MCFixup.h:35
std::unique_ptr< MCObjectTargetWriter > createSparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, uint8_t OSABI)