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