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