Skip to content

Commit 48a12ae

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
1 parent c7eb1b0 commit 48a12ae

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
@@ -808,7 +808,7 @@ void DynamicLoaderDarwin::ImageInfo::PutToLog(Log *log) const {
808808
LLDB_LOG(log, "uuid={1} path='{2}' (UNLOADED)", uuid.GetAsString(),
809809
file_spec.GetPath());
810810
} else {
811-
LLDB_LOG(log, "address={0:x+16} uuid={2} path='{3}'", address,
811+
LLDB_LOG(log, "address={0:x+16} uuid={1} path='{2}'", address,
812812
uuid.GetAsString(), file_spec.GetPath());
813813
for (uint32_t i = 0; i < segments.size(); ++i)
814814
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
@@ -6878,62 +6878,22 @@ bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {
68786878
continue;
68796879
}
68806880

6881-
// If this binary is currently executing, we want to force a
6882-
// possibly expensive search for the binary and its dSYM.
6883-
if (image.currently_executing && image.uuid.IsValid()) {
6884-
ModuleSpec module_spec;
6885-
module_spec.GetUUID() = image.uuid;
6886-
Symbols::DownloadObjectAndSymbolFile(module_spec, error, true);
6887-
if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
6888-
module_sp = process.GetTarget().GetOrCreateModule(module_spec, false);
6889-
process.GetTarget().GetImages().AppendIfNeeded(module_sp,
6890-
false /* notify */);
6891-
}
6892-
}
6893-
6894-
// We have an address, that's the best way to discover the binary.
6895-
if (!module_sp && image.load_address != LLDB_INVALID_ADDRESS) {
6896-
module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress(
6897-
&process, image.filename, image.uuid, image.load_address,
6898-
false /* value_is_offset */, image.currently_executing,
6899-
false /* notify */);
6900-
if (module_sp) {
6901-
// We've already set the load address in the Target,
6902-
// don't do any more processing on this module.
6903-
added_modules.Append(module_sp, false /* notify */);
6904-
continue;
6905-
}
6881+
bool value_is_offset = image.load_address == LLDB_INVALID_ADDRESS;
6882+
uint64_t value = value_is_offset ? image.slide : image.load_address;
6883+
if (value_is_offset && value == LLDB_INVALID_ADDRESS) {
6884+
// We have neither address nor slide; so we will find the binary
6885+
// by UUID and load it at slide/offset 0.
6886+
value = 0;
69066887
}
69076888

6908-
// If we have a slide, we need to find the original binary
6909-
// by UUID, then we can apply the slide value.
6910-
if (!module_sp && image.uuid.IsValid() &&
6911-
image.slide != LLDB_INVALID_ADDRESS) {
6889+
// We have either a UUID, or we have a load address which
6890+
// and can try to read load commands and find a UUID.
6891+
if (image.uuid.IsValid() ||
6892+
(!value_is_offset && value != LLDB_INVALID_ADDRESS)) {
6893+
const bool set_load_address = image.segment_load_addresses.size() == 0;
69126894
module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress(
6913-
&process, image.filename, image.uuid, image.slide,
6914-
true /* value_is_offset */, image.currently_executing,
6915-
false /* notify */);
6916-
if (module_sp) {
6917-
// We've already set the load address in the Target,
6918-
// don't do any more processing on this module.
6919-
added_modules.Append(module_sp, false /* notify */);
6920-
continue;
6921-
}
6922-
}
6923-
6924-
// Try to find the binary by UUID or filename on the local
6925-
// filesystem or in lldb's global module cache.
6926-
if (!module_sp) {
6927-
Status error;
6928-
ModuleSpec module_spec;
6929-
if (image.uuid.IsValid())
6930-
module_spec.GetUUID() = image.uuid;
6931-
if (!image.filename.empty())
6932-
module_spec.GetFileSpec() = FileSpec(image.filename.c_str());
6933-
module_sp =
6934-
process.GetTarget().GetOrCreateModule(module_spec, false, &error);
6935-
process.GetTarget().GetImages().AppendIfNeeded(module_sp,
6936-
false /* notify */);
6895+
&process, image.filename, image.uuid, value, value_is_offset,
6896+
image.currently_executing, false /* notify */, set_load_address);
69376897
}
69386898

69396899
// We have a ModuleSP to load in the Target. Load it at the
@@ -6947,7 +6907,8 @@ bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {
69476907
std::string uuidstr = image.uuid.GetAsString();
69486908
log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
69496909
"UUID %s with section load addresses",
6950-
image.filename.c_str(), uuidstr.c_str());
6910+
module_sp->GetFileSpec().GetPath().c_str(),
6911+
uuidstr.c_str());
69516912
}
69526913
for (auto name_vmaddr_tuple : image.segment_load_addresses) {
69536914
SectionList *sectlist = module_sp->GetObjectFile()->GetSectionList();
@@ -6960,39 +6921,17 @@ bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {
69606921
}
69616922
}
69626923
}
6963-
} else if (image.load_address != LLDB_INVALID_ADDRESS) {
6964-
if (log) {
6965-
std::string uuidstr = image.uuid.GetAsString();
6966-
log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
6967-
"UUID %s with load address 0x%" PRIx64,
6968-
image.filename.c_str(), uuidstr.c_str(),
6969-
image.load_address);
6970-
}
6971-
const bool address_is_slide = false;
6972-
bool changed = false;
6973-
module_sp->SetLoadAddress(process.GetTarget(), image.load_address,
6974-
address_is_slide, changed);
6975-
} else if (image.slide != 0) {
6976-
if (log) {
6977-
std::string uuidstr = image.uuid.GetAsString();
6978-
log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
6979-
"UUID %s with slide amount 0x%" PRIx64,
6980-
image.filename.c_str(), uuidstr.c_str(), image.slide);
6981-
}
6982-
const bool address_is_slide = true;
6983-
bool changed = false;
6984-
module_sp->SetLoadAddress(process.GetTarget(), image.slide,
6985-
address_is_slide, changed);
69866924
} else {
69876925
if (log) {
69886926
std::string uuidstr = image.uuid.GetAsString();
69896927
log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
6990-
"UUID %s at its file address, no slide applied",
6991-
image.filename.c_str(), uuidstr.c_str());
6928+
"UUID %s with %s 0x%" PRIx64,
6929+
module_sp->GetFileSpec().GetPath().c_str(),
6930+
uuidstr.c_str(),
6931+
value_is_offset ? "slide" : "load address", value);
69926932
}
6993-
const bool address_is_slide = true;
6994-
bool changed = false;
6995-
module_sp->SetLoadAddress(process.GetTarget(), 0, address_is_slide,
6933+
bool changed;
6934+
module_sp->SetLoadAddress(process.GetTarget(), value, value_is_offset,
69966935
changed);
69976936
}
69986937
}

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

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

