Index: ELF/Driver.h =================================================================== --- ELF/Driver.h +++ ELF/Driver.h @@ -63,7 +63,7 @@ #undef OPTION }; -void printHelp(const char *Argv0); +void printHelp(); std::string createResponseFile(const llvm::opt::InputArgList &Args); llvm::Optional findFromSearchPaths(StringRef Path); Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -317,7 +317,7 @@ // Handle -help if (Args.hasArg(OPT_help)) { - printHelp(ArgsArr[0]); + printHelp(); return; } Index: ELF/DriverUtils.cpp =================================================================== --- ELF/DriverUtils.cpp +++ ELF/DriverUtils.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "Driver.h" +#include "Target.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/Memory.h" #include "lld/Common/Reproduce.h" @@ -113,9 +114,9 @@ return Args; } -void elf::printHelp(const char *Argv0) { - ELFOptTable().PrintHelp(outs(), Argv0, "lld", false /*ShowHidden*/, - true /*ShowAllAliases*/); +void elf::printHelp() { + ELFOptTable().PrintHelp(outs(), Config->Argv[0].data(), "lld", + false /*ShowHidden*/, true /*ShowAllAliases*/); outs() << "\n"; // Scripts generated by Libtool versions up to at least 2.4.6 (the most @@ -124,12 +125,10 @@ // assume that the linker doesn't support very basic features such as // shared libraries. Therefore, we need to print out at least "elf". // Here, we print out all the targets that we support. - outs() << Argv0 << ": supported targets: " - << "elf32-i386 elf32-iamcu elf32-littlearm elf32-ntradbigmips " - << "elf32-ntradlittlemips elf32-powerpc elf32-tradbigmips " - << "elf32-tradlittlemips elf32-x86-64 " - << "elf64-amdgpu elf64-littleaarch64 elf64-powerpc elf64-tradbigmips " - << "elf64-tradlittlemips elf64-x86-64\n"; + outs() << Config->Argv[0] << ": supported targets: "; + for (StringRef Name : getTargetNames()) + outs() << Name << ' '; + outs() << '\n'; } // Reconstructs command line arguments so that so that you can re-run Index: ELF/Target.h =================================================================== --- ELF/Target.h +++ ELF/Target.h @@ -141,6 +141,7 @@ extern TargetInfo *Target; TargetInfo *getTarget(); +std::vector getTargetNames(); template bool isMipsPIC(const Defined *Sym); Index: ELF/Target.cpp =================================================================== --- ELF/Target.cpp +++ ELF/Target.cpp @@ -47,46 +47,54 @@ return S; } +namespace { +struct TargetDescription { + uint16_t EMachine; + ELFKind EKind; + llvm::function_ref Create; + StringRef Name; +}; + +std::vector getAllTargets() { + return { + {EM_386, ELFNoneKind, getX86TargetInfo, "elf32-i386"}, + {EM_IAMCU, ELFNoneKind, getX86TargetInfo, "elf32-iamcu"}, + {EM_AARCH64, ELFNoneKind, getAArch64TargetInfo, "elf64-littleaarch64"}, + {EM_AMDGPU, ELFNoneKind, getAMDGPUTargetInfo, "elf64-amdgpu"}, + {EM_ARM, ELFNoneKind, getARMTargetInfo, "elf32-littlearm"}, + {EM_AVR, ELFNoneKind, getAVRTargetInfo, "elf32-avr"}, + {EM_MIPS, ELF32LEKind, getMipsTargetInfo, + "elf32-tradlittlemips elf32-ntradlittlemips"}, + {EM_MIPS, ELF32BEKind, getMipsTargetInfo, + "elf32-tradbigmips elf32-ntradbigmips"}, + {EM_MIPS, ELF64LEKind, getMipsTargetInfo, + "elf64-tradlittlemips elf64-ntradlittlemips"}, + {EM_MIPS, ELF64BEKind, getMipsTargetInfo, + "elf64-tradbigmips elf64-ntradbigmips"}, + {EM_PPC, ELFNoneKind, getPPCTargetInfo, "elf32-powerpc"}, + {EM_PPC64, ELFNoneKind, getPPC64TargetInfo, "elf64-powerpc"}, + {EM_SPARCV9, ELFNoneKind, getSPARCV9TargetInfo, "elf64-sparc"}, + {EM_X86_64, ELF32LEKind, getX32TargetInfo, "elf32-x86-64"}, + {EM_X86_64, ELFNoneKind, getX86_64TargetInfo, "elf64-x86-64"}, + }; +} +}; // namespace + TargetInfo *elf::getTarget() { - switch (Config->EMachine) { - case EM_386: - case EM_IAMCU: - return getX86TargetInfo(); - case EM_AARCH64: - return getAArch64TargetInfo(); - case EM_AMDGPU: - return getAMDGPUTargetInfo(); - case EM_ARM: - return getARMTargetInfo(); - case EM_AVR: - return getAVRTargetInfo(); - case EM_MIPS: - switch (Config->EKind) { - case ELF32LEKind: - return getMipsTargetInfo(); - case ELF32BEKind: - return getMipsTargetInfo(); - case ELF64LEKind: - return getMipsTargetInfo(); - case ELF64BEKind: - return getMipsTargetInfo(); - default: - fatal("unsupported MIPS target"); - } - case EM_PPC: - return getPPCTargetInfo(); - case EM_PPC64: - return getPPC64TargetInfo(); - case EM_SPARCV9: - return getSPARCV9TargetInfo(); - case EM_X86_64: - if (Config->EKind == ELF32LEKind) - return getX32TargetInfo(); - return getX86_64TargetInfo(); - } + for (TargetDescription &T : getAllTargets()) + if (T.EMachine == Config->EMachine) + if (T.EKind == ELFNoneKind || T.EKind == Config->EKind) + return T.Create(); fatal("unknown target machine"); } +std::vector elf::getTargetNames() { + std::vector Ret; + for (TargetDescription &T : getAllTargets()) + Ret.push_back(T.Name); + return Ret; +} + template static std::string getErrorLoc(const uint8_t *Loc) { for (InputSectionBase *D : InputSections) { auto *IS = dyn_cast(D);