Skip to content

Commit 4043026

Browse files
authored
Merge pull request #7243 from jasonmolenda/cp/qhostinfo-lcnote-multiple-address-bits-plus-uuid-in-lowmemory-corefile-1013-3
Cp/qhostinfo lcnote multiple address bits plus UUID in lowmemory corefile 1013 3
2 parents f931f17 + 90067ac commit 4043026

File tree

12 files changed

+236
-31
lines changed

12 files changed

+236
-31
lines changed

lldb/docs/lldb-gdb-remote.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,14 @@ addressing_bits: optional, specifies how many bits in addresses are
978978
v8.3 ABIs that use pointer authentication, so lldb
979979
knows which bits to clear/set to get the actual
980980
addresses.
981+
low_mem_addressing_bits: optional, specifies how many bits in
982+
addresses in low memory are significant for addressing, base 10.
983+
AArch64 can have different page table setups for low and high
984+
memory, and therefore a different number of bits used for addressing.
985+
high_mem_addressing_bits: optional, specifies how many bits in
986+
addresses in high memory are significant for addressing, base 10.
987+
AArch64 can have different page table setups for low and high
988+
memory, and therefore a different number of bits used for addressing.
981989

982990
//----------------------------------------------------------------------
983991
// "qGDBServerVersion"

lldb/include/lldb/Symbol/ObjectFile.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "lldb/Core/PluginInterface.h"
1515
#include "lldb/Symbol/Symtab.h"
1616
#include "lldb/Symbol/UnwindTable.h"
17+
#include "lldb/Utility/AddressableBits.h"
1718
#include "lldb/Utility/DataExtractor.h"
1819
#include "lldb/Utility/Endian.h"
1920
#include "lldb/Utility/FileSpec.h"
@@ -517,13 +518,18 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
517518

518519
/// Some object files may have the number of bits used for addressing
519520
/// embedded in them, e.g. a Mach-O core file using an LC_NOTE. These
520-
/// object files can return the address mask that should be used in
521-
/// the Process.
521+
/// object files can return an AddressableBits object that can can be
522+
/// used to set the address masks in the Process.
523+
///
524+
/// \param[out] address_bits
525+
/// Can be used to set the Process address masks.
526+
///
522527
/// \return
523-
/// The mask will have bits set which aren't used for addressing --
524-
/// typically, the high bits.
525-
/// Zero is returned when no address bits mask is available.
526-
virtual lldb::addr_t GetAddressMask() { return 0; }
528+
/// Returns true if addressable bits metadata was found.
529+
virtual bool GetAddressableBits(lldb_private::AddressableBits &address_bits) {
530+
address_bits.Clear();
531+
return false;
532+
}
527533

528534
/// When the ObjectFile is a core file, lldb needs to locate the "binary" in
529535
/// the core file. lldb can iterate over the pages looking for a valid
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//===-- AddressableBits.h ---------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_UTILITY_ADDRESSABLEBITS_H
10+
#define LLDB_UTILITY_ADDRESSABLEBITS_H
11+
12+
#include "lldb/lldb-forward.h"
13+
14+
namespace lldb_private {
15+
16+
/// \class AddressableBits AddressableBits.h "lldb/Core/AddressableBits.h"
17+
/// A class which holds the metadata from a remote stub/corefile note
18+
/// about how many bits are used for addressing on this target.
19+
///
20+
class AddressableBits {
21+
public:
22+
AddressableBits() : m_low_memory_addr_bits(0), m_high_memory_addr_bits(0) {}
23+
24+
/// When a single value is available for the number of bits.
25+
void SetAddressableBits(uint32_t addressing_bits);
26+
27+
/// When we have separate values for low memory addresses and high memory
28+
/// addresses.
29+
void SetAddressableBits(uint32_t lowmem_addressing_bits,
30+
uint32_t highmem_addressing_bits);
31+
32+
void SetProcessMasks(lldb_private::Process &process);
33+
34+
void Clear();
35+
36+
private:
37+
uint32_t m_low_memory_addr_bits;
38+
uint32_t m_high_memory_addr_bits;
39+
};
40+
41+
} // namespace lldb_private
42+
43+
#endif // LLDB_UTILITY_ADDRESSABLEBITS_H

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

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5533,8 +5533,9 @@ std::string ObjectFileMachO::GetIdentifierString() {
55335533
return result;
55345534
}
55355535

