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