1 //===- MipsArchTree.cpp --------------------------------------------------===// 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 // This file contains a helper function for the Writer. 10 // 11 //===---------------------------------------------------------------------===// 12 13 #include "InputFiles.h" 14 #include "SymbolTable.h" 15 #include "Writer.h" 16 17 #include "lld/Common/ErrorHandler.h" 18 #include "llvm/BinaryFormat/ELF.h" 19 #include "llvm/Support/MipsABIFlags.h" 20 21 using namespace llvm; 22 using namespace llvm::object; 23 using namespace llvm::ELF; 24 25 using namespace lld; 26 using namespace lld::elf; 27 28 namespace { 29 struct ArchTreeEdge { 30 uint32_t child; 31 uint32_t parent; 32 }; 33 34 struct FileFlags { 35 InputFile *file; 36 uint32_t flags; 37 }; 38 } // namespace 39 40 static StringRef getAbiName(uint32_t flags) { 41 switch (flags) { 42 case 0: 43 return "n64"; 44 case EF_MIPS_ABI2: 45 return "n32"; 46 case EF_MIPS_ABI_O32: 47 return "o32"; 48 case EF_MIPS_ABI_O64: 49 return "o64"; 50 case EF_MIPS_ABI_EABI32: 51 return "eabi32"; 52 case EF_MIPS_ABI_EABI64: 53 return "eabi64"; 54 default: 55 return "unknown"; 56 } 57 } 58 59 static StringRef getNanName(bool isNan2008) { 60 return isNan2008 ? "2008" : "legacy"; 61 } 62 63 static StringRef getFpName(bool isFp64) { return isFp64 ? "64" : "32"; } 64 65 static void checkFlags(ArrayRef<FileFlags> files) { 66 assert(!files.empty() && "expected non-empty file list"); 67 68 uint32_t abi = files[0].flags & (EF_MIPS_ABI | EF_MIPS_ABI2); 69 bool nan = files[0].flags & EF_MIPS_NAN2008; 70 bool fp = files[0].flags & EF_MIPS_FP64; 71 72 for (const FileFlags &f : files) { 73 if (config->is64 && f.flags & EF_MIPS_MICROMIPS) 74 error(toString(f.file) + ": microMIPS 64-bit is not supported"); 75 76 uint32_t abi2 = f.flags & (EF_MIPS_ABI | EF_MIPS_ABI2); 77 if (abi != abi2) 78 error(toString(f.file) + ": ABI '" + getAbiName(abi2) + 79 "' is incompatible with target ABI '" + getAbiName(abi) + "'"); 80 81 bool nan2 = f.flags & EF_MIPS_NAN2008; 82 if (nan != nan2) 83 error(toString(f.file) + ": -mnan=" + getNanName(nan2) + 84 " is incompatible with target -mnan=" + getNanName(nan)); 85 86 bool fp2 = f.flags & EF_MIPS_FP64; 87 if (fp != fp2) 88 error(toString(f.file) + ": -mfp" + getFpName(fp2) + 89 " is incompatible with target -mfp" + getFpName(fp)); 90 } 91 } 92 93 static uint32_t getMiscFlags(ArrayRef<FileFlags> files) { 94 uint32_t ret = 0; 95 for (const FileFlags &f : files) 96 ret |= f.flags & 97 (EF_MIPS_ABI | EF_MIPS_ABI2 | EF_MIPS_ARCH_ASE | EF_MIPS_NOREORDER | 98 EF_MIPS_MICROMIPS | EF_MIPS_NAN2008 | EF_MIPS_32BITMODE); 99 return ret; 100 } 101 102 static uint32_t getPicFlags(ArrayRef<FileFlags> files) { 103 // Check PIC/non-PIC compatibility. 104 bool isPic = files[0].flags & (EF_MIPS_PIC | EF_MIPS_CPIC); 105 for (const FileFlags &f : files.slice(1)) { 106 bool isPic2 = f.flags & (EF_MIPS_PIC | EF_MIPS_CPIC); 107 if (isPic && !isPic2) 108 warn(toString(f.file) + 109 ": linking non-abicalls code with abicalls code " + 110 toString(files[0].file)); 111 if (!isPic && isPic2) 112 warn(toString(f.file) + 113 ": linking abicalls code with non-abicalls code " + 114 toString(files[0].file)); 115 } 116 117 // Compute the result PIC/non-PIC flag. 118 uint32_t ret = files[0].flags & (EF_MIPS_PIC | EF_MIPS_CPIC); 119 for (const FileFlags &f : files.slice(1)) 120 ret &= f.flags & (EF_MIPS_PIC | EF_MIPS_CPIC); 121 122 // PIC code is inherently CPIC and may not set CPIC flag explicitly. 123 if (ret & EF_MIPS_PIC) 124 ret |= EF_MIPS_CPIC; 125 return ret; 126 } 127 128 static ArchTreeEdge archTree[] = { 129 // MIPS32R6 and MIPS64R6 are not compatible with other extensions 130 // MIPS64R2 extensions. 131 {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON3, EF_MIPS_ARCH_64R2}, 132 {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON2, EF_MIPS_ARCH_64R2}, 133 {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON, EF_MIPS_ARCH_64R2}, 134 {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_LS3A, EF_MIPS_ARCH_64R2}, 135 // MIPS64 extensions. 136 {EF_MIPS_ARCH_64 | EF_MIPS_MACH_SB1, EF_MIPS_ARCH_64}, 137 {EF_MIPS_ARCH_64 | EF_MIPS_MACH_XLR, EF_MIPS_ARCH_64}, 138 {EF_MIPS_ARCH_64R2, EF_MIPS_ARCH_64}, 139 // MIPS V extensions. 140 {EF_MIPS_ARCH_64, EF_MIPS_ARCH_5}, 141 // R5000 extensions. 142 {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5500, EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400}, 143 // MIPS IV extensions. 144 {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400, EF_MIPS_ARCH_4}, 145 {EF_MIPS_ARCH_4 | EF_MIPS_MACH_9000, EF_MIPS_ARCH_4}, 146 {EF_MIPS_ARCH_5, EF_MIPS_ARCH_4}, 147 // VR4100 extensions. 148 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4111, EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100}, 149 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4120, EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100}, 150 // MIPS III extensions. 151 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4010, EF_MIPS_ARCH_3}, 152 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100, EF_MIPS_ARCH_3}, 153 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4650, EF_MIPS_ARCH_3}, 154 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_5900, EF_MIPS_ARCH_3}, 155 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2E, EF_MIPS_ARCH_3}, 156 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2F, EF_MIPS_ARCH_3}, 157 {EF_MIPS_ARCH_4, EF_MIPS_ARCH_3}, 158 // MIPS32 extensions. 159 {EF_MIPS_ARCH_32R2, EF_MIPS_ARCH_32}, 160 // MIPS II extensions. 161 {EF_MIPS_ARCH_3, EF_MIPS_ARCH_2}, 162 {EF_MIPS_ARCH_32, EF_MIPS_ARCH_2}, 163 // MIPS I extensions. 164 {EF_MIPS_ARCH_1 | EF_MIPS_MACH_3900, EF_MIPS_ARCH_1}, 165 {EF_MIPS_ARCH_2, EF_MIPS_ARCH_1}, 166 }; 167 168 static bool isArchMatched(uint32_t newFlags, uint32_t res) { 169 if (newFlags == res) 170 return true; 171 if (newFlags == EF_MIPS_ARCH_32 && isArchMatched(EF_MIPS_ARCH_64, res)) 172 return true; 173 if (newFlags == EF_MIPS_ARCH_32R2 && isArchMatched(EF_MIPS_ARCH_64R2, res)) 174 return true; 175 for (const auto &edge : archTree) { 176 if (res == edge.child) { 177 res = edge.parent; 178 if (res == newFlags) 179 return true; 180 } 181 } 182 return false; 183 } 184 185 static StringRef getMachName(uint32_t flags) { 186 switch (flags & EF_MIPS_MACH) { 187 case EF_MIPS_MACH_NONE: 188 return ""; 189 case EF_MIPS_MACH_3900: 190 return "r3900"; 191 case EF_MIPS_MACH_4010: 192 return "r4010"; 193 case EF_MIPS_MACH_4100: 194 return "r4100"; 195 case EF_MIPS_MACH_4650: 196 return "r4650"; 197 case EF_MIPS_MACH_4120: 198 return "r4120"; 199 case EF_MIPS_MACH_4111: 200 return "r4111"; 201 case EF_MIPS_MACH_5400: 202 return "vr5400"; 203 case EF_MIPS_MACH_5900: 204 return "vr5900"; 205 case EF_MIPS_MACH_5500: 206 return "vr5500"; 207 case EF_MIPS_MACH_9000: 208 return "rm9000"; 209 case EF_MIPS_MACH_LS2E: 210 return "loongson2e"; 211 case EF_MIPS_MACH_LS2F: 212 return "loongson2f"; 213 case EF_MIPS_MACH_LS3A: 214 return "loongson3a"; 215 case EF_MIPS_MACH_OCTEON: 216 return "octeon"; 217 case EF_MIPS_MACH_OCTEON2: 218 return "octeon2"; 219 case EF_MIPS_MACH_OCTEON3: 220 return "octeon3"; 221 case EF_MIPS_MACH_SB1: 222 return "sb1"; 223 case EF_MIPS_MACH_XLR: 224 return "xlr"; 225 default: 226 return "unknown machine"; 227 } 228 } 229 230 static StringRef getArchName(uint32_t flags) { 231 switch (flags & EF_MIPS_ARCH) { 232 case EF_MIPS_ARCH_1: 233 return "mips1"; 234 case EF_MIPS_ARCH_2: 235 return "mips2"; 236 case EF_MIPS_ARCH_3: 237 return "mips3"; 238 case EF_MIPS_ARCH_4: 239 return "mips4"; 240 case EF_MIPS_ARCH_5: 241 return "mips5"; 242 case EF_MIPS_ARCH_32: 243 return "mips32"; 244 case EF_MIPS_ARCH_64: 245 return "mips64"; 246 case EF_MIPS_ARCH_32R2: 247 return "mips32r2"; 248 case EF_MIPS_ARCH_64R2: 249 return "mips64r2"; 250 case EF_MIPS_ARCH_32R6: 251 return "mips32r6"; 252 case EF_MIPS_ARCH_64R6: 253 return "mips64r6"; 254 default: 255 return "unknown arch"; 256 } 257 } 258 259 static std::string getFullArchName(uint32_t flags) { 260 StringRef arch = getArchName(flags); 261 StringRef mach = getMachName(flags); 262 if (mach.empty()) 263 return arch.str(); 264 return (arch + " (" + mach + ")").str(); 265 } 266 267 // There are (arguably too) many MIPS ISAs out there. Their relationships 268 // can be represented as a forest. If all input files have ISAs which 269 // reachable by repeated proceeding from the single child to the parent, 270 // these input files are compatible. In that case we need to return "highest" 271 // ISA. If there are incompatible input files, we show an error. 272 // For example, mips1 is a "parent" of mips2 and such files are compatible. 273 // Output file gets EF_MIPS_ARCH_2 flag. From the other side mips3 and mips32 274 // are incompatible because nor mips3 is a parent for misp32, nor mips32 275 // is a parent for mips3. 276 static uint32_t getArchFlags(ArrayRef<FileFlags> files) { 277 uint32_t ret = files[0].flags & (EF_MIPS_ARCH | EF_MIPS_MACH); 278 279 for (const FileFlags &f : files.slice(1)) { 280 uint32_t newFlags = f.flags & (EF_MIPS_ARCH | EF_MIPS_MACH); 281 282 // Check ISA compatibility. 283 if (isArchMatched(newFlags, ret)) 284 continue; 285 if (!isArchMatched(ret, newFlags)) { 286 error("incompatible target ISA:\n>>> " + toString(files[0].file) + ": " + 287 getFullArchName(ret) + "\n>>> " + toString(f.file) + ": " + 288 getFullArchName(newFlags)); 289 return 0; 290 } 291 ret = newFlags; 292 } 293 return ret; 294 } 295 296 template <class ELFT> uint32_t elf::calcMipsEFlags() { 297 std::vector<FileFlags> v; 298 for (InputFile *f : ctx->objectFiles) 299 v.push_back({f, cast<ObjFile<ELFT>>(f)->getObj().getHeader().e_flags}); 300 if (v.empty()) { 301 // If we don't have any input files, we'll have to rely on the information 302 // we can derive from emulation information, since this at least gets us 303 // ABI. 304 if (config->emulation.empty() || config->is64) 305 return 0; 306 return config->mipsN32Abi ? EF_MIPS_ABI2 : EF_MIPS_ABI_O32; 307 } 308 checkFlags(v); 309 return getMiscFlags(v) | getPicFlags(v) | getArchFlags(v); 310 } 311 312 static int compareMipsFpAbi(uint8_t fpA, uint8_t fpB) { 313 if (fpA == fpB) 314 return 0; 315 if (fpB == Mips::Val_GNU_MIPS_ABI_FP_ANY) 316 return 1; 317 if (fpB == Mips::Val_GNU_MIPS_ABI_FP_64A && 318 fpA == Mips::Val_GNU_MIPS_ABI_FP_64) 319 return 1; 320 if (fpB != Mips::Val_GNU_MIPS_ABI_FP_XX) 321 return -1; 322 if (fpA == Mips::Val_GNU_MIPS_ABI_FP_DOUBLE || 323 fpA == Mips::Val_GNU_MIPS_ABI_FP_64 || 324 fpA == Mips::Val_GNU_MIPS_ABI_FP_64A) 325 return 1; 326 return -1; 327 } 328 329 static StringRef getMipsFpAbiName(uint8_t fpAbi) { 330 switch (fpAbi) { 331 case Mips::Val_GNU_MIPS_ABI_FP_ANY: 332 return "any"; 333 case Mips::Val_GNU_MIPS_ABI_FP_DOUBLE: 334 return "-mdouble-float"; 335 case Mips::Val_GNU_MIPS_ABI_FP_SINGLE: 336 return "-msingle-float"; 337 case Mips::Val_GNU_MIPS_ABI_FP_SOFT: 338 return "-msoft-float"; 339 case Mips::Val_GNU_MIPS_ABI_FP_OLD_64: 340 return "-mgp32 -mfp64 (old)"; 341 case Mips::Val_GNU_MIPS_ABI_FP_XX: 342 return "-mfpxx"; 343 case Mips::Val_GNU_MIPS_ABI_FP_64: 344 return "-mgp32 -mfp64"; 345 case Mips::Val_GNU_MIPS_ABI_FP_64A: 346 return "-mgp32 -mfp64 -mno-odd-spreg"; 347 default: 348 return "unknown"; 349 } 350 } 351 352 uint8_t elf::getMipsFpAbiFlag(uint8_t oldFlag, uint8_t newFlag, 353 StringRef fileName) { 354 if (compareMipsFpAbi(newFlag, oldFlag) >= 0) 355 return newFlag; 356 if (compareMipsFpAbi(oldFlag, newFlag) < 0) 357 error(fileName + ": floating point ABI '" + getMipsFpAbiName(newFlag) + 358 "' is incompatible with target floating point ABI '" + 359 getMipsFpAbiName(oldFlag) + "'"); 360 return oldFlag; 361 } 362 363 template <class ELFT> static bool isN32Abi(const InputFile *f) { 364 if (auto *ef = dyn_cast<ELFFileBase>(f)) 365 return ef->template getObj<ELFT>().getHeader().e_flags & EF_MIPS_ABI2; 366 return false; 367 } 368 369 bool elf::isMipsN32Abi(const InputFile *f) { 370 switch (config->ekind) { 371 case ELF32LEKind: 372 return isN32Abi<ELF32LE>(f); 373 case ELF32BEKind: 374 return isN32Abi<ELF32BE>(f); 375 case ELF64LEKind: 376 return isN32Abi<ELF64LE>(f); 377 case ELF64BEKind: 378 return isN32Abi<ELF64BE>(f); 379 default: 380 llvm_unreachable("unknown Config->EKind"); 381 } 382 } 383 384 bool elf::isMicroMips() { return config->eflags & EF_MIPS_MICROMIPS; } 385 386 bool elf::isMipsR6() { 387 uint32_t arch = config->eflags & EF_MIPS_ARCH; 388 return arch == EF_MIPS_ARCH_32R6 || arch == EF_MIPS_ARCH_64R6; 389 } 390 391 template uint32_t elf::calcMipsEFlags<ELF32LE>(); 392 template uint32_t elf::calcMipsEFlags<ELF32BE>(); 393 template uint32_t elf::calcMipsEFlags<ELF64LE>(); 394 template uint32_t elf::calcMipsEFlags<ELF64BE>(); 395