5536-
addr_t ObjectFileMachO::GetAddressMask() {
5537-
addr_t mask = 0;
5536+
bool ObjectFileMachO::GetAddressableBits(AddressableBits &address_bits) {
5537+
address_bits.Clear();
5538+
55385539
Log *log(GetLog(LLDBLog::Process));
55395540
ModuleSP module_sp(GetModule());
55405541
if (module_sp) {
@@ -5561,21 +5562,32 @@ addr_t ObjectFileMachO::GetAddressMask() {
55615562
if (version == 3) {
55625563
uint32_t num_addr_bits = m_data.GetU32_unchecked(&offset);
55635564
if (num_addr_bits != 0) {
5564-
mask = ~((1ULL << num_addr_bits) - 1);
5565+
address_bits.SetAddressableBits(num_addr_bits);
55655566
}
55665567
LLDB_LOGF(log,
5567-
"LC_NOTE 'addrable bits' found, value %d bits, "
5568-
"mask 0x%" PRIx64,
5569-
num_addr_bits, mask);
5570-
break;
5568+
"LC_NOTE 'addrable bits' v3 found, value %d "
5569+
"bits",
5570+
num_addr_bits);
5571+
return true;
5572+
}
5573+
if (version == 4) {
5574+
uint32_t lo_addr_bits = m_data.GetU32_unchecked(&offset);
5575+
uint32_t hi_addr_bits = m_data.GetU32_unchecked(&offset);
5576+
5577+
address_bits.SetAddressableBits(lo_addr_bits, hi_addr_bits);
5578+
LLDB_LOGF(log,
5579+
"LC_NOTE 'addrable bits' v4 found, value %d & %d bits",
5580+
lo_addr_bits, hi_addr_bits);
5581+
5582+
return true;
55715583
}
55725584
}
55735585
}
55745586
}
55755587
offset = cmd_offset + lc.cmdsize;
55765588
}
55775589
}
5578-
return mask;
5590+
return false;
55795591
}
55805592

55815593
bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value,
@@ -6783,10 +6795,12 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
67836795
addrable_bits_lcnote_up->name = "addrable bits";
67846796
addrable_bits_lcnote_up->payload_file_offset = file_offset;
67856797
int bits = std::bitset<64>(~address_mask).count();
6786-
addrable_bits_lcnote_up->payload.PutHex32(3); // version
6798+
addrable_bits_lcnote_up->payload.PutHex32(4); // version
6799+
addrable_bits_lcnote_up->payload.PutHex32(
6800+
bits); // # of bits used for low addresses
67876801
addrable_bits_lcnote_up->payload.PutHex32(
6788-
bits); // # of bits used for addressing
6789-
addrable_bits_lcnote_up->payload.PutHex64(0); // unused
6802+
bits); // # of bits used for high addresses
6803+
addrable_bits_lcnote_up->payload.PutHex32(0); // reserved
67906804

