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