/src/keystone/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- SystemZMCObjectWriter.cpp - SystemZ 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/SystemZMCTargetDesc.h" |
11 | | #include "MCTargetDesc/SystemZMCFixups.h" |
12 | | #include "llvm/MC/MCELFObjectWriter.h" |
13 | | #include "llvm/MC/MCExpr.h" |
14 | | #include "llvm/MC/MCValue.h" |
15 | | |
16 | | using namespace llvm_ks; |
17 | | |
18 | | namespace { |
19 | | class SystemZObjectWriter : public MCELFObjectTargetWriter { |
20 | | public: |
21 | | SystemZObjectWriter(uint8_t OSABI); |
22 | | |
23 | | ~SystemZObjectWriter() override; |
24 | | |
25 | | protected: |
26 | | // Override MCELFObjectTargetWriter. |
27 | | unsigned getRelocType(MCContext &Ctx, const MCValue &Target, |
28 | | const MCFixup &Fixup, bool IsPCRel) const override; |
29 | | }; |
30 | | } // end anonymous namespace |
31 | | |
32 | | SystemZObjectWriter::SystemZObjectWriter(uint8_t OSABI) |
33 | 46 | : MCELFObjectTargetWriter(/*Is64Bit=*/true, OSABI, ELF::EM_S390, |
34 | 46 | /*HasRelocationAddend=*/ true) {} |
35 | | |
36 | | SystemZObjectWriter::~SystemZObjectWriter() { |
37 | | } |
38 | | |
39 | | // Return the relocation type for an absolute value of MCFixupKind Kind. |
40 | 0 | static unsigned getAbsoluteReloc(unsigned Kind) { |
41 | 0 | switch (Kind) { |
42 | 0 | case FK_Data_1: return ELF::R_390_8; |
43 | 0 | case FK_Data_2: return ELF::R_390_16; |
44 | 0 | case FK_Data_4: return ELF::R_390_32; |
45 | 0 | case FK_Data_8: return ELF::R_390_64; |
46 | 0 | } |
47 | 0 | llvm_unreachable("Unsupported absolute address"); |
48 | 0 | } |
49 | | |
50 | | // Return the relocation type for a PC-relative value of MCFixupKind Kind. |
51 | 0 | static unsigned getPCRelReloc(unsigned Kind) { |
52 | 0 | switch (Kind) { |
53 | 0 | case FK_Data_2: return ELF::R_390_PC16; |
54 | 0 | case FK_Data_4: return ELF::R_390_PC32; |
55 | 0 | case FK_Data_8: return ELF::R_390_PC64; |
56 | 0 | case SystemZ::FK_390_PC16DBL: return ELF::R_390_PC16DBL; |
57 | 0 | case SystemZ::FK_390_PC32DBL: return ELF::R_390_PC32DBL; |
58 | 0 | } |
59 | 0 | llvm_unreachable("Unsupported PC-relative address"); |
60 | 0 | } |
61 | | |
62 | | // Return the R_390_TLS_LE* relocation type for MCFixupKind Kind. |
63 | 0 | static unsigned getTLSLEReloc(unsigned Kind) { |
64 | 0 | switch (Kind) { |
65 | 0 | case FK_Data_4: return ELF::R_390_TLS_LE32; |
66 | 0 | case FK_Data_8: return ELF::R_390_TLS_LE64; |
67 | 0 | } |
68 | 0 | llvm_unreachable("Unsupported absolute address"); |
69 | 0 | } |
70 | | |
71 | | // Return the R_390_TLS_LDO* relocation type for MCFixupKind Kind. |
72 | 0 | static unsigned getTLSLDOReloc(unsigned Kind) { |
73 | 0 | switch (Kind) { |
74 | 0 | case FK_Data_4: return ELF::R_390_TLS_LDO32; |
75 | 0 | case FK_Data_8: return ELF::R_390_TLS_LDO64; |
76 | 0 | } |
77 | 0 | llvm_unreachable("Unsupported absolute address"); |
78 | 0 | } |
79 | | |
80 | | // Return the R_390_TLS_LDM* relocation type for MCFixupKind Kind. |
81 | 0 | static unsigned getTLSLDMReloc(unsigned Kind) { |
82 | 0 | switch (Kind) { |
83 | 0 | case FK_Data_4: return ELF::R_390_TLS_LDM32; |
84 | 0 | case FK_Data_8: return ELF::R_390_TLS_LDM64; |
85 | 0 | case SystemZ::FK_390_TLS_CALL: return ELF::R_390_TLS_LDCALL; |
86 | 0 | } |
87 | 0 | llvm_unreachable("Unsupported absolute address"); |
88 | 0 | } |
89 | | |
90 | | // Return the R_390_TLS_GD* relocation type for MCFixupKind Kind. |
91 | 0 | static unsigned getTLSGDReloc(unsigned Kind) { |
92 | 0 | switch (Kind) { |
93 | 0 | case FK_Data_4: return ELF::R_390_TLS_GD32; |
94 | 0 | case FK_Data_8: return ELF::R_390_TLS_GD64; |
95 | 0 | case SystemZ::FK_390_TLS_CALL: return ELF::R_390_TLS_GDCALL; |
96 | 0 | } |
97 | 0 | llvm_unreachable("Unsupported absolute address"); |
98 | 0 | } |
99 | | |
100 | | // Return the PLT relocation counterpart of MCFixupKind Kind. |
101 | 0 | static unsigned getPLTReloc(unsigned Kind) { |
102 | 0 | switch (Kind) { |
103 | 0 | case SystemZ::FK_390_PC16DBL: return ELF::R_390_PLT16DBL; |
104 | 0 | case SystemZ::FK_390_PC32DBL: return ELF::R_390_PLT32DBL; |
105 | 0 | } |
106 | 0 | llvm_unreachable("Unsupported absolute address"); |
107 | 0 | } |
108 | | |
109 | | unsigned SystemZObjectWriter::getRelocType(MCContext &Ctx, |
110 | | const MCValue &Target, |
111 | | const MCFixup &Fixup, |
112 | 0 | bool IsPCRel) const { |
113 | 0 | MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); |
114 | 0 | unsigned Kind = Fixup.getKind(); |
115 | 0 | switch (Modifier) { |
116 | 0 | case MCSymbolRefExpr::VK_None: |
117 | 0 | if (IsPCRel) |
118 | 0 | return getPCRelReloc(Kind); |
119 | 0 | return getAbsoluteReloc(Kind); |
120 | | |
121 | 0 | case MCSymbolRefExpr::VK_NTPOFF: |
122 | 0 | assert(!IsPCRel && "NTPOFF shouldn't be PC-relative"); |
123 | 0 | return getTLSLEReloc(Kind); |
124 | | |
125 | 0 | case MCSymbolRefExpr::VK_INDNTPOFF: |
126 | 0 | if (IsPCRel && Kind == SystemZ::FK_390_PC32DBL) |
127 | 0 | return ELF::R_390_TLS_IEENT; |
128 | 0 | llvm_unreachable("Only PC-relative INDNTPOFF accesses are supported for now"); |
129 | | |
130 | 0 | case MCSymbolRefExpr::VK_DTPOFF: |
131 | 0 | assert(!IsPCRel && "DTPOFF shouldn't be PC-relative"); |
132 | 0 | return getTLSLDOReloc(Kind); |
133 | | |
134 | 0 | case MCSymbolRefExpr::VK_TLSLDM: |
135 | 0 | assert(!IsPCRel && "TLSLDM shouldn't be PC-relative"); |
136 | 0 | return getTLSLDMReloc(Kind); |
137 | | |
138 | 0 | case MCSymbolRefExpr::VK_TLSGD: |
139 | 0 | assert(!IsPCRel && "TLSGD shouldn't be PC-relative"); |
140 | 0 | return getTLSGDReloc(Kind); |
141 | | |
142 | 0 | case MCSymbolRefExpr::VK_GOT: |
143 | 0 | if (IsPCRel && Kind == SystemZ::FK_390_PC32DBL) |
144 | 0 | return ELF::R_390_GOTENT; |
145 | 0 | llvm_unreachable("Only PC-relative GOT accesses are supported for now"); |
146 | | |
147 | 0 | case MCSymbolRefExpr::VK_PLT: |
148 | 0 | assert(IsPCRel && "@PLT shouldt be PC-relative"); |
149 | 0 | return getPLTReloc(Kind); |
150 | | |
151 | 0 | default: |
152 | 0 | llvm_unreachable("Modifier not supported"); |
153 | 0 | } |
154 | 0 | } |
155 | | |
156 | | MCObjectWriter *llvm_ks::createSystemZObjectWriter(raw_pwrite_stream &OS, |
157 | 46 | uint8_t OSABI) { |
158 | 46 | MCELFObjectTargetWriter *MOTW = new SystemZObjectWriter(OSABI); |
159 | 46 | return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/false); |
160 | 46 | } |