Skip to content

Commit

Permalink
Numerous fixes to stack unwinding for .eh_frame.
Browse files Browse the repository at this point in the history
- Add address size parameter to EvaluateExpression since the compilation
  unit may not be available (i.e. in non-debug code). Accordingly, also
  add accessor for address size to DwarfExpressionEvaluationContext,
  and adjust callers accordingly.

- Correctly handle augmentation 'P'. This one consists of a data byte
  describing the address encoding, followed by the address of the
  personality function encoded in the aforementioned format. Not
  skipping this correctly was resulting in us retrieving the wrong
  FDE address format in e.g. CIEs encoded with augmentation 'zPLR'.

- The address range should be retrieved as value only without accounting
  for the relative offset portion of the address encoding format. Fixes
  some issues where we'd pick the wrong FDE to use for unwinding due
  to us misinterpreting it as covering a far larger PC range than it
  in fact did.

- DW_CFA_set_loc also needs to respect the encoded address format.

Overall, these changes fix a number of regressions introduced by the
previous commits, and also mean that stack unwinding for x86-64 should
now work as expected in all cases where either debug information or
an exception table is available.
  • Loading branch information
anevilyak committed Dec 23, 2012
1 parent 3fbf5d6 commit 16b8573
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 101 deletions.
42 changes: 25 additions & 17 deletions src/apps/debugger/debug_info/DwarfTypeFactory.cpp
Expand Up @@ -625,17 +625,19 @@ DwarfTypeFactory::_CreatePrimitiveType(const BString& name,
if (byteSizeValue->IsValid()) {
BVariant value;
status_t error = fTypeContext->File()->EvaluateDynamicValue(
fTypeContext->GetCompilationUnit(), fTypeContext->SubprogramEntry(),
byteSizeValue, fTypeContext->TargetInterface(),
fTypeContext->GetCompilationUnit(), fTypeContext->AddressSize(),
fTypeContext->SubprogramEntry(), byteSizeValue,
fTypeContext->TargetInterface(),
fTypeContext->InstructionPointer(), fTypeContext->FramePointer(),
value);
if (error == B_OK && value.IsInteger())
bitSize = value.ToUInt32() * 8;
} else if (bitSizeValue->IsValid()) {
BVariant value;
status_t error = fTypeContext->File()->EvaluateDynamicValue(
fTypeContext->GetCompilationUnit(), fTypeContext->SubprogramEntry(),
bitSizeValue, fTypeContext->TargetInterface(),
fTypeContext->GetCompilationUnit(), fTypeContext->AddressSize(),
fTypeContext->SubprogramEntry(), bitSizeValue,
fTypeContext->TargetInterface(),
fTypeContext->InstructionPointer(), fTypeContext->FramePointer(),
value);
if (error == B_OK && value.IsInteger())
Expand Down Expand Up @@ -973,6 +975,7 @@ DwarfTypeFactory::_CreateEnumerationType(const BString& name,
BVariant value;
status_t error = fTypeContext->File()->EvaluateConstantValue(
fTypeContext->GetCompilationUnit(),
fTypeContext->AddressSize(),
fTypeContext->SubprogramEntry(), enumeratorEntry->ConstValue(),
fTypeContext->TargetInterface(),
fTypeContext->InstructionPointer(),
Expand Down Expand Up @@ -1019,10 +1022,12 @@ DwarfTypeFactory::_CreateSubrangeType(const BString& name,
// evaluate it
DIEType* valueType;
status_t error = fTypeContext->File()->EvaluateDynamicValue(
fTypeContext->GetCompilationUnit(), fTypeContext->SubprogramEntry(),
lowerBoundOwnerEntry->LowerBound(), fTypeContext->TargetInterface(),
fTypeContext->InstructionPointer(), fTypeContext->FramePointer(),
lowerBound, &valueType);
fTypeContext->GetCompilationUnit(), fTypeContext->AddressSize(),
fTypeContext->SubprogramEntry(),
lowerBoundOwnerEntry->LowerBound(),
fTypeContext->TargetInterface(),
fTypeContext->InstructionPointer(),
fTypeContext->FramePointer(), lowerBound, &valueType);
if (error != B_OK) {
WARNING(" failed to evaluate lower bound: %s\n", strerror(error));
return error;
Expand All @@ -1046,8 +1051,10 @@ DwarfTypeFactory::_CreateSubrangeType(const BString& name,
// evaluate it
DIEType* valueType;
status_t error = fTypeContext->File()->EvaluateDynamicValue(
fTypeContext->GetCompilationUnit(), fTypeContext->SubprogramEntry(),
upperBoundOwnerEntry->UpperBound(), fTypeContext->TargetInterface(),
fTypeContext->GetCompilationUnit(), fTypeContext->AddressSize(),
fTypeContext->SubprogramEntry(),
upperBoundOwnerEntry->UpperBound(),
fTypeContext->TargetInterface(),
fTypeContext->InstructionPointer(), fTypeContext->FramePointer(),
upperBound, &valueType);
if (error != B_OK) {
Expand All @@ -1069,10 +1076,10 @@ DwarfTypeFactory::_CreateSubrangeType(const BString& name,
DIEType* valueType;
status_t error = fTypeContext->File()->EvaluateDynamicValue(
fTypeContext->GetCompilationUnit(),
fTypeContext->SubprogramEntry(), countOwnerEntry->Count(),
fTypeContext->TargetInterface(),
fTypeContext->InstructionPointer(), fTypeContext->FramePointer(),
count, &valueType);
fTypeContext->AddressSize(), fTypeContext->SubprogramEntry(),
countOwnerEntry->Count(), fTypeContext->TargetInterface(),
fTypeContext->InstructionPointer(),
fTypeContext->FramePointer(), count, &valueType);
if (error != B_OK) {
WARNING(" failed to evaluate count: %s\n", strerror(error));
return error;
Expand Down Expand Up @@ -1375,9 +1382,10 @@ DwarfTypeFactory::_ResolveTypeByteSize(DIEType* typeEntry,
// get the actual value
BVariant size;
status_t error = fTypeContext->File()->EvaluateDynamicValue(
fTypeContext->GetCompilationUnit(), fTypeContext->SubprogramEntry(),
sizeValue, fTypeContext->TargetInterface(),
fTypeContext->InstructionPointer(), fTypeContext->FramePointer(), size);
fTypeContext->GetCompilationUnit(), fTypeContext->AddressSize(),
fTypeContext->SubprogramEntry(), sizeValue,
fTypeContext->TargetInterface(), fTypeContext->InstructionPointer(),
fTypeContext->FramePointer(), size);
if (error != B_OK) {
TRACE_LOCALS(" failed to resolve attribute: %s\n", strerror(error));
return error;
Expand Down
53 changes: 32 additions & 21 deletions src/apps/debugger/debug_info/DwarfTypes.cpp
Expand Up @@ -11,6 +11,7 @@

#include "Architecture.h"
#include "ArrayIndexPath.h"
#include "CompilationUnit.h"
#include "Dwarf.h"
#include "DwarfFile.h"
#include "DwarfTargetInterface.h"
Expand Down Expand Up @@ -162,6 +163,14 @@ DwarfTypeContext::~DwarfTypeContext()
}


uint8
DwarfTypeContext::AddressSize() const
{
return fCompilationUnit != NULL ? fCompilationUnit->AddressSize()
: fArchitecture->AddressSize();
}


// #pragma mark - DwarfType


Expand Down Expand Up @@ -310,11 +319,11 @@ DwarfType::ResolveLocation(DwarfTypeContext* typeContext,
bool hasObjectAddress, ValueLocation& _location)
{
status_t error = typeContext->File()->ResolveLocation(
typeContext->GetCompilationUnit(), typeContext->SubprogramEntry(),
description, typeContext->TargetInterface(),
typeContext->InstructionPointer(), objectAddress, hasObjectAddress,
typeContext->FramePointer(), typeContext->RelocationDelta(),
_location);
typeContext->GetCompilationUnit(), typeContext->AddressSize(),
typeContext->SubprogramEntry(), description,
typeContext->TargetInterface(), typeContext->InstructionPointer(),
objectAddress, hasObjectAddress, typeContext->FramePointer(),
typeContext->RelocationDelta(), _location);
if (error != B_OK)
return error;

Expand Down Expand Up @@ -707,10 +716,10 @@ DwarfCompoundType::ResolveDataMemberLocation(DataMember* _member,
if (memberEntry->ByteSize()->IsValid()) {
BVariant value;
error = typeContext->File()->EvaluateDynamicValue(
typeContext->GetCompilationUnit(), typeContext->SubprogramEntry(),
memberEntry->ByteSize(), typeContext->TargetInterface(),
typeContext->InstructionPointer(), typeContext->FramePointer(),
value);
typeContext->GetCompilationUnit(), typeContext->AddressSize(),
typeContext->SubprogramEntry(), memberEntry->ByteSize(),
typeContext->TargetInterface(), typeContext->InstructionPointer(),
typeContext->FramePointer(), value);
if (error != B_OK)
return error;
byteSize = value.ToUInt64();
Expand All @@ -722,10 +731,10 @@ DwarfCompoundType::ResolveDataMemberLocation(DataMember* _member,
if (memberEntry->BitOffset()->IsValid()) {
BVariant value;
error = typeContext->File()->EvaluateDynamicValue(
typeContext->GetCompilationUnit(), typeContext->SubprogramEntry(),
memberEntry->BitOffset(), typeContext->TargetInterface(),
typeContext->InstructionPointer(), typeContext->FramePointer(),
value);
typeContext->GetCompilationUnit(), typeContext->AddressSize(),
typeContext->SubprogramEntry(), memberEntry->BitOffset(),
typeContext->TargetInterface(), typeContext->InstructionPointer(),
typeContext->FramePointer(), value);
if (error != B_OK)
return error;
bitOffset = value.ToUInt64();
Expand All @@ -736,10 +745,10 @@ DwarfCompoundType::ResolveDataMemberLocation(DataMember* _member,
if (memberEntry->BitSize()->IsValid()) {
BVariant value;
error = typeContext->File()->EvaluateDynamicValue(
typeContext->GetCompilationUnit(), typeContext->SubprogramEntry(),
memberEntry->BitSize(), typeContext->TargetInterface(),
typeContext->InstructionPointer(), typeContext->FramePointer(),
value);
typeContext->GetCompilationUnit(), typeContext->AddressSize(),
typeContext->SubprogramEntry(), memberEntry->BitSize(),
typeContext->TargetInterface(), typeContext->InstructionPointer(),
typeContext->FramePointer(), value);
if (error != B_OK)
return error;
bitSize = value.ToUInt64();
Expand Down Expand Up @@ -944,10 +953,10 @@ DwarfArrayType::ResolveElementLocation(const ArrayIndexPath& indexPath,
fEntry, HasBitStridePredicate<DIEArrayType>())) {
BVariant value;
status_t error = typeContext->File()->EvaluateDynamicValue(
typeContext->GetCompilationUnit(), typeContext->SubprogramEntry(),
bitStrideOwnerEntry->BitStride(), typeContext->TargetInterface(),
typeContext->InstructionPointer(), typeContext->FramePointer(),
value);
typeContext->GetCompilationUnit(), typeContext->AddressSize(),
typeContext->SubprogramEntry(), bitStrideOwnerEntry->BitStride(),
typeContext->TargetInterface(), typeContext->InstructionPointer(),
typeContext->FramePointer(), value);
if (error != B_OK)
return error;
if (!value.IsInteger())
Expand Down Expand Up @@ -980,6 +989,7 @@ DwarfArrayType::ResolveElementLocation(const ArrayIndexPath& indexPath,
BVariant value;
status_t error = typeContext->File()->EvaluateDynamicValue(
typeContext->GetCompilationUnit(),
typeContext->AddressSize(),
typeContext->SubprogramEntry(),
bitStrideOwnerEntry->BitStride(),
typeContext->TargetInterface(),
Expand All @@ -998,6 +1008,7 @@ DwarfArrayType::ResolveElementLocation(const ArrayIndexPath& indexPath,
BVariant value;
status_t error = typeContext->File()->EvaluateDynamicValue(
typeContext->GetCompilationUnit(),
typeContext->AddressSize(),
typeContext->SubprogramEntry(),
byteStrideOwnerEntry->ByteStride(),
typeContext->TargetInterface(),
Expand Down
1 change: 1 addition & 0 deletions src/apps/debugger/debug_info/DwarfTypes.h
Expand Up @@ -81,6 +81,7 @@ class DwarfTypeContext : public BReferenceable {
{ return fTargetInterface; }
RegisterMap* FromDwarfRegisterMap() const
{ return fFromDwarfRegisterMap; }
uint8 AddressSize() const;

private:
Architecture* fArchitecture;
Expand Down

0 comments on commit 16b8573

Please sign in to comment.