diff options
Diffstat (limited to 'ELF/Arch/MipsArchTree.cpp')
-rw-r--r-- | ELF/Arch/MipsArchTree.cpp | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/ELF/Arch/MipsArchTree.cpp b/ELF/Arch/MipsArchTree.cpp index 3d1dc1daf0c12..754a470015793 100644 --- a/ELF/Arch/MipsArchTree.cpp +++ b/ELF/Arch/MipsArchTree.cpp @@ -11,11 +11,11 @@ // //===---------------------------------------------------------------------===// -#include "Error.h" #include "InputFiles.h" #include "SymbolTable.h" #include "Writer.h" +#include "lld/Common/ErrorHandler.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/Object/ELF.h" #include "llvm/Support/MipsABIFlags.h" @@ -34,7 +34,7 @@ struct ArchTreeEdge { }; struct FileFlags { - StringRef Filename; + InputFile *File; uint32_t Flags; }; } // namespace @@ -73,17 +73,17 @@ static void checkFlags(ArrayRef<FileFlags> Files) { uint32_t ABI2 = F.Flags & (EF_MIPS_ABI | EF_MIPS_ABI2); if (ABI != ABI2) error("target ABI '" + getAbiName(ABI) + "' is incompatible with '" + - getAbiName(ABI2) + "': " + F.Filename); + getAbiName(ABI2) + "': " + toString(F.File)); bool Nan2 = F.Flags & EF_MIPS_NAN2008; if (Nan != Nan2) error("target -mnan=" + getNanName(Nan) + " is incompatible with -mnan=" + - getNanName(Nan2) + ": " + F.Filename); + getNanName(Nan2) + ": " + toString(F.File)); bool Fp2 = F.Flags & EF_MIPS_FP64; if (Fp != Fp2) error("target -mfp" + getFpName(Fp) + " is incompatible with -mfp" + - getFpName(Fp2) + ": " + F.Filename); + getFpName(Fp2) + ": " + toString(F.File)); } } @@ -102,9 +102,11 @@ static uint32_t getPicFlags(ArrayRef<FileFlags> Files) { for (const FileFlags &F : Files.slice(1)) { bool IsPic2 = F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC); if (IsPic && !IsPic2) - warn("linking abicalls code with non-abicalls file: " + F.Filename); + warn("linking abicalls code " + toString(Files[0].File) + + " with non-abicalls file: " + toString(F.File)); if (!IsPic && IsPic2) - warn("linking non-abicalls code with abicalls file: " + F.Filename); + warn("linking non-abicalls code " + toString(Files[0].File) + + " with abicalls file: " + toString(F.File)); } // Compute the result PIC/non-PIC flag. @@ -221,10 +223,6 @@ static StringRef getMachName(uint32_t Flags) { } static StringRef getArchName(uint32_t Flags) { - StringRef S = getMachName(Flags); - if (!S.empty()) - return S; - switch (Flags & EF_MIPS_ARCH) { case EF_MIPS_ARCH_1: return "mips1"; @@ -253,6 +251,14 @@ static StringRef getArchName(uint32_t Flags) { } } +static std::string getFullArchName(uint32_t Flags) { + StringRef Arch = getArchName(Flags); + StringRef Mach = getMachName(Flags); + if (Mach.empty()) + return Arch.str(); + return (Arch + " (" + Mach + ")").str(); +} + // There are (arguably too) many MIPS ISAs out there. Their relationships // can be represented as a forest. If all input files have ISAs which // reachable by repeated proceeding from the single child to the parent, @@ -272,8 +278,9 @@ static uint32_t getArchFlags(ArrayRef<FileFlags> Files) { if (isArchMatched(New, Ret)) continue; if (!isArchMatched(Ret, New)) { - error("target ISA '" + getArchName(Ret) + "' is incompatible with '" + - getArchName(New) + "': " + F.Filename); + error("incompatible target ISA:\n>>> " + toString(Files[0].File) + ": " + + getFullArchName(Ret) + "\n>>> " + toString(F.File) + ": " + + getFullArchName(New)); return 0; } Ret = New; @@ -281,10 +288,10 @@ static uint32_t getArchFlags(ArrayRef<FileFlags> Files) { return Ret; } -template <class ELFT> uint32_t elf::getMipsEFlags() { +template <class ELFT> uint32_t elf::calcMipsEFlags() { std::vector<FileFlags> V; - for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) - V.push_back({F->getName(), F->getObj().getHeader()->e_flags}); + for (InputFile *F : ObjectFiles) + V.push_back({F, cast<ObjFile<ELFT>>(F)->getObj().getHeader()->e_flags}); if (V.empty()) return 0; checkFlags(V); @@ -363,7 +370,14 @@ bool elf::isMipsN32Abi(const InputFile *F) { } } -template uint32_t elf::getMipsEFlags<ELF32LE>(); -template uint32_t elf::getMipsEFlags<ELF32BE>(); -template uint32_t elf::getMipsEFlags<ELF64LE>(); -template uint32_t elf::getMipsEFlags<ELF64BE>(); +bool elf::isMicroMips() { return Config->EFlags & EF_MIPS_MICROMIPS; } + +bool elf::isMipsR6() { + uint32_t Arch = Config->EFlags & EF_MIPS_ARCH; + return Arch == EF_MIPS_ARCH_32R6 || Arch == EF_MIPS_ARCH_64R6; +} + +template uint32_t elf::calcMipsEFlags<ELF32LE>(); +template uint32_t elf::calcMipsEFlags<ELF32BE>(); +template uint32_t elf::calcMipsEFlags<ELF64LE>(); +template uint32_t elf::calcMipsEFlags<ELF64BE>(); |