67916805
file_offset += addrable_bits_lcnote_up->payload.GetSize();
67926806

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ class ObjectFileMachO : public lldb_private::ObjectFile {
121121

122122
std::string GetIdentifierString() override;
123123

124-
lldb::addr_t GetAddressMask() override;
124+
bool GetAddressableBits(lldb_private::AddressableBits &address_bits) override;
125125

126126
bool GetCorefileMainBinaryInfo(lldb::addr_t &value, bool &value_is_offset,
127127
lldb_private::UUID &uuid,

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

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,7 +1260,15 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
12601260
if (!value.getAsInteger(0, pointer_byte_size))
12611261
++num_keys_decoded;
12621262
} else if (name.equals("addressing_bits")) {
1263-
if (!value.getAsInteger(0, m_addressing_bits))
1263+
if (!value.getAsInteger(0, m_low_mem_addressing_bits)) {
1264+
m_high_mem_addressing_bits = m_low_mem_addressing_bits;
1265+
++num_keys_decoded;
1266+
}
1267+
} else if (name.equals("high_mem_addressing_bits")) {
1268+
if (!value.getAsInteger(0, m_high_mem_addressing_bits))
1269+
++num_keys_decoded;
1270+
} else if (name.equals("low_mem_addressing_bits")) {
1271+
if (!value.getAsInteger(0, m_low_mem_addressing_bits))
12641272
++num_keys_decoded;
12651273
} else if (name.equals("os_version") ||
12661274
name.equals("version")) // Older debugserver binaries used
@@ -1404,11 +1412,19 @@ GDBRemoteCommunicationClient::GetHostArchitecture() {
14041412
return m_host_arch;
14051413
}
14061414

1407-
uint32_t GDBRemoteCommunicationClient::GetAddressingBits() {
1415+
bool GDBRemoteCommunicationClient::GetAddressableBits(
1416+
lldb_private::AddressableBits &addressable_bits) {
1417+
addressable_bits.Clear();
14081418
if (m_qHostInfo_is_valid == eLazyBoolCalculate)
14091419
GetHostInfo();
1410-
return m_addressing_bits;
1420+
if (m_low_mem_addressing_bits != 0 || m_high_mem_addressing_bits != 0) {
1421+
addressable_bits.SetAddressableBits(m_low_mem_addressing_bits,
1422+
m_high_mem_addressing_bits);
1423+
return true;
1424+
}
1425+
return false;
14111426
}
1427+
14121428
seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
14131429
if (m_qHostInfo_is_valid == eLazyBoolCalculate)
14141430
GetHostInfo();

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <vector>
1919

2020
#include "lldb/Host/File.h"
21+
#include "lldb/Utility/AddressableBits.h"
2122
#include "lldb/Utility/ArchSpec.h"
2223
#include "lldb/Utility/GDBRemote.h"
2324
#include "lldb/Utility/ProcessInfo.h"
@@ -237,7 +238,7 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
237238

238239
ArchSpec GetSystemArchitecture();
239240

240-
uint32_t GetAddressingBits();
241+
bool GetAddressableBits(lldb_private::AddressableBits &addressable_bits);
241242

242243
bool GetHostname(std::string &s);
243244

@@ -580,7 +581,8 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
580581
lldb::tid_t m_curr_tid_run = LLDB_INVALID_THREAD_ID;
581582

582583
uint32_t m_num_supported_hardware_watchpoints = 0;
583-
uint32_t m_addressing_bits = 0;
584+
uint32_t m_low_mem_addressing_bits = 0;
585+
uint32_t m_high_mem_addressing_bits = 0;
584586

585587
ArchSpec m_host_arch;
586588
ArchSpec m_process_arch;

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -892,10 +892,9 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
892892
process_arch.GetTriple().getTriple());
893893
}
894894

