Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/BinaryFormat/XCOFF.cpp
35234 views
1
//===-- llvm/BinaryFormat/XCOFF.cpp - The XCOFF file format -----*- C++/-*-===//
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
9
#include "llvm/BinaryFormat/XCOFF.h"
10
#include "llvm/ADT/SmallString.h"
11
#include "llvm/ADT/StringRef.h"
12
#include "llvm/Support/Errc.h"
13
#include "llvm/Support/Error.h"
14
15
using namespace llvm;
16
17
#define SMC_CASE(A) \
18
case XCOFF::XMC_##A: \
19
return #A;
20
StringRef XCOFF::getMappingClassString(XCOFF::StorageMappingClass SMC) {
21
switch (SMC) {
22
SMC_CASE(PR)
23
SMC_CASE(RO)
24
SMC_CASE(DB)
25
SMC_CASE(GL)
26
SMC_CASE(XO)
27
SMC_CASE(SV)
28
SMC_CASE(SV64)
29
SMC_CASE(SV3264)
30
SMC_CASE(TI)
31
SMC_CASE(TB)
32
SMC_CASE(RW)
33
SMC_CASE(TC0)
34
SMC_CASE(TC)
35
SMC_CASE(TD)
36
SMC_CASE(DS)
37
SMC_CASE(UA)
38
SMC_CASE(BS)
39
SMC_CASE(UC)
40
SMC_CASE(TL)
41
SMC_CASE(UL)
42
SMC_CASE(TE)
43
#undef SMC_CASE
44
}
45
46
// TODO: need to add a test case for "Unknown" and other SMC.
47
return "Unknown";
48
}
49
50
#define RELOC_CASE(A) \
51
case XCOFF::A: \
52
return #A;
53
StringRef XCOFF::getRelocationTypeString(XCOFF::RelocationType Type) {
54
switch (Type) {
55
RELOC_CASE(R_POS)
56
RELOC_CASE(R_RL)
57
RELOC_CASE(R_RLA)
58
RELOC_CASE(R_NEG)
59
RELOC_CASE(R_REL)
60
RELOC_CASE(R_TOC)
61
RELOC_CASE(R_TRL)
62
RELOC_CASE(R_TRLA)
63
RELOC_CASE(R_GL)
64
RELOC_CASE(R_TCL)
65
RELOC_CASE(R_REF)
66
RELOC_CASE(R_BA)
67
RELOC_CASE(R_BR)
68
RELOC_CASE(R_RBA)
69
RELOC_CASE(R_RBR)
70
RELOC_CASE(R_TLS)
71
RELOC_CASE(R_TLS_IE)
72
RELOC_CASE(R_TLS_LD)
73
RELOC_CASE(R_TLS_LE)
74
RELOC_CASE(R_TLSM)
75
RELOC_CASE(R_TLSML)
76
RELOC_CASE(R_TOCU)
77
RELOC_CASE(R_TOCL)
78
}
79
return "Unknown";
80
}
81
#undef RELOC_CASE
82
83
#define LANG_CASE(A) \
84
case XCOFF::TracebackTable::A: \
85
return #A;
86
87
StringRef XCOFF::getNameForTracebackTableLanguageId(
88
XCOFF::TracebackTable::LanguageID LangId) {
89
switch (LangId) {
90
LANG_CASE(C)
91
LANG_CASE(Fortran)
92
LANG_CASE(Pascal)
93
LANG_CASE(Ada)
94
LANG_CASE(PL1)
95
LANG_CASE(Basic)
96
LANG_CASE(Lisp)
97
LANG_CASE(Cobol)
98
LANG_CASE(Modula2)
99
LANG_CASE(Rpg)
100
LANG_CASE(PL8)
101
LANG_CASE(Assembly)
102
LANG_CASE(Java)
103
LANG_CASE(ObjectiveC)
104
LANG_CASE(CPlusPlus)
105
}
106
return "Unknown";
107
}
108
#undef LANG_CASE
109
110
Expected<SmallString<32>> XCOFF::parseParmsType(uint32_t Value,
111
unsigned FixedParmsNum,
112
unsigned FloatingParmsNum) {
113
SmallString<32> ParmsType;
114
int Bits = 0;
115
unsigned ParsedFixedNum = 0;
116
unsigned ParsedFloatingNum = 0;
117
unsigned ParsedNum = 0;
118
unsigned ParmsNum = FixedParmsNum + FloatingParmsNum;
119
120
// In the function PPCFunctionInfo::getParmsType(), when there are no vector
121
// parameters, the 31st bit of ParmsType is always zero even if it indicates a
122
// floating point parameter. The parameter type information is lost. There
123
// are only 8 GPRs used for parameters passing, the floating parameters
124
// also occupy GPRs if there are available, so the 31st bit can never be a
125
// fixed parameter. At the same time, we also do not know whether the zero of
126
// the 31st bit indicates a float or double parameter type here. Therefore, we
127
// ignore the 31st bit.
128
while (Bits < 31 && ParsedNum < ParmsNum) {
129
if (++ParsedNum > 1)
130
ParmsType += ", ";
131
if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) {
132
// Fixed parameter type.
133
ParmsType += "i";
134
++ParsedFixedNum;
135
Value <<= 1;
136
++Bits;
137
} else {
138
if ((Value & TracebackTable::ParmTypeFloatingIsDoubleBit) == 0)
139
// Float parameter type.
140
ParmsType += "f";
141
else
142
// Double parameter type.
143
ParmsType += "d";
144
++ParsedFloatingNum;
145
Value <<= 2;
146
Bits += 2;
147
}
148
}
149
150
// We have more parameters than the 32 Bits could encode.
151
if (ParsedNum < ParmsNum)
152
ParmsType += ", ...";
153
154
if (Value != 0u || ParsedFixedNum > FixedParmsNum ||
155
ParsedFloatingNum > FloatingParmsNum)
156
return createStringError(errc::invalid_argument,
157
"ParmsType encodes can not map to ParmsNum "
158
"parameters in parseParmsType.");
159
return ParmsType;
160
}
161
162
SmallString<32> XCOFF::getExtendedTBTableFlagString(uint8_t Flag) {
163
SmallString<32> Res;
164
165
if (Flag & ExtendedTBTableFlag::TB_OS1)
166
Res += "TB_OS1 ";
167
if (Flag & ExtendedTBTableFlag::TB_RESERVED)
168
Res += "TB_RESERVED ";
169
if (Flag & ExtendedTBTableFlag::TB_SSP_CANARY)
170
Res += "TB_SSP_CANARY ";
171
if (Flag & ExtendedTBTableFlag::TB_OS2)
172
Res += "TB_OS2 ";
173
if (Flag & ExtendedTBTableFlag::TB_EH_INFO)
174
Res += "TB_EH_INFO ";
175
if (Flag & ExtendedTBTableFlag::TB_LONGTBTABLE2)
176
Res += "TB_LONGTBTABLE2 ";
177
178
// Two of the bits that haven't got used in the mask.
179
if (Flag & 0x06)
180
Res += "Unknown ";
181
182
// Pop the last space.
183
Res.pop_back();
184
return Res;
185
}
186
187
Expected<SmallString<32>>
188
XCOFF::parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum,
189
unsigned FloatingParmsNum,
190
unsigned VectorParmsNum) {
191
SmallString<32> ParmsType;
192
193
unsigned ParsedFixedNum = 0;
194
unsigned ParsedFloatingNum = 0;
195
unsigned ParsedVectorNum = 0;
196
unsigned ParsedNum = 0;
197
unsigned ParmsNum = FixedParmsNum + FloatingParmsNum + VectorParmsNum;
198
199
for (int Bits = 0; Bits < 32 && ParsedNum < ParmsNum; Bits += 2) {
200
if (++ParsedNum > 1)
201
ParmsType += ", ";
202
203
switch (Value & TracebackTable::ParmTypeMask) {
204
case TracebackTable::ParmTypeIsFixedBits:
205
ParmsType += "i";
206
++ParsedFixedNum;
207
break;
208
case TracebackTable::ParmTypeIsVectorBits:
209
ParmsType += "v";
210
++ParsedVectorNum;
211
break;
212
case TracebackTable::ParmTypeIsFloatingBits:
213
ParmsType += "f";
214
++ParsedFloatingNum;
215
break;
216
case TracebackTable::ParmTypeIsDoubleBits:
217
ParmsType += "d";
218
++ParsedFloatingNum;
219
break;
220
default:
221
assert(false && "Unrecognized bits in ParmsType.");
222
}
223
Value <<= 2;
224
}
225
226
// We have more parameters than the 32 Bits could encode.
227
if (ParsedNum < ParmsNum)
228
ParmsType += ", ...";
229
230
if (Value != 0u || ParsedFixedNum > FixedParmsNum ||
231
ParsedFloatingNum > FloatingParmsNum || ParsedVectorNum > VectorParmsNum)
232
return createStringError(
233
errc::invalid_argument,
234
"ParmsType encodes can not map to ParmsNum parameters "
235
"in parseParmsTypeWithVecInfo.");
236
237
return ParmsType;
238
}
239
240
Expected<SmallString<32>> XCOFF::parseVectorParmsType(uint32_t Value,
241
unsigned ParmsNum) {
242
SmallString<32> ParmsType;
243
unsigned ParsedNum = 0;
244
for (int Bits = 0; ParsedNum < ParmsNum && Bits < 32; Bits += 2) {
245
if (++ParsedNum > 1)
246
ParmsType += ", ";
247
switch (Value & TracebackTable::ParmTypeMask) {
248
case TracebackTable::ParmTypeIsVectorCharBit:
249
ParmsType += "vc";
250
break;
251
252
case TracebackTable::ParmTypeIsVectorShortBit:
253
ParmsType += "vs";
254
break;
255
256
case TracebackTable::ParmTypeIsVectorIntBit:
257
ParmsType += "vi";
258
break;
259
260
case TracebackTable::ParmTypeIsVectorFloatBit:
261
ParmsType += "vf";
262
break;
263
}
264
265
Value <<= 2;
266
}
267
268
// We have more parameters than the 32 Bits could encode.
269
if (ParsedNum < ParmsNum)
270
ParmsType += ", ...";
271
272
if (Value != 0u)
273
return createStringError(errc::invalid_argument,
274
"ParmsType encodes more than ParmsNum parameters "
275
"in parseVectorParmsType.");
276
return ParmsType;
277
}
278
279