19#include "llvm/ADT/StringMap.h"
20#include "llvm/BinaryFormat/Magic.h"
21#include "llvm/Object/ObjectFile.h"
22#include "llvm/Object/OffloadBundle.h"
23#include "llvm/Support/Chrono.h"
53 llvm::StringRef bytes(
reinterpret_cast<const char *
>(data.
GetDataStart()),
55 llvm::file_magic magic = llvm::identify_magic(bytes);
57 case llvm::file_magic::elf:
58 case llvm::file_magic::elf_relocatable:
59 case llvm::file_magic::elf_executable:
60 case llvm::file_magic::elf_shared_object:
61 case llvm::file_magic::elf_core:
71 auto [Kind, Triple] =
ID.split(
'-');
78 const FileSpec &file, std::vector<Entry> &entries) {
79 std::string path = file.
GetPath();
87 llvm::sys::TimePoint<> mod_time;
88 std::vector<Entry> entries;
90 static std::mutex cache_mutex;
91 static llvm::StringMap<CacheValue> cache;
93 llvm::sys::TimePoint<> mod_time =
97 std::lock_guard<std::mutex> lock(cache_mutex);
98 auto it = cache.find(path);
99 if (it != cache.end() && it->second.mod_time == mod_time) {
100 entries = it->second.entries;
101 return !entries.empty();
106 auto parse = [&path]() -> std::vector<Entry> {
107 std::vector<Entry> result;
108 auto obj_or_err = llvm::object::ObjectFile::createObjectFile(path);
110 llvm::consumeError(obj_or_err.takeError());
114 llvm::SmallVector<llvm::object::OffloadBundleFatBin> bundles;
115 if (
auto err = llvm::object::extractOffloadBundleFatBinary(
116 *obj_or_err->getBinary(), bundles)) {
117 llvm::consumeError(std::move(err));
121 for (
auto &bundle : bundles) {
122 for (
auto &bundle_entry : bundle.getEntries()) {
123 if (bundle_entry.Size == 0)
127 uint64_t offset = bundle_entry.Offset;
128 if (bundle.isDecompressed()) {
129 if (!bundle.DecompressedBuffer)
132 llvm::StringRef decompressed = bundle.DecompressedBuffer->getBuffer();
133 if (offset > decompressed.size() ||
134 bundle_entry.Size > decompressed.size() - offset)
137 auto entry_data_sp = std::make_shared<DataBufferHeap>(
138 decompressed.data() + offset, bundle_entry.Size);
139 entry_extractor_sp = std::make_shared<DataExtractor>(entry_data_sp);
148 entry.
size = bundle_entry.Size;
151 result.push_back(std::move(entry));
157 std::vector<Entry> parsed = parse();
162 std::lock_guard<std::mutex> lock(cache_mutex);
163 cache[path] = CacheValue{mod_time, parsed};
166 entries = std::move(parsed);
167 return !entries.empty();
174 if (!data_sp || !file)
178 data.
SetData(data_sp, data_offset, length);
182 auto container_up = std::make_unique<ObjectContainerClangOffloadBundle>(
183 module_sp, data_sp, data_offset, file, file_offset, length);
184 if (!container_up->ParseHeader())
187 return container_up.release();
202 uint32_t idx,
ArchSpec &arch)
const {
216 std::vector<Entry> entries;
221 for (
const Entry &entry : entries) {
225 if (entry.extractor_sp)
240 ArchSpec arch = module_sp->GetArchitecture();
247 for (
int pass = 0; pass < 2; ++pass) {
249 bool match = (pass == 0) ? arch.
IsExactMatch(entry.arch)
255 extractor_sp, data_offset);
static ArchSpec ParseArchFromBundleEntryID(llvm::StringRef ID)
#define LLDB_PLUGIN_DEFINE(PluginName)
ObjectContainerClangOffloadBundle(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length)
std::vector< Entry > m_entries
static bool MagicBytesMatch(const lldb_private::DataExtractor &data)
lldb::ObjectFileSP GetObjectFile(const lldb_private::FileSpec *file) override
Selects an architecture in an object file.
static llvm::StringRef GetPluginDescriptionStatic()
static llvm::StringRef GetPluginNameStatic()
static bool FindBundleEntries(const lldb_private::FileSpec &file, std::vector< Entry > &entries)
bool ParseHeader() override
Attempts to parse the object header.
static lldb_private::ObjectContainer * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length)
size_t GetNumArchitectures() const override
Get the number of architectures in this object file.
static lldb_private::ModuleSpecList GetModuleSpecifications(const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp, lldb::offset_t file_offset, lldb::offset_t file_size)
bool GetArchitectureAtIndex(uint32_t idx, lldb_private::ArchSpec &arch) const override
Gets the architecture given an index.
~ObjectContainerClangOffloadBundle() override
An architecture specification class.
bool IsValid() const
Tests if this ArchSpec is valid.
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
bool IsCompatibleMatch(const ArchSpec &rhs) const
Shorthand for IsMatch(rhs, CompatibleMatch).
bool IsExactMatch(const ArchSpec &rhs) const
Shorthand for IsMatch(rhs, ExactMatch).
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
llvm::sys::TimePoint GetModificationTime(const FileSpec &file_spec) const
Returns the modification time of the given file.
static FileSystem & Instance()
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
void Append(const ModuleSpec &spec)
void SetObjectSize(uint64_t object_size)
ArchSpec & GetArchitecture()
void SetObjectOffset(uint64_t object_offset)
FileSpec m_file
The file that represents this container objects (which can be different from the module's file).
ObjectContainer(const lldb::ModuleSP &module_sp, const FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length, lldb::DataBufferSP data_sp, lldb::offset_t data_offset)
Construct with a parent module, offset, and header data.
static lldb::ObjectFileSP FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file_spec, lldb::offset_t file_offset, lldb::offset_t file_size, lldb::DataExtractorSP extractor_sp, lldb::offset_t &data_offset)
Find a ObjectFile plug-in that can parse file_spec.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
static ArchSpec GetDefaultArchitecture()
Represents UUID's of various sizes.
#define LLDB_ARCH_DEFAULT
CPU Type definitions.
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::ObjectFile > ObjectFileSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
std::shared_ptr< lldb_private::Module > ModuleSP
lldb_private::ArchSpec arch
lldb::DataExtractorSP extractor_sp