Skip to content

Commit be4d0b2

Browse files
committed
Fix a few bugs with Mach-O corefile loading, plus perf
In ProcessMachCore::LoadBinariesViaMetadata(), if we did load some binaries via metadata in the core file, don't then search for a userland dyld in the corefile / kernel and throw away that binary list. Also fix a little bug with correctly recognizing corefiles using a `main bin spec` LC_NOTE that explicitly declare that this is a userland corefile. LocateSymbolFileMacOSX.cpp's Symbols::DownloadObjectAndSymbolFile clarify the comments on how the force_lookup and how the dbgshell_command local both have the same effect. In PlatformDarwinKernel::LoadPlatformBinaryAndSetup, don't log a message unless we actually found a kernel fileset. Reorganize ObjectFileMachO::LoadCoreFileImages so that it delegates binary searching to DynamicLoader::LoadBinaryWithUUIDAndAddress and doesn't duplicate those searches. For searches that fail, we would perform them multiple times in both methods. When we have the mach-o segment vmaddrs for a binary, don't let LoadBinaryWithUUIDAndAddress load the binary first at its mach-o header address in the Target; we'll load the segments at the correct addresses individually later in this method. DynamicLoaderDarwin::ImageInfo::PutToLog fix a LLDB_LOG logging formatter. In DynamicLoader::LoadBinaryWithUUIDAndAddress, instead of using Target::GetOrCreateModule as a way to find a binary already registered in lldb's global module cache (and implicitly add it to the Target image list), use ModuleList::GetSharedModule() which only searches the global module cache, don't add it to the Target. We may not want to add an unstripped binary to the Target. Add a call to Symbols::DownloadObjectAndSymbolFile() even if "force_symbol_search" isn't set -- this will turn into a DebugSymbols call / Spotlight search on a macOS system, which we want. Only set the Module's LoadAddress if the caller asked us to do that. Differential Revision: https://reviews.llvm.org/D150928 rdar://109186357 (cherry picked from commit 48a12ae)
1 parent 0a3c328 commit be4d0b2

File tree

8 files changed

+119
-128
lines changed

8 files changed

+119
-128
lines changed

