LLDB mainline
ProcessElfCore.cpp
Go to the documentation of this file.
1//===-- ProcessElfCore.cpp ------------------------------------------------===//
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#include <algorithm>
10#include <cstdlib>
11
12#include <memory>
13#include <vector>
14
15#include "lldb/Core/Module.h"
18#include "lldb/Core/Section.h"
19#include "lldb/Target/ABI.h"
22#include "lldb/Target/Target.h"
26#include "lldb/Utility/Log.h"
27#include "lldb/Utility/State.h"
28
29#include "llvm/BinaryFormat/ELF.h"
30
36#include "ProcessElfCore.h"
37#include "ThreadElfCore.h"
38
39using namespace lldb_private;
40namespace ELF = llvm::ELF;
41
43
45 return "ELF core dump plug-in.";
46}
47
51
53 lldb::ListenerSP listener_sp,
54 const FileSpec *crash_file,
55 bool can_connect) {
56 lldb::ProcessSP process_sp;
57 if (crash_file && !can_connect) {
58 // Read enough data for an ELF32 header or ELF64 header Note: Here we care
59 // about e_type field only, so it is safe to ignore possible presence of
60 // the header extension.
61 const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr);
62
64 crash_file->GetPath(), header_size, 0);
65 if (data_sp && data_sp->GetByteSize() == header_size &&
66 elf::ELFHeader::MagicBytesMatch(data_sp->GetBytes())) {
67 elf::ELFHeader elf_header;
68 DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
69 lldb::offset_t data_offset = 0;
70 if (elf_header.Parse(data, &data_offset)) {
71 // Check whether we're dealing with a raw FreeBSD "full memory dump"
72 // ELF vmcore that needs to be handled via FreeBSDKernel plugin instead.
73 if (elf_header.e_ident[7] == 0xFF && elf_header.e_version == 0)
74 return process_sp;
75 if (elf_header.e_type == llvm::ELF::ET_CORE)
76 process_sp = std::make_shared<ProcessElfCore>(target_sp, listener_sp,
77 *crash_file);
78 }
79 }
80 }
81 return process_sp;
82}
83
85 bool plugin_specified_by_name) {
86 // For now we are just making sure the file exists for a given module
88 ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture());
89 core_module_spec.SetTarget(target_sp);
91 nullptr, nullptr));
92 if (m_core_module_sp) {
93 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
94 if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
95 return true;
96 }
97 }
98 return false;
99}
100
101// ProcessElfCore constructor
103 lldb::ListenerSP listener_sp,
104 const FileSpec &core_file)
105 : PostMortemProcess(target_sp, listener_sp, core_file), m_uuids() {}
106
107// Destructor
109 Clear();
110 // We need to call finalize on the process before destroying ourselves to
111 // make sure all of the broadcaster cleanup goes as planned. If we destruct
112 // this class, then Process::~Process() might have problems trying to fully
113 // destroy the broadcaster.
114 Finalize(true /* destructing */);
115}
116
118 const elf::ELFProgramHeader &header) {
119 const lldb::addr_t addr = header.p_vaddr;
120 FileRange file_range(header.p_offset, header.p_filesz);
121 VMRangeToFileOffset::Entry range_entry(addr, header.p_memsz, file_range);
122
123 // Only add to m_core_aranges if the file size is non zero. Some core files
124 // have PT_LOAD segments for all address ranges, but set f_filesz to zero for
125 // the .text sections since they can be retrieved from the object files.
126 if (header.p_filesz > 0) {
127 VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
128 if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
129 last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() &&
130 last_entry->GetByteSize() == last_entry->data.GetByteSize()) {
131 last_entry->SetRangeEnd(range_entry.GetRangeEnd());
132 last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
133 } else {
134 m_core_aranges.Append(range_entry);
135 }
136 }
137 // Keep mapped regions separate from m_core_aranges and uncoalesced so each
138 // PT_LOAD's permissions are preserved.
139 const uint32_t permissions =
140 ((header.p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0u) |
141 ((header.p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0u) |
142 ((header.p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0u);
143
144 MemoryRegionInfo region_info;
145 region_info.GetRange() = MemoryRegionInfo::RangeType(addr, header.p_memsz);
146 region_info.SetLLDBPermissions(permissions);
147 region_info.SetMapped(eLazyBoolYes);
148 region_info.SetMemoryTagged(eLazyBoolNo);
149 m_core_range_infos.insert(std::move(region_info));
150
151 return addr;
152}
153
155 const elf::ELFProgramHeader &header) {
156 // If lldb understood multiple kinds of tag segments we would record the type
157 // of the segment here also. As long as there is only 1 type lldb looks for,
158 // there is no need.
159 FileRange file_range(header.p_offset, header.p_filesz);
160 m_core_tag_ranges.Append(
161 VMRangeToFileOffset::Entry(header.p_vaddr, header.p_memsz, file_range));
162
163 return header.p_vaddr;
164}
165
166// Process Control
169 if (!m_core_module_sp) {
170 error = Status::FromErrorString("invalid core module");
171 return error;
172 }
173
174 ObjectFileELF *core = (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
175 if (core == nullptr) {
176 error = Status::FromErrorString("invalid core object file");
177 return error;
178 }
179
180 llvm::ArrayRef<elf::ELFProgramHeader> segments = core->ProgramHeaders();
181 if (segments.size() == 0) {
182 error = Status::FromErrorString("core file has no segments");
183 return error;
184 }
185
186 // Even if the architecture is set in the target, we need to override it to
187 // match the core file which is always single arch.
188 ArchSpec arch(m_core_module_sp->GetArchitecture());
189
190 ArchSpec target_arch = GetTarget().GetArchitecture();
191 ArchSpec core_arch(m_core_module_sp->GetArchitecture());
192 target_arch.MergeFrom(core_arch);
193 GetTarget().SetArchitecture(target_arch, /*set_platform*/ true);
194
196
197 SetCanJIT(false);
198
199 m_thread_data_valid = true;
200
201 bool ranges_are_sorted = true;
202 lldb::addr_t vm_addr = 0;
203 lldb::addr_t tag_addr = 0;
204 /// Walk through segments and Thread and Address Map information.
205 /// PT_NOTE - Contains Thread and Register information
206 /// PT_LOAD - Contains a contiguous range of Process Address Space
207 /// PT_AARCH64_MEMTAG_MTE - Contains AArch64 MTE memory tags for a range of
208 /// Process Address Space.
209 for (const elf::ELFProgramHeader &H : segments) {
210
211 // Parse thread contexts and auxv structure
212 if (H.p_type == llvm::ELF::PT_NOTE) {
213 DataExtractor data = core->GetSegmentData(H);
214 if (llvm::Error error = ParseThreadContextsFromNoteSegment(H, data))
215 return Status::FromError(std::move(error));
216 }
217 // PT_LOAD segments contains address map
218 if (H.p_type == llvm::ELF::PT_LOAD) {
220 if (vm_addr > last_addr)
221 ranges_are_sorted = false;
222 vm_addr = last_addr;
223 } else if (H.p_type == llvm::ELF::PT_AARCH64_MEMTAG_MTE) {
225 if (tag_addr > last_addr)
226 ranges_are_sorted = false;
227 tag_addr = last_addr;
228 }
229 }
230
231 if (!ranges_are_sorted) {
232 m_core_aranges.Sort();
233 m_core_tag_ranges.Sort();
234 }
235
237
238 // Ensure we found at least one thread that was stopped on a signal.
239 bool siginfo_signal_found = false;
240 bool prstatus_signal_found = false;
241 // Check we found a signal in a SIGINFO note.
242 for (const auto &thread_data : m_thread_data) {
243 if (!thread_data.siginfo_bytes.empty() || thread_data.signo != 0)
244 siginfo_signal_found = true;
245 if (thread_data.prstatus_sig != 0)
246 prstatus_signal_found = true;
247 }
248 if (!siginfo_signal_found) {
249 // If we don't have signal from SIGINFO use the signal from each threads
250 // PRSTATUS note.
251 if (prstatus_signal_found) {
252 for (auto &thread_data : m_thread_data)
253 thread_data.signo = thread_data.prstatus_sig;
254 } else if (m_thread_data.size() > 0) {
255 // If all else fails force the first thread to be SIGSTOP
256 m_thread_data.begin()->signo =
257 GetUnixSignals()->GetSignalNumberFromName("SIGSTOP");
258 }
259 }
260
261 // Try to find gnu build id before we load the executable.
263
264 // Core files are useless without the main executable. See if we can locate
265 // the main executable using data we found in the core file notes.
266 lldb::ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
267 if (!exe_module_sp) {
268 ModuleSpec exe_module_spec;
269 if (GetMainExecutableModuleSpec(exe_module_spec)) {
270 exe_module_sp =
271 GetTarget().GetOrCreateModule(exe_module_spec, true /* notify */);
272 if (!exe_module_sp) {
273 // Create an ELF file from memory for the main executable. The dynamic
274 // loader requires the main executable so that it can extract the
275 // DT_DEBUG key/value pair from the dynamic section and get the list
276 // of shared libraries.
277 std::optional<NT_FILE_Entry> exe_header =
279 if (exe_header) {
280 if (llvm::Expected<lldb::ModuleSP> module_sp_or_err =
281 ReadModuleFromMemory(exe_module_spec.GetFileSpec(),
282 exe_header->start,
283 exe_header->end - exe_header->start))
284 exe_module_sp = *module_sp_or_err;
285 else
286 llvm::consumeError(module_sp_or_err.takeError());
287 }
288 // Create a placeholder module for the main executable if we failed to
289 // create an ELF module from memory.
290 if (!exe_module_sp) {
291 lldb::addr_t load_addr =
292 exe_header ? exe_header->start : LLDB_INVALID_ADDRESS;
293 lldb::addr_t size =
294 exe_header ? (exe_header->end - exe_header->start) : 0;
295 exe_module_sp =
297 exe_module_spec, load_addr, size);
298 if (exe_module_spec.GetPlatformFileSpec())
299 exe_module_sp->SetPlatformFileSpec(
300 exe_module_spec.GetPlatformFileSpec());
301 }
302 }
303 if (exe_module_sp)
306 }
307 }
308 return error;
309}
310
313 m_uuids.clear();
314 for (NT_FILE_Entry &entry : m_nt_file_entries) {
315 UUID uuid = FindBuidIdInCoreMemory(entry.start);
316 if (uuid.IsValid()) {
317 // Assert that either the path is not in the map or the UUID matches
318 assert(m_uuids.count(entry.path) == 0 || m_uuids[entry.path] == uuid);
319 m_uuids[entry.path] = uuid;
320 LLDB_LOGF(log, "%s found UUID @ %16.16" PRIx64 ": %s \"%s\"",
321 __FUNCTION__, entry.start, uuid.GetAsString().c_str(),
322 entry.path.c_str());
323 }
324 }
325}
326
328 std::set<MemoryRegionInfo, std::less<>> finalized_regions;
329 // Add NT_FILE paths as names to PT_LOAD regions with matching start
330 // addresses, preserving the PT_LOAD ranges and permissions.
331 for (MemoryRegionInfo region_info : m_core_range_infos) {
332 const lldb::addr_t range_base = region_info.GetRange().GetRangeBase();
333 const lldb::addr_t range_end = region_info.GetRange().GetRangeEnd();
334
335 auto file_entry =
336 std::find_if(m_nt_file_entries.begin(), m_nt_file_entries.end(),
337 [range_base](const NT_FILE_Entry &entry) {
338 return entry.start == range_base;
339 });
340 if (file_entry != m_nt_file_entries.end() && !file_entry->path.empty())
341 region_info.SetName(file_entry->path.c_str());
342
343 const VMRangeToFileOffset::Entry *tag_entry =
344 m_core_tag_ranges.FindEntryStartsAt(range_base);
345 if (tag_entry && tag_entry->GetRangeEnd() == range_end)
346 region_info.SetMemoryTagged(eLazyBoolYes);
347
348 finalized_regions.insert(std::move(region_info));
349 }
350
351 // Create mapped regions with unknown permissions for portions of NT_FILE
352 // entries not covered by any PT_LOAD region.
353 for (const NT_FILE_Entry &file_entry : m_nt_file_entries) {
354 if (file_entry.start >= file_entry.end)
355 continue;
356
357 lldb::addr_t cursor = file_entry.start;
358 std::vector<MemoryRegionInfo::RangeType> uncovered_ranges;
359 for (const MemoryRegionInfo &region_info : finalized_regions) {
360 const lldb::addr_t range_base = region_info.GetRange().GetRangeBase();
361 const lldb::addr_t range_end = region_info.GetRange().GetRangeEnd();
362
363 if (range_end <= cursor)
364 continue;
365 if (range_base >= file_entry.end)
366 break;
367
368 if (cursor < range_base)
369 uncovered_ranges.emplace_back(cursor, range_base - cursor);
370
371 cursor = std::max(cursor, range_end);
372 if (cursor >= file_entry.end)
373 break;
374 }
375
376 if (cursor < file_entry.end)
377 uncovered_ranges.emplace_back(cursor, file_entry.end - cursor);
378
379 for (const MemoryRegionInfo::RangeType &range : uncovered_ranges) {
380 MemoryRegionInfo region_info;
381 region_info.GetRange() = range;
382 region_info.SetMapped(eLazyBoolYes);
383 if (!file_entry.path.empty())
384 region_info.SetName(file_entry.path.c_str());
385 finalized_regions.insert(std::move(region_info));
386 }
387 }
388 m_core_range_infos = std::move(finalized_regions);
389}
390
391/// Correctly create a FileSpec from a path found in a core file.
392///
393/// This method will guess the path style more intelligently that specifying
394/// a native path style since core files can contain paths from a different
395/// system than the host system.
396static FileSpec CreateFileSpecFromPath(llvm::StringRef path) {
397 FileSpec::Style path_style = FileSpec::Style::native;
398 if (auto guessed_style = FileSpec::GuessPathStyle(path))
399 path_style = *guessed_style;
400 return FileSpec(path, path_style);
401}
402
404 AuxVector aux_vector(m_auxv);
406
407 // Find the NT_FILE_Entry for the main executable's ELF header.
408 std::optional<NT_FILE_Entry> exe_header =
410 if (exe_header) {
411 exe_spec.GetFileSpec() = CreateFileSpecFromPath(exe_header->path);
412 exe_spec.SetLoadAddress(exe_header->start);
413 }
414
415 // If we failed to find the executable program in the NT_FILE list with the
416 // program header address, then we can read the executable name from the value
417 // of the AUXV_AT_EXECFN in the AUX vector. The reason we don't use this file
418 // all of the time is if the program is launched using a symlink, the value of
419 // the AUXV_AT_EXECFN string will be the symlink itself. The same goes for the
420 // m_executable_name found in the NT_PRPSINFO section, it will be the name of
421 // the symlink. Even if we did find a path above, we want to fill in this path
422 // if it is different from main executable's path in the platform file name
423 // in case someone needs to know how the executable was launched.
424 if (auto execfn = aux_vector.GetAuxValue(AuxVector::AUXV_AT_EXECFN)) {
426 std::string execfn_str;
427 if (ReadCStringFromMemory(*execfn, execfn_str, error)) {
428 // This path can be a symlink path. Set it as the main file spec if one
429 // hasn't been set, else set the platform file spec.
430 FileSpec execfn_spec = CreateFileSpecFromPath(execfn_str);
431 if (exe_spec.GetFileSpec()) {
432 // Fill in the platform file spec if it differs from the main path from
433 // the resolved file info in the NT_FILE note.
434 if (exe_spec.GetFileSpec() != execfn_spec)
435 exe_spec.GetPlatformFileSpec() = execfn_spec;
436 } else {
437 // We don't have an executable file spec yet, lets set it.
438 exe_spec.GetFileSpec() = execfn_spec;
439 }
440 }
441 }
442
443 // If we didn't set the executable file spec yet, lets set it from the info
444 // from the NT_PRPSINFO. This usually is just a basename of the actual path
445 // used to launch the binary, so this can be a symlink basename. But it will
446 // be better than nothing since we will create a placeholder module for any
447 // files that don't exist.
448 if (!exe_spec.GetFileSpec() && !m_executable_name.empty())
450
451 // Try and find the UUID after the module spec was filled in.
452 FindModuleUUID(exe_spec);
453
454 // We succeeded if we got a path.
455 return (bool)exe_spec.GetFileSpec();
456}
457
459 if (spec.GetUUID().IsValid())
460 return true;
461 // Lookup the UUID for the given path in the map.
462 // Note that this could be called by multiple threads so make sure
463 // we access the map in a thread safe way (i.e. don't use operator[]).
464 std::string path;
465 // Sometimes the path to a file or shared library from the dynamic loader,
466 // one of the main clients of this function, is a symlink. The information
467 // in the NT_FILE note contains resolved paths and might not match. The
468 // best way for us to find a module is by load address, so use this trick
469 // if the load address is set in the module specification.
470 if (std::optional<lldb::addr_t> load_addr = spec.GetLoadAddress()) {
471 if (std::optional<NT_FILE_Entry> nt =
473 path = nt->path;
474 }
475 // If we didn't find a file spec from the load address, fall back to using
476 // the file spec.
477 if (path.empty())
478 path = spec.GetFileSpec().GetPath();
479
480 auto it = m_uuids.find(path);
481 if (it != m_uuids.end()) {
483 spec.GetUUID() = it->second;
484 LLDB_LOGF(log, "ProcessElfCore::FindModuleUUID() found UUID for %s: %s",
485 spec.GetFileSpec().GetPath().c_str(),
486 it->second.GetAsString().c_str());
487 }
488 return spec.GetUUID().IsValid();
489}
490
492 if (!m_dyld_up) {
493 llvm::StringRef dyld_name;
494 if (GetTarget().GetArchitecture().GetMachine() == llvm::Triple::riscv32 &&
495 GetTarget().GetArchitecture().GetTriple().getOS() ==
496 llvm::Triple::UnknownOS)
498 else
500 m_dyld_up.reset(DynamicLoader::FindPlugin(this, dyld_name));
501 }
502 return m_dyld_up.get();
503}
504
506 ThreadList &new_thread_list) {
507 const uint32_t num_threads = GetNumThreadContexts();
509 return false;
510
511 for (lldb::tid_t tid = 0; tid < num_threads; ++tid) {
512 const ThreadData &td = m_thread_data[tid];
513 lldb::ThreadSP thread_sp(new ThreadElfCore(*this, td));
514 new_thread_list.AddThread(thread_sp);
515 }
516 return new_thread_list.GetSize(false) > 0;
517}
518
520
522
523// Process Queries
524
525bool ProcessElfCore::IsAlive() { return true; }
526
527// Process Memory
528size_t ProcessElfCore::ReadMemory(const ProcessAddress &process_addr, void *buf,
529 size_t size, Status &error) {
530 lldb::addr_t addr = process_addr.GetValue();
531 if (lldb::ABISP abi_sp = GetABI())
532 addr = abi_sp->FixAnyAddress(addr);
533
534 // Don't allow the caching that lldb_private::Process::ReadMemory does since
535 // in core files we have it all cached our our core file anyway.
536 return DoReadMemory(addr, buf, size, error);
537}
538
540 MemoryRegionInfo &region_info) {
541 region_info.Clear();
542 auto following = m_core_range_infos.upper_bound(load_addr);
543 // PT_LOAD ranges can overlap, so the immediate predecessor is not
544 // necessarily the range containing load_addr.
545 auto range_entry = std::find_if(m_core_range_infos.begin(), following,
546 [load_addr](const auto &entry) {
547 return entry.GetRange().Contains(load_addr);
548 });
549 if (range_entry != following) {
550 region_info = *range_entry;
551 return Status();
552 }
553
554 region_info.GetRange().SetRangeBase(load_addr);
555 region_info.GetRange().SetRangeEnd(
556 following == m_core_range_infos.end()
558 : following->GetRange().GetRangeBase());
559 region_info.SetReadable(eLazyBoolNo);
560 region_info.SetWritable(eLazyBoolNo);
561 region_info.SetExecutable(eLazyBoolNo);
562 region_info.SetMapped(eLazyBoolNo);
563 region_info.SetMemoryTagged(eLazyBoolNo);
564 return Status();
565}
566
568 void *buf, size_t size, Status &error) {
569 lldb::addr_t addr = process_addr.GetValue();
570 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
571
572 if (core_objfile == nullptr)
573 return 0;
574
575 // Get the address range
576 const VMRangeToFileOffset::Entry *address_range =
577 m_core_aranges.FindEntryThatContains(addr);
578 if (address_range == nullptr || address_range->GetRangeEnd() < addr) {
580 "core file does not contain 0x%" PRIx64, addr);
581 return 0;
582 }
583
584 // Convert the address into core file offset
585 const lldb::addr_t offset = addr - address_range->GetRangeBase();
586 const lldb::addr_t file_start = address_range->data.GetRangeBase();
587 const lldb::addr_t file_end = address_range->data.GetRangeEnd();
588 size_t bytes_to_read = size; // Number of bytes to read from the core file
589 size_t bytes_copied = 0; // Number of bytes actually read from the core file
590 lldb::addr_t bytes_left =
591 0; // Number of bytes available in the core file from the given address
592
593 // Don't proceed if core file doesn't contain the actual data for this
594 // address range.
595 if (file_start == file_end)
596 return 0;
597
598 // Figure out how many on-disk bytes remain in this segment starting at the
599 // given offset
600 if (file_end > file_start + offset)
601 bytes_left = file_end - (file_start + offset);
602
603 if (bytes_to_read > bytes_left)
604 bytes_to_read = bytes_left;
605
606 // If there is data available on the core file read it
607 if (bytes_to_read)
608 bytes_copied =
609 core_objfile->CopyData(offset + file_start, bytes_to_read, buf);
610
611 return bytes_copied;
612}
613
614llvm::Expected<std::vector<lldb::addr_t>>
616 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
617 if (core_objfile == nullptr)
618 return llvm::createStringError(llvm::inconvertibleErrorCode(),
619 "No core object file.");
620
621 llvm::Expected<const MemoryTagManager *> tag_manager_or_err =
623 if (!tag_manager_or_err)
624 return tag_manager_or_err.takeError();
625
626 // LLDB only supports AArch64 MTE tag segments so we do not need to worry
627 // about the segment type here. If you got here then you must have a tag
628 // manager (meaning you are debugging AArch64) and all the segments in this
629 // list will have had type PT_AARCH64_MEMTAG_MTE.
630 const VMRangeToFileOffset::Entry *tag_entry =
631 m_core_tag_ranges.FindEntryThatContains(addr);
632 // If we don't have a tag segment or the range asked for extends outside the
633 // segment.
634 if (!tag_entry || (addr + len) >= tag_entry->GetRangeEnd())
635 return llvm::createStringError(llvm::inconvertibleErrorCode(),
636 "No tag segment that covers this range.");
637
638 const MemoryTagManager *tag_manager = *tag_manager_or_err;
639 return tag_manager->UnpackTagsFromCoreFileSegment(
640 [core_objfile](lldb::offset_t offset, size_t length, void *dst) {
641 return core_objfile->CopyData(offset, length, dst);
642 },
643 tag_entry->GetRangeBase(), tag_entry->data.GetRangeBase(), addr, len);
644}
645
647 m_thread_list.Clear();
648
649 SetUnixSignals(std::make_shared<UnixSignals>());
650}
651
656
658 lldb::ModuleSP executable_sp = GetTarget().GetExecutableModule();
659 if (!executable_sp)
661 ObjectFile *obj_file = executable_sp->GetObjectFile();
662 Address addr = obj_file->GetImageInfoAddress(&GetTarget());
663
664 if (addr.IsValid())
665 return addr.GetLoadAddress(&GetTarget());
667}
668
669// Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
670static void ParseFreeBSDPrStatus(ThreadData &thread_data,
671 const DataExtractor &data,
672 bool lp64) {
673 lldb::offset_t offset = 0;
674 int pr_version = data.GetU32(&offset);
675
677 if (pr_version > 1)
678 LLDB_LOGF(log, "FreeBSD PRSTATUS unexpected version %d", pr_version);
679
680 // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate
681 if (lp64)
682 offset += 32;
683 else
684 offset += 16;
685
686 thread_data.signo = data.GetU32(&offset); // pr_cursig
687 thread_data.tid = data.GetU32(&offset); // pr_pid
688 if (lp64)
689 offset += 4;
690
691 size_t len = data.GetByteSize() - offset;
692 thread_data.gpregset = DataExtractor(data, offset, len);
693}
694
695// Parse a FreeBSD NT_PRPSINFO note - see FreeBSD sys/procfs.h for details.
697 const DataExtractor &data,
698 bool lp64) {
699 lldb::offset_t offset = 0;
700 int pr_version = data.GetU32(&offset);
701
703 if (pr_version > 1)
704 LLDB_LOGF(log, "FreeBSD PRPSINFO unexpected version %d", pr_version);
705
706 // Skip pr_psinfosz, pr_fname, pr_psargs
707 offset += 108;
708 if (lp64)
709 offset += 4;
710
711 process.SetID(data.GetU32(&offset)); // pr_pid
712}
713
714static llvm::Error ParseNetBSDProcInfo(const DataExtractor &data,
715 uint32_t &cpi_nlwps,
716 uint32_t &cpi_signo,
717 uint32_t &cpi_siglwp,
718 uint32_t &cpi_pid) {
719 lldb::offset_t offset = 0;
720
721 uint32_t version = data.GetU32(&offset);
722 if (version != 1)
723 return llvm::createStringError(
724 "Error parsing NetBSD core(5) notes: Unsupported procinfo version");
725
726 uint32_t cpisize = data.GetU32(&offset);
727 if (cpisize != NETBSD::NT_PROCINFO_SIZE)
728 return llvm::createStringError(
729 "Error parsing NetBSD core(5) notes: Unsupported procinfo size");
730
731 cpi_signo = data.GetU32(&offset); /* killing signal */
732
738 cpi_pid = data.GetU32(&offset);
748 cpi_nlwps = data.GetU32(&offset); /* number of LWPs */
749
751 cpi_siglwp = data.GetU32(&offset); /* LWP target of killing signal */
752
753 return llvm::Error::success();
754}
755
756static void ParseOpenBSDProcInfo(ThreadData &thread_data,
757 const DataExtractor &data) {
758 lldb::offset_t offset = 0;
759
760 int version = data.GetU32(&offset);
761 if (version != 1)
762 return;
763
764 offset += 4;
765 thread_data.signo = data.GetU32(&offset);
766}
767
768llvm::Expected<std::vector<CoreNote>>
770 lldb::offset_t offset = 0;
771 std::vector<CoreNote> result;
772
773 while (offset < segment.GetByteSize()) {
774 ELFNote note = ELFNote();
775 if (!note.Parse(segment, &offset))
776 return llvm::createStringError("unable to parse note segment");
777
778 size_t note_start = offset;
779 size_t note_size = llvm::alignTo(note.n_descsz, 4);
780
781 result.push_back({note, DataExtractor(segment, note_start, note_size)});
782 offset += note_size;
783 }
784
785 return std::move(result);
786}
787
788llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) {
789 ArchSpec arch = GetArchitecture();
790 bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
791 arch.GetMachine() == llvm::Triple::ppc64 ||
792 arch.GetMachine() == llvm::Triple::x86_64);
793 bool have_prstatus = false;
794 bool have_prpsinfo = false;
795 ThreadData thread_data;
796 for (const auto &note : notes) {
797 if (note.info.n_name != "FreeBSD")
798 continue;
799
800 if ((note.info.n_type == ELF::NT_PRSTATUS && have_prstatus) ||
801 (note.info.n_type == ELF::NT_PRPSINFO && have_prpsinfo)) {
802 assert(thread_data.gpregset.GetByteSize() > 0);
803 // Add the new thread to thread list
804 m_thread_data.push_back(thread_data);
805 thread_data = ThreadData();
806 have_prstatus = false;
807 have_prpsinfo = false;
808 }
809
810 switch (note.info.n_type) {
811 case ELF::NT_PRSTATUS:
812 have_prstatus = true;
813 ParseFreeBSDPrStatus(thread_data, note.data, lp64);
814 break;
815 case ELF::NT_PRPSINFO:
816 have_prpsinfo = true;
817 ParseFreeBSDPrPsInfo(*this, note.data, lp64);
818 break;
819 case ELF::NT_FREEBSD_THRMISC: {
820 lldb::offset_t offset = 0;
821 thread_data.name = note.data.GetCStr(&offset, 20);
822 break;
823 }
824 case ELF::NT_FREEBSD_PROCSTAT_AUXV:
825 // FIXME: FreeBSD sticks an int at the beginning of the note
826 m_auxv = DataExtractor(note.data, 4, note.data.GetByteSize() - 4);
827 break;
828 default:
829 thread_data.notes.push_back(note);
830 break;
831 }
832 }
833 if (!have_prstatus) {
834 return llvm::createStringError(
835 "Could not find NT_PRSTATUS note in core file.");
836 }
837 m_thread_data.push_back(thread_data);
838 return llvm::Error::success();
839}
840
841/// NetBSD specific Thread context from PT_NOTE segment
842///
843/// NetBSD ELF core files use notes to provide information about
844/// the process's state. The note name is "NetBSD-CORE" for
845/// information that is global to the process, and "NetBSD-CORE@nn",
846/// where "nn" is the lwpid of the LWP that the information belongs
847/// to (such as register state).
848///
849/// NetBSD uses the following note identifiers:
850///
851/// ELF_NOTE_NETBSD_CORE_PROCINFO (value 1)
852/// Note is a "netbsd_elfcore_procinfo" structure.
853/// ELF_NOTE_NETBSD_CORE_AUXV (value 2; since NetBSD 8.0)
854/// Note is an array of AuxInfo structures.
855///
856/// NetBSD also uses ptrace(2) request numbers (the ones that exist in
857/// machine-dependent space) to identify register info notes. The
858/// info in such notes is in the same format that ptrace(2) would
859/// export that information.
860///
861/// For more information see /usr/include/sys/exec_elf.h
862///
863llvm::Error ProcessElfCore::parseNetBSDNotes(llvm::ArrayRef<CoreNote> notes) {
864 ThreadData thread_data;
865 bool had_nt_regs = false;
866
867 // To be extracted from struct netbsd_elfcore_procinfo
868 // Used to sanity check of the LWPs of the process
869 uint32_t nlwps = 0;
870 uint32_t signo = 0; // killing signal
871 uint32_t siglwp = 0; // LWP target of killing signal
872 uint32_t pr_pid = 0;
873
874 for (const auto &note : notes) {
875 llvm::StringRef name = note.info.n_name;
876
877 if (name == "NetBSD-CORE") {
878 if (note.info.n_type == NETBSD::NT_PROCINFO) {
879 llvm::Error error = ParseNetBSDProcInfo(note.data, nlwps, signo,
880 siglwp, pr_pid);
881 if (error)
882 return error;
883 SetID(pr_pid);
884 } else if (note.info.n_type == NETBSD::NT_AUXV) {
885 m_auxv = note.data;
886 }
887 } else if (name.consume_front("NetBSD-CORE@")) {
888 lldb::tid_t tid;
889 if (name.getAsInteger(10, tid))
890 return llvm::createStringError(
891 "Error parsing NetBSD core(5) notes: Cannot convert LWP ID "
892 "to integer");
893
894 switch (GetArchitecture().GetMachine()) {
895 case llvm::Triple::aarch64: {
896 // Assume order PT_GETREGS, PT_GETFPREGS
897 if (note.info.n_type == NETBSD::AARCH64::NT_REGS) {
898 // If this is the next thread, push the previous one first.
899 if (had_nt_regs) {
900 m_thread_data.push_back(thread_data);
901 thread_data = ThreadData();
902 had_nt_regs = false;
903 }
904
905 thread_data.gpregset = note.data;
906 thread_data.tid = tid;
907 if (thread_data.gpregset.GetByteSize() == 0)
908 return llvm::createStringError(
909 "Could not find general purpose registers note in core file.");
910 had_nt_regs = true;
911 } else if (note.info.n_type == NETBSD::AARCH64::NT_FPREGS) {
912 if (!had_nt_regs || tid != thread_data.tid)
913 return llvm::createStringError(
914 "Error parsing NetBSD core(5) notes: Unexpected order "
915 "of NOTEs PT_GETFPREG before PT_GETREG");
916 thread_data.notes.push_back(note);
917 }
918 } break;
919 case llvm::Triple::x86: {
920 // Assume order PT_GETREGS, PT_GETFPREGS
921 if (note.info.n_type == NETBSD::I386::NT_REGS) {
922 // If this is the next thread, push the previous one first.
923 if (had_nt_regs) {
924 m_thread_data.push_back(thread_data);
925 thread_data = ThreadData();
926 had_nt_regs = false;
927 }
928
929 thread_data.gpregset = note.data;
930 thread_data.tid = tid;
931 if (thread_data.gpregset.GetByteSize() == 0)
932 return llvm::createStringError(
933 "Could not find general purpose registers note in core file.");
934 had_nt_regs = true;
935 } else if (note.info.n_type == NETBSD::I386::NT_FPREGS) {
936 if (!had_nt_regs || tid != thread_data.tid)
937 return llvm::createStringError(
938 "Error parsing NetBSD core(5) notes: Unexpected order "
939 "of NOTEs PT_GETFPREG before PT_GETREG");
940 thread_data.notes.push_back(note);
941 }
942 } break;
943 case llvm::Triple::x86_64: {
944 // Assume order PT_GETREGS, PT_GETFPREGS
945 if (note.info.n_type == NETBSD::AMD64::NT_REGS) {
946 // If this is the next thread, push the previous one first.
947 if (had_nt_regs) {
948 m_thread_data.push_back(thread_data);
949 thread_data = ThreadData();
950 had_nt_regs = false;
951 }
952
953 thread_data.gpregset = note.data;
954 thread_data.tid = tid;
955 if (thread_data.gpregset.GetByteSize() == 0)
956 return llvm::createStringError(
957 "Could not find general purpose registers note in core file.");
958 had_nt_regs = true;
959 } else if (note.info.n_type == NETBSD::AMD64::NT_FPREGS) {
960 if (!had_nt_regs || tid != thread_data.tid)
961 return llvm::createStringError(
962 "Error parsing NetBSD core(5) notes: Unexpected order "
963 "of NOTEs PT_GETFPREG before PT_GETREG");
964 thread_data.notes.push_back(note);
965 }
966 } break;
967 default:
968 break;
969 }
970 }
971 }
972
973 // Push the last thread.
974 if (had_nt_regs)
975 m_thread_data.push_back(thread_data);
976
977 if (m_thread_data.empty())
978 return llvm::createStringError(
979 "Error parsing NetBSD core(5) notes: No threads information "
980 "specified in notes");
981
982 if (m_thread_data.size() != nlwps)
983 return llvm::createStringError(
984 "Error parsing NetBSD core(5) notes: Mismatch between the number "
985 "of LWPs in netbsd_elfcore_procinfo and the number of LWPs specified "
986 "by MD notes");
987
988 // Signal targeted at the whole process.
989 if (siglwp == 0) {
990 for (auto &data : m_thread_data)
991 data.signo = signo;
992 }
993 // Signal destined for a particular LWP.
994 else {
995 bool passed = false;
996
997 for (auto &data : m_thread_data) {
998 if (data.tid == siglwp) {
999 data.signo = signo;
1000 passed = true;
1001 break;
1002 }
1003 }
1004
1005 if (!passed)
1006 return llvm::createStringError(
1007 "Error parsing NetBSD core(5) notes: Signal passed to unknown LWP");
1008 }
1009
1010 return llvm::Error::success();
1011}
1012
1013llvm::Error ProcessElfCore::parseOpenBSDNotes(llvm::ArrayRef<CoreNote> notes) {
1014 ThreadData thread_data = {};
1015 for (const auto &note : notes) {
1016 // OpenBSD per-thread information is stored in notes named "OpenBSD@nnn" so
1017 // match on the initial part of the string.
1018 if (!llvm::StringRef(note.info.n_name).starts_with("OpenBSD"))
1019 continue;
1020
1021 switch (note.info.n_type) {
1023 ParseOpenBSDProcInfo(thread_data, note.data);
1024 break;
1025 case OPENBSD::NT_AUXV:
1026 m_auxv = note.data;
1027 break;
1028 case OPENBSD::NT_REGS:
1029 thread_data.gpregset = note.data;
1030 break;
1031 default:
1032 thread_data.notes.push_back(note);
1033 break;
1034 }
1035 }
1036 if (thread_data.gpregset.GetByteSize() == 0) {
1037 return llvm::createStringError(
1038 "Could not find general purpose registers note in core file.");
1039 }
1040 m_thread_data.push_back(thread_data);
1041 return llvm::Error::success();
1042}
1043
1044/// A description of a linux process usually contains the following NOTE
1045/// entries:
1046/// - NT_PRPSINFO - General process information like pid, uid, name, ...
1047/// - NT_SIGINFO - Information about the signal that terminated the process
1048/// - NT_AUXV - Process auxiliary vector
1049/// - NT_FILE - Files mapped into memory
1050///
1051/// Additionally, for each thread in the process the core file will contain at
1052/// least the NT_PRSTATUS note, containing the thread id and general purpose
1053/// registers. It may include additional notes for other register sets (floating
1054/// point and vector registers, ...). The tricky part here is that some of these
1055/// notes have "CORE" in their owner fields, while other set it to "LINUX".
1056llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
1057 const ArchSpec &arch = GetArchitecture();
1058 bool have_prstatus = false;
1059 bool have_prpsinfo = false;
1060 ThreadData thread_data;
1061 for (const auto &note : notes) {
1062 if (note.info.n_name != "CORE" && note.info.n_name != "LINUX")
1063 continue;
1064
1065 if ((note.info.n_type == ELF::NT_PRSTATUS && have_prstatus) ||
1066 (note.info.n_type == ELF::NT_PRPSINFO && have_prpsinfo)) {
1067 assert(thread_data.gpregset.GetByteSize() > 0);
1068 // Add the new thread to thread list
1069 m_thread_data.push_back(thread_data);
1070 thread_data = ThreadData();
1071 have_prstatus = false;
1072 have_prpsinfo = false;
1073 }
1074
1075 switch (note.info.n_type) {
1076 case ELF::NT_PRSTATUS: {
1077 have_prstatus = true;
1078 ELFLinuxPrStatus prstatus;
1079 Status status = prstatus.Parse(note.data, arch);
1080 if (status.Fail())
1081 return status.ToError();
1082 thread_data.prstatus_sig = prstatus.pr_cursig;
1083 thread_data.tid = prstatus.pr_pid;
1084 uint32_t header_size = ELFLinuxPrStatus::GetSize(arch);
1085 size_t len = note.data.GetByteSize() - header_size;
1086 thread_data.gpregset = DataExtractor(note.data, header_size, len);
1087 break;
1088 }
1089 case ELF::NT_PRPSINFO: {
1090 have_prpsinfo = true;
1091 ELFLinuxPrPsInfo prpsinfo;
1092 Status status = prpsinfo.Parse(note.data, arch);
1093 if (status.Fail())
1094 return status.ToError();
1095 thread_data.name.assign (prpsinfo.pr_fname, strnlen (prpsinfo.pr_fname, sizeof (prpsinfo.pr_fname)));
1096 SetID(prpsinfo.pr_pid);
1097 m_executable_name = thread_data.name;
1098 auto core_arg = llvm::StringRef(prpsinfo.pr_psargs,
1099 strnlen(prpsinfo.pr_psargs,
1100 sizeof(prpsinfo.pr_psargs)))
1101 .str();
1102 // pr_psargs's char array used to represent arguments is only 80 character
1103 // long (\0 included), for a total of 79.
1104 // We set core_arg's m_might_be_truncated = true if its size
1105 // is the maximum (79).
1107 CoreArgs(core_arg, /*might_be_truncated=*/core_arg.size() ==
1108 sizeof(prpsinfo.pr_psargs) - 1);
1109 break;
1110 }
1111 case ELF::NT_SIGINFO: {
1112 lldb::offset_t size = note.data.GetByteSize();
1113 lldb::offset_t offset = 0;
1114 const char *bytes =
1115 static_cast<const char *>(note.data.GetData(&offset, size));
1116 thread_data.siginfo_bytes = llvm::StringRef(bytes, size);
1117 break;
1118 }
1119 case ELF::NT_FILE: {
1120 m_nt_file_entries.clear();
1121 lldb::offset_t offset = 0;
1122 const uint64_t count = note.data.GetAddress(&offset);
1123 note.data.GetAddress(&offset); // Skip page size
1124 for (uint64_t i = 0; i < count; ++i) {
1125 NT_FILE_Entry entry;
1126 entry.start = note.data.GetAddress(&offset);
1127 entry.end = note.data.GetAddress(&offset);
1128 entry.file_ofs = note.data.GetAddress(&offset);
1129 m_nt_file_entries.push_back(entry);
1130 }
1131 for (uint64_t i = 0; i < count; ++i) {
1132 const char *path = note.data.GetCStr(&offset);
1133 if (path && path[0])
1134 m_nt_file_entries[i].path.assign(path);
1135 }
1136 break;
1137 }
1138 case ELF::NT_AUXV:
1139 m_auxv = note.data;
1140 break;
1141 default:
1142 thread_data.notes.push_back(note);
1143 break;
1144 }
1145 }
1146 // Add last entry in the note section
1147 if (have_prstatus)
1148 m_thread_data.push_back(thread_data);
1149 return llvm::Error::success();
1150}
1151
1152/// Parse Thread context from PT_NOTE segment and store it in the thread list
1153/// A note segment consists of one or more NOTE entries, but their types and
1154/// meaning differ depending on the OS.
1156 const elf::ELFProgramHeader &segment_header,
1157 const DataExtractor &segment_data) {
1158 assert(segment_header.p_type == llvm::ELF::PT_NOTE);
1159
1160 auto notes_or_error = parseSegment(segment_data);
1161 if(!notes_or_error)
1162 return notes_or_error.takeError();
1163 switch (GetArchitecture().GetTriple().getOS()) {
1164 case llvm::Triple::FreeBSD:
1165 return parseFreeBSDNotes(*notes_or_error);
1166 case llvm::Triple::Linux:
1167 return parseLinuxNotes(*notes_or_error);
1168 case llvm::Triple::NetBSD:
1169 return parseNetBSDNotes(*notes_or_error);
1170 case llvm::Triple::OpenBSD:
1171 return parseOpenBSDNotes(*notes_or_error);
1172 default:
1173 // Treat bare-metal 32-bit RISC-V like Linux.
1174 if (GetTarget().GetArchitecture().GetMachine() == llvm::Triple::riscv32 &&
1175 GetTarget().GetArchitecture().GetTriple().getOS() ==
1176 llvm::Triple::UnknownOS)
1177 return parseLinuxNotes(*notes_or_error);
1178 else
1179 return llvm::createStringError(
1180 "don't know how to parse core file: unsupported OS");
1181 }
1182}
1183
1185 UUID invalid_uuid;
1186 const uint32_t addr_size = GetAddressByteSize();
1187 const size_t elf_header_size = addr_size == 4 ? sizeof(llvm::ELF::Elf32_Ehdr)
1188 : sizeof(llvm::ELF::Elf64_Ehdr);
1189
1190 std::vector<uint8_t> elf_header_bytes;
1191 elf_header_bytes.resize(elf_header_size);
1192 Status error;
1193 size_t byte_read =
1194 ReadMemory(address, elf_header_bytes.data(), elf_header_size, error);
1195 if (byte_read != elf_header_size ||
1196 !elf::ELFHeader::MagicBytesMatch(elf_header_bytes.data()))
1197 return invalid_uuid;
1198 DataExtractor elf_header_data(elf_header_bytes.data(), elf_header_size,
1199 GetByteOrder(), addr_size);
1200 lldb::offset_t offset = 0;
1201
1202 elf::ELFHeader elf_header;
1203 elf_header.Parse(elf_header_data, &offset);
1204
1205 const lldb::addr_t ph_addr = address + elf_header.e_phoff;
1206
1207 std::vector<uint8_t> ph_bytes;
1208 ph_bytes.resize(elf_header.e_phentsize);
1209 lldb::addr_t base_addr = 0;
1210 bool found_first_load_segment = false;
1211 for (unsigned int i = 0; i < elf_header.e_phnum; ++i) {
1212 byte_read = ReadMemory(ph_addr + i * elf_header.e_phentsize,
1213 ph_bytes.data(), elf_header.e_phentsize, error);
1214 if (byte_read != elf_header.e_phentsize)
1215 break;
1216 DataExtractor program_header_data(ph_bytes.data(), elf_header.e_phentsize,
1217 GetByteOrder(), addr_size);
1218 offset = 0;
1219 elf::ELFProgramHeader program_header;
1220 program_header.Parse(program_header_data, &offset);
1221 if (program_header.p_type == llvm::ELF::PT_LOAD &&
1222 !found_first_load_segment) {
1223 base_addr = program_header.p_vaddr;
1224 found_first_load_segment = true;
1225 }
1226 if (program_header.p_type != llvm::ELF::PT_NOTE)
1227 continue;
1228
1229 std::vector<uint8_t> note_bytes;
1230 note_bytes.resize(program_header.p_memsz);
1231
1232 // We need to slide the address of the p_vaddr as these values don't get
1233 // relocated in memory.
1234 const lldb::addr_t vaddr = program_header.p_vaddr + address - base_addr;
1235 byte_read =
1236 ReadMemory(vaddr, note_bytes.data(), program_header.p_memsz, error);
1237 if (byte_read != program_header.p_memsz)
1238 continue;
1239 DataExtractor segment_data(note_bytes.data(), note_bytes.size(),
1240 GetByteOrder(), addr_size);
1241 auto notes_or_error = parseSegment(segment_data);
1242 if (!notes_or_error) {
1243 llvm::consumeError(notes_or_error.takeError());
1244 return invalid_uuid;
1245 }
1246 for (const CoreNote &note : *notes_or_error) {
1247 if (note.info.n_namesz == 4 &&
1248 note.info.n_type == llvm::ELF::NT_GNU_BUILD_ID &&
1249 "GNU" == note.info.n_name &&
1250 note.data.ValidOffsetForDataOfSize(0, note.info.n_descsz))
1251 return UUID(note.data.GetData().take_front(note.info.n_descsz));
1252 }
1253 }
1254 return invalid_uuid;
1255}
1256
1259 DoLoadCore();
1260 return m_thread_data.size();
1261}
1262
1264 ArchSpec arch = m_core_module_sp->GetObjectFile()->GetArchitecture();
1265
1266 ArchSpec target_arch = GetTarget().GetArchitecture();
1267 arch.MergeFrom(target_arch);
1268
1269 // On MIPS there is no way to differentiate betwenn 32bit and 64bit core
1270 // files and this information can't be merged in from the target arch so we
1271 // fail back to unconditionally returning the target arch in this config.
1272 if (target_arch.IsMIPS()) {
1273 return target_arch;
1274 }
1275
1276 return arch;
1277}
1278
1280 assert(m_auxv.GetByteSize() == 0 ||
1281 (m_auxv.GetByteOrder() == GetByteOrder() &&
1282 m_auxv.GetAddressByteSize() == GetAddressByteSize()));
1283 return DataExtractor(m_auxv);
1284}
1285std::optional<Process::CoreArgs> ProcessElfCore::GetCoreFileArgs() {
1286 if (m_process_args.empty())
1287 return std::nullopt;
1288 return m_process_args;
1289}
1290
1292 info.Clear();
1293 info.SetProcessID(GetID());
1295 ModuleSpec exe_module_spec;
1296 bool added_executable = false;
1298 const bool add_exe_file_as_first_arg = true;
1299 if (module_sp) {
1300 info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
1301 add_exe_file_as_first_arg);
1302 added_executable = true;
1303 } else {
1304 ModuleSpec exe_module_spec;
1305 if (GetMainExecutableModuleSpec(exe_module_spec)) {
1306 if (exe_module_spec.GetFileSpec()) {
1307 info.SetExecutableFile(exe_module_spec.GetFileSpec(),
1308 add_exe_file_as_first_arg);
1309 added_executable = true;
1310 }
1311 }
1312 }
1313 Args process_args = m_process_args.as_args();
1314 bool first_arg_is_executable = true;
1315 if (added_executable) {
1316 // Strip the executable name from the process args as it can be a symlink
1317 // that doesn't match the executable we would have created from a call to
1318 // GetMainExecutableModuleSpec(...).
1319 first_arg_is_executable = false;
1320 info.SetArg0(process_args.GetArgumentAtIndex(0));
1321 process_args.DeleteArgumentAtIndex(0);
1322 }
1323 info.SetArguments(process_args, first_arg_is_executable);
1324 return true;
1325}
1326
1327/// Find the NT_FILE entry that contains an address.
1328std::optional<ProcessElfCore::NT_FILE_Entry>
1330 for (const NT_FILE_Entry &file_entry : m_nt_file_entries) {
1331 if (file_entry.start <= addr && addr < file_entry.end)
1332 return file_entry;
1333 }
1334 return std::nullopt;
1335}
1336
1337std::optional<ProcessElfCore::NT_FILE_Entry>
1339 /// This method will search for the first NT_FILE entry that contains the
1340 /// executable's ELF header. We use the AUXV_AT_PHDR from the aux vector to
1341 /// find the address of the main executable's program headers and then find
1342 /// the NT_FILE entry that contains this address.
1343 ///
1344 /// Previously we would try to find the first NT_FILE entry that had a path
1345 /// that ended with the executable name found in the NT_PRPSINFO note, but
1346 /// this basename can be the name of a symlink and not the actual resolved
1347 /// executable file found in the NT_FILE entry so this could fail for cases
1348 /// where a symlink was used to launch the program, and that symlink's
1349 /// base name was different from the resolved executable file's name in
1350 /// the NT_FILE entry.
1351 if (m_nt_file_entries.empty())
1352 return std::nullopt;
1353 // The AUX vector has the load address of the program headers from the main
1354 // executable as the value for AUXV_AT_PHDR. We can use this value to find
1355 // the NT_FILE entry that contains this address and this will locate the main
1356 // executable's mapping that contains the ELF header.
1357 AuxVector aux_vector(m_auxv);
1358 if (std::optional<uint64_t> opt_value =
1360 if (std::optional<NT_FILE_Entry> nt =
1362 return *nt;
1363 }
1364 // Fall back to trying to find the first NT_FILE entry that contains the entry
1365 // point address.
1366 if (std::optional<uint64_t> opt_value =
1368 if (std::optional<NT_FILE_Entry> nt =
1370 return *nt;
1371 }
1372 return std::nullopt;
1373}
static llvm::raw_ostream & error(Stream &strm)
static llvm::raw_ostream & note(Stream &strm)
#define LLDB_LOGF(log,...)
Definition Log.h:389
#define LLDB_PLUGIN_DEFINE(PluginName)
static FileSpec CreateFileSpecFromPath(llvm::StringRef path)
Correctly create a FileSpec from a path found in a core file.
static void ParseOpenBSDProcInfo(ThreadData &thread_data, const DataExtractor &data)
static void ParseFreeBSDPrPsInfo(ProcessElfCore &process, const DataExtractor &data, bool lp64)
static void ParseFreeBSDPrStatus(ThreadData &thread_data, const DataExtractor &data, bool lp64)
static llvm::Error ParseNetBSDProcInfo(const DataExtractor &data, uint32_t &cpi_nlwps, uint32_t &cpi_signo, uint32_t &cpi_siglwp, uint32_t &cpi_pid)
@ AUXV_AT_EXECFN
Filename of executable.
Definition AuxVector.h:61
@ AUXV_AT_PHDR
Program headers.
Definition AuxVector.h:30
@ AUXV_AT_ENTRY
Program entry point.
Definition AuxVector.h:36
std::optional< uint64_t > GetAuxValue(enum EntryType entry_type) const
Definition AuxVector.cpp:34
static llvm::StringRef GetPluginNameStatic()
static llvm::StringRef GetPluginNameStatic()
Generic COFF object file reader.
lldb_private::DataExtractor GetSegmentData(const elf::ELFProgramHeader &H)
llvm::ArrayRef< elf::ELFProgramHeader > ProgramHeaders()
std::vector< NT_FILE_Entry > m_nt_file_entries
std::optional< NT_FILE_Entry > GetNTFileEntryForExecutableELFHeader()
Intelligently find the NT_FILE entry for the executable's ELF header.
std::set< lldb_private::MemoryRegionInfo, std::less<> > m_core_range_infos
lldb::addr_t GetImageInfoAddress() override
Get the image information address for the current process.
lldb::addr_t AddAddressRangeFromMemoryTagSegment(const elf::ELFProgramHeader &header)
lldb_private::DataExtractor m_auxv
bool FindModuleUUID(lldb_private::ModuleSpec &spec) override
Given a module spec, try to find the UUID information.
llvm::Error parseLinuxNotes(llvm::ArrayRef< lldb_private::CoreNote > notes)
A description of a linux process usually contains the following NOTE entries:
llvm::Error ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader &segment_header, const lldb_private::DataExtractor &segment_data)
Parse Thread context from PT_NOTE segment and store it in the thread list A note segment consists of ...
void UpdateBuildIdForNTFileEntries()
std::vector< ThreadData > m_thread_data
lldb_private::Range< lldb::addr_t, lldb::addr_t > FileRange
static void Initialize()
bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list) override
Update the thread list following process plug-in's specific logic.
static llvm::StringRef GetPluginDescriptionStatic()
std::unordered_map< std::string, lldb_private::UUID > m_uuids
llvm::Expected< std::vector< lldb_private::CoreNote > > parseSegment(const lldb_private::DataExtractor &segment)
lldb::addr_t AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader &header)
~ProcessElfCore() override
bool GetMainExecutableModuleSpec(lldb_private::ModuleSpec &exe_spec)
llvm::Error parseFreeBSDNotes(llvm::ArrayRef< lldb_private::CoreNote > notes)
size_t DoReadMemory(const lldb_private::ProcessAddress &addr, void *buf, size_t size, lldb_private::Status &error) override
Actually do the reading of memory from a process.
lldb_private::UUID FindBuidIdInCoreMemory(lldb::addr_t address)
VMRangeToFileOffset m_core_aranges
lldb_private::Status DoGetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &region_info) override
DoGetMemoryRegionInfo is called by GetMemoryRegionInfo after it has removed non address bits from loa...
Process::CoreArgs m_process_args
size_t ReadMemory(const lldb_private::ProcessAddress &addr, void *buf, size_t size, lldb_private::Status &error) override
Read of memory from a process.
VMRangeToFileOffset m_core_tag_ranges
llvm::Error parseNetBSDNotes(llvm::ArrayRef< lldb_private::CoreNote > notes)
NetBSD specific Thread context from PT_NOTE segment.
lldb_private::Status DoLoadCore() override
static void Terminate()
ProcessElfCore(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const lldb_private::FileSpec &core_file)
lldb_private::DynamicLoader * GetDynamicLoader() override
Get the dynamic loader plug-in for this process.
llvm::Expected< std::vector< lldb::addr_t > > ReadMemoryTags(lldb::addr_t addr, size_t len) override
Read memory tags for the range addr to addr+len.
lldb_private::DataExtractor GetAuxvData() override
bool IsAlive() override
Check if a process is still alive.
uint32_t GetNumThreadContexts()
std::string m_executable_name
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const lldb_private::FileSpec *crash_file_path, bool can_connect)
llvm::Error parseOpenBSDNotes(llvm::ArrayRef< lldb_private::CoreNote > notes)
void RefreshStateAfterStop() override
Currently called as part of ShouldStop.
lldb_private::ArchSpec GetArchitecture()
bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override
Check if a plug-in instance can debug the file in module.
std::optional< Process::CoreArgs > GetCoreFileArgs() override
Provide arguments of a command that triggered a core dump.
bool GetProcessInfo(lldb_private::ProcessInstanceInfo &info) override
static llvm::StringRef GetPluginNameStatic()
void FinalizeMemoryRegionInfos()
lldb::ModuleSP m_core_module_sp
std::optional< NT_FILE_Entry > GetNTFileEntryContainingAddress(lldb::addr_t addr)
Find the NT_FILE entry that contains an address.
lldb_private::Status DoDestroy() override
A section + offset based address class.
Definition Address.h:62
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition Address.cpp:303
bool IsValid() const
Check if the object state is valid.
Definition Address.h:355
An architecture specification class.
Definition ArchSpec.h:32
void MergeFrom(const ArchSpec &other)
Merges fields from another ArchSpec into this ArchSpec.
bool IsMIPS() const
if MIPS architecture return true.
Definition ArchSpec.cpp:749
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition ArchSpec.cpp:883
A command line argument class.
Definition Args.h:33
void DeleteArgumentAtIndex(size_t idx)
Deletes the argument value at index if idx is a valid argument index.
Definition Args.cpp:359
const char * GetArgumentAtIndex(size_t idx) const
Gets the null-terminated C string argument pointer for the argument at index idx.
Definition Args.cpp:273
An data extractor class.
virtual uint64_t GetByteSize() const
Get the number of bytes contained in this object.
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
A plug-in interface definition class for dynamic loaders.
static DynamicLoader * FindPlugin(Process *process, llvm::StringRef plugin_name)
Find a dynamic loader plugin for a given process.
A file utility class.
Definition FileSpec.h:56
static std::optional< Style > GuessPathStyle(llvm::StringRef absolute_path)
Attempt to guess path style for a given path string.
Definition FileSpec.cpp:326
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:380
llvm::sys::path::Style Style
Definition FileSpec.h:58
static FileSystem & Instance()
std::shared_ptr< DataBuffer > CreateDataBuffer(const llvm::Twine &path, uint64_t size=0, uint64_t offset=0)
Create memory buffer from path.
MemoryRegionInfo & SetMemoryTagged(LazyBool val)
void SetName(const char *name)
Range< lldb::addr_t, lldb::addr_t > RangeType
void SetLLDBPermissions(uint32_t permissions)
virtual llvm::Expected< std::vector< lldb::addr_t > > UnpackTagsFromCoreFileSegment(CoreReaderFn reader, lldb::addr_t tag_segment_virtual_address, lldb::addr_t tag_segment_data_address, lldb::addr_t addr, size_t len) const =0
static Status GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, llvm::SmallVectorImpl< lldb::ModuleSP > *old_modules, bool *did_create_ptr, bool invoke_locate_callback=true, bool invoke_symbol_locators=true)
void SetLoadAddress(lldb::addr_t addr)
Set the load address of a module in process memory.
Definition ModuleSpec.h:126
FileSpec & GetPlatformFileSpec()
Definition ModuleSpec.h:69
FileSpec & GetFileSpec()
Definition ModuleSpec.h:57
ArchSpec & GetArchitecture()
Definition ModuleSpec.h:93
void SetTarget(lldb::TargetSP target)
Set the target to be used when resolving a module.
Definition ModuleSpec.h:150
std::optional< lldb::addr_t > GetLoadAddress() const
Get the load address of a module in process memory.
Definition ModuleSpec.h:123
static lldb::ModuleSP CreateModuleFromObjectFile(Args &&...args)
Definition Module.h:136
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:46
virtual lldb_private::Address GetImageInfoAddress(Target *target)
Similar to Process::GetImageInfoAddress().
Definition ObjectFile.h:448
@ eTypeCoreFile
A core file that has a checkpoint of a program's execution state.
Definition ObjectFile.h:53
size_t CopyData(lldb::offset_t offset, size_t length, void *dst) const
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
PostMortemProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec &core_file)
An address in a process, qualified by an address space.
lldb::addr_t GetValue() const
void SetExecutableFile(const FileSpec &exe_file, bool add_exe_file_as_first_arg)
void SetArchitecture(const ArchSpec &arch)
Definition ProcessInfo.h:64
void SetArg0(llvm::StringRef arg)
void SetArguments(const Args &args, bool first_arg_is_executable)
void SetProcessID(lldb::pid_t pid)
Definition ProcessInfo.h:68
lldb::pid_t GetID() const
Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is no known pid.
Definition Process.h:552
void SetUnixSignals(lldb::UnixSignalsSP &&signals_sp)
Definition Process.cpp:3935
size_t ReadCStringFromMemory(lldb::addr_t vm_addr, char *cstr, size_t cstr_max_len, Status &error)
Read a null-terminated C string from memory.
Definition Process.cpp:2410
void SetCanJIT(bool can_jit)
Sets whether executing JIT-compiled code in this process is possible.
Definition Process.cpp:2769
lldb::DynamicLoaderUP m_dyld_up
Definition Process.h:3511
llvm::Expected< const MemoryTagManager * > GetMemoryTagManager()
If this architecture and process supports memory tagging, return a tag manager that can be used to ma...
Definition Process.cpp:6776
lldb::ByteOrder GetByteOrder() const
Definition Process.cpp:3945
llvm::Expected< lldb::ModuleSP > ReadModuleFromMemory(const FileSpec &file_spec, lldb::addr_t header_addr, size_t size_to_read=512)
Creates and populates a module using an in-memory object file.
Definition Process.cpp:2807
void SetID(lldb::pid_t new_pid)
Sets the stored pid.
Definition Process.h:557
uint32_t GetAddressByteSize() const
Definition Process.cpp:3949
virtual void Finalize(bool destructing)
This object is about to be destroyed, do any necessary cleanup.
Definition Process.cpp:596
ThreadList m_thread_list
The threads for this process as the user will see them.
Definition Process.h:3481
const lldb::UnixSignalsSP & GetUnixSignals()
Definition Process.cpp:3940
const lldb::ABISP & GetABI()
Definition Process.cpp:1525
friend class ThreadList
Definition Process.h:375
Target & GetTarget()
Get the target object pointer for this module.
Definition Process.h:1267
RangeData< lldb::addr_t, lldb::addr_t, FileRange > Entry
Definition RangeMap.h:462
An error handling class.
Definition Status.h:118
llvm::Error ToError() const
FIXME: Replace all uses with takeError() instead.
Definition Status.cpp:138
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
bool Fail() const
Test for error condition.
Definition Status.cpp:293
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:136
lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec, bool notify, Status *error_ptr=nullptr)
Find a binary on the system and return its Module, or return an existing Module that is already in th...
Definition Target.cpp:2470
bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform=false, bool merge=true)
Set the architecture for this target.
Definition Target.cpp:1807
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition Target.cpp:1630
const ArchSpec & GetArchitecture() const
Definition Target.h:1315
void RebuildModuleListWithExecutable(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Clear the module list and rebuild it around a new main executable.
Definition Target.cpp:1673
void AddThread(const lldb::ThreadSP &thread_sp)
uint32_t GetSize(bool can_update=true)
Represents UUID's of various sizes.
Definition UUID.h:27
std::string GetAsString(llvm::StringRef separator="-") const
Definition UUID.cpp:54
bool IsValid() const
Definition UUID.h:69
static lldb::UnixSignalsSP Create(const ArchSpec &arch)
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:338
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::Thread > ThreadSP
uint64_t offset_t
Definition lldb-types.h:86
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Listener > ListenerSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
uint64_t tid_t
Definition lldb-types.h:85
std::shared_ptr< lldb_private::Module > ModuleSP
lldb_private::Status Parse(const lldb_private::DataExtractor &data, const lldb_private::ArchSpec &arch)
static size_t GetSize(const lldb_private::ArchSpec &arch)
lldb_private::Status Parse(const lldb_private::DataExtractor &data, const lldb_private::ArchSpec &arch)
lldb::addr_t file_ofs
lldb::addr_t end
lldb::addr_t start
llvm::StringRef siginfo_bytes
lldb::tid_t tid
std::string name
lldb_private::DataExtractor gpregset
std::vector< lldb_private::CoreNote > notes
Generic representation of an ELF file header.
Definition ELFHeader.h:56
elf_off e_phoff
File offset of program header table.
Definition ELFHeader.h:59
elf_half e_phentsize
Size of a program header table entry.
Definition ELFHeader.h:66
static bool MagicBytesMatch(const uint8_t *magic)
Examines at most EI_NIDENT bytes starting from the given pointer and determines if the magic ELF iden...
bool Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset)
Parse an ELFHeader entry starting at position offset and update the data extractor with the address s...
elf_word e_phnum
Number of program header entries.
Definition ELFHeader.h:75
elf_word e_version
Version of object file (always 1).
Definition ELFHeader.h:62
unsigned char e_ident[llvm::ELF::EI_NIDENT]
ELF file identification.
Definition ELFHeader.h:57
elf_half e_type
Object file type.
Definition ELFHeader.h:63
Generic representation of an ELF program header.
Definition ELFHeader.h:192
bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
Parse an ELFProgramHeader entry from the given DataExtractor starting at position offset.
elf_word p_flags
Segment attributes.
Definition ELFHeader.h:194
elf_xword p_filesz
Byte size of the segment in file.
Definition ELFHeader.h:198
elf_off p_offset
Start of segment from beginning of file.
Definition ELFHeader.h:195
elf_addr p_vaddr
Virtual address of segment in memory.
Definition ELFHeader.h:196
elf_xword p_memsz
Byte size of the segment in memory.
Definition ELFHeader.h:199
elf_word p_type
Type of program segment.
Definition ELFHeader.h:193
BaseType GetRangeBase() const
Definition RangeMap.h:45
void SetRangeEnd(BaseType end)
Definition RangeMap.h:80
SizeType GetByteSize() const
Definition RangeMap.h:87
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
Definition RangeMap.h:48
BaseType GetRangeEnd() const
Definition RangeMap.h:78