953953
addr_t actual_address = find_kernel_in_macho_fileset(process, input_addr);
954954

955+
if (actual_address == LLDB_INVALID_ADDRESS)
956+
return false;
957+
955958
LLDB_LOGF(log,
956959
"PlatformDarwinKernel::%s check address 0x%" PRIx64 " for "
957960
"a macho fileset, got back kernel address 0x%" PRIx64,
958961
__FUNCTION__, input_addr, actual_address);
959962

960-
if (actual_address == LLDB_INVALID_ADDRESS)
961-
return false;
962-
963963
// We have a xnu kernel binary, this is a kernel debug session.
964964
// Set the Target's Platform to be PlatformDarwinKernel, and the
965965
// 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
@@ -995,9 +995,11 @@ void ProcessGDBRemote::LoadStubBinaries() {
995995
if (standalone_uuid.IsValid()) {
996996
const bool force_symbol_search = true;
997997
const bool notify = true;
998+
const bool set_address_in_target = true;
998999
DynamicLoader::LoadBinaryWithUUIDAndAddress(
9991000
this, "", standalone_uuid, standalone_value,
1000-
standalone_value_is_offset, force_symbol_search, notify);
1001+
standalone_value_is_offset, force_symbol_search, notify,
1002+
set_address_in_target);
10011003
}
10021004
}
10031005

@@ -1025,10 +1027,11 @@ void ProcessGDBRemote::LoadStubBinaries() {
10251027
continue;
10261028

10271029
const bool force_symbol_search = true;
1030+
const bool set_address_in_target = true;
10281031
// Second manually load this binary into the Target.
1029-
DynamicLoader::LoadBinaryWithUUIDAndAddress(this, llvm::StringRef(), uuid,
1030-
addr, value_is_slide,
1031-
force_symbol_search, notify);
1032+
DynamicLoader::LoadBinaryWithUUIDAndAddress(
1033+
this, llvm::StringRef(), uuid, addr, value_is_slide,
1034+
force_symbol_search, notify, set_address_in_target);
10321035
}
10331036
}
10341037
}

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)