diff options
author | Jacek Caban <jacek@codeweavers.com> | 2023-04-21 15:31:21 +0300 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2023-04-21 15:46:19 +0300 |
commit | eb56ef3edd9f1d21e625f0158dfc4edc48bd7349 (patch) | |
tree | 29a636c63322099679dcf8707ad1dd0f567467c6 /llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp | |
parent | 9d7785b2e99548f3fde6fa030443a4d443dec647 (diff) | |
download | llvm-eb56ef3edd9f1d21e625f0158dfc4edc48bd7349.zip llvm-eb56ef3edd9f1d21e625f0158dfc4edc48bd7349.tar.gz llvm-eb56ef3edd9f1d21e625f0158dfc4edc48bd7349.tar.bz2 |
[llvm-lib] Add support for ARM64EC libraries.
ARM64EC allows having both pure ARM64 objects and ARM64EC in the
same archive. This allows using single static library for linking
pure ARM64, pure ARM64EC or mixed modules (what MS calls ARM64X:
a single module that may be used in both modes). To achieve that,
such static libraries need two separated symbol maps. The usual map
contains only pure ARM64 symbols, while a new /<ECSYMBOLS>/ section
contains EC symbols. EC symbols map has very similar format to the
usual map, except it doesn't contain object offsets and uses offsets
from regular map instead. This is true even for pure ARM64EC static
library: it will simply have 0 symbols in the symbol map.
Reviewed By: efriedma
Differential Revision: https://reviews.llvm.org/D143541
Diffstat (limited to 'llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp')
-rw-r--r-- | llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp index 9ca63be..9bde40d 100644 --- a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp +++ b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp @@ -168,7 +168,8 @@ static Expected<COFF::MachineTypes> getCOFFFileMachine(MemoryBufferRef MB) { if (Machine != COFF::IMAGE_FILE_MACHINE_I386 && Machine != COFF::IMAGE_FILE_MACHINE_AMD64 && Machine != COFF::IMAGE_FILE_MACHINE_ARMNT && - Machine != COFF::IMAGE_FILE_MACHINE_ARM64) { + Machine != COFF::IMAGE_FILE_MACHINE_ARM64 && + Machine != COFF::IMAGE_FILE_MACHINE_ARM64EC) { return createStringError(inconvertibleErrorCode(), "unknown machine: " + std::to_string(Machine)); } @@ -181,7 +182,8 @@ static Expected<COFF::MachineTypes> getBitcodeFileMachine(MemoryBufferRef MB) { if (!TripleStr) return TripleStr.takeError(); - switch (Triple(*TripleStr).getArch()) { + Triple T(*TripleStr); + switch (T.getArch()) { case Triple::x86: return COFF::IMAGE_FILE_MACHINE_I386; case Triple::x86_64: @@ -189,13 +191,25 @@ static Expected<COFF::MachineTypes> getBitcodeFileMachine(MemoryBufferRef MB) { case Triple::arm: return COFF::IMAGE_FILE_MACHINE_ARMNT; case Triple::aarch64: - return COFF::IMAGE_FILE_MACHINE_ARM64; + return T.isWindowsArm64EC() ? COFF::IMAGE_FILE_MACHINE_ARM64EC + : COFF::IMAGE_FILE_MACHINE_ARM64; default: return createStringError(inconvertibleErrorCode(), "unknown arch in target triple: " + *TripleStr); } } +static bool machineMatches(COFF::MachineTypes LibMachine, + COFF::MachineTypes FileMachine) { + if (LibMachine == FileMachine) + return true; + // ARM64EC mode allows both pure ARM64, ARM64EC and X64 objects to be mixed in + // the archive. + return LibMachine == COFF::IMAGE_FILE_MACHINE_ARM64EC && + (FileMachine == COFF::IMAGE_FILE_MACHINE_ARM64 || + FileMachine == COFF::IMAGE_FILE_MACHINE_AMD64); +} + static void appendFile(std::vector<NewArchiveMember> &Members, COFF::MachineTypes &LibMachine, std::string &LibMachineSource, MemoryBufferRef MB) { @@ -263,11 +277,18 @@ static void appendFile(std::vector<NewArchiveMember> &Members, // this check. See PR42180. if (FileMachine != COFF::IMAGE_FILE_MACHINE_UNKNOWN) { if (LibMachine == COFF::IMAGE_FILE_MACHINE_UNKNOWN) { + if (FileMachine == COFF::IMAGE_FILE_MACHINE_ARM64EC) { + llvm::errs() << MB.getBufferIdentifier() << ": file machine type " + << machineToStr(FileMachine) + << " conflicts with inferred library machine type," + << " use /machine:arm64ec or /machine:arm64x\n"; + exit(1); + } LibMachine = FileMachine; LibMachineSource = (" (inferred from earlier file '" + MB.getBufferIdentifier() + "')") .str(); - } else if (LibMachine != FileMachine) { + } else if (!machineMatches(LibMachine, FileMachine)) { llvm::errs() << MB.getBufferIdentifier() << ": file machine type " << machineToStr(FileMachine) << " conflicts with library machine type " @@ -460,7 +481,8 @@ int llvm::libDriverMain(ArrayRef<const char *> ArgsArr) { writeArchive(OutputPath, Members, /*WriteSymtab=*/true, Thin ? object::Archive::K_GNU : object::Archive::K_COFF, - /*Deterministic*/ true, Thin)) { + /*Deterministic*/ true, Thin, nullptr, + LibMachine == COFF::IMAGE_FILE_MACHINE_ARM64EC)) { handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) { llvm::errs() << OutputPath << ": " << EI.message() << "\n"; }); |