Skip to content

Commit bcf654c

Browse files
authored
[lldb] Fix loading UUIDs from ELF headers. (llvm#117028)
A previous patch added the ability to load UUID from ELF headers using the program header and finding PT_NOTE entries. The fix would attempt to read the data for the PT_NOTE from memory, but it didn't slide the address so it ended up only working for the main executable if it wasn't moved in memory. This patch slides the address and adds logging. All processes map the ELF header + program headers + some program header contents into memory. The program header for the `PT_NOTE` entries are mapped, but the p_vaddr doesn't get relocated and is relative to the load address of the ELF header. So we take a "p_vaddr" (file address) and convert it into a load address in the process so we can load the correct bytes that contain the `PT_NOTE` contents.
1 parent 926a71f commit bcf654c

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp

+15-5
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ Status ProcessElfCore::DoLoadCore() {
224224
ArchSpec core_arch(m_core_module_sp->GetArchitecture());
225225
target_arch.MergeFrom(core_arch);
226226
GetTarget().SetArchitecture(target_arch);
227-
227+
228228
SetUnixSignals(UnixSignals::Create(GetArchitecture()));
229229

230230
// Ensure we found at least one thread that was stopped on a signal.
@@ -276,8 +276,13 @@ Status ProcessElfCore::DoLoadCore() {
276276
}
277277

278278
void ProcessElfCore::UpdateBuildIdForNTFileEntries() {
279+
Log *log = GetLog(LLDBLog::Process);
279280
for (NT_FILE_Entry &entry : m_nt_file_entries) {
280281
entry.uuid = FindBuidIdInCoreMemory(entry.start);
282+
if (log && entry.uuid.IsValid())
283+
LLDB_LOGF(log, "%s found UUID @ %16.16" PRIx64 ": %s \"%s\"",
284+
__FUNCTION__, entry.start, entry.uuid.GetAsString().c_str(),
285+
entry.path.c_str());
281286
}
282287
}
283288

@@ -875,7 +880,7 @@ llvm::Error ProcessElfCore::parseOpenBSDNotes(llvm::ArrayRef<CoreNote> notes) {
875880
/// - NT_SIGINFO - Information about the signal that terminated the process
876881
/// - NT_AUXV - Process auxiliary vector
877882
/// - NT_FILE - Files mapped into memory
878-
///
883+
///
879884
/// Additionally, for each thread in the process the core file will contain at
880885
/// least the NT_PRSTATUS note, containing the thread id and general purpose
881886
/// registers. It may include additional notes for other register sets (floating
@@ -1034,15 +1039,20 @@ UUID ProcessElfCore::FindBuidIdInCoreMemory(lldb::addr_t address) {
10341039
std::vector<uint8_t> note_bytes;
10351040
note_bytes.resize(program_header.p_memsz);
10361041

1037-
byte_read = ReadMemory(program_header.p_vaddr, note_bytes.data(),
1038-
program_header.p_memsz, error);
1042+
// We need to slide the address of the p_vaddr as these values don't get
1043+
// relocated in memory.
1044+
const lldb::addr_t vaddr = program_header.p_vaddr + address;
1045+
byte_read =
1046+
ReadMemory(vaddr, note_bytes.data(), program_header.p_memsz, error);
10391047
if (byte_read != program_header.p_memsz)
10401048
continue;
10411049
DataExtractor segment_data(note_bytes.data(), note_bytes.size(),
10421050
GetByteOrder(), addr_size);
10431051
auto notes_or_error = parseSegment(segment_data);
1044-
if (!notes_or_error)
1052+
if (!notes_or_error) {
1053+
llvm::consumeError(notes_or_error.takeError());
10451054
return invalid_uuid;
1055+
}
10461056
for (const CoreNote &note : *notes_or_error) {
10471057
if (note.info.n_namesz == 4 &&
10481058
note.info.n_type == llvm::ELF::NT_GNU_BUILD_ID &&

0 commit comments

Comments
 (0)