[Lldb-commits] [lldb] 803386d - Revert "Allow firmware binaries to be specified only by load address"
Jason Molenda via lldb-commits
lldb-commits at lists.llvm.org
Tue Aug 2 13:54:23 PDT 2022
Author: Jason Molenda
Date: 2022-08-02T13:53:34-07:00
New Revision: 803386da2ff80f0a5e75d2baee6dfa79d9d8d26f
URL: https://github.com/llvm/llvm-project/commit/803386da2ff80f0a5e75d2baee6dfa79d9d8d26f
DIFF: https://github.com/llvm/llvm-project/commit/803386da2ff80f0a5e75d2baee6dfa79d9d8d26f.diff
LOG: Revert "Allow firmware binaries to be specified only by load address"
This reverts commit d8879fba8825b9799166ba0ea552d4027bfb8ad1.
Debian bot failure; I included <uuid/uuid.h> to get uuid_is_null() but
don't get it there. Will memcmp or whatever & recommit.
Added:
Modified:
lldb/docs/lldb-gdb-remote.txt
lldb/include/lldb/Target/DynamicLoader.h
lldb/source/Core/DynamicLoader.cpp
lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
Removed:
lldb/test/API/macosx/lc-note/multiple-binary-corefile/Makefile
lldb/test/API/macosx/lc-note/multiple-binary-corefile/TestMultipleBinaryCorefile.py
lldb/test/API/macosx/lc-note/multiple-binary-corefile/create-multibin-corefile.cpp
lldb/test/API/macosx/lc-note/multiple-binary-corefile/main.c
lldb/test/API/macosx/lc-note/multiple-binary-corefile/one.c
lldb/test/API/macosx/lc-note/multiple-binary-corefile/two.c
################################################################################
diff --git a/lldb/docs/lldb-gdb-remote.txt b/lldb/docs/lldb-gdb-remote.txt
index 497980ed1229..820f3bd7bbc2 100644
--- a/lldb/docs/lldb-gdb-remote.txt
+++ b/lldb/docs/lldb-gdb-remote.txt
@@ -1073,12 +1073,6 @@ main-binary-uuid: is the UUID of a firmware type binary that the gdb stub knows
main-binary-address: is the load address of the firmware type binary
main-binary-slide: is the slide of the firmware type binary, if address isn't known
-binary-addresses: A comma-separated list of binary load addresses base16.
- lldb will parse the binaries in memory to get UUIDs, then
- try to find the binaries & debug info by UUID. Intended for
- use with a small number of firmware type binaries where the
- search for binary/debug info may be expensive.
-
//----------------------------------------------------------------------
// "qShlibInfoAddr"
//
diff --git a/lldb/include/lldb/Target/DynamicLoader.h b/lldb/include/lldb/Target/DynamicLoader.h
index 7e7a4218810b..397b4aa30344 100644
--- a/lldb/include/lldb/Target/DynamicLoader.h
+++ b/lldb/include/lldb/Target/DynamicLoader.h
@@ -210,52 +210,6 @@ class DynamicLoader : public PluginInterface {
lldb::addr_t base_addr,
bool base_addr_is_offset);
- /// Find/load a binary into lldb given a UUID and the address where it is
- /// loaded in memory, or a slide to be applied to the file address.
- /// May force an expensive search on the computer to find the binary by
- /// UUID, should not be used for a large number of binaries - intended for
- /// an environment where there may be one, or a few, binaries resident in
- /// memory.
- ///
- /// Given a UUID, search for a binary and load it at the address provided,
- /// or with the slide applied, or at the file address unslid.
- ///
- /// Given an address, try to read the binary out of memory, get the UUID,
- /// find the file if possible and load it unslid, or add the memory module.
- ///
- /// \param[in] process
- /// The process to add this binary to.
- ///
- /// \param[in] uuid
- /// UUID of the binary to be loaded. UUID may be empty, and if a
- /// load address is supplied, will read the binary from memory, get
- /// a UUID and try to find a local binary. There is a performance
- /// cost to doing this, it is not preferable.
- ///
- /// \param[in] value
- /// Address where the binary should be loaded, or read out of memory.
- /// Or a slide value, to be applied to the file addresses of the binary.
- ///
- /// \param[in] value_is_offset
- /// A flag indicating that \p value is an address, or an offset to
- /// be applied to the file addresses.
- ///
- /// \param[in] force_symbol_search
- /// Allow the search to do a possibly expensive external search for
- /// the ObjectFile and/or SymbolFile.
- ///
- /// \param[in] notify
- /// Whether ModulesDidLoad should be called when a binary has been added
- /// to the Target. The caller may prefer to batch up these when loading
- /// multiple binaries.
- ///
- /// \return
- /// Returns a shared pointer for the Module that has been added.
- static lldb::ModuleSP
- LoadBinaryWithUUIDAndAddress(Process *process, UUID uuid, lldb::addr_t value,
- bool value_is_offset, bool force_symbol_search,
- bool notify);
-
/// Get information about the shared cache for a process, if possible.
///
/// On some systems (e.g. Darwin based systems), a set of libraries that are
diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp
index 1fe60e000c6d..96e0d4ec6555 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -13,15 +13,11 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
-#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/LLDBLog.h"
-#include "lldb/Utility/Log.h"
#include "lldb/lldb-private-interfaces.h"
#include "llvm/ADT/StringRef.h"
@@ -175,100 +171,6 @@ ModuleSP DynamicLoader::LoadModuleAtAddress(const FileSpec &file,
return nullptr;
}
-static ModuleSP ReadUnnamedMemoryModule(Process *process, addr_t addr) {
- char namebuf[80];
- snprintf(namebuf, sizeof(namebuf), "memory-image-0x%" PRIx64, addr);
- return process->ReadModuleFromMemory(FileSpec(namebuf), addr);
-}
-
-ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(Process *process,
- UUID uuid, addr_t value,
- bool value_is_offset,
- bool force_symbol_search,
- bool notify) {
- ModuleSP memory_module_sp;
- ModuleSP module_sp;
- PlatformSP platform_sp = process->GetTarget().GetPlatform();
- Target &target = process->GetTarget();
- Status error;
- ModuleSpec module_spec;
- module_spec.GetUUID() = uuid;
-
- if (!uuid.IsValid() && !value_is_offset) {
- memory_module_sp = ReadUnnamedMemoryModule(process, value);
-
- if (memory_module_sp)
- uuid = memory_module_sp->GetUUID();
- }
-
- if (uuid.IsValid()) {
- ModuleSpec module_spec;
- module_spec.GetUUID() = uuid;
-
- if (!module_sp)
- module_sp = target.GetOrCreateModule(module_spec, false, &error);
-
- // If we haven't found a binary, or we don't have a SymbolFile, see
- // if there is an external search tool that can find it.
- if (force_symbol_search &&
- (!module_sp || !module_sp->GetSymbolFileFileSpec())) {
- Symbols::DownloadObjectAndSymbolFile(module_spec, error, true);
- if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
- module_sp = std::make_shared<Module>(module_spec);
- }
- }
- }
-
- // If we couldn't find the binary anywhere else, as a last resort,
- // read it out of memory.
- if (!module_sp.get() && value != LLDB_INVALID_ADDRESS && !value_is_offset) {
- if (!memory_module_sp)
- memory_module_sp = ReadUnnamedMemoryModule(process, value);
- if (memory_module_sp)
- module_sp = memory_module_sp;
- }
-
- Log *log = GetLog(LLDBLog::DynamicLoader);
- if (module_sp.get()) {
- target.GetImages().AppendIfNeeded(module_sp, false);
-
- bool changed = false;
- if (module_sp->GetObjectFile()) {
- if (value != LLDB_INVALID_ADDRESS) {
- LLDB_LOGF(log, "Loading binary UUID %s at %s 0x%" PRIx64,
- uuid.GetAsString().c_str(),
- value_is_offset ? "offset" : "address", value);
- module_sp->SetLoadAddress(target, value, value_is_offset, changed);
- } else {
- // No address/offset/slide, load the binary at file address,
- // offset 0.
- LLDB_LOGF(log, "Loading binary UUID %s at file address",
- uuid.GetAsString().c_str());
- module_sp->SetLoadAddress(target, 0, true /* value_is_slide */,
- changed);
- }
- } else {
- // In-memory image, load at its true address, offset 0.
- LLDB_LOGF(log, "Loading binary UUID %s from memory at address 0x%" PRIx64,
- uuid.GetAsString().c_str(), value);
- module_sp->SetLoadAddress(target, 0, true /* value_is_slide */, changed);
- }
-
- if (notify) {
- ModuleList added_module;
- added_module.Append(module_sp, false);
- target.ModulesDidLoad(added_module);
- }
- } else {
- LLDB_LOGF(log, "Unable to find binary with UUID %s and load it at "
- "%s 0x%" PRIx64,
- uuid.GetAsString().c_str(),
- value_is_offset ? "offset" : "address", value);
- }
-
- return module_sp;
-}
-
int64_t DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr,
int size_in_bytes) {
Status error;
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 15b06dbbfaec..5dc71fca36c2 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -5600,8 +5600,7 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value,
}
if (m_data.CopyData(offset, sizeof(uuid_t), raw_uuid) != 0) {
- if (!uuid_is_null(raw_uuid))
- uuid = UUID::fromOptionalData(raw_uuid, sizeof(uuid_t));
+ uuid = UUID::fromOptionalData(raw_uuid, sizeof(uuid_t));
// convert the "main bin spec" type into our
// ObjectFile::BinaryType enum
switch (binspec_type) {
@@ -6902,8 +6901,7 @@ ObjectFileMachO::GetCorefileAllImageInfos() {
MachOCorefileImageEntry image_entry;
image_entry.filename = (const char *)m_data.GetCStr(&filepath_offset);
- if (!uuid_is_null(uuid))
- image_entry.uuid = UUID::fromData(uuid, sizeof(uuid_t));
+ image_entry.uuid = UUID::fromData(uuid, sizeof(uuid_t));
image_entry.load_address = load_address;
image_entry.currently_executing = currently_executing;
@@ -6934,11 +6932,9 @@ ObjectFileMachO::GetCorefileAllImageInfos() {
MachOCorefileImageEntry image_entry;
image_entry.filename = filename;
- if (!uuid_is_null(uuid))
- image_entry.uuid = UUID::fromData(uuid, sizeof(uuid_t));
+ image_entry.uuid = UUID::fromData(uuid, sizeof(uuid_t));
image_entry.load_address = load_address;
image_entry.slide = slide;
- image_entry.currently_executing = true;
image_infos.all_image_infos.push_back(image_entry);
}
}
@@ -6955,41 +6951,42 @@ bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {
ModuleList added_modules;
for (const MachOCorefileImageEntry &image : image_infos.all_image_infos) {
- ModuleSP module_sp;
-
- if (!image.filename.empty()) {
- Status error;
- ModuleSpec module_spec;
- module_spec.GetUUID() = image.uuid;
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = image.uuid;
+ if (image.filename.empty()) {
+ char namebuf[80];
+ if (image.load_address != LLDB_INVALID_ADDRESS)
+ snprintf(namebuf, sizeof(namebuf), "mem-image-0x%" PRIx64,
+ image.load_address);
+ else
+ snprintf(namebuf, sizeof(namebuf), "mem-image+0x%" PRIx64, image.slide);
+ module_spec.GetFileSpec() = FileSpec(namebuf);
+ } else {
module_spec.GetFileSpec() = FileSpec(image.filename.c_str());
- if (image.currently_executing) {
- Symbols::DownloadObjectAndSymbolFile(module_spec, error, true);
- if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
- process.GetTarget().GetOrCreateModule(module_spec, false);
- }
+ }
+ if (image.currently_executing) {
+ Status error;
+ Symbols::DownloadObjectAndSymbolFile(module_spec, error, true);
+ if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
+ process.GetTarget().GetOrCreateModule(module_spec, false);
}
- module_sp =
- process.GetTarget().GetOrCreateModule(module_spec, false, &error);
- process.GetTarget().GetImages().AppendIfNeeded(module_sp,
- false /* notify */);
- } else {
+ }
+ Status error;
+ ModuleSP module_sp =
+ process.GetTarget().GetOrCreateModule(module_spec, false, &error);
+ if (!module_sp.get() || !module_sp->GetObjectFile()) {
if (image.load_address != LLDB_INVALID_ADDRESS) {
- module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress(
- &process, image.uuid, image.load_address,
- false /* value_is_offset */, image.currently_executing,
- false /* notify */);
- } else if (image.slide != LLDB_INVALID_ADDRESS) {
- module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress(
- &process, image.uuid, image.slide, true /* value_is_offset */,
- image.currently_executing, false /* notify */);
+ module_sp = process.ReadModuleFromMemory(module_spec.GetFileSpec(),
+ image.load_address);
}
}
-
if (module_sp.get()) {
// Will call ModulesDidLoad with all modules once they've all
// been added to the Target with load addresses. Don't notify
// here, before the load address is set.
- added_modules.Append(module_sp, false /* notify */);
+ const bool notify = false;
+ process.GetTarget().GetImages().AppendIfNeeded(module_sp, notify);
+ added_modules.Append(module_sp, notify);
if (image.segment_load_addresses.size() > 0) {
if (log) {
std::string uuidstr = image.uuid.GetAsString();
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 8687175ee36c..580cdde57d80 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1033,13 +1033,6 @@ bool GDBRemoteCommunicationClient::GetProcessStandaloneBinary(
return true;
}
-std::vector<addr_t>
-GDBRemoteCommunicationClient::GetProcessStandaloneBinaries() {
- if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
- GetCurrentProcessInfo();
- return m_binary_addresses;
-}
-
bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {
m_gdb_server_name.clear();
@@ -2199,14 +2192,6 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
m_process_standalone_value_is_offset = false;
++num_keys_decoded;
}
- } else if (name.equals("binary-addresses")) {
- addr_t addr;
- while (!value.empty()) {
- llvm::StringRef addr_str;
- std::tie(addr_str, value) = value.split(',');
- if (!addr_str.getAsInteger(16, addr))
- m_binary_addresses.push_back(addr);
- }
}
}
if (num_keys_decoded > 0)
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 3a62747603f6..3d838d6d8074 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -220,8 +220,6 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
bool GetProcessStandaloneBinary(UUID &uuid, lldb::addr_t &value,
bool &value_is_offset);
- std::vector<lldb::addr_t> GetProcessStandaloneBinaries();
-
void GetRemoteQSupported();
bool GetVContSupported(char flavor);
@@ -595,7 +593,6 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
UUID m_process_standalone_uuid;
lldb::addr_t m_process_standalone_value = LLDB_INVALID_ADDRESS;
bool m_process_standalone_value_is_offset = false;
- std::vector<lldb::addr_t> m_binary_addresses;
llvm::VersionTuple m_os_version;
llvm::VersionTuple m_maccatalyst_version;
std::string m_os_build;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index e3dada1864da..b7de05d498aa 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -581,31 +581,80 @@ Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) {
ModuleSP module_sp;
if (standalone_uuid.IsValid()) {
- const bool force_symbol_search = true;
- const bool notify = true;
- DynamicLoader::LoadBinaryWithUUIDAndAddress(
- this, standalone_uuid, standalone_value,
- standalone_value_is_offset, force_symbol_search, notify);
- }
- }
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = standalone_uuid;
+
+ // Look up UUID in global module cache before attempting
+ // a more expensive search.
+ Status error = ModuleList::GetSharedModule(module_spec, module_sp,
+ nullptr, nullptr, nullptr);
+
+ if (!module_sp) {
+ // Force a an external lookup, if that tool is available.
+ if (!module_spec.GetSymbolFileSpec()) {
+ Status error;
+ Symbols::DownloadObjectAndSymbolFile(module_spec, error, true);
+ }
+
+ if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
+ module_sp = std::make_shared<Module>(module_spec);
+ }
+ }
+
+ // If we couldn't find the binary anywhere else, as a last resort,
+ // read it out of memory.
+ if (!module_sp.get() && standalone_value != LLDB_INVALID_ADDRESS &&
+ !standalone_value_is_offset) {
+ char namebuf[80];
+ snprintf(namebuf, sizeof(namebuf), "mem-image-0x%" PRIx64,
+ standalone_value);
+ module_sp =
+ ReadModuleFromMemory(FileSpec(namebuf), standalone_value);
+ }
- // The remote stub may know about a list of binaries to
- // force load into the process -- a firmware type situation
- // where multiple binaries are present in virtual memory,
- // and we are only given the addresses of the binaries.
- // Not intended for use with userland debugging when we
- // a DynamicLoader plugin that knows how to find the loaded
- // binaries and will track updates as binaries are added.
-
- std::vector<addr_t> bin_addrs = m_gdb_comm.GetProcessStandaloneBinaries();
- if (bin_addrs.size()) {
- UUID uuid;
- const bool value_is_slide = false;
- for (addr_t addr : bin_addrs) {
- const bool force_symbol_search = true;
- const bool notify = true;
- DynamicLoader::LoadBinaryWithUUIDAndAddress(
- this, uuid, addr, value_is_slide, force_symbol_search, notify);
+ Log *log = GetLog(LLDBLog::DynamicLoader);
+ if (module_sp.get()) {
+ target.GetImages().AppendIfNeeded(module_sp, false);
+
+ bool changed = false;
+ if (module_sp->GetObjectFile()) {
+ if (standalone_value != LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Loading binary UUID %s at %s 0x%" PRIx64,
+ standalone_uuid.GetAsString().c_str(),
+ standalone_value_is_offset ? "offset" : "address",
+ standalone_value);
+ module_sp->SetLoadAddress(target, standalone_value,
+ standalone_value_is_offset, changed);
+ } else {
+ // No address/offset/slide, load the binary at file address,
+ // offset 0.
+ if (log)
+ log->Printf("Loading binary UUID %s at file address",
+ standalone_uuid.GetAsString().c_str());
+ const bool value_is_slide = true;
+ module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
+ }
+ } else {
+ // In-memory image, load at its true address, offset 0.
+ if (log)
+ log->Printf("Loading binary UUID %s from memory",
+ standalone_uuid.GetAsString().c_str());
+ const bool value_is_slide = true;
+ module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
+ }
+
+ ModuleList added_module;
+ added_module.Append(module_sp, false);
+ target.ModulesDidLoad(added_module);
+ } else {
+ if (log)
+ log->Printf("Unable to find binary with UUID %s and load it at "
+ "%s 0x%" PRIx64,
+ standalone_uuid.GetAsString().c_str(),
+ standalone_value_is_offset ? "offset" : "address",
+ standalone_value);
+ }
}
}
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index 68786e8d80b0..7f943a5258c4 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -180,6 +180,88 @@ bool ProcessMachCore::GetDynamicLoaderAddress(lldb::addr_t addr) {
return false;
}
+// We have a hint about a binary -- a UUID, possibly a load address.
+// Try to load a file with that UUID into lldb, and if we have a load
+// address, set it correctly. Else assume that the binary was loaded
+// with no slide.
+static bool load_standalone_binary(UUID uuid, addr_t value,
+ bool value_is_offset, Target &target) {
+ if (uuid.IsValid()) {
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = uuid;
+
+ // Look up UUID in global module cache before attempting
+ // dsymForUUID-like action.
+ ModuleSP module_sp;
+ Status error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
+ nullptr, nullptr);
+
+ if (!module_sp.get()) {
+ // Force a a dsymForUUID lookup, if that tool is available.
+ if (!module_spec.GetSymbolFileSpec()) {
+ Status error;
+ Symbols::DownloadObjectAndSymbolFile(module_spec, error, true);
+ }
+
+ if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
+ module_sp = std::make_shared<Module>(module_spec);
+ }
+ }
+
+ // If we couldn't find the binary anywhere else, as a last resort,
+ // read it out of memory in the corefile.
+ if (!module_sp.get() && value != LLDB_INVALID_ADDRESS && !value_is_offset) {
+ char namebuf[80];
+ snprintf(namebuf, sizeof(namebuf), "mem-image-0x%" PRIx64, value);
+ module_sp =
+ target.GetProcessSP()->ReadModuleFromMemory(FileSpec(namebuf), value);
+ }
+
+ if (module_sp.get()) {
+ target.SetArchitecture(module_sp->GetObjectFile()->GetArchitecture());
+ target.GetImages().AppendIfNeeded(module_sp, false);
+
+ // TODO: Instead of using the load address as a value, if we create a
+ // memory module from that address, we could get the correct segment
+ // offset values from the in-memory load commands and set them correctly.
+ // In case the load address we were given is not correct for all segments,
+ // e.g. something in the shared cache. DynamicLoaderDarwinKernel does
+ // something similar for kexts. In the context of a corefile, this would
+ // be an inexpensive operation. Not all binaries in a corefile will have
+ // a Mach-O header/load commands in memory, so this will not work in all
+ // cases.
+
+ bool changed = false;
+ if (module_sp->GetObjectFile()) {
+ if (value != LLDB_INVALID_ADDRESS) {
+ module_sp->SetLoadAddress(target, value, value_is_offset, changed);
+ } else {
+ // No address/offset/slide, load the binary at file address,
+ // offset 0.
+ const bool value_is_slide = true;
+ module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
+ }
+ } else {
+ // In-memory image, load at its true address, offset 0.
+ const bool value_is_slide = true;
+ module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
+ }
+
+ ModuleList added_module;
+ added_module.Append(module_sp, false);
+ target.ModulesDidLoad(added_module);
+
+ // Flush info in the process (stack frames, etc).
+ ProcessSP process_sp(target.GetProcessSP());
+ if (process_sp)
+ process_sp->Flush();
+
+ return true;
+ }
+ }
+ return false;
+}
+
// Process Control
Status ProcessMachCore::DoLoadCore() {
Log *log(GetLog(LLDBLog::DynamicLoader | LLDBLog::Process));
@@ -277,21 +359,28 @@ Status ProcessMachCore::DoLoadCore() {
objfile_binary_uuid.GetAsString().c_str(), objfile_binary_value,
objfile_binary_value_is_offset, type);
}
- const bool force_symbol_search = true;
- const bool notify = true;
- if (DynamicLoader::LoadBinaryWithUUIDAndAddress(
- this, objfile_binary_uuid, objfile_binary_value,
- objfile_binary_value_is_offset, force_symbol_search, notify)) {
- found_main_binary_definitively = true;
- m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
- }
- if (type == ObjectFile::eBinaryTypeUser) {
- m_dyld_addr = objfile_binary_value;
- m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
+ if (objfile_binary_value != LLDB_INVALID_ADDRESS &&
+ !objfile_binary_value_is_offset) {
+ if (type == ObjectFile::eBinaryTypeUser) {
+ load_standalone_binary(objfile_binary_uuid, objfile_binary_value,
+ objfile_binary_value_is_offset, GetTarget());
+ m_dyld_addr = objfile_binary_value;
+ m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
+ found_main_binary_definitively = true;
+ }
+ if (type == ObjectFile::eBinaryTypeKernel) {
+ m_mach_kernel_addr = objfile_binary_value;
+ m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
+ found_main_binary_definitively = true;
+ }
}
- if (type == ObjectFile::eBinaryTypeKernel) {
- m_mach_kernel_addr = objfile_binary_value;
- m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
+ if (!found_main_binary_definitively) {
+ // ObjectFile::eBinaryTypeStandalone, undeclared types
+ if (load_standalone_binary(objfile_binary_uuid, objfile_binary_value,
+ objfile_binary_value_is_offset, GetTarget())) {
+ found_main_binary_definitively = true;
+ m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
+ }
}
}
@@ -337,11 +426,8 @@ Status ProcessMachCore::DoLoadCore() {
// We have no address specified, only a UUID. Load it at the file
// address.
const bool value_is_offset = false;
- const bool force_symbol_search = true;
- const bool notify = true;
- if (DynamicLoader::LoadBinaryWithUUIDAndAddress(
- this, ident_uuid, ident_binary_addr, value_is_offset,
- force_symbol_search, notify)) {
+ if (load_standalone_binary(ident_uuid, ident_binary_addr, value_is_offset,
+ GetTarget())) {
found_main_binary_definitively = true;
m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
}
diff --git a/lldb/test/API/macosx/lc-note/multiple-binary-corefile/Makefile b/lldb/test/API/macosx/lc-note/multiple-binary-corefile/Makefile
deleted file mode 100644
index 8e561f17383f..000000000000
--- a/lldb/test/API/macosx/lc-note/multiple-binary-corefile/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-MAKE_DSYM := NO
-C_SOURCES := main.c
-LD_EXTRAS := -L. -lone -ltwo
-
-.PHONY: libone.dylib libtwo.dylib
-all: libone.dylib libtwo.dylib a.out create-empty-corefile
-
-create-empty-corefile:
- "$(MAKE)" -f "$(MAKEFILE_RULES)" EXE=create-multibin-corefile \
- CXX_SOURCES=create-multibin-corefile.cpp
-
-libone.dylib: one.c
- $(MAKE) -f $(MAKEFILE_RULES) \
- DYLIB_ONLY=YES DYLIB_NAME=one DYLIB_C_SOURCES=one.c
-
-libtwo.dylib: two.c
- $(MAKE) -f $(MAKEFILE_RULES) \
- DYLIB_ONLY=YES DYLIB_NAME=two DYLIB_C_SOURCES=two.c
-
-include Makefile.rules
diff --git a/lldb/test/API/macosx/lc-note/multiple-binary-corefile/TestMultipleBinaryCorefile.py b/lldb/test/API/macosx/lc-note/multiple-binary-corefile/TestMultipleBinaryCorefile.py
deleted file mode 100644
index 5e74f0c3f8bf..000000000000
--- a/lldb/test/API/macosx/lc-note/multiple-binary-corefile/TestMultipleBinaryCorefile.py
+++ /dev/null
@@ -1,187 +0,0 @@
-"""Test corefiles with "main bin spec"/"load binary" with only addrs work."""
-
-
-import os
-import re
-import subprocess
-
-import lldb
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
-
-
-class TestMultipleBinaryCorefile(TestBase):
-
- def initial_setup(self):
- self.build()
- self.aout_exe_basename = "a.out"
- self.libone_exe_basename = "libone.dylib"
- self.libtwo_exe_basename = "libtwo.dylib"
- self.aout_exe = self.getBuildArtifact(self.aout_exe_basename)
- self.aout_slide = 0x5000
- self.libone_exe = self.getBuildArtifact(self.libone_exe_basename)
- self.libone_slide = 0x100840000
- self.libtwo_exe = self.getBuildArtifact(self.libtwo_exe_basename)
- self.libtwo_slide = 0
- self.corefile = self.getBuildArtifact("multiple-binaries.core")
- self.create_corefile = self.getBuildArtifact("create-multibin-corefile")
- cmd="%s %s %s@%x %s@%x %s@%x" % (self.create_corefile, self.corefile,
- self.aout_exe, self.aout_slide,
- self.libone_exe, self.libone_slide,
- self.libtwo_exe, self.libtwo_slide)
- call(cmd, shell=True)
-
-
- def load_corefile_and_test(self):
- target = self.dbg.CreateTarget('')
- err = lldb.SBError()
- if self.TraceOn():
- self.runCmd("script print('loading corefile %s')" % self.corefile)
- process = target.LoadCore(self.corefile)
- self.assertEqual(process.IsValid(), True)
- if self.TraceOn():
- self.runCmd("script print('image list after loading corefile:')")
- self.runCmd("image list")
-
- self.assertEqual(target.GetNumModules(), 3)
- fspec = target.GetModuleAtIndex(0).GetFileSpec()
- self.assertEqual(fspec.GetFilename(), self.aout_exe_basename)
-
- # libone.dylib was never loaded into lldb, see that we added a memory module.
- fspec = target.GetModuleAtIndex(1).GetFileSpec()
- self.assertIn('memory-image', fspec.GetFilename())
-
- dwarfdump_uuid_regex = re.compile(
- 'UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*')
- dwarfdump_cmd_output = subprocess.check_output(
- ('/usr/bin/dwarfdump --uuid "%s"' % self.libone_exe), shell=True).decode("utf-8")
- libone_uuid = None
- for line in dwarfdump_cmd_output.splitlines():
- match = dwarfdump_uuid_regex.search(line)
- if match:
- libone_uuid = match.group(1)
-
- memory_image_uuid = target.GetModuleAtIndex(1).GetUUIDString()
- self.assertEqual(libone_uuid, memory_image_uuid)
-
- fspec = target.GetModuleAtIndex(2).GetFileSpec()
- self.assertEqual(fspec.GetFilename(), self.libtwo_exe_basename)
-
- # Executables "always" have this base address
- aout_load = target.GetModuleAtIndex(0).GetObjectFileHeaderAddress().GetLoadAddress(target)
- self.assertEqual(aout_load, 0x100000000 + self.aout_slide)
-
- # Value from Makefile
- libone_load = target.GetModuleAtIndex(1).GetObjectFileHeaderAddress().GetLoadAddress(target)
- self.assertEqual(libone_load, self.libone_slide)
-
- # Value from Makefile
- libtwo_load = target.GetModuleAtIndex(2).GetObjectFileHeaderAddress().GetLoadAddress(target)
- self.assertEqual(libtwo_load, self.libtwo_slide)
-
- self.dbg.DeleteTarget(target)
- self.dbg.Clear()
-
- NO_DEBUG_INFO_TESTCASE = True
-
- @skipIf(archs=no_match(['x86_64', 'arm64', 'arm64e', 'aarch64']))
- @skipIfRemote
- @skipUnlessDarwin
- def test_corefile_binaries_dsymforuuid(self):
- self.initial_setup()
-
- if self.TraceOn():
- self.runCmd("log enable lldb dyld host")
- self.addTearDownHook(lambda: self.runCmd("log disable lldb dyld host"))
-
- ## We can hook in our dsym-for-uuid shell script to lldb with this env
- ## var instead of requiring a defaults write.
- dsym_for_uuid = self.getBuildArtifact("dsym-for-uuid.sh")
- os.environ['LLDB_APPLE_DSYMFORUUID_EXECUTABLE'] = dsym_for_uuid
- if self.TraceOn():
- print("Setting env var LLDB_APPLE_DSYMFORUUID_EXECUTABLE=" + dsym_for_uuid)
- self.addTearDownHook(lambda: os.environ.pop('LLDB_APPLE_DSYMFORUUID_EXECUTABLE', None))
-
- self.runCmd("settings set target.load-script-from-symbol-file true")
- self.addTearDownHook(lambda: self.runCmd("settings set target.load-script-from-symbol-file false"))
-
- dwarfdump_uuid_regex = re.compile(
- 'UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*')
- dwarfdump_cmd_output = subprocess.check_output(
- ('/usr/bin/dwarfdump --uuid "%s"' % self.libtwo_exe), shell=True).decode("utf-8")
- libtwo_uuid = None
- for line in dwarfdump_cmd_output.splitlines():
- match = dwarfdump_uuid_regex.search(line)
- if match:
- libtwo_uuid = match.group(1)
- self.assertNotEqual(libtwo_uuid, None, "Could not get uuid of built libtwo.dylib")
-
- ### Create our dsym-for-uuid shell script which returns aout_exe
- shell_cmds = [
- '#! /bin/sh',
- '# the last argument is the uuid',
- 'while [ $# -gt 1 ]',
- 'do',
- ' shift',
- 'done',
- 'ret=0',
- 'echo "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>"',
- 'echo "<!DOCTYPE plist PUBLIC \\"-//Apple//DTD PLIST 1.0//EN\\" \\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\\">"',
- 'echo "<plist version=\\"1.0\\">"',
- '',
- 'if [ "$1" != "%s" ]' % (libtwo_uuid),
- 'then',
- ' echo "<key>DBGError</key><string>not found</string>"',
- ' echo "</plist>"',
- ' exit 1',
- 'fi',
- ' uuid=%s' % libtwo_uuid,
- ' bin=%s' % self.libtwo_exe,
- ' dsym=%s.dSYM/Contents/Resources/DWARF/%s' % (self.libtwo_exe, os.path.basename(self.libtwo_exe)),
- 'echo "<dict><key>$uuid</key><dict>"',
- '',
- 'echo "<key>DBGDSYMPath</key><string>$dsym</string>"',
- 'echo "<key>DBGSymbolRichExecutable</key><string>$bin</string>"',
- 'echo "</dict></dict></plist>"',
- 'exit $ret'
- ]
-
- with open(dsym_for_uuid, "w") as writer:
- for l in shell_cmds:
- writer.write(l + '\n')
-
- os.chmod(dsym_for_uuid, 0o755)
-
- # Register TWO of our binaries, but require dsymForUUID to find the third.
- target = self.dbg.CreateTarget(self.aout_exe, '', '', False, lldb.SBError())
- self.dbg.DeleteTarget(target)
-
- if self.TraceOn():
- self.runCmd("script print('Global image list, before loading corefile:')")
- self.runCmd("image list -g")
-
- self.load_corefile_and_test()
-
- @skipIf(archs=no_match(['x86_64', 'arm64', 'arm64e', 'aarch64']))
- @skipIfRemote
- @skipUnlessDarwin
- def test_corefile_binaries_preloaded(self):
- self.initial_setup()
-
- if self.TraceOn():
- self.runCmd("log enable lldb dyld host")
- self.addTearDownHook(lambda: self.runCmd("log disable lldb dyld host"))
-
- # Register all three binaries in lldb's global module
- # cache, then throw the Targets away.
- target = self.dbg.CreateTarget(self.aout_exe, '', '', False, lldb.SBError())
- self.dbg.DeleteTarget(target)
- target = self.dbg.CreateTarget(self.libtwo_exe, '', '', False, lldb.SBError())
- self.dbg.DeleteTarget(target)
-
- if self.TraceOn():
- self.runCmd("script print('Global image list, before loading corefile:')")
- self.runCmd("image list -g")
-
- self.load_corefile_and_test()
diff --git a/lldb/test/API/macosx/lc-note/multiple-binary-corefile/create-multibin-corefile.cpp b/lldb/test/API/macosx/lc-note/multiple-binary-corefile/create-multibin-corefile.cpp
deleted file mode 100644
index ebe71606806d..000000000000
--- a/lldb/test/API/macosx/lc-note/multiple-binary-corefile/create-multibin-corefile.cpp
+++ /dev/null
@@ -1,484 +0,0 @@
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <mach-o/loader.h>
-#include <mach/thread_status.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <string>
-#include <sys/errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <uuid/uuid.h>
-#include <vector>
-
-// Given a list of binaries, and optional slides to be applied,
-// create a corefile whose memory is those binaries laid at at
-// their slid addresses.
-//
-// Add a 'main bin spec' LC_NOTE for the first binary, and
-// 'load binary' LC_NOTEs for any additional binaries, and
-// these LC_NOTEs will ONLY have the vmaddr of the binary - no
-// UUID, no slide, no filename.
-//
-// Test that lldb can use the load addresses, find the UUIDs,
-// and load the binaries/dSYMs and put them at the correct load
-// address.
-
-struct main_bin_spec_payload {
- uint32_t version;
- uint32_t type;
- uint64_t address;
- uint64_t slide;
- uuid_t uuid;
- uint32_t log2_pagesize;
- uint32_t platform;
-};
-
-struct load_binary_payload {
- uint32_t version;
- uuid_t uuid;
- uint64_t address;
- uint64_t slide;
- const char name[4];
-};
-
-union uint32_buf {
- uint8_t bytebuf[4];
- uint32_t val;
-};
-
-union uint64_buf {
- uint8_t bytebuf[8];
- uint64_t val;
-};
-
-void add_uint64(std::vector<uint8_t> &buf, uint64_t val) {
- uint64_buf conv;
- conv.val = val;
- for (int i = 0; i < 8; i++)
- buf.push_back(conv.bytebuf[i]);
-}
-
-void add_uint32(std::vector<uint8_t> &buf, uint32_t val) {
- uint32_buf conv;
- conv.val = val;
- for (int i = 0; i < 4; i++)
- buf.push_back(conv.bytebuf[i]);
-}
-
-std::vector<uint8_t> lc_thread_load_command(cpu_type_t cputype) {
- std::vector<uint8_t> data;
- // Emit an LC_THREAD register context appropriate for the cputype
- // of the binary we're embedded. The tests in this case do not
- // use the register values, so 0's are fine, lldb needs to see at
- // least one LC_THREAD in the corefile.
-#if defined(__x86_64__)
- if (cputype == CPU_TYPE_X86_64) {
- add_uint32(data, LC_THREAD); // thread_command.cmd
- add_uint32(data,
- 16 + (x86_THREAD_STATE64_COUNT * 4)); // thread_command.cmdsize
- add_uint32(data, x86_THREAD_STATE64); // thread_command.flavor
- add_uint32(data, x86_THREAD_STATE64_COUNT); // thread_command.count
- for (int i = 0; i < x86_THREAD_STATE64_COUNT; i++) {
- add_uint32(data, 0); // whatever, just some empty register values
- }
- }
-#endif
-#if defined(__arm64__) || defined(__aarch64__)
- if (cputype == CPU_TYPE_ARM64) {
- add_uint32(data, LC_THREAD); // thread_command.cmd
- add_uint32(data,
- 16 + (ARM_THREAD_STATE64_COUNT * 4)); // thread_command.cmdsize
- add_uint32(data, ARM_THREAD_STATE64); // thread_command.flavor
- add_uint32(data, ARM_THREAD_STATE64_COUNT); // thread_command.count
- for (int i = 0; i < ARM_THREAD_STATE64_COUNT; i++) {
- add_uint32(data, 0); // whatever, just some empty register values
- }
- }
-#endif
- return data;
-}
-
-void add_lc_note_main_bin_spec_load_command(
- std::vector<std::vector<uint8_t>> &loadcmds, std::vector<uint8_t> &payload,
- int payload_file_offset, std::string uuidstr, uint64_t address,
- uint64_t slide) {
- std::vector<uint8_t> loadcmd_data;
-
- add_uint32(loadcmd_data, LC_NOTE); // note_command.cmd
- add_uint32(loadcmd_data, 40); // note_command.cmdsize
- char lc_note_name[16];
- memset(lc_note_name, 0, 16);
- strcpy(lc_note_name, "main bin spec");
-
- // lc_note.data_owner
- for (int i = 0; i < 16; i++)
- loadcmd_data.push_back(lc_note_name[i]);
-
- // we start writing the payload at payload_file_offset to leave
- // room at the start for the header & the load commands.
- uint64_t current_payload_offset = payload.size() + payload_file_offset;
-
- add_uint64(loadcmd_data, current_payload_offset); // note_command.offset
- add_uint64(loadcmd_data,
- sizeof(struct main_bin_spec_payload)); // note_command.size
-
- loadcmds.push_back(loadcmd_data);
-
- // Now write the "main bin spec" payload.
- add_uint32(payload, 2); // version
- add_uint32(payload, 3); // type == 3 [ firmware, standalone, etc ]
- add_uint64(payload, address); // load address
- add_uint64(payload, slide); // slide
- uuid_t uuid;
- uuid_parse(uuidstr.c_str(), uuid);
- for (int i = 0; i < sizeof(uuid_t); i++)
- payload.push_back(uuid[i]);
- add_uint32(payload, 0); // log2_pagesize unspecified
- add_uint32(payload, 0); // platform unspecified
-}
-
-void add_lc_note_load_binary_load_command(
- std::vector<std::vector<uint8_t>> &loadcmds, std::vector<uint8_t> &payload,
- int payload_file_offset, std::string uuidstr, uint64_t address,
- uint64_t slide) {
- std::vector<uint8_t> loadcmd_data;
-
- add_uint32(loadcmd_data, LC_NOTE); // note_command.cmd
- add_uint32(loadcmd_data, 40); // note_command.cmdsize
- char lc_note_name[16];
- memset(lc_note_name, 0, 16);
- strcpy(lc_note_name, "load binary");
-
- // lc_note.data_owner
- for (int i = 0; i < 16; i++)
- loadcmd_data.push_back(lc_note_name[i]);
-
- // we start writing the payload at payload_file_offset to leave
- // room at the start for the header & the load commands.
- uint64_t current_payload_offset = payload.size() + payload_file_offset;
-
- add_uint64(loadcmd_data, current_payload_offset); // note_command.offset
- add_uint64(loadcmd_data,
- sizeof(struct load_binary_payload)); // note_command.size
-
- loadcmds.push_back(loadcmd_data);
-
- // Now write the "load binary" payload.
- add_uint32(payload, 1); // version
- uuid_t uuid;
- uuid_parse(uuidstr.c_str(), uuid);
- for (int i = 0; i < sizeof(uuid_t); i++)
- payload.push_back(uuid[i]);
- add_uint64(payload, address); // load address
- add_uint64(payload, slide); // slide
- add_uint32(payload, 0); // name
-}
-
-void add_lc_segment(std::vector<std::vector<uint8_t>> &loadcmds,
- std::vector<uint8_t> &payload, int payload_file_offset,
- uint64_t vmaddr, uint64_t size) {
- std::vector<uint8_t> loadcmd_data;
- struct segment_command_64 seg;
- seg.cmd = LC_SEGMENT_64;
- seg.cmdsize = sizeof(struct segment_command_64); // no sections
- memset(seg.segname, 0, 16);
- seg.vmaddr = vmaddr;
- seg.vmsize = size;
- seg.fileoff = payload.size() + payload_file_offset;
- seg.filesize = size;
- seg.maxprot = 1;
- seg.initprot = 1;
- seg.nsects = 0;
- seg.flags = 0;
-
- uint8_t *p = (uint8_t *)&seg;
- for (int i = 0; i < sizeof(struct segment_command_64); i++) {
- loadcmd_data.push_back(*(p + i));
- }
- loadcmds.push_back(loadcmd_data);
-}
-
-std::string scan_binary(const char *fn, uint64_t &vmaddr, cpu_type_t &cputype,
- cpu_subtype_t &cpusubtype) {
- FILE *f = fopen(fn, "r");
- if (f == nullptr) {
- fprintf(stderr, "Unable to open binary '%s' to get uuid\n", fn);
- exit(1);
- }
- uint32_t num_of_load_cmds = 0;
- uint32_t size_of_load_cmds = 0;
- std::string uuid;
- off_t file_offset = 0;
- vmaddr = UINT64_MAX;
-
- uint8_t magic[4];
- if (::fread(magic, 1, 4, f) != 4) {
- fprintf(stderr, "Failed to read magic number from input file %s\n", fn);
- exit(1);
- }
- uint8_t magic_32_be[] = {0xfe, 0xed, 0xfa, 0xce};
- uint8_t magic_32_le[] = {0xce, 0xfa, 0xed, 0xfe};
- uint8_t magic_64_be[] = {0xfe, 0xed, 0xfa, 0xcf};
- uint8_t magic_64_le[] = {0xcf, 0xfa, 0xed, 0xfe};
-
- if (memcmp(magic, magic_32_be, 4) == 0 ||
- memcmp(magic, magic_64_be, 4) == 0) {
- fprintf(stderr, "big endian corefiles not supported\n");
- exit(1);
- }
-
- ::fseeko(f, 0, SEEK_SET);
- if (memcmp(magic, magic_32_le, 4) == 0) {
- struct mach_header mh;
- if (::fread(&mh, 1, sizeof(mh), f) != sizeof(mh)) {
- fprintf(stderr, "error reading mach header from input file\n");
- exit(1);
- }
- if (mh.cputype != CPU_TYPE_X86_64 && mh.cputype != CPU_TYPE_ARM64) {
- fprintf(stderr,
- "This tool creates an x86_64/arm64 corefile but "
- "the supplied binary '%s' is cputype 0x%x\n",
- fn, (uint32_t)mh.cputype);
- exit(1);
- }
- num_of_load_cmds = mh.ncmds;
- size_of_load_cmds = mh.sizeofcmds;
- file_offset += sizeof(struct mach_header);
- cputype = mh.cputype;
- cpusubtype = mh.cpusubtype;
- } else {
- struct mach_header_64 mh;
- if (::fread(&mh, 1, sizeof(mh), f) != sizeof(mh)) {
- fprintf(stderr, "error reading mach header from input file\n");
- exit(1);
- }
- if (mh.cputype != CPU_TYPE_X86_64 && mh.cputype != CPU_TYPE_ARM64) {
- fprintf(stderr,
- "This tool creates an x86_64/arm64 corefile but "
- "the supplied binary '%s' is cputype 0x%x\n",
- fn, (uint32_t)mh.cputype);
- exit(1);
- }
- num_of_load_cmds = mh.ncmds;
- size_of_load_cmds = mh.sizeofcmds;
- file_offset += sizeof(struct mach_header_64);
- cputype = mh.cputype;
- cpusubtype = mh.cpusubtype;
- }
-
- off_t load_cmds_offset = file_offset;
-
- for (int i = 0; i < num_of_load_cmds &&
- (file_offset - load_cmds_offset) < size_of_load_cmds;
- i++) {
- ::fseeko(f, file_offset, SEEK_SET);
- uint32_t cmd;
- uint32_t cmdsize;
- ::fread(&cmd, sizeof(uint32_t), 1, f);
- ::fread(&cmdsize, sizeof(uint32_t), 1, f);
- if (vmaddr == UINT64_MAX && cmd == LC_SEGMENT_64) {
- struct segment_command_64 segcmd;
- ::fseeko(f, file_offset, SEEK_SET);
- if (::fread(&segcmd, 1, sizeof(segcmd), f) != sizeof(segcmd)) {
- fprintf(stderr, "Unable to read LC_SEGMENT_64 load command.\n");
- exit(1);
- }
- if (strcmp("__TEXT", segcmd.segname) == 0)
- vmaddr = segcmd.vmaddr;
- }
- if (cmd == LC_UUID) {
- struct uuid_command uuidcmd;
- ::fseeko(f, file_offset, SEEK_SET);
- if (::fread(&uuidcmd, 1, sizeof(uuidcmd), f) != sizeof(uuidcmd)) {
- fprintf(stderr, "Unable to read LC_UUID load command.\n");
- exit(1);
- }
- uuid_string_t uuidstr;
- uuid_unparse(uuidcmd.uuid, uuidstr);
- uuid = uuidstr;
- }
- file_offset += cmdsize;
- }
- return uuid;
-}
-
-void slide_macho_binary(std::vector<uint8_t> &image, uint64_t slide) {
- uint8_t *p = image.data();
- struct mach_header_64 *mh = (struct mach_header_64 *)p;
- p += sizeof(struct mach_header_64);
- for (int lc_idx = 0; lc_idx < mh->ncmds; lc_idx++) {
- struct load_command *lc = (struct load_command *)p;
- if (lc->cmd == LC_SEGMENT_64) {
- struct segment_command_64 *seg = (struct segment_command_64 *)p;
- if (seg->maxprot != 0 && seg->nsects > 0) {
- seg->vmaddr += slide;
- uint8_t *j = p + sizeof(segment_command_64);
- for (int sect_idx = 0; sect_idx < seg->nsects; sect_idx++) {
- struct section_64 *sect = (struct section_64 *)j;
- sect->addr += slide;
- j += sizeof(struct section_64);
- }
- }
- }
- p += lc->cmdsize;
- }
-}
-
-int main(int argc, char **argv) {
- if (argc < 3) {
- fprintf(stderr,
- "usage: output-corefile binary1[@optional-slide] "
- "[binary2[@optional-slide] [binary3[@optional-slide] ...]]\n");
- exit(1);
- }
-
- // An array of load commands (in the form of byte arrays)
- std::vector<std::vector<uint8_t>> load_commands;
-
- // An array of corefile contents (page data, lc_note data, etc)
- std::vector<uint8_t> payload;
-
- std::vector<std::string> input_filenames;
- std::vector<uint64_t> input_slides;
- std::vector<uint64_t> input_filesizes;
- std::vector<uint64_t> input_filevmaddrs;
- uint64_t main_binary_cputype = CPU_TYPE_ARM64;
- uint64_t vmaddr = UINT64_MAX;
- cpu_type_t cputype;
- cpu_subtype_t cpusubtype;
- for (int i = 2; i < argc; i++) {
- std::string filename;
- std::string filename_and_opt_hex(argv[i]);
- uint64_t slide = 0;
- auto at_pos = filename_and_opt_hex.find_last_of('@');
- if (at_pos == std::string::npos) {
- filename = filename_and_opt_hex;
- } else {
- filename = filename_and_opt_hex.substr(0, at_pos);
- std::string hexstr = filename_and_opt_hex.substr(at_pos + 1);
- errno = 0;
- slide = (uint64_t)strtoull(hexstr.c_str(), nullptr, 16);
- if (errno != 0) {
- fprintf(stderr, "Unable to parse hex slide value in %s\n", argv[i]);
- exit(1);
- }
- }
- struct stat stbuf;
- if (stat(filename.c_str(), &stbuf) == -1) {
- fprintf(stderr, "Unable to stat '%s', exiting.\n", filename.c_str());
- exit(1);
- }
- input_filenames.push_back(filename);
- input_slides.push_back(slide);
- input_filesizes.push_back(stbuf.st_size);
- scan_binary(filename.c_str(), vmaddr, cputype, cpusubtype);
- input_filevmaddrs.push_back(vmaddr + slide);
- if (i == 2) {
- main_binary_cputype = cputype;
- }
- }
-
- const char *output_corefile_name = argv[1];
- std::string empty_uuidstr = "00000000-0000-0000-0000-000000000000";
-
- // First add all the load commands / payload so we can figure out how large
- // the load commands will actually be.
- load_commands.push_back(lc_thread_load_command(cputype));
-
- add_lc_note_main_bin_spec_load_command(load_commands, payload, 0,
- empty_uuidstr, 0, UINT64_MAX);
- for (int i = 1; i < input_filenames.size(); i++) {
- add_lc_note_load_binary_load_command(load_commands, payload, 0,
- empty_uuidstr, 0, UINT64_MAX);
- }
-
- for (int i = 0; i < input_filenames.size(); i++) {
- add_lc_segment(load_commands, payload, 0, 0, 0);
- }
-
- int size_of_load_commands = 0;
- for (const auto &lc : load_commands)
- size_of_load_commands += lc.size();
-
- int size_of_header_and_load_cmds =
- sizeof(struct mach_header_64) + size_of_load_commands;
-
- // Erase the load commands / payload now that we know how much space is
- // needed, redo it.
- load_commands.clear();
- payload.clear();
-
- // Push the LC_THREAD load command.
- load_commands.push_back(lc_thread_load_command(main_binary_cputype));
-
- const off_t payload_offset = size_of_header_and_load_cmds;
-
- add_lc_note_main_bin_spec_load_command(load_commands, payload, payload_offset,
- empty_uuidstr, input_filevmaddrs[0],
- UINT64_MAX);
-
- for (int i = 1; i < input_filenames.size(); i++) {
- add_lc_note_load_binary_load_command(load_commands, payload, payload_offset,
- empty_uuidstr, input_filevmaddrs[i],
- UINT64_MAX);
- }
-
- for (int i = 0; i < input_filenames.size(); i++) {
- add_lc_segment(load_commands, payload, payload_offset, input_filevmaddrs[i],
- input_filesizes[i]);
-
- // Copy the contents of the binary into payload.
- int fd = open(input_filenames[i].c_str(), O_RDONLY);
- if (fd == -1) {
- fprintf(stderr, "Unable to open %s for reading\n",
- input_filenames[i].c_str());
- exit(1);
- }
- std::vector<uint8_t> binary_contents;
- for (int j = 0; j < input_filesizes[i]; j++) {
- uint8_t byte;
- read(fd, &byte, 1);
- binary_contents.push_back(byte);
- }
- close(fd);
-
- size_t cur_payload_size = payload.size();
- payload.resize(cur_payload_size + binary_contents.size());
- slide_macho_binary(binary_contents, input_slides[i]);
- memcpy(payload.data() + cur_payload_size, binary_contents.data(),
- binary_contents.size());
- }
-
- struct mach_header_64 mh;
- mh.magic = MH_MAGIC_64;
- mh.cputype = cputype;
-
- mh.cpusubtype = cpusubtype;
- mh.filetype = MH_CORE;
- mh.ncmds = load_commands.size();
- mh.sizeofcmds = size_of_load_commands;
- mh.flags = 0;
- mh.reserved = 0;
-
- FILE *f = fopen(output_corefile_name, "w");
-
- if (f == nullptr) {
- fprintf(stderr, "Unable to open file %s for writing\n",
- output_corefile_name);
- exit(1);
- }
-
- fwrite(&mh, sizeof(mh), 1, f);
-
- for (const auto &lc : load_commands)
- fwrite(lc.data(), lc.size(), 1, f);
-
- fwrite(payload.data(), payload.size(), 1, f);
-
- fclose(f);
-}
diff --git a/lldb/test/API/macosx/lc-note/multiple-binary-corefile/main.c b/lldb/test/API/macosx/lc-note/multiple-binary-corefile/main.c
deleted file mode 100644
index eaab873b53e4..000000000000
--- a/lldb/test/API/macosx/lc-note/multiple-binary-corefile/main.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <stdio.h>
-int one();
-int two();
-int main() {
- puts("this is the standalone binary test program");
- return one() + two();
-}
diff --git a/lldb/test/API/macosx/lc-note/multiple-binary-corefile/one.c b/lldb/test/API/macosx/lc-note/multiple-binary-corefile/one.c
deleted file mode 100644
index 6e8fe4ad5ff7..000000000000
--- a/lldb/test/API/macosx/lc-note/multiple-binary-corefile/one.c
+++ /dev/null
@@ -1 +0,0 @@
-int one() { return 5; }
diff --git a/lldb/test/API/macosx/lc-note/multiple-binary-corefile/two.c b/lldb/test/API/macosx/lc-note/multiple-binary-corefile/two.c
deleted file mode 100644
index f44baa69c293..000000000000
--- a/lldb/test/API/macosx/lc-note/multiple-binary-corefile/two.c
+++ /dev/null
@@ -1 +0,0 @@
-int two() { return 10; }
More information about the lldb-commits
mailing list