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 while (Bits < 32 && ParsedNum < ParmsNum) { 121 if (++ParsedNum > 1) 122 ParmsType += ", "; 123 if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) { 124 // Fixed parameter type. 125 ParmsType += "i"; 126 ++ParsedFixedNum; 127 Value <<= 1; 128 ++Bits; 129 } else { 130 if ((Value & TracebackTable::ParmTypeFloatingIsDoubleBit) == 0) 131 // Float parameter type. 132 ParmsType += "f"; 133 else 134 // Double parameter type. 135 ParmsType += "d"; 136 ++ParsedFloatingNum; 137 Value <<= 2; 138 Bits += 2; 139 } 140 } 141 142 // We have more parameters than the 32 Bits could encode. 143 if (ParsedNum < ParmsNum) 144 ParmsType += ", ..."; 145 146 if (Value != 0u || ParsedFixedNum > FixedParmsNum || 147 ParsedFloatingNum > FloatingParmsNum) 148 return createStringError(errc::invalid_argument, 149 "ParmsType encodes can not map to ParmsNum " 150 "parameters in parseParmsType."); 151 return ParmsType; 152 } 153 154 SmallString<32> XCOFF::getExtendedTBTableFlagString(uint8_t Flag) { 155 SmallString<32> Res; 156 157 if (Flag & ExtendedTBTableFlag::TB_OS1) 158 Res += "TB_OS1 "; 159 if (Flag & ExtendedTBTableFlag::TB_RESERVED) 160 Res += "TB_RESERVED "; 161 if (Flag & ExtendedTBTableFlag::TB_SSP_CANARY) 162 Res += "TB_SSP_CANARY "; 163 if (Flag & ExtendedTBTableFlag::TB_OS2) 164 Res += "TB_OS2 "; 165 if (Flag & ExtendedTBTableFlag::TB_EH_INFO) 166 Res += "TB_EH_INFO "; 167 if (Flag & ExtendedTBTableFlag::TB_LONGTBTABLE2) 168 Res += "TB_LONGTBTABLE2 "; 169 170 // Two of the bits that haven't got used in the mask. 171 if (Flag & 0x06) 172 Res += "Unknown "; 173 174 // Pop the last space. 175 Res.pop_back(); 176 return Res; 177 } 178 179 Expected<SmallString<32>> 180 XCOFF::parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum, 181 unsigned FloatingParmsNum, 182 unsigned VectorParmsNum) { 183 SmallString<32> ParmsType; 184 185 unsigned ParsedFixedNum = 0; 186 unsigned ParsedFloatingNum = 0; 187 unsigned ParsedVectorNum = 0; 188 unsigned ParsedNum = 0; 189 unsigned ParmsNum = FixedParmsNum + FloatingParmsNum + VectorParmsNum; 190 191 for (int Bits = 0; Bits < 32 && ParsedNum < ParmsNum; Bits += 2) { 192 if (++ParsedNum > 1) 193 ParmsType += ", "; 194 195 switch (Value & TracebackTable::ParmTypeMask) { 196 case TracebackTable::ParmTypeIsFixedBits: 197 ParmsType += "i"; 198 ++ParsedFixedNum; 199 break; 200 case TracebackTable::ParmTypeIsVectorBits: 201 ParmsType += "v"; 202 ++ParsedVectorNum; 203 break; 204 case TracebackTable::ParmTypeIsFloatingBits: 205 ParmsType += "f"; 206 ++ParsedFloatingNum; 207 break; 208 case TracebackTable::ParmTypeIsDoubleBits: 209 ParmsType += "d"; 210 ++ParsedFloatingNum; 211 break; 212 default: 213 assert(false && "Unrecognized bits in ParmsType."); 214 } 215 Value <<= 2; 216 } 217 218 // We have more parameters than the 32 Bits could encode. 219 if (ParsedNum < ParmsNum) 220 ParmsType += ", ..."; 221 222 if (Value != 0u || ParsedFixedNum > FixedParmsNum || 223 ParsedFloatingNum > FloatingParmsNum || ParsedVectorNum > VectorParmsNum) 224 return createStringError( 225 errc::invalid_argument, 226 "ParmsType encodes can not map to ParmsNum parameters " 227 "in parseParmsTypeWithVecInfo."); 228 229 return ParmsType; 230 } 231 232 Expected<SmallString<32>> XCOFF::parseVectorParmsType(uint32_t Value, 233 unsigned ParmsNum) { 234 SmallString<32> ParmsType; 235 unsigned ParsedNum = 0; 236 for (int Bits = 0; ParsedNum < ParmsNum && Bits < 32; Bits += 2) { 237 if (++ParsedNum > 1) 238 ParmsType += ", "; 239 switch (Value & TracebackTable::ParmTypeMask) { 240 case TracebackTable::ParmTypeIsVectorCharBit: 241 ParmsType += "vc"; 242 break; 243 244 case TracebackTable::ParmTypeIsVectorShortBit: 245 ParmsType += "vs"; 246 break; 247 248 case TracebackTable::ParmTypeIsVectorIntBit: 249 ParmsType += "vi"; 250 break; 251 252 case TracebackTable::ParmTypeIsVectorFloatBit: 253 ParmsType += "vf"; 254 break; 255 } 256 257 Value <<= 2; 258 } 259 260 // We have more parameters than the 32 Bits could encode. 261 if (ParsedNum < ParmsNum) 262 ParmsType += ", ..."; 263 264 if (Value != 0u) 265 return createStringError(errc::invalid_argument, 266 "ParmsType encodes more than ParmsNum parameters " 267 "in parseVectorParmsType."); 268 return ParmsType; 269 } 270