Add a new method GetFunctionAddressAndSizeVector to DWARFCallFrameInfo.
This returns a vector of <file address, size> entries for all of the functions in the module that have an eh_frame FDE. Update ObjectFileMachO to use the eh_frame FDE function addresses if the LC_FUNCTION_STARTS section is missing, to fill in the start addresses of any symbols that have been stripped from the binary. Generally speaking, lldb works best if it knows the actual start address of every function in a module - it's especially important for unwinding, where lldb inspects the instructions in the prologue of the function. In a stripped binary, it is deprived of this information and it reduces the quality of our unwinds and saved register retrieval. Other ObjectFile users may want to use the function addresses from DWARFCallFrameInfo to fill in any stripped symbols like ObjectFileMachO does already. <rdar://problem/13365659> llvm-svn: 177624
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
#include "lldb/Host/Host.h"
|
||||
#include "lldb/Host/FileSpec.h"
|
||||
#include "lldb/Symbol/ClangNamespaceDecl.h"
|
||||
#include "lldb/Symbol/DWARFCallFrameInfo.h"
|
||||
#include "lldb/Symbol/ObjectFile.h"
|
||||
#include "lldb/Target/Platform.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
@@ -1449,6 +1450,17 @@ ObjectFileMachO::ParseSymtab (bool minimize)
|
||||
eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
|
||||
|
||||
const bool is_arm = (m_header.cputype == llvm::MachO::CPUTypeARM);
|
||||
|
||||
// lldb works best if it knows the start addresss of all functions in a module.
|
||||
// Linker symbols or debug info are normally the best source of information for start addr / size but
|
||||
// they may be stripped in a released binary.
|
||||
// Two additional sources of information exist in Mach-O binaries:
|
||||
// LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each function's start address in the
|
||||
// binary, relative to the text section.
|
||||
// eh_frame - the eh_frame FDEs have the start addr & size of each function
|
||||
// LC_FUNCTION_STARTS is the fastest source to read in, and is present on all modern binaries.
|
||||
// Binaries built to run on older releases may need to use eh_frame information.
|
||||
|
||||
if (text_section_sp && function_starts_data.GetByteSize())
|
||||
{
|
||||
FunctionStarts::Entry function_start_entry;
|
||||
@@ -1462,6 +1474,27 @@ ObjectFileMachO::ParseSymtab (bool minimize)
|
||||
function_start_entry.addr += delta;
|
||||
function_starts.Append(function_start_entry);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (text_section_sp.get() && eh_frame_section_sp.get())
|
||||
{
|
||||
DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp, eRegisterKindGCC, true);
|
||||
DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
|
||||
eh_frame.GetFunctionAddressAndSizeVector (functions);
|
||||
addr_t text_base_addr = text_section_sp->GetFileAddress();
|
||||
size_t count = functions.GetSize();
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func = functions.GetEntryAtIndex (i);
|
||||
if (func)
|
||||
{
|
||||
FunctionStarts::Entry function_start_entry;
|
||||
function_start_entry.addr = func->base - text_base_addr;
|
||||
function_starts.Append(function_start_entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const size_t function_starts_count = function_starts.GetSize();
|
||||
|
||||
Reference in New Issue
Block a user