lldb/include/lldb/Target/DynamicLoader.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,21 @@ class DynamicLoader : public PluginInterface {
256256
/// to the Target. The caller may prefer to batch up these when loading
257257
/// multiple binaries.
258258
///
259+
/// \param[in] set_address_in_target
260+
/// Whether the address of the binary should be set in the Target if it
261+
/// is added. The caller may want to set the section addresses
262+
/// individually, instead of loading the binary the entire based on the
263+
/// start address or slide. The caller is responsible for setting the
264+
/// load address for the binary or its segments in the Target if it passes
265+
/// true.
266+
///
259267
/// \return
260268
/// Returns a shared pointer for the Module that has been added.
261-
static lldb::ModuleSP LoadBinaryWithUUIDAndAddress(
262-
Process *process, llvm::StringRef name, UUID uuid, lldb::addr_t value,
263-
bool value_is_offset, bool force_symbol_search, bool notify);
269+
static lldb::ModuleSP
270+
LoadBinaryWithUUIDAndAddress(Process *process, llvm::StringRef name,
271+
UUID uuid, lldb::addr_t value,
272+
bool value_is_offset, bool force_symbol_search,
273+
bool notify, bool set_address_in_target);
264274

265275
/// Get information about the shared cache for a process, if possible.
266276
///

lldb/source/Core/DynamicLoader.cpp

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -187,38 +187,60 @@ static ModuleSP ReadUnnamedMemoryModule(Process *process, addr_t addr,
187187

188188
ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
189189
Process *process, llvm::StringRef name, UUID uuid, addr_t value,
190-
bool value_is_offset, bool force_symbol_search, bool notify) {
190+
bool value_is_offset, bool force_symbol_search, bool notify,
191+
bool set_address_in_target) {
191192
ModuleSP memory_module_sp;
192193
ModuleSP module_sp;
193194
PlatformSP platform_sp = process->GetTarget().GetPlatform();
194195
Target &target = process->GetTarget();
195196
Status error;
196-
ModuleSpec module_spec;
197-
module_spec.GetUUID() = uuid;
198197

199198
if (!uuid.IsValid() && !value_is_offset) {
200199
memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
201200

202201
if (memory_module_sp)
203202
uuid = memory_module_sp->GetUUID();
204203
}
204+
ModuleSpec module_spec;
205+
module_spec.GetUUID() = uuid;
206+
FileSpec name_filespec(name);
207+
if (FileSystem::Instance().Exists(name_filespec))
208+
module_spec.GetFileSpec() = name_filespec;
205209

206210
if (uuid.IsValid()) {
207-
ModuleSpec module_spec;
208-
module_spec.GetUUID() = uuid;
209-
211+
// Has lldb already seen a module with this UUID?
210212
if (!module_sp)
211-
module_sp = target.GetOrCreateModule(module_spec, false, &error);
213+
error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
214+
nullptr, nullptr);
215+
216+
// Can lldb's symbol/executable location schemes
217+
// find an executable and symbol file.
218+
if (!module_sp) {
219+
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
220+
module_spec.GetSymbolFileSpec() =
221+
Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
222+
ModuleSpec objfile_module_spec =
223+
Symbols::LocateExecutableObjectFile(module_spec);
224+
module_spec.GetFileSpec() = objfile_module_spec.GetFileSpec();
225+
if (FileSystem::Instance().Exists(module_spec.GetFileSpec()) &&
226+
FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec())) {
227+
module_sp = std::make_shared<Module>(module_spec);
228+
}
229+
}
212230

213231
// If we haven't found a binary, or we don't have a SymbolFile, see
214232
// if there is an external search tool that can find it.
215-
if (force_symbol_search &&
216-
(!module_sp || !module_sp->GetSymbolFileFileSpec())) {
217-
Symbols::DownloadObjectAndSymbolFile(module_spec, error, true);
233+
if (!module_sp || !module_sp->GetSymbolFileFileSpec()) {
234+
Symbols::DownloadObjectAndSymbolFile(module_spec, error,
235+
force_symbol_search);
218236
if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
219237
module_sp = std::make_shared<Module>(module_spec);
220238
}
221239
}
240+
241+
// If we only found the executable, create a Module based on that.
242+
if (!module_sp && FileSystem::Instance().Exists(module_spec.GetFileSpec()))
243+
module_sp = std::make_shared<Module>(module_spec);
222244
}
223245

224246
// If we couldn't find the binary anywhere else, as a last resort,
@@ -239,25 +261,34 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
239261
target.GetImages().AppendIfNeeded(module_sp, false);
240262