895-
if (int addressable_bits = m_gdb_comm.GetAddressingBits()) {
896-
lldb::addr_t address_mask = ~((1ULL << addressable_bits) - 1);
897-
SetCodeAddressMask(address_mask);
898-
SetDataAddressMask(address_mask);
895+
AddressableBits addressable_bits;
896+
if (m_gdb_comm.GetAddressableBits(addressable_bits)) {
897+
addressable_bits.SetProcessMasks(*this);
899898
}
900899

901900
if (process_arch.IsValid()) {

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

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@
2828
#include "lldb/Utility/LLDBLog.h"
2929
#include "lldb/Utility/Log.h"
3030
#include "lldb/Utility/State.h"
31+
#include "lldb/Utility/UUID.h"
3132

3233
#include "ProcessMachCore.h"
3334
#include "Plugins/Process/Utility/StopInfoMachException.h"
3435
#include "ThreadMachCore.h"
36+
#include "Utility/UuidCompatibility.h"
3537

3638
// Needed for the plug-in names for the dynamic loaders.
3739
#include "lldb/Host/SafeMachO.h"
@@ -223,6 +225,66 @@ void ProcessMachCore::CreateMemoryRegions() {
223225
}
224226
}
225227

228+
// Some corefiles have a UUID stored in a low memory
229+
// address. We inspect a set list of addresses for
230+
// the characters 'uuid' and 16 bytes later there will
231+
// be a uuid_t UUID. If we can find a binary that
232+
// matches the UUID, it is loaded with no slide in the target.
233+
bool ProcessMachCore::LoadBinaryViaLowmemUUID() {
234+
Log *log(GetLog(LLDBLog::DynamicLoader | LLDBLog::Process));
235+
ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
236+
237+
uint64_t lowmem_uuid_addresses[] = {0x2000204, 0x1000204, 0x1000020, 0x4204,
238+
0x1204, 0x1020, 0x4020, 0xc00,
239+
0xC0, 0};
240+
241+
for (uint64_t addr : lowmem_uuid_addresses) {
242+
const VMRangeToFileOffset::Entry *core_memory_entry =
243+
m_core_aranges.FindEntryThatContains(addr);
244+
if (core_memory_entry) {
245+
const addr_t offset = addr - core_memory_entry->GetRangeBase();
246+
const addr_t bytes_left = core_memory_entry->GetRangeEnd() - addr;
247+
// (4-bytes 'uuid' + 12 bytes pad for align + 16 bytes uuid_t) == 32 bytes
248+
if (bytes_left >= 32) {
249+
char strbuf[4];
250+
if (core_objfile->CopyData(
251+
core_memory_entry->data.GetRangeBase() + offset, 4, &strbuf) &&
252+
strncmp("uuid", (char *)&strbuf, 4) == 0) {
253+
uuid_t uuid_bytes;
254+
if (core_objfile->CopyData(core_memory_entry->data.GetRangeBase() +
255+
offset + 16,
256+
sizeof(uuid_t), uuid_bytes)) {
257+
UUID uuid(uuid_bytes, sizeof(uuid_t));
258+
if (uuid.IsValid()) {
259+
LLDB_LOGF(log,
260+
"ProcessMachCore::LoadBinaryViaLowmemUUID: found "
261+
"binary uuid %s at low memory address 0x%" PRIx64,
262+
uuid.GetAsString().c_str(), addr);
263+
// We have no address specified, only a UUID. Load it at the file
264+
// address.
265+
const bool value_is_offset = true;
266+
const bool force_symbol_search = true;
267+
const bool notify = true;
268+
const bool set_address_in_target = true;
269+
const bool allow_memory_image_last_resort = false;
270+
if (DynamicLoader::LoadBinaryWithUUIDAndAddress(
271+
this, llvm::StringRef(), uuid, 0, value_is_offset,
272+
force_symbol_search, notify, set_address_in_target,
273+
allow_memory_image_last_resort)) {
274+
m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
275+
}
276+
// We found metadata saying which binary should be loaded; don't
277+
// try an exhaustive search.
278+
return true;
279+
}
280+
}
281+
}
282+
}
283+
}
284+
}
285+
return false;
286+
}
287+
226288
bool ProcessMachCore::LoadBinariesViaMetadata() {
227289
Log *log(GetLog(LLDBLog::DynamicLoader | LLDBLog::Process));
228290
ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
@@ -338,6 +400,9 @@ bool ProcessMachCore::LoadBinariesViaMetadata() {
338400
m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
339401
}
340402

403+
if (!found_binary_spec_in_metadata && LoadBinaryViaLowmemUUID())
404+
found_binary_spec_in_metadata = true;
405+
341406
// LoadCoreFileImges may have set the dynamic loader, e.g. in
342407
// PlatformDarwinKernel::LoadPlatformBinaryAndSetup().
343408
// If we now have a dynamic loader, save its name so we don't
@@ -509,10 +574,9 @@ Status ProcessMachCore::DoLoadCore() {
509574

510575
CleanupMemoryRegionPermissions();
511576

512-
addr_t address_mask = core_objfile->GetAddressMask();
513-
if (address_mask != 0) {
514-
SetCodeAddressMask(address_mask);
515-
SetDataAddressMask(address_mask);
577+
AddressableBits addressable_bits;
578+
if (core_objfile->GetAddressableBits(addressable_bits)) {
579+
addressable_bits.SetProcessMasks(*this);
516580
}
517581
return error;
518582
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ class ProcessMachCore : public lldb_private::PostMortemProcess {
8787
private:
8888
void CreateMemoryRegions();
8989

90+
bool LoadBinaryViaLowmemUUID();
91+
9092
/// \return
9193
/// True if any metadata were found indicating the binary that should
9294
/// be loaded, regardless of whether the specified binary could be found.

0 commit comments

Comments
 (0)