1 //===-- SparcELFObjectWriter.cpp - Sparc ELF Writer -----------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "MCTargetDesc/SparcFixupKinds.h"
10 #include "MCTargetDesc/SparcMCExpr.h"
11 #include "MCTargetDesc/SparcMCTargetDesc.h"
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/MC/MCELFObjectWriter.h"
14 #include "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCObjectWriter.h"
16 #include "llvm/MC/MCValue.h"
17 #include "llvm/Support/ErrorHandling.h"
22 class SparcELFObjectWriter
: public MCELFObjectTargetWriter
{
24 SparcELFObjectWriter(bool Is64Bit
, uint8_t OSABI
)
25 : MCELFObjectTargetWriter(Is64Bit
, OSABI
,
26 Is64Bit
? ELF::EM_SPARCV9
: ELF::EM_SPARC
,
27 /*HasRelocationAddend*/ true) {}
29 ~SparcELFObjectWriter() override
{}
32 unsigned getRelocType(MCContext
&Ctx
, const MCValue
&Target
,
33 const MCFixup
&Fixup
, bool IsPCRel
) const override
;
35 bool needsRelocateWithSymbol(const MCSymbol
&Sym
,
36 unsigned Type
) const override
;
41 unsigned SparcELFObjectWriter::getRelocType(MCContext
&Ctx
,
42 const MCValue
&Target
,
46 if (const SparcMCExpr
*SExpr
= dyn_cast
<SparcMCExpr
>(Fixup
.getValue())) {
47 if (SExpr
->getKind() == SparcMCExpr::VK_Sparc_R_DISP32
)
48 return ELF::R_SPARC_DISP32
;
52 switch(Fixup
.getTargetKind()) {
54 llvm_unreachable("Unimplemented fixup -> relocation");
55 case FK_Data_1
: return ELF::R_SPARC_DISP8
;
56 case FK_Data_2
: return ELF::R_SPARC_DISP16
;
57 case FK_Data_4
: return ELF::R_SPARC_DISP32
;
58 case FK_Data_8
: return ELF::R_SPARC_DISP64
;
59 case Sparc::fixup_sparc_call30
: return ELF::R_SPARC_WDISP30
;
60 case Sparc::fixup_sparc_br22
: return ELF::R_SPARC_WDISP22
;
61 case Sparc::fixup_sparc_br19
: return ELF::R_SPARC_WDISP19
;
62 case Sparc::fixup_sparc_pc22
: return ELF::R_SPARC_PC22
;
63 case Sparc::fixup_sparc_pc10
: return ELF::R_SPARC_PC10
;
64 case Sparc::fixup_sparc_wplt30
: return ELF::R_SPARC_WPLT30
;
68 switch(Fixup
.getTargetKind()) {
70 llvm_unreachable("Unimplemented fixup -> relocation");
71 case FK_Data_1
: return ELF::R_SPARC_8
;
72 case FK_Data_2
: return ((Fixup
.getOffset() % 2)
75 case FK_Data_4
: return ((Fixup
.getOffset() % 4)
78 case FK_Data_8
: return ((Fixup
.getOffset() % 8)
81 case Sparc::fixup_sparc_13
: return ELF::R_SPARC_13
;
82 case Sparc::fixup_sparc_hi22
: return ELF::R_SPARC_HI22
;
83 case Sparc::fixup_sparc_lo10
: return ELF::R_SPARC_LO10
;
84 case Sparc::fixup_sparc_h44
: return ELF::R_SPARC_H44
;
85 case Sparc::fixup_sparc_m44
: return ELF::R_SPARC_M44
;
86 case Sparc::fixup_sparc_l44
: return ELF::R_SPARC_L44
;
87 case Sparc::fixup_sparc_hh
: return ELF::R_SPARC_HH22
;
88 case Sparc::fixup_sparc_hm
: return ELF::R_SPARC_HM10
;
89 case Sparc::fixup_sparc_got22
: return ELF::R_SPARC_GOT22
;
90 case Sparc::fixup_sparc_got10
: return ELF::R_SPARC_GOT10
;
91 case Sparc::fixup_sparc_got13
: return ELF::R_SPARC_GOT13
;
92 case Sparc::fixup_sparc_tls_gd_hi22
: return ELF::R_SPARC_TLS_GD_HI22
;
93 case Sparc::fixup_sparc_tls_gd_lo10
: return ELF::R_SPARC_TLS_GD_LO10
;
94 case Sparc::fixup_sparc_tls_gd_add
: return ELF::R_SPARC_TLS_GD_ADD
;
95 case Sparc::fixup_sparc_tls_gd_call
: return ELF::R_SPARC_TLS_GD_CALL
;
96 case Sparc::fixup_sparc_tls_ldm_hi22
: return ELF::R_SPARC_TLS_LDM_HI22
;
97 case Sparc::fixup_sparc_tls_ldm_lo10
: return ELF::R_SPARC_TLS_LDM_LO10
;
98 case Sparc::fixup_sparc_tls_ldm_add
: return ELF::R_SPARC_TLS_LDM_ADD
;
99 case Sparc::fixup_sparc_tls_ldm_call
: return ELF::R_SPARC_TLS_LDM_CALL
;
100 case Sparc::fixup_sparc_tls_ldo_hix22
: return ELF::R_SPARC_TLS_LDO_HIX22
;
101 case Sparc::fixup_sparc_tls_ldo_lox10
: return ELF::R_SPARC_TLS_LDO_LOX10
;
102 case Sparc::fixup_sparc_tls_ldo_add
: return ELF::R_SPARC_TLS_LDO_ADD
;
103 case Sparc::fixup_sparc_tls_ie_hi22
: return ELF::R_SPARC_TLS_IE_HI22
;
104 case Sparc::fixup_sparc_tls_ie_lo10
: return ELF::R_SPARC_TLS_IE_LO10
;
105 case Sparc::fixup_sparc_tls_ie_ld
: return ELF::R_SPARC_TLS_IE_LD
;
106 case Sparc::fixup_sparc_tls_ie_ldx
: return ELF::R_SPARC_TLS_IE_LDX
;
107 case Sparc::fixup_sparc_tls_ie_add
: return ELF::R_SPARC_TLS_IE_ADD
;
108 case Sparc::fixup_sparc_tls_le_hix22
: return ELF::R_SPARC_TLS_LE_HIX22
;
109 case Sparc::fixup_sparc_tls_le_lox10
: return ELF::R_SPARC_TLS_LE_LOX10
;
112 return ELF::R_SPARC_NONE
;
115 bool SparcELFObjectWriter::needsRelocateWithSymbol(const MCSymbol
&Sym
,
116 unsigned Type
) const {
121 // All relocations that use a GOT need a symbol, not an offset, as
122 // the offset of the symbol within the section is irrelevant to
123 // where the GOT entry is. Don't need to list all the TLS entries,
124 // as they're all marked as requiring a symbol anyways.
125 case ELF::R_SPARC_GOT10
:
126 case ELF::R_SPARC_GOT13
:
127 case ELF::R_SPARC_GOT22
:
128 case ELF::R_SPARC_GOTDATA_HIX22
:
129 case ELF::R_SPARC_GOTDATA_LOX10
:
130 case ELF::R_SPARC_GOTDATA_OP_HIX22
:
131 case ELF::R_SPARC_GOTDATA_OP_LOX10
:
136 std::unique_ptr
<MCObjectTargetWriter
>
137 llvm::createSparcELFObjectWriter(bool Is64Bit
, uint8_t OSABI
) {
138 return std::make_unique
<SparcELFObjectWriter
>(Is64Bit
, OSABI
);