241263
bool changed = false;
242-
if (module_sp->GetObjectFile()) {
243-
if (value != LLDB_INVALID_ADDRESS) {
244-
LLDB_LOGF(log, "Loading binary UUID %s at %s 0x%" PRIx64,
245-
uuid.GetAsString().c_str(),
246-
value_is_offset ? "offset" : "address", value);
247-
module_sp->SetLoadAddress(target, value, value_is_offset, changed);
264+
if (set_address_in_target) {
265+
if (module_sp->GetObjectFile()) {
266+
if (value != LLDB_INVALID_ADDRESS) {
267+
LLDB_LOGF(log,
268+
"DynamicLoader::LoadBinaryWithUUIDAndAddress Loading "
269+
"binary UUID %s at %s 0x%" PRIx64,
270+
uuid.GetAsString().c_str(),
271+
value_is_offset ? "offset" : "address", value);
272+
module_sp->SetLoadAddress(target, value, value_is_offset, changed);
273+
} else {
274+
// No address/offset/slide, load the binary at file address,
275+
// offset 0.
276+
LLDB_LOGF(log,
277+
"DynamicLoader::LoadBinaryWithUUIDAndAddress Loading "
278+
"binary UUID %s at file address",
279+
uuid.GetAsString().c_str());
280+
module_sp->SetLoadAddress(target, 0, true /* value_is_slide */,
281+
changed);
282+
}
248283
} else {
249-
// No address/offset/slide, load the binary at file address,
250-
// offset 0.
251-
LLDB_LOGF(log, "Loading binary UUID %s at file address",
252-
uuid.GetAsString().c_str());
284+
// In-memory image, load at its true address, offset 0.
285+
LLDB_LOGF(log,
286+
"DynamicLoader::LoadBinaryWithUUIDAndAddress Loading binary "
287+
"UUID %s from memory at address 0x%" PRIx64,
288+
uuid.GetAsString().c_str(), value);
253289
module_sp->SetLoadAddress(target, 0, true /* value_is_slide */,
254290
changed);
255291
}
256-
} else {
257-
// In-memory image, load at its true address, offset 0.
258-
LLDB_LOGF(log, "Loading binary UUID %s from memory at address 0x%" PRIx64,
259-
uuid.GetAsString().c_str(), value);
260-
module_sp->SetLoadAddress(target, 0, true /* value_is_slide */, changed);
261292
}
262293

263294
if (notify) {

lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,7 @@ void DynamicLoaderDarwin::ImageInfo::PutToLog(Log *log) const {
811811
LLDB_LOG(log, "uuid={1} path='{2}' (UNLOADED)", uuid.GetAsString(),
812812
file_spec.GetPath());
813813
} else {
814-
LLDB_LOG(log, "address={0:x+16} uuid={2} path='{3}'", address,
814+
LLDB_LOG(log, "address={0:x+16} uuid={1} path='{2}'", address,
815815
uuid.GetAsString(), file_spec.GetPath());
816816
for (uint32_t i = 0; i < segments.size(); ++i)
817817
segments[i].PutToLog(log, slide);

lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp

Lines changed: 21 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -7055,62 +7055,22 @@ bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {
70557055
continue;
70567056
}
70577057

7058-
// If this binary is currently executing, we want to force a
7059-
// possibly expensive search for the binary and its dSYM.
7060-
if (image.currently_executing && image.uuid.IsValid()) {
7061-
ModuleSpec module_spec;
7062-
module_spec.GetUUID() = image.uuid;
7063-
Symbols::DownloadObjectAndSymbolFile(module_spec, error, true);
7064-
if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
7065-
module_sp = process.GetTarget().GetOrCreateModule(module_spec, false);
7066-
process.GetTarget().GetImages().AppendIfNeeded(module_sp,
7067-
false /* notify */);
7068-
}
7069-
}
7070-
7071-
// We have an address, that's the best way to discover the binary.
7072-
if (!module_sp && image.load_address != LLDB_INVALID_ADDRESS) {
7073-
module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress(
7074-
&process, image.filename, image.uuid, image.load_address,
7075-
false /* value_is_offset */, image.currently_executing,
7076-
false /* notify */);
7077-
if (module_sp) {
7078-
// We've already set the load address in the Target,
7079-
// don't do any more processing on this module.
7080-
added_modules.Append(module_sp, false /* notify */);
7081-
continue;
7082-
}
7058+
bool value_is_offset = image.load_address == LLDB_INVALID_ADDRESS;
7059+
uint64_t value = value_is_offset ? image.slide : image.load_address;
7060+
if (value_is_offset && value == LLDB_INVALID_ADDRESS) {
7061+
// We have neither address nor slide; so we will find the binary
7062+
// by UUID and load it at slide/offset 0.
7063+
value = 0;
70837064
}
70847065

7085-
// If we have a slide, we need to find the original binary
7086-
// by UUID, then we can apply the slide value.
7087-
if (!module_sp && image.uuid.IsValid() &&
7088-
image.slide != LLDB_INVALID_ADDRESS) {
7066+
// We have either a UUID, or we have a load address which
7067+
// and can try to read load commands and find a UUID.
7068+
if (image.uuid.IsValid() ||
7069+
(!value_is_offset && value != LLDB_INVALID_ADDRESS)) {
7070+
const bool set_load_address = image.segment_load_addresses.size() == 0;
70897071
module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress(
7090-
&process, image.filename, image.uuid, image.slide,
7091-
true /* value_is_offset */, image.currently_executing,
7092-
false /* notify */);
7093-
if (module_sp) {
7094-
// We've already set the load address in the Target,
7095-
// don't do any more processing on this module.
7096-
added_modules.Append(module_sp, false /* notify */);
7097-
continue;
7098-
}
7099-
}
7100-
7101-
// Try to find the binary by UUID or filename on the local
7102-
// filesystem or in lldb's global module cache.
7103-
if (!module_sp) {
7104-
Status error;
7105-
ModuleSpec module_spec;
7106-
if (image.uuid.IsValid())
7107-
module_spec.GetUUID() = image.uuid;
7108-
if (!image.filename.empty())
7109-
module_spec.GetFileSpec() = FileSpec(image.filename.c_str());
7110-
module_sp =
7111-
process.GetTarget().GetOrCreateModule(module_spec, false, &error);
7112-
process.GetTarget().GetImages().AppendIfNeeded(module_sp,
7113-
false /* notify */);
7072+
&process, image.filename, image.uuid, value, value_is_offset,
7073+
image.currently_executing, false /* notify */, set_load_address);
71147074
}
71157075

71167076
// We have a ModuleSP to load in the Target. Load it at the
@@ -7124,7 +7084,8 @@ bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {
71247084
std::string uuidstr = image.uuid.GetAsString();
71257085
log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
71267086
"UUID %s with section load addresses",
7127-
image.filename.c_str(), uuidstr.c_str());
7087+
module_sp->GetFileSpec().GetPath().c_str(),
7088+
uuidstr.c_str());
71287089
}
71297090
for (auto name_vmaddr_tuple : image.segment_load_addresses) {
71307091
SectionList *sectlist = module_sp->GetObjectFile()->GetSectionList();
@@ -7137,39 +7098,17 @@ bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {
71377098
}
71387099
}
71397100
}
7140-
} else if (image.load_address != LLDB_INVALID_ADDRESS) {
7141-
if (log) {
7142-
std::string uuidstr = image.uuid.GetAsString();
7143-
log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
7144-
"UUID %s with load address 0x%" PRIx64,
7145-
image.filename.c_str(), uuidstr.c_str(),
7146-
image.load_address);
7147-
}
7148-
const bool address_is_slide = false;
7149-
bool changed = false;
7150-
module_sp->SetLoadAddress(process.GetTarget(), image.load_address,
7151-
address_is_slide, changed);
7152-
} else if (image.slide != 0) {
7153-
if (log) {
7154-
std::string uuidstr = image.uuid.GetAsString();
7155-
log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
7156-
"UUID %s with slide amount 0x%" PRIx64,
7157-
image.filename.c_str(), uuidstr.c_str(), image.slide);
7158-
}
7159-
const bool address_is_slide = true;
7160-
bool changed = false;
7161-
module_sp->SetLoadAddress(process.GetTarget(), image.slide,
7162-
address_is_slide, changed);
71637101
} else {
71647102
if (log) {
71657103
std::string uuidstr = image.uuid.GetAsString();
71667104
log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
7167-
"UUID %s at its file address, no slide applied",
7168-
image.filename.c_str(), uuidstr.c_str());
7105+
"UUID %s with %s 0x%" PRIx64,
7106+
module_sp->GetFileSpec().GetPath().c_str(),
7107+
uuidstr.c_str(),
7108+
value_is_offset ? "slide" : "load address", value);
71697109
}
7170-
const bool address_is_slide = true;
7171-
bool changed = false;
7172-
module_sp->SetLoadAddress(process.GetTarget(), 0, address_is_slide,
7110+
bool changed;
7111+
module_sp->SetLoadAddress(process.GetTarget(), value, value_is_offset,
71737112
changed);
71747113
}
71757114
}

lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -959,14 +959,14 @@ bool PlatformDarwinKernel::LoadPlatformBinaryAndSetup(Process *process,
959959

960960
addr_t actual_address = find_kernel_in_macho_fileset(process, input_addr);
961961

962+
if (actual_address == LLDB_INVALID_ADDRESS)
963+
return false;
964+
962965
LLDB_LOGF(log,
963966
"PlatformDarwinKernel::%s check address 0x%" PRIx64 " for "
964967
"a macho fileset, got back kernel address 0x%" PRIx64,
965968
__FUNCTION__, input_addr, actual_address);
966969

967-
if (actual_address == LLDB_INVALID_ADDRESS)
968-
return false;
969-
970970
// We have a xnu kernel binary, this is a kernel debug session.
971971
// Set the Target's Platform to be PlatformDarwinKernel, and the
972972
// Process' DynamicLoader to be DynamicLoaderDarwinKernel.

lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -993,9 +993,11 @@ void ProcessGDBRemote::LoadStubBinaries() {
993993
if (standalone_uuid.IsValid()) {
994994
const bool force_symbol_search = true;
995995
const bool notify = true;
996+
const bool set_address_in_target = true;
996997
DynamicLoader::LoadBinaryWithUUIDAndAddress(
997998
this, "", standalone_uuid, standalone_value,
998-
standalone_value_is_offset, force_symbol_search, notify);
999+
standalone_value_is_offset, force_symbol_search, notify,
1000+
set_address_in_target);
9991001
}
10001002
}
10011003

