[Openmp-commits] [openmp] fb7cc73 - Revert "[libomptarget] Support BE ELF files in plugins-nextgen (#83976)"
Ulrich Weigand via Openmp-commits
openmp-commits at lists.llvm.org
Wed Mar 6 12:38:10 PST 2024
Author: Ulrich Weigand
Date: 2024-03-06T21:37:45+01:00
New Revision: fb7cc73975f3ac262f2c80af2f399caead005259
URL: https://github.com/llvm/llvm-project/commit/fb7cc73975f3ac262f2c80af2f399caead005259
DIFF: https://github.com/llvm/llvm-project/commit/fb7cc73975f3ac262f2c80af2f399caead005259.diff
LOG: Revert "[libomptarget] Support BE ELF files in plugins-nextgen (#83976)"
This reverts commit 15b7b3182cc28f4f0b950bd73d931caa27b833ec.
Added:
Modified:
openmp/libomptarget/plugins-nextgen/common/include/GlobalHandler.h
openmp/libomptarget/plugins-nextgen/common/include/Utils/ELF.h
openmp/libomptarget/plugins-nextgen/common/src/GlobalHandler.cpp
openmp/libomptarget/plugins-nextgen/common/src/Utils/ELF.cpp
Removed:
################################################################################
diff --git a/openmp/libomptarget/plugins-nextgen/common/include/GlobalHandler.h b/openmp/libomptarget/plugins-nextgen/common/include/GlobalHandler.h
index 57d93b88afcaa9..5c767995126b77 100644
--- a/openmp/libomptarget/plugins-nextgen/common/include/GlobalHandler.h
+++ b/openmp/libomptarget/plugins-nextgen/common/include/GlobalHandler.h
@@ -103,6 +103,9 @@ class GenericGlobalHandlerTy {
public:
virtual ~GenericGlobalHandlerTy() {}
+ /// Helper function for getting an ELF from a device image.
+ Expected<ELF64LEObjectFile> getELFObjectFile(DeviceImageTy &Image);
+
/// Returns whether the symbol named \p SymName is present in the given \p
/// Image.
bool isSymbolInImage(GenericDeviceTy &Device, DeviceImageTy &Image,
diff --git a/openmp/libomptarget/plugins-nextgen/common/include/Utils/ELF.h b/openmp/libomptarget/plugins-nextgen/common/include/Utils/ELF.h
index 2268e4b6c4af6b..140a6b6b84aa12 100644
--- a/openmp/libomptarget/plugins-nextgen/common/include/Utils/ELF.h
+++ b/openmp/libomptarget/plugins-nextgen/common/include/Utils/ELF.h
@@ -27,14 +27,18 @@ bool isELF(llvm::StringRef Buffer);
/// Checks if the given \p Object is a valid ELF matching the e_machine value.
llvm::Expected<bool> checkMachine(llvm::StringRef Object, uint16_t EMachine);
-/// Returns the symbol associated with the \p Name in the \p Obj. It will
+/// Returns a pointer to the given \p Symbol inside of an ELF object.
+llvm::Expected<const void *> getSymbolAddress(
+ const llvm::object::ELFObjectFile<llvm::object::ELF64LE> &ELFObj,
+ const llvm::object::ELF64LE::Sym &Symbol);
+
+/// Returns the symbol associated with the \p Name in the \p ELFObj. It will
/// first search for the hash sections to identify symbols from the hash table.
/// If that fails it will fall back to a linear search in the case of an
-/// executable file without a hash table. If the symbol is found, it returns
-/// a StringRef covering the symbol's data in the Obj buffer, based on its
-/// address and size; otherwise, it returns std::nullopt.
-llvm::Expected<std::optional<llvm::StringRef>>
-findSymbolInImage(const llvm::StringRef Obj, llvm::StringRef Name);
+/// executable file without a hash table.
+llvm::Expected<const typename llvm::object::ELF64LE::Sym *>
+getSymbol(const llvm::object::ELFObjectFile<llvm::object::ELF64LE> &ELFObj,
+ llvm::StringRef Name);
} // namespace elf
} // namespace utils
diff --git a/openmp/libomptarget/plugins-nextgen/common/src/GlobalHandler.cpp b/openmp/libomptarget/plugins-nextgen/common/src/GlobalHandler.cpp
index 2269f27e460205..d398f60c55bd13 100644
--- a/openmp/libomptarget/plugins-nextgen/common/src/GlobalHandler.cpp
+++ b/openmp/libomptarget/plugins-nextgen/common/src/GlobalHandler.cpp
@@ -25,6 +25,16 @@ using namespace omp;
using namespace target;
using namespace plugin;
+Expected<ELF64LEObjectFile>
+GenericGlobalHandlerTy::getELFObjectFile(DeviceImageTy &Image) {
+ assert(utils::elf::isELF(Image.getMemoryBuffer().getBuffer()) &&
+ "Input is not an ELF file");
+
+ Expected<ELF64LEObjectFile> ElfOrErr =
+ ELF64LEObjectFile::create(Image.getMemoryBuffer());
+ return ElfOrErr;
+}
+
Error GenericGlobalHandlerTy::moveGlobalBetweenDeviceAndHost(
GenericDeviceTy &Device, DeviceImageTy &Image, const GlobalTy &HostGlobal,
bool Device2Host) {
@@ -71,37 +81,55 @@ Error GenericGlobalHandlerTy::moveGlobalBetweenDeviceAndHost(
bool GenericGlobalHandlerTy::isSymbolInImage(GenericDeviceTy &Device,
DeviceImageTy &Image,
StringRef SymName) {
+ // Get the ELF object file for the image. Notice the ELF object may already
+ // be created in previous calls, so we can reuse it. If this is unsuccessful
+ // just return false as we couldn't find it.
+ auto ELFObjOrErr = getELFObjectFile(Image);
+ if (!ELFObjOrErr) {
+ consumeError(ELFObjOrErr.takeError());
+ return false;
+ }
// Search the ELF symbol using the symbol name.
- auto SymOrErr = utils::elf::findSymbolInImage(
- Image.getMemoryBuffer().getBuffer(), SymName);
+ auto SymOrErr = utils::elf::getSymbol(*ELFObjOrErr, SymName);
if (!SymOrErr) {
consumeError(SymOrErr.takeError());
return false;
}
- return SymOrErr->has_value();
+ return *SymOrErr;
}
Error GenericGlobalHandlerTy::getGlobalMetadataFromImage(
GenericDeviceTy &Device, DeviceImageTy &Image, GlobalTy &ImageGlobal) {
+ // Get the ELF object file for the image. Notice the ELF object may already
+ // be created in previous calls, so we can reuse it.
+ auto ELFObj = getELFObjectFile(Image);
+ if (!ELFObj)
+ return ELFObj.takeError();
+
// Search the ELF symbol using the symbol name.
- auto SymOrErr = utils::elf::findSymbolInImage(
- Image.getMemoryBuffer().getBuffer(), ImageGlobal.getName());
+ auto SymOrErr = utils::elf::getSymbol(*ELFObj, ImageGlobal.getName());
if (!SymOrErr)
return Plugin::error("Failed ELF lookup of global '%s': %s",
ImageGlobal.getName().data(),
toString(SymOrErr.takeError()).data());
- if (!SymOrErr->has_value())
+ if (!*SymOrErr)
return Plugin::error("Failed to find global symbol '%s' in the ELF image",
ImageGlobal.getName().data());
+ auto AddrOrErr = utils::elf::getSymbolAddress(*ELFObj, **SymOrErr);
+ // Get the section to which the symbol belongs.
+ if (!AddrOrErr)
+ return Plugin::error("Failed to get ELF symbol from global '%s': %s",
+ ImageGlobal.getName().data(),
+ toString(AddrOrErr.takeError()).data());
+
// Setup the global symbol's address and size.
- auto Symbol = **SymOrErr;
- ImageGlobal.setPtr(static_cast<void *>(const_cast<char *>(Symbol.data())));
- ImageGlobal.setSize(Symbol.size());
+ ImageGlobal.setPtr(const_cast<void *>(*AddrOrErr));
+ ImageGlobal.setSize((*SymOrErr)->st_size);
return Plugin::success();
}
diff --git a/openmp/libomptarget/plugins-nextgen/common/src/Utils/ELF.cpp b/openmp/libomptarget/plugins-nextgen/common/src/Utils/ELF.cpp
index 88bb097165ef7c..c84c3bad5def0a 100644
--- a/openmp/libomptarget/plugins-nextgen/common/src/Utils/ELF.cpp
+++ b/openmp/libomptarget/plugins-nextgen/common/src/Utils/ELF.cpp
@@ -36,10 +36,18 @@ bool utils::elf::isELF(StringRef Buffer) {
}
}
-template <class ELFT>
-static Expected<bool>
-checkMachineImpl(const object::ELFObjectFile<ELFT> &ELFObj, uint16_t EMachine) {
- const auto Header = ELFObj.getELFFile().getHeader();
+Expected<bool> utils::elf::checkMachine(StringRef Object, uint16_t EMachine) {
+ assert(isELF(Object) && "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");
@@ -63,25 +71,6 @@ checkMachineImpl(const object::ELFObjectFile<ELFT> &ELFObj, uint16_t EMachine) {
return Header.e_machine == EMachine;
}
-Expected<bool> utils::elf::checkMachine(StringRef Object, uint16_t EMachine) {
- assert(isELF(Object) && "Input is not an ELF!");
-
- Expected<std::unique_ptr<ObjectFile>> ElfOrErr =
- ObjectFile::createELFObjectFile(
- MemoryBufferRef(Object, /*Identifier=*/""),
- /*InitContent=*/false);
- if (!ElfOrErr)
- return ElfOrErr.takeError();
-
- if (const ELF64LEObjectFile *ELFObj =
- dyn_cast<ELF64LEObjectFile>(&**ElfOrErr))
- return checkMachineImpl(*ELFObj, EMachine);
- if (const ELF64BEObjectFile *ELFObj =
- dyn_cast<ELF64BEObjectFile>(&**ElfOrErr))
- return checkMachineImpl(*ELFObj, EMachine);
- return createError("Only 64-bit ELF files are supported");
-}
-
template <class ELFT>
static Expected<const typename ELFT::Sym *>
getSymbolFromGnuHashTable(StringRef Name, const typename ELFT::GnuHash &HashTab,
@@ -242,9 +231,8 @@ getSymTableSymbol(const ELFFile<ELFT> &Elf, const typename ELFT::Shdr &Sec,
return nullptr;
}
-template <class ELFT>
-static Expected<const typename ELFT::Sym *>
-getSymbol(const ELFObjectFile<ELFT> &ELFObj, StringRef Name) {
+Expected<const typename ELF64LE::Sym *>
+utils::elf::getSymbol(const ELFObjectFile<ELF64LE> &ELFObj, StringRef Name) {
// First try to look up the symbol via the hash table.
for (ELFSectionRef Sec : ELFObj.sections()) {
if (Sec.getType() != SHT_HASH && Sec.getType() != SHT_GNU_HASH)
@@ -253,7 +241,8 @@ getSymbol(const ELFObjectFile<ELFT> &ELFObj, StringRef Name) {
auto HashTabOrErr = ELFObj.getELFFile().getSection(Sec.getIndex());
if (!HashTabOrErr)
return HashTabOrErr.takeError();
- return getHashTableSymbol<ELFT>(ELFObj.getELFFile(), **HashTabOrErr, Name);
+ return getHashTableSymbol<ELF64LE>(ELFObj.getELFFile(), **HashTabOrErr,
+ Name);
}
// If this is an executable file check the entire standard symbol table.
@@ -264,17 +253,16 @@ getSymbol(const ELFObjectFile<ELFT> &ELFObj, StringRef Name) {
auto SymTabOrErr = ELFObj.getELFFile().getSection(Sec.getIndex());
if (!SymTabOrErr)
return SymTabOrErr.takeError();
- return getSymTableSymbol<ELFT>(ELFObj.getELFFile(), **SymTabOrErr, Name);
+ return getSymTableSymbol<ELF64LE>(ELFObj.getELFFile(), **SymTabOrErr, Name);
}
return nullptr;
}
-template <class ELFT>
-static Expected<const void *>
-getSymbolAddress(const object::ELFObjectFile<ELFT> &ELFObj,
- const typename ELFT::Sym &Symbol) {
- const ELFFile<ELFT> &ELFFile = ELFObj.getELFFile();
+Expected<const void *> utils::elf::getSymbolAddress(
+ const object::ELFObjectFile<object::ELF64LE> &ELFObj,
+ const object::ELF64LE::Sym &Symbol) {
+ const ELFFile<ELF64LE> &ELFFile = ELFObj.getELFFile();
auto SecOrErr = ELFFile.getSection(Symbol.st_shndx);
if (!SecOrErr)
@@ -295,40 +283,3 @@ getSymbolAddress(const object::ELFObjectFile<ELFT> &ELFObj,
return ELFFile.base() + Offset;
}
-
-template <class ELFT>
-static Expected<std::optional<StringRef>>
-findSymbolInImageImpl(const object::ELFObjectFile<ELFT> &ELFObj,
- StringRef Name) {
- auto SymOrErr = getSymbol(ELFObj, Name);
- if (!SymOrErr)
- return SymOrErr.takeError();
- if (!*SymOrErr)
- return std::nullopt;
-
- // If the symbol was found, return a StringRef covering the associated data,
- // based on the symbol's address and size.
- auto AddrOrErr = getSymbolAddress(ELFObj, **SymOrErr);
- if (!AddrOrErr)
- return AddrOrErr.takeError();
- return StringRef(static_cast<const char *>(*AddrOrErr), (*SymOrErr)->st_size);
-}
-
-Expected<std::optional<StringRef>>
-utils::elf::findSymbolInImage(StringRef Obj, StringRef Name) {
- assert(isELF(Obj) && "Input is not an ELF!");
-
- Expected<std::unique_ptr<ObjectFile>> ElfOrErr =
- ObjectFile::createELFObjectFile(MemoryBufferRef(Obj, /*Identifier=*/""),
- /*InitContent=*/false);
- if (!ElfOrErr)
- return ElfOrErr.takeError();
-
- if (const ELF64LEObjectFile *ELFObj =
- dyn_cast<ELF64LEObjectFile>(&**ElfOrErr))
- return findSymbolInImageImpl(*ELFObj, Name);
- if (const ELF64BEObjectFile *ELFObj =
- dyn_cast<ELF64BEObjectFile>(&**ElfOrErr))
- return findSymbolInImageImpl(*ELFObj, Name);
- return createError("Only 64-bit ELF files are supported");
-}
More information about the Openmp-commits
mailing list