Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion lldb/include/lldb/Target/Process.h
Original file line number Diff line number Diff line change
Expand Up @@ -1923,9 +1923,30 @@ class Process : public std::enable_shared_from_this<Process>,
/// the instruction has completed executing.
bool GetWatchpointReportedAfter();

/// Load a module image from memory.
///
/// \param[in] file_spec
/// The path to use to represent this module. This will show up in the
/// the image list.
///
/// \param[in] header_addr
/// The address of the object file header.
///
/// \param[in] size_to_read
/// The number of contiguous bytes to read that can be used to provide
/// all of the data for this module in memory. If this value is set to
/// zero, the memory region that contains \a header_addr will be found
/// and the size will be to the end address of this memory region. If
/// there is no memory region info that contains \a header_addr, then
/// default to 512 bytes.
///
/// \return
/// A valid module shared pointer if this succeeds, or an empty shared
/// pointer if no ObjectFile plug-ins recognize the object file header or
/// memory can not be read from \a header_addr.
lldb::ModuleSP ReadModuleFromMemory(const FileSpec &file_spec,
lldb::addr_t header_addr,
size_t size_to_read = 512);
size_t size_to_read = 0);

/// Attempt to get the attributes for a region of memory in the process.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -538,16 +538,7 @@ void DynamicLoaderPOSIXDYLD::LoadVDSO() {

FileSpec file("[vdso]");

MemoryRegionInfo info;
Status status = m_process->GetMemoryRegionInfo(m_vdso_base, info);
if (status.Fail()) {
Log *log = GetLog(LLDBLog::DynamicLoader);
LLDB_LOG(log, "Failed to get vdso region info: {0}", status);
return;
}

if (ModuleSP module_sp = m_process->ReadModuleFromMemory(
file, m_vdso_base, info.GetRange().GetByteSize())) {
if (ModuleSP module_sp = m_process->ReadModuleFromMemory(file, m_vdso_base)) {
UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_vdso_base, false);
m_process->GetTarget().GetImages().AppendIfNeeded(module_sp);
}
Expand Down
20 changes: 20 additions & 0 deletions lldb/source/Target/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2544,6 +2544,26 @@ ModuleSP Process::ReadModuleFromMemory(const FileSpec &file_spec,
progress_up = std::make_unique<Progress>(
"Reading binary from memory", file_spec.GetFilename().GetString());

if (size_to_read == 0) {
// No size was provided, figure out the size of the memory region that
// contains "header_addr"
MemoryRegionInfo header_region_info;
Status error(GetMemoryRegionInfo(header_addr, header_region_info));
// Default to 512 in case we can't find a memory region.
size_to_read = 512;
if (error.Success()) {
// We found a memory region, set the range of bytes ro read to read to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set the range of bytes ro read to read to the end of the memory region.

Typo plus maybe rephrase to

set the range to read to the end of the memory region.

// the end of the memory region. This should be enough to contain the
// file header and important bits.
const auto &range = header_region_info.GetRange();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Echoing what Pavel said a little bit, I do think an upper bound makes sense. I think we can be pretty heavy handed with that upper-bound. I'm not an expert on ELF files by any means, but I suspect something like 10MB or even 100 MB, will be a sane expectation for even the largest set of ELF headers.

const addr_t end = range.GetRangeBase() + range.GetByteSize();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be an error?

The end should always be greater than the addr correct?

if (end > header_addr) {
const addr_t new_size = end - header_addr;
if (new_size > size_to_read)
size_to_read = new_size;
}
}
}
ObjectFile *objfile = module_sp->GetMemoryObjectFile(
shared_from_this(), header_addr, error, size_to_read);
if (objfile)
Expand Down
Loading