[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