@@ -1023,10 +1025,11 @@ void ProcessGDBRemote::LoadStubBinaries() {
10231025
continue;
10241026

10251027
const bool force_symbol_search = true;
1028+
const bool set_address_in_target = true;
10261029
// Second manually load this binary into the Target.
1027-
DynamicLoader::LoadBinaryWithUUIDAndAddress(this, llvm::StringRef(), uuid,
1028-
addr, value_is_slide,
1029-
force_symbol_search, notify);
1030+
DynamicLoader::LoadBinaryWithUUIDAndAddress(
1031+
this, llvm::StringRef(), uuid, addr, value_is_slide,
1032+
force_symbol_search, notify, set_address_in_target);
10301033
}
10311034
}
10321035
}

lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -252,20 +252,20 @@ void ProcessMachCore::LoadBinariesViaMetadata() {
252252
m_mach_kernel_addr = objfile_binary_value;
253253
m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
254254
found_main_binary_definitively = true;
255+
} else if (type == ObjectFile::eBinaryTypeUser) {
256+
m_dyld_addr = objfile_binary_value;
257+
m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
255258
} else {
256259
const bool force_symbol_search = true;
257260
const bool notify = true;
261+
const bool set_address_in_target = true;
258262
if (DynamicLoader::LoadBinaryWithUUIDAndAddress(
259263
this, llvm::StringRef(), objfile_binary_uuid,
260264
objfile_binary_value, objfile_binary_value_is_offset,
261-
force_symbol_search, notify)) {
265+
force_symbol_search, notify, set_address_in_target)) {
262266
found_main_binary_definitively = true;
263267
m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
264268
}
265-
if (type == ObjectFile::eBinaryTypeUser) {
266-
m_dyld_addr = objfile_binary_value;
267-
m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
268-
}
269269
}
270270
}
271271

@@ -314,9 +314,11 @@ void ProcessMachCore::LoadBinariesViaMetadata() {
314314
const bool value_is_offset = false;
315315
const bool force_symbol_search = true;
316316
const bool notify = true;
317+
const bool set_address_in_target = true;
317318
if (DynamicLoader::LoadBinaryWithUUIDAndAddress(
318319
this, llvm::StringRef(), ident_uuid, ident_binary_addr,
319-
value_is_offset, force_symbol_search, notify)) {
320+
value_is_offset, force_symbol_search, notify,
321+
set_address_in_target)) {
320322
found_main_binary_definitively = true;
321323
m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
322324
}
@@ -325,7 +327,10 @@ void ProcessMachCore::LoadBinariesViaMetadata() {
325327

326328
// Finally, load any binaries noted by "load binary" LC_NOTEs in the
327329
// corefile
328-
core_objfile->LoadCoreFileImages(*this);
330+
if (core_objfile->LoadCoreFileImages(*this)) {
331+
found_main_binary_definitively = true;
332+
m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
333+
}
329334

330335
// LoadCoreFileImges may have set the dynamic loader, e.g. in
331336
// PlatformDarwinKernel::LoadPlatformBinaryAndSetup().

0 commit comments

Comments
 (0)