[Openmp-commits] [openmp] [Libomptarget] Remove __tgt_image_info and use the ELF directly (PR #75720)
Jan Patrick Lehr via Openmp-commits
openmp-commits at lists.llvm.org
Mon Dec 18 01:39:18 PST 2023
================
@@ -26,52 +26,228 @@ using namespace llvm;
using namespace llvm::ELF;
using namespace llvm::object;
-/// If the given range of bytes [\p BytesBegin, \p BytesEnd) represents
-/// a valid ELF, then invoke \p Callback on the ELFObjectFileBase
-/// created from this range, otherwise, return 0.
-/// If \p Callback is invoked, then return whatever value \p Callback returns.
-template <typename F>
-static int32_t withBytesAsElf(char *BytesBegin, char *BytesEnd, F Callback) {
- size_t Size = BytesEnd - BytesBegin;
- StringRef StrBuf(BytesBegin, Size);
-
- auto Magic = identify_magic(StrBuf);
- if (Magic != file_magic::elf && Magic != file_magic::elf_relocatable &&
- Magic != file_magic::elf_executable &&
- Magic != file_magic::elf_shared_object && Magic != file_magic::elf_core) {
- DP("Not an ELF image!\n");
- return 0;
+bool utils::elf::isELF(StringRef Buffer) {
+ switch (identify_magic(Buffer)) {
+ case file_magic::elf:
+ case file_magic::elf_relocatable:
+ case file_magic::elf_executable:
+ case file_magic::elf_shared_object:
+ case file_magic::elf_core:
+ return true;
+ default:
+ return false;
}
+}
- std::unique_ptr<MemoryBuffer> MemBuf =
- MemoryBuffer::getMemBuffer(StrBuf, "", false);
- Expected<std::unique_ptr<ObjectFile>> BinOrErr =
- ObjectFile::createELFObjectFile(MemBuf->getMemBufferRef(),
- /*InitContent=*/false);
- if (!BinOrErr) {
- DP("Unable to get ELF handle: %s!\n",
- toString(BinOrErr.takeError()).c_str());
- return 0;
+Expected<bool> utils::elf::checkMachine(StringRef Object, uint16_t EMachine) {
+ if (!isELF(Object))
+ return createError("Input is not an ELF.");
+
+ Expected<ELF64LEObjectFile> ElfOrErr =
+ ELF64LEObjectFile::create(MemoryBufferRef(Object, /*Identifier=*/""),
+ /*InitContent=*/false);
+ if (!ElfOrErr)
+ return ElfOrErr.takeError();
+
+ const auto Header = ElfOrErr->getELFFile().getHeader();
+ if (Header.e_ident[EI_CLASS] != ELFCLASS64)
+ return createError("Only 64-bit ELF files are supported");
+ if (Header.e_type != ET_EXEC && Header.e_type != ET_DYN)
+ return createError("Only executable ELF files are supported");
+
+ if (Header.e_machine == EM_AMDGPU) {
+ if (Header.e_ident[EI_OSABI] != ELFOSABI_AMDGPU_HSA)
+ return createError("Invalid AMD OS/ABI, must be AMDGPU_HSA");
+ if (Header.e_ident[EI_ABIVERSION] != ELFABIVERSION_AMDGPU_HSA_V4 &&
+ Header.e_ident[EI_ABIVERSION] != ELFABIVERSION_AMDGPU_HSA_V5)
+ return createError("Invalid AMD ABI version, must be version 4 or 5");
+ if ((Header.e_flags & EF_AMDGPU_MACH) < EF_AMDGPU_MACH_AMDGCN_GFX700 ||
+ (Header.e_flags & EF_AMDGPU_MACH) > EF_AMDGPU_MACH_AMDGCN_GFX1201)
+ return createError("Unsupported AMDGPU architecture");
+ } else if (Header.e_machine == EM_CUDA) {
+ if (~Header.e_flags & EF_CUDA_64BIT_ADDRESS)
+ return createError("Invalid CUDA addressing mode");
+ if ((Header.e_flags & EF_CUDA_SM) < EF_CUDA_SM35 ||
+ (Header.e_flags & EF_CUDA_SM) > EF_CUDA_SM90)
+ return createError("Unsupported NVPTX architecture");
}
- auto *Object = dyn_cast<const ELFObjectFileBase>(BinOrErr->get());
+ return Header.e_machine == EMachine;
+}
+
+static Expected<StringRef> getNVPTXProcessor(uint32_t Flags) {
+ switch (Flags & EF_CUDA_SM) {
+ case EF_CUDA_SM20:
+ return "sm_20";
+ case EF_CUDA_SM21:
+ return "sm_21";
+ case EF_CUDA_SM30:
+ return "sm_30";
+ case EF_CUDA_SM32:
+ return "sm_32";
+ case EF_CUDA_SM35:
+ return "sm_35";
+ case EF_CUDA_SM37:
+ return "sm_37";
+ case EF_CUDA_SM50:
+ return "sm_50";
+ case EF_CUDA_SM52:
+ return "sm_52";
+ case EF_CUDA_SM53:
+ return "sm_53";
+ case EF_CUDA_SM60:
+ return "sm_60";
+ case EF_CUDA_SM61:
+ return "sm_61";
+ case EF_CUDA_SM62:
+ return "sm_62";
+ case EF_CUDA_SM70:
+ return "sm_70";
+ case EF_CUDA_SM72:
+ return "sm_72";
+ case EF_CUDA_SM75:
+ return "sm_75";
+ case EF_CUDA_SM80:
+ return "sm_80";
+ case EF_CUDA_SM86:
+ return "sm_86";
+ case EF_CUDA_SM87:
+ return "sm_87";
+ case EF_CUDA_SM89:
+ return "sm_89";
+ case EF_CUDA_SM90:
+ return Flags & EF_CUDA_ACCELERATORS ? "sm_90a" : "sm_90";
+ default:
+ return createError("Unknown CUDA architecture");
+ }
+}
- if (!Object) {
- DP("Unknown ELF format!\n");
- return 0;
+static Expected<StringRef> getAMDGPUProcessor(uint32_t Flags) {
----------------
jplehr wrote:
Not really part of this patch, but should this generally live somewhere to be reused by more than just libomptarget?
https://github.com/llvm/llvm-project/pull/75720
More information about the Openmp-commits
mailing list