22using namespace llvm::MachO;
35 static_assert(offsetof(T, cmd) == 0,
"T::cmd must be the first field");
36 static_assert(offsetof(T, cmdsize) ==
sizeof(uint32_t),
37 "T::cmdsize must immediately follow T::cmd");
38 static_assert(std::is_same<
decltype(T::cmd), uint32_t>::value,
39 "T::cmd must be uint32_t");
40 static_assert(std::is_same<
decltype(T::cmdsize), uint32_t>::value,
41 "T::cmdsize must be uint32_t");
42 if (data.
GetU32(&offset, &cmd, 2) ==
nullptr)
44 if (cmd.cmdsize <
sizeof(load_command))
65 :
ObjectContainer(module_sp, file, offset, length, data_sp, data_offset),
83 extractor.
SetData(data_sp, data_offset, length);
87 auto container_up = std::make_unique<ObjectContainerMachOFileset>(
88 module_sp, data_sp, data_offset, file, file_offset, length);
89 if (!container_up->ParseHeader())
92 return container_up.release();
101 auto container_up = std::make_unique<ObjectContainerMachOFileset>(
102 module_sp, data_sp, process_sp, header_addr);
103 if (!container_up->ParseHeader())
106 return container_up.release();
115 return sizeof(
struct mach_header);
118 return sizeof(
struct mach_header_64);
127 header.magic = extractor.
GetU32(&offset);
128 switch (header.magic) {
153 header.cputype = extractor.
GetU32(&offset);
154 header.cpusubtype = extractor.
GetU32(&offset);
155 header.filetype = extractor.
GetU32(&offset);
156 header.ncmds = extractor.
GetU32(&offset);
157 header.sizeofcmds = extractor.
GetU32(&offset);
163 std::vector<ObjectContainerMachOFileset::Entry> &entries,
164 std::optional<lldb::addr_t> load_addr = std::nullopt) {
167 for (uint32_t i = 0; i < header.ncmds; ++i) {
169 load_command lc = {};
175 if (lc.cmd == llvm::MachO::LC_SEGMENT_64) {
177 extractor.
CopyData(load_cmd_offset,
sizeof(segment_command_64),
179 if (llvm::StringRef(
segment.segname) ==
"__TEXT")
184 if (lc.cmd == LC_FILESET_ENTRY) {
185 fileset_entry_command entry;
186 extractor.
CopyData(load_cmd_offset,
sizeof(fileset_entry_command),
188 lldb::offset_t entry_id_offset = load_cmd_offset + entry.entry_id.offset;
189 if (
const char *
id = extractor.
GetCStr(&entry_id_offset))
190 entries.emplace_back(entry.vmaddr + slide, entry.fileoff,
194 offset = load_cmd_offset + lc.cmdsize;
209 const size_t header_and_lc_size = header_size + header->sizeofcmds;
211 if (extractor.
GetByteSize() < header_and_lc_size) {
225 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
232 const size_t header_and_lc_size = header_size + header->sizeofcmds;
255 std::vector<Entry> entries;
256 if (
ParseHeader(*extractor_sp, file, file_offset, entries)) {
257 for (
const Entry &entry : entries) {
260 file, entry_offset, file_size - entry_offset);
261 if (entry_specs.
GetSize() > 0) {
277 extractor.
SetData(data_sp, data_offset, data_length);
284 uint32_t magic = extractor.
GetU32(&offset);
296 uint32_t filetype = extractor.
GetU32(&offset);
297 return filetype == MH_FILESET;
306 ConstString object_name = module_sp->GetObjectName();
318 extractor_sp, data_offset);
static bool ReadMachOCommand(DataExtractor &data, lldb::offset_t &offset, T &cmd)
Read a Mach-O load-command header (cmd + cmdsize) from data at offset into cmd, advancing offset by 8...
static bool ParseFileset(DataExtractor &extractor, mach_header header, std::vector< ObjectContainerMachOFileset::Entry > &entries, std::optional< lldb::addr_t > load_addr=std::nullopt)
static std::optional< mach_header > ParseMachOHeader(DataExtractor &extractor)
static uint32_t MachHeaderSizeFromMagic(uint32_t magic)
#define LLDB_PLUGIN_DEFINE(PluginName)
A uniqued constant string class.
const char * GetCString() const
Get the string value as a C string.
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
void Append(const ModuleSpec &spec)
ModuleSpec & GetModuleSpecRefAtIndex(size_t i)
ConstString & GetObjectName()
static bool MagicBytesMatch(const lldb_private::DataExtractor &data)
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 offset, lldb::offset_t length)
static llvm::StringRef GetPluginNameStatic()
~ObjectContainerMachOFileset() override
ObjectContainerMachOFileset(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t offset, lldb::offset_t length)
static lldb_private::ObjectContainer * CreateMemoryInstance(const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr)
Entry * FindEntry(llvm::StringRef id)
const lldb::addr_t m_memory_addr
static ModuleSpecList GetModuleSpecifications(const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp, lldb::offset_t file_offset, lldb::offset_t length)
lldb::ProcessWP m_process_wp
static llvm::StringRef GetPluginDescriptionStatic()
std::vector< Entry > m_entries
bool ParseHeader() override
Attempts to parse the object header.
lldb::ObjectFileSP GetObjectFile(const lldb_private::FileSpec *file) override
Selects an architecture in an object file.
virtual lldb::addr_t GetByteSize() const
lldb::DataExtractorSP m_extractor_sp
The data for this object file so things can be parsed lazily.
FileSpec m_file
The file that represents this container objects (which can be different from the module's file).
lldb::addr_t m_offset
The offset in bytes into the file, or the address in memory.
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 lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset)
static lldb::WritableDataBufferSP ReadMemory(const lldb::ProcessSP &process_sp, lldb::addr_t addr, size_t byte_size)
static ModuleSpecList GetModuleSpecifications(const FileSpec &file, lldb::offset_t file_offset, lldb::offset_t file_size, lldb::DataExtractorSP=lldb::DataExtractorSP())
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
#define LLDB_INVALID_ADDRESS
lldb::ByteOrder InlHostByteOrder()
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::ObjectFile > ObjectFileSP
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
std::shared_ptr< lldb_private::Module > ModuleSP