Refactor Dwarf*DebugInfo to be able to work with limited info.
- DwarfImageDebugInfo and DwarfFile will now allow us to construct DWARF debug info objects even if the only section available for use is .eh_frame. This essentially allows us to use CFI-based unwinding even for release executables (assuming C++ is involved), which means we can properly unwind the stack even for binaries compiled with fomit-frame-pointer. This becomes more important for x86-64, since omit is the ABI default there. - Pull a GetFunctionsFromSymbols() out of DebuggerImageDebugInfo. This is shared between DebuggerImageDebugInfo and DwarfImageDebugInfo for creating debug information entries in the absence of debugging information.
This commit is contained in:
parent
dc95dfe60b
commit
5bda396ef4
@ -44,39 +44,8 @@ DebuggerImageDebugInfo::Init()
|
||||
status_t
|
||||
DebuggerImageDebugInfo::GetFunctions(BObjectList<FunctionDebugInfo>& functions)
|
||||
{
|
||||
BObjectList<SymbolInfo> symbols(20, true);
|
||||
status_t error = fDebuggerInterface->GetSymbolInfos(fImageInfo.TeamID(),
|
||||
fImageInfo.ImageID(), symbols);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// sort the symbols -- not necessary, but a courtesy to ImageDebugInfo which
|
||||
// will peform better when inserting functions at the end of a list
|
||||
symbols.SortItems(&_CompareSymbols);
|
||||
|
||||
// create the function infos
|
||||
int32 functionsAdded = 0;
|
||||
for (int32 i = 0; SymbolInfo* symbol = symbols.ItemAt(i); i++) {
|
||||
if (symbol->Type() != B_SYMBOL_TYPE_TEXT)
|
||||
continue;
|
||||
|
||||
FunctionDebugInfo* function = new(std::nothrow) BasicFunctionDebugInfo(
|
||||
this, symbol->Address(), symbol->Size(), symbol->Name(),
|
||||
Demangler::Demangle(symbol->Name()));
|
||||
if (function == NULL || !functions.AddItem(function)) {
|
||||
delete function;
|
||||
int32 index = functions.CountItems() - 1;
|
||||
for (; functionsAdded >= 0; functionsAdded--, index--) {
|
||||
function = functions.RemoveItemAt(index);
|
||||
delete function;
|
||||
}
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
functionsAdded++;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
return SpecificImageDebugInfo::GetFunctionsFromSymbols(functions,
|
||||
fDebuggerInterface, fImageInfo, this);
|
||||
}
|
||||
|
||||
|
||||
@ -144,12 +113,3 @@ DebuggerImageDebugInfo::AddSourceCodeInfo(LocatableFile* file,
|
||||
{
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ int
|
||||
DebuggerImageDebugInfo::_CompareSymbols(const SymbolInfo* a,
|
||||
const SymbolInfo* b)
|
||||
{
|
||||
return a->Address() < b->Address()
|
||||
? -1 : (a->Address() == b->Address() ? 0 : 1);
|
||||
}
|
||||
|
@ -54,10 +54,6 @@ public:
|
||||
virtual status_t AddSourceCodeInfo(LocatableFile* file,
|
||||
FileSourceCode* sourceCode);
|
||||
|
||||
private:
|
||||
static int _CompareSymbols(const SymbolInfo* a,
|
||||
const SymbolInfo* b);
|
||||
|
||||
private:
|
||||
ImageInfo fImageInfo;
|
||||
DebuggerInterface* fDebuggerInterface;
|
||||
|
@ -18,11 +18,14 @@
|
||||
#include <AutoLocker.h>
|
||||
|
||||
#include "Architecture.h"
|
||||
#include "BasicFunctionDebugInfo.h"
|
||||
#include "CLanguage.h"
|
||||
#include "CompilationUnit.h"
|
||||
#include "CppLanguage.h"
|
||||
#include "CpuState.h"
|
||||
#include "DebuggerInterface.h"
|
||||
#include "DebugInfoEntries.h"
|
||||
#include "Demangler.h"
|
||||
#include "Dwarf.h"
|
||||
#include "DwarfFile.h"
|
||||
#include "DwarfFunctionDebugInfo.h"
|
||||
@ -44,6 +47,7 @@
|
||||
#include "StackFrame.h"
|
||||
#include "Statement.h"
|
||||
#include "StringUtils.h"
|
||||
#include "SymbolInfo.h"
|
||||
#include "TargetAddressRangeList.h"
|
||||
#include "TeamMemory.h"
|
||||
#include "Tracing.h"
|
||||
@ -226,14 +230,14 @@ struct DwarfImageDebugInfo::EntryListWrapper {
|
||||
|
||||
|
||||
DwarfImageDebugInfo::DwarfImageDebugInfo(const ImageInfo& imageInfo,
|
||||
Architecture* architecture, TeamMemory* teamMemory,
|
||||
DebuggerInterface* interface, Architecture* architecture,
|
||||
FileManager* fileManager, GlobalTypeLookup* typeLookup,
|
||||
GlobalTypeCache* typeCache, DwarfFile* file)
|
||||
:
|
||||
fLock("dwarf image debug info"),
|
||||
fImageInfo(imageInfo),
|
||||
fDebuggerInterface(interface),
|
||||
fArchitecture(architecture),
|
||||
fTeamMemory(teamMemory),
|
||||
fFileManager(fileManager),
|
||||
fTypeLookup(typeLookup),
|
||||
fTypeCache(typeCache),
|
||||
@ -245,6 +249,7 @@ DwarfImageDebugInfo::DwarfImageDebugInfo(const ImageInfo& imageInfo,
|
||||
fPLTSectionStart(0),
|
||||
fPLTSectionEnd(0)
|
||||
{
|
||||
fDebuggerInterface->AcquireReference();
|
||||
fFile->AcquireReference();
|
||||
fTypeCache->AcquireReference();
|
||||
}
|
||||
@ -252,6 +257,7 @@ DwarfImageDebugInfo::DwarfImageDebugInfo(const ImageInfo& imageInfo,
|
||||
|
||||
DwarfImageDebugInfo::~DwarfImageDebugInfo()
|
||||
{
|
||||
fDebuggerInterface->ReleaseReference();
|
||||
fFile->ReleaseReference();
|
||||
fTypeCache->ReleaseReference();
|
||||
}
|
||||
@ -397,7 +403,13 @@ DwarfImageDebugInfo::GetFunctions(BObjectList<FunctionDebugInfo>& functions)
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
if (fFile->CountCompilationUnits() != 0)
|
||||
return B_OK;
|
||||
|
||||
// if we had no compilation units, fall back to providing basic
|
||||
// debug infos with DWARF-supported call frame unwinding
|
||||
return SpecificImageDebugInfo::GetFunctionsFromSymbols(functions,
|
||||
fDebuggerInterface, fImageInfo, this);
|
||||
}
|
||||
|
||||
|
||||
@ -419,7 +431,7 @@ DwarfImageDebugInfo::GetType(GlobalTypeCache* cache,
|
||||
// create the target interface
|
||||
BasicTargetInterface *inputInterface
|
||||
= new(std::nothrow) BasicTargetInterface(registers, registerCount,
|
||||
fromDwarfMap, fArchitecture, fTeamMemory);
|
||||
fromDwarfMap, fArchitecture, fDebuggerInterface);
|
||||
|
||||
if (inputInterface == NULL)
|
||||
return B_NO_MEMORY;
|
||||
@ -508,16 +520,17 @@ DwarfImageDebugInfo::CreateFrame(Image* image,
|
||||
{
|
||||
DwarfFunctionDebugInfo* function = dynamic_cast<DwarfFunctionDebugInfo*>(
|
||||
functionInstance->GetFunctionDebugInfo());
|
||||
if (function == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
FunctionID* functionID = functionInstance->GetFunctionID();
|
||||
if (functionID == NULL)
|
||||
return B_NO_MEMORY;
|
||||
BReference<FunctionID> functionIDReference(functionID, true);
|
||||
BReference<FunctionID> functionIDReference;
|
||||
if (functionID != NULL)
|
||||
functionIDReference.SetTo(functionID, true);
|
||||
|
||||
DIESubprogram* entry = function != NULL
|
||||
? function->SubprogramEntry() : NULL;
|
||||
|
||||
TRACE_CFI("DwarfImageDebugInfo::CreateFrame(): subprogram DIE: %p, "
|
||||
"function: %s\n", function->SubprogramEntry(),
|
||||
"function: %s\n", entry,
|
||||
functionID->FunctionName().String());
|
||||
|
||||
int32 registerCount = fArchitecture->CountRegisters();
|
||||
@ -543,7 +556,8 @@ DwarfImageDebugInfo::CreateFrame(Image* image,
|
||||
// create the target interfaces
|
||||
UnwindTargetInterface* inputInterface
|
||||
= new(std::nothrow) UnwindTargetInterface(registers, registerCount,
|
||||
fromDwarfMap, toDwarfMap, cpuState, fArchitecture, fTeamMemory);
|
||||
fromDwarfMap, toDwarfMap, cpuState, fArchitecture,
|
||||
fDebuggerInterface);
|
||||
if (inputInterface == NULL)
|
||||
return B_NO_MEMORY;
|
||||
BReference<UnwindTargetInterface> inputInterfaceReference(inputInterface,
|
||||
@ -552,7 +566,7 @@ DwarfImageDebugInfo::CreateFrame(Image* image,
|
||||
UnwindTargetInterface* outputInterface
|
||||
= new(std::nothrow) UnwindTargetInterface(registers, registerCount,
|
||||
fromDwarfMap, toDwarfMap, previousCpuState, fArchitecture,
|
||||
fTeamMemory);
|
||||
fDebuggerInterface);
|
||||
if (outputInterface == NULL)
|
||||
return B_NO_MEMORY;
|
||||
BReference<UnwindTargetInterface> outputInterfaceReference(outputInterface,
|
||||
@ -562,8 +576,9 @@ DwarfImageDebugInfo::CreateFrame(Image* image,
|
||||
target_addr_t instructionPointer
|
||||
= cpuState->InstructionPointer() - fRelocationDelta;
|
||||
target_addr_t framePointer;
|
||||
CompilationUnit* unit = function->GetCompilationUnit();
|
||||
error = fFile->UnwindCallFrame(unit, function->SubprogramEntry(),
|
||||
CompilationUnit* unit = function != NULL ? function->GetCompilationUnit()
|
||||
: NULL;
|
||||
error = fFile->UnwindCallFrame(unit, fArchitecture->AddressSize(), entry,
|
||||
instructionPointer, inputInterface, outputInterface, framePointer);
|
||||
|
||||
if (error != B_OK) {
|
||||
@ -585,7 +600,8 @@ DwarfImageDebugInfo::CreateFrame(Image* image,
|
||||
)
|
||||
|
||||
// create the stack frame debug info
|
||||
DIESubprogram* subprogramEntry = function->SubprogramEntry();
|
||||
DIESubprogram* subprogramEntry = function != NULL ?
|
||||
function->SubprogramEntry() : NULL;
|
||||
DwarfStackFrameDebugInfo* stackFrameDebugInfo
|
||||
= new(std::nothrow) DwarfStackFrameDebugInfo(fArchitecture,
|
||||
fImageInfo.ImageID(), fFile, unit, subprogramEntry, fTypeLookup,
|
||||
@ -616,35 +632,41 @@ DwarfImageDebugInfo::CreateFrame(Image* image,
|
||||
// Note, this is correct, since we actually retrieved the return
|
||||
// address. Our caller will fix the IP for us.
|
||||
|
||||
// create function parameter objects
|
||||
for (DebugInfoEntryList::ConstIterator it = subprogramEntry->Parameters()
|
||||
.GetIterator(); DebugInfoEntry* entry = it.Next();) {
|
||||
if (entry->Tag() != DW_TAG_formal_parameter)
|
||||
continue;
|
||||
// The subprogram entry may not be available since this may be a case
|
||||
// where .eh_frame was used to unwind the stack without other DWARF
|
||||
// info being available.
|
||||
if (subprogramEntry != NULL) {
|
||||
// create function parameter objects
|
||||
for (DebugInfoEntryList::ConstIterator it
|
||||
= subprogramEntry->Parameters().GetIterator();
|
||||
DebugInfoEntry* entry = it.Next();) {
|
||||
if (entry->Tag() != DW_TAG_formal_parameter)
|
||||
continue;
|
||||
|
||||
BString parameterName;
|
||||
DwarfUtils::GetDIEName(entry, parameterName);
|
||||
if (parameterName.Length() == 0)
|
||||
continue;
|
||||
BString parameterName;
|
||||
DwarfUtils::GetDIEName(entry, parameterName);
|
||||
if (parameterName.Length() == 0)
|
||||
continue;
|
||||
|
||||
DIEFormalParameter* parameterEntry
|
||||
= dynamic_cast<DIEFormalParameter*>(entry);
|
||||
Variable* parameter;
|
||||
if (stackFrameDebugInfo->CreateParameter(functionID, parameterEntry,
|
||||
parameter) != B_OK) {
|
||||
continue;
|
||||
DIEFormalParameter* parameterEntry
|
||||
= dynamic_cast<DIEFormalParameter*>(entry);
|
||||
Variable* parameter;
|
||||
if (stackFrameDebugInfo->CreateParameter(functionID,
|
||||
parameterEntry, parameter) != B_OK) {
|
||||
continue;
|
||||
}
|
||||
BReference<Variable> parameterReference(parameter, true);
|
||||
|
||||
if (!frame->AddParameter(parameter))
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
BReference<Variable> parameterReference(parameter, true);
|
||||
|
||||
if (!frame->AddParameter(parameter))
|
||||
return B_NO_MEMORY;
|
||||
// create objects for the local variables
|
||||
_CreateLocalVariables(unit, frame, functionID, *stackFrameDebugInfo,
|
||||
instructionPointer, functionInstance->Address() - fRelocationDelta,
|
||||
subprogramEntry->Variables(), subprogramEntry->Blocks());
|
||||
}
|
||||
|
||||
// create objects for the local variables
|
||||
_CreateLocalVariables(unit, frame, functionID, *stackFrameDebugInfo,
|
||||
instructionPointer, functionInstance->Address() - fRelocationDelta,
|
||||
subprogramEntry->Variables(), subprogramEntry->Blocks());
|
||||
|
||||
_frame = frameReference.Detach();
|
||||
_previousCpuState = previousCpuStateReference.Detach();
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2010, Rene Gollent, rene@gollent.com.
|
||||
* Copyright 2010-2012, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef DWARF_IMAGE_DEBUG_INFO_H
|
||||
@ -19,6 +19,7 @@
|
||||
|
||||
class Architecture;
|
||||
class CompilationUnit;
|
||||
class DebuggerInterface;
|
||||
class DIEType;
|
||||
class DwarfStackFrameDebugInfo;
|
||||
class DwarfFile;
|
||||
@ -30,14 +31,13 @@ class GlobalTypeCache;
|
||||
class GlobalTypeLookup;
|
||||
class LocatableFile;
|
||||
class SourceCode;
|
||||
class TeamMemory;
|
||||
|
||||
|
||||
class DwarfImageDebugInfo : public SpecificImageDebugInfo {
|
||||
public:
|
||||
DwarfImageDebugInfo(const ImageInfo& imageInfo,
|
||||
DebuggerInterface* interface,
|
||||
Architecture* architecture,
|
||||
TeamMemory* teamMemory,
|
||||
FileManager* fileManager,
|
||||
GlobalTypeLookup* typeLookup,
|
||||
GlobalTypeCache* typeCache,
|
||||
@ -106,8 +106,8 @@ private:
|
||||
private:
|
||||
BLocker fLock;
|
||||
ImageInfo fImageInfo;
|
||||
DebuggerInterface* fDebuggerInterface;
|
||||
Architecture* fArchitecture;
|
||||
TeamMemory* fTeamMemory;
|
||||
FileManager* fFileManager;
|
||||
GlobalTypeLookup* fTypeLookup;
|
||||
GlobalTypeCache* fTypeCache;
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "DebuggerInterface.h"
|
||||
#include "DwarfFile.h"
|
||||
#include "DwarfImageDebugInfo.h"
|
||||
#include "DwarfManager.h"
|
||||
@ -17,22 +18,24 @@
|
||||
|
||||
|
||||
DwarfTeamDebugInfo::DwarfTeamDebugInfo(Architecture* architecture,
|
||||
TeamMemory* teamMemory, FileManager* fileManager,
|
||||
DebuggerInterface* interface, FileManager* fileManager,
|
||||
GlobalTypeLookup* typeLookup, GlobalTypeCache* typeCache)
|
||||
:
|
||||
fArchitecture(architecture),
|
||||
fTeamMemory(teamMemory),
|
||||
fDebuggerInterface(interface),
|
||||
fFileManager(fileManager),
|
||||
fManager(NULL),
|
||||
fTypeLookup(typeLookup),
|
||||
fTypeCache(typeCache)
|
||||
{
|
||||
fDebuggerInterface->AcquireReference();
|
||||
fTypeCache->AcquireReference();
|
||||
}
|
||||
|
||||
|
||||
DwarfTeamDebugInfo::~DwarfTeamDebugInfo()
|
||||
{
|
||||
fDebuggerInterface->ReleaseReference();
|
||||
fTypeCache->ReleaseReference();
|
||||
delete fManager;
|
||||
}
|
||||
@ -75,8 +78,8 @@ DwarfTeamDebugInfo::CreateImageDebugInfo(const ImageInfo& imageInfo,
|
||||
|
||||
// create the image debug info
|
||||
DwarfImageDebugInfo* debugInfo = new(std::nothrow) DwarfImageDebugInfo(
|
||||
imageInfo, fArchitecture, fTeamMemory, fFileManager, fTypeLookup,
|
||||
fTypeCache, file);
|
||||
imageInfo, fDebuggerInterface, fArchitecture, fFileManager,
|
||||
fTypeLookup, fTypeCache, file);
|
||||
if (debugInfo == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
|
||||
class Architecture;
|
||||
class DebuggerInterface;
|
||||
class DwarfManager;
|
||||
class FileManager;
|
||||
class ImageInfo;
|
||||
@ -20,7 +21,7 @@ class TeamMemory;
|
||||
class DwarfTeamDebugInfo : public SpecificTeamDebugInfo {
|
||||
public:
|
||||
DwarfTeamDebugInfo(Architecture* architecture,
|
||||
TeamMemory* teamMemory,
|
||||
DebuggerInterface* interface,
|
||||
FileManager* fileManager,
|
||||
GlobalTypeLookup* typeLookup,
|
||||
GlobalTypeCache* typeCache);
|
||||
@ -34,7 +35,7 @@ public:
|
||||
|
||||
private:
|
||||
Architecture* fArchitecture;
|
||||
TeamMemory* fTeamMemory;
|
||||
DebuggerInterface* fDebuggerInterface;
|
||||
FileManager* fFileManager;
|
||||
DwarfManager* fManager;
|
||||
GlobalTypeLookup* fTypeLookup;
|
||||
|
@ -5,7 +5,62 @@
|
||||
|
||||
#include "SpecificImageDebugInfo.h"
|
||||
|
||||
#include "BasicFunctionDebugInfo.h"
|
||||
#include "DebuggerInterface.h"
|
||||
#include "Demangler.h"
|
||||
#include "ImageInfo.h"
|
||||
#include "SymbolInfo.h"
|
||||
|
||||
|
||||
SpecificImageDebugInfo::~SpecificImageDebugInfo()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*static*/ status_t
|
||||
SpecificImageDebugInfo::GetFunctionsFromSymbols(
|
||||
BObjectList<FunctionDebugInfo>& functions, DebuggerInterface* interface,
|
||||
const ImageInfo& imageInfo, SpecificImageDebugInfo* info)
|
||||
{
|
||||
BObjectList<SymbolInfo> symbols(20, true);
|
||||
status_t error = interface->GetSymbolInfos(imageInfo.TeamID(),
|
||||
imageInfo.ImageID(), symbols);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// sort the symbols -- not necessary, but a courtesy to ImageDebugInfo which
|
||||
// will peform better when inserting functions at the end of a list
|
||||
symbols.SortItems(&_CompareSymbols);
|
||||
|
||||
// create the function infos
|
||||
int32 functionsAdded = 0;
|
||||
for (int32 i = 0; SymbolInfo* symbol = symbols.ItemAt(i); i++) {
|
||||
if (symbol->Type() != B_SYMBOL_TYPE_TEXT)
|
||||
continue;
|
||||
|
||||
FunctionDebugInfo* function = new(std::nothrow) BasicFunctionDebugInfo(
|
||||
info, symbol->Address(), symbol->Size(), symbol->Name(),
|
||||
Demangler::Demangle(symbol->Name()));
|
||||
if (function == NULL || !functions.AddItem(function)) {
|
||||
delete function;
|
||||
int32 index = functions.CountItems() - 1;
|
||||
for (; functionsAdded >= 0; functionsAdded--, index--) {
|
||||
function = functions.RemoveItemAt(index);
|
||||
delete function;
|
||||
}
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
functionsAdded++;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/*static*/ int
|
||||
SpecificImageDebugInfo::_CompareSymbols(const SymbolInfo* a,
|
||||
const SymbolInfo* b)
|
||||
{
|
||||
return a->Address() < b->Address()
|
||||
? -1 : (a->Address() == b->Address() ? 0 : 1);
|
||||
}
|
||||
|
@ -23,11 +23,13 @@ class FunctionDebugInfo;
|
||||
class FunctionInstance;
|
||||
class GlobalTypeCache;
|
||||
class Image;
|
||||
class ImageInfo;
|
||||
class LocatableFile;
|
||||
class SourceLanguage;
|
||||
class SourceLocation;
|
||||
class StackFrame;
|
||||
class Statement;
|
||||
class SymbolInfo;
|
||||
class Type;
|
||||
class TypeLookupConstraints;
|
||||
class ValueLocation;
|
||||
@ -76,6 +78,17 @@ public:
|
||||
|
||||
virtual status_t AddSourceCodeInfo(LocatableFile* file,
|
||||
FileSourceCode* sourceCode) = 0;
|
||||
|
||||
protected:
|
||||
static status_t GetFunctionsFromSymbols(
|
||||
BObjectList<FunctionDebugInfo>& functions,
|
||||
DebuggerInterface* interface,
|
||||
const ImageInfo& imageInfo,
|
||||
SpecificImageDebugInfo* info);
|
||||
|
||||
private:
|
||||
static int _CompareSymbols(const SymbolInfo* a,
|
||||
const SymbolInfo* b);
|
||||
};
|
||||
|
||||
|
||||
|
@ -386,10 +386,16 @@ DwarfFile::Load(const char* fileName)
|
||||
// .eh_frame doesn't appear to get copied into separate debug
|
||||
// info files properly, therefore always use it off the main
|
||||
// executable image
|
||||
fEHFrameSection = fElfFile->GetSection(".eh_frame");
|
||||
if (fEHFrameSection == NULL)
|
||||
fEHFrameSection = fElfFile->GetSection(".eh_frame");
|
||||
fDebugLocationSection = debugInfoFile->GetSection(".debug_loc");
|
||||
fDebugPublicTypesSection = debugInfoFile->GetSection(".debug_pubtypes");
|
||||
|
||||
if (fDebugInfoSection == NULL) {
|
||||
fFinished = true;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// iterate through the debug info section
|
||||
DataReader dataReader(fDebugInfoSection->Data(),
|
||||
fDebugInfoSection->Size(), 4);
|
||||
@ -570,7 +576,7 @@ DwarfFile::ResolveRangeList(CompilationUnit* unit, uint64 offset) const
|
||||
|
||||
|
||||
status_t
|
||||
DwarfFile::UnwindCallFrame(CompilationUnit* unit,
|
||||
DwarfFile::UnwindCallFrame(CompilationUnit* unit, uint8 addressSize,
|
||||
DIESubprogram* subprogramEntry, target_addr_t location,
|
||||
const DwarfTargetInterface* inputInterface,
|
||||
DwarfTargetInterface* outputInterface, target_addr_t& _framePointer)
|
||||
@ -579,15 +585,15 @@ DwarfFile::UnwindCallFrame(CompilationUnit* unit,
|
||||
|
||||
// first try to find the FDE in .debug_frame
|
||||
if (fDebugFrameSection != NULL) {
|
||||
result = _UnwindCallFrame(false, unit, subprogramEntry, location,
|
||||
inputInterface, outputInterface, _framePointer);
|
||||
result = _UnwindCallFrame(false, unit, addressSize, subprogramEntry,
|
||||
location, inputInterface, outputInterface, _framePointer);
|
||||
}
|
||||
|
||||
// if .debug_frame isn't present, or if the FDE wasn't found there,
|
||||
// try .eh_frame
|
||||
if (result == B_ENTRY_NOT_FOUND && fEHFrameSection != NULL) {
|
||||
result = _UnwindCallFrame(true, unit, subprogramEntry, location,
|
||||
inputInterface, outputInterface, _framePointer);
|
||||
result = _UnwindCallFrame(true, unit, addressSize, subprogramEntry,
|
||||
location, inputInterface, outputInterface, _framePointer);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -1329,7 +1335,7 @@ DwarfFile::_ParseLineInfo(CompilationUnit* unit)
|
||||
|
||||
status_t
|
||||
DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
|
||||
DIESubprogram* subprogramEntry, target_addr_t location,
|
||||
uint8 addressSize, DIESubprogram* subprogramEntry, target_addr_t location,
|
||||
const DwarfTargetInterface* inputInterface,
|
||||
DwarfTargetInterface* outputInterface, target_addr_t& _framePointer)
|
||||
{
|
||||
@ -1350,7 +1356,8 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
|
||||
TRACE_CFI("DwarfFile::_UnwindCallFrame(%#" B_PRIx64 ")\n", location);
|
||||
|
||||
DataReader dataReader((uint8*)currentFrameSection->Data(),
|
||||
currentFrameSection->Size(), unit->AddressSize());
|
||||
currentFrameSection->Size(), unit != NULL
|
||||
? unit->AddressSize() : addressSize);
|
||||
|
||||
while (dataReader.BytesRemaining() > 0) {
|
||||
// length
|
||||
@ -1448,7 +1455,7 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
|
||||
// process the CIE
|
||||
CIEAugmentation cieAugmentation;
|
||||
error = _ParseCIE(currentFrameSection, usingEHFrameSection,
|
||||
unit, context, cieID, cieAugmentation);
|
||||
unit, addressSize, context, cieID, cieAugmentation);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
@ -1618,20 +1625,22 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
|
||||
|
||||
status_t
|
||||
DwarfFile::_ParseCIE(ElfSection* debugFrameSection, bool usingEHFrameSection,
|
||||
CompilationUnit* unit, CfaContext& context, off_t cieOffset,
|
||||
CIEAugmentation& cieAugmentation)
|
||||
CompilationUnit* unit, uint8 addressSize, CfaContext& context,
|
||||
off_t cieOffset, CIEAugmentation& cieAugmentation)
|
||||
{
|
||||
if (cieOffset < 0 || cieOffset >= debugFrameSection->Size())
|
||||
return B_BAD_DATA;
|
||||
|
||||
DataReader dataReader((uint8*)debugFrameSection->Data() + cieOffset,
|
||||
debugFrameSection->Size() - cieOffset, unit->AddressSize());
|
||||
debugFrameSection->Size() - cieOffset, unit != NULL
|
||||
? unit->AddressSize() : addressSize);
|
||||
|
||||
// length
|
||||
bool dwarf64;
|
||||
uint64 length = dataReader.ReadInitialLength(dwarf64);
|
||||
if (length > (uint64)dataReader.BytesRemaining())
|
||||
return B_BAD_DATA;
|
||||
|
||||
off_t lengthOffset = dataReader.Offset();
|
||||
|
||||
// CIE ID/CIE pointer
|
||||
@ -2328,7 +2337,12 @@ DwarfFile::_LocateDebugInfo()
|
||||
if (fDebugInfoSection == NULL || fDebugAbbrevSection == NULL) {
|
||||
WARNING("DwarfManager::File::Load(\"%s\"): no "
|
||||
".debug_info or .debug_abbrev.\n", fName);
|
||||
return B_ERROR;
|
||||
|
||||
// if we at least have an EH frame, use that for stack unwinding
|
||||
// if nothing else.
|
||||
fEHFrameSection = fElfFile->GetSection(".eh_frame");
|
||||
if (fEHFrameSection == NULL)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
uint64 offset) const;
|
||||
|
||||
status_t UnwindCallFrame(CompilationUnit* unit,
|
||||
uint8 addressSize,
|
||||
DIESubprogram* subprogramEntry,
|
||||
target_addr_t location,
|
||||
const DwarfTargetInterface* inputInterface,
|
||||
@ -115,6 +116,7 @@ private:
|
||||
|
||||
status_t _UnwindCallFrame(bool usingEHFrameSection,
|
||||
CompilationUnit* unit,
|
||||
uint8 addressSize,
|
||||
DIESubprogram* subprogramEntry,
|
||||
target_addr_t location,
|
||||
const DwarfTargetInterface* inputInterface,
|
||||
@ -124,6 +126,7 @@ private:
|
||||
status_t _ParseCIE(ElfSection* debugFrameSection,
|
||||
bool usingEHFrameSection,
|
||||
CompilationUnit* unit,
|
||||
uint8 addressSize,
|
||||
CfaContext& context, off_t cieOffset,
|
||||
CIEAugmentation& cieAugmentation);
|
||||
status_t _ParseFrameInfoInstructions(
|
||||
|
Loading…
Reference in New Issue
Block a user