Numerous fixes to stack unwinding for .eh_frame.

- 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.
This commit is contained in:
Rene Gollent 2012-12-23 16:30:51 -05:00
parent 3fbf5d6809
commit 16b8573bae
5 changed files with 145 additions and 101 deletions

View File

@ -625,8 +625,9 @@ 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())
@ -634,8 +635,9 @@ DwarfTypeFactory::_CreatePrimitiveType(const BString& name,
} 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())
@ -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(),
@ -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;
@ -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) {
@ -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;
@ -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;

View File

@ -11,6 +11,7 @@
#include "Architecture.h"
#include "ArrayIndexPath.h"
#include "CompilationUnit.h"
#include "Dwarf.h"
#include "DwarfFile.h"
#include "DwarfTargetInterface.h"
@ -162,6 +163,14 @@ DwarfTypeContext::~DwarfTypeContext()
}
uint8
DwarfTypeContext::AddressSize() const
{
return fCompilationUnit != NULL ? fCompilationUnit->AddressSize()
: fArchitecture->AddressSize();
}
// #pragma mark - DwarfType
@ -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;
@ -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();
@ -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();
@ -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();
@ -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())
@ -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(),
@ -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(),

View File

@ -81,6 +81,7 @@ public:
{ return fTargetInterface; }
RegisterMap* FromDwarfRegisterMap() const
{ return fFromDwarfRegisterMap; }
uint8 AddressSize() const;
private:
Architecture* fArchitecture;

View File

@ -61,13 +61,13 @@ struct DwarfFile::ExpressionEvaluationContext
: DwarfExpressionEvaluationContext {
public:
ExpressionEvaluationContext(DwarfFile* file, CompilationUnit* unit,
DIESubprogram* subprogramEntry,
uint8 addressSize, DIESubprogram* subprogramEntry,
const DwarfTargetInterface* targetInterface,
target_addr_t instructionPointer, target_addr_t objectPointer,
bool hasObjectPointer, target_addr_t framePointer,
target_addr_t relocationDelta)
:
DwarfExpressionEvaluationContext(targetInterface, unit->AddressSize(),
DwarfExpressionEvaluationContext(targetInterface, addressSize,
relocationDelta),
fFile(file),
fUnit(unit),
@ -254,9 +254,13 @@ struct DwarfFile::CIEAugmentation {
fFlags |= CFI_AUGMENTATION_DATA;
const char* string = fString + 1;
// read the augmentation data block -- it is preceeded by an
// LEB128 indicating the length of the data block
uint64 length = dataReader.ReadUnsignedLEB128(0);
uint64 remaining = length;
// let's see what data we have to expect
TRACE_CFI(" %" B_PRIu64 " bytes of augmentation data\n", length);
while (*string != '\0') {
switch (*string) {
case 'L':
@ -265,10 +269,14 @@ struct DwarfFile::CIEAugmentation {
--remaining;
break;
case 'P':
fFlags |= CFI_AUGMENTATION_PERSONALITY;
dataReader.Read<char>(0);
--remaining;
break;
{
char personalityEncoding = dataReader.Read<char>(0);
uint8 addressSize = EncodedAddressSize(
personalityEncoding, NULL);
dataReader.Skip(addressSize);
remaining -= addressSize + 1;
break;
}
case 'R':
fFlags |= CFI_AUGMENTATION_ADDRESS_POINTER_FORMAT;
fAddressEncoding = dataReader.Read<char>(0);
@ -280,14 +288,11 @@ struct DwarfFile::CIEAugmentation {
string++;
}
// read the augmentation data block -- it is preceeded by an
// LEB128 indicating the length of the data block
dataReader.Skip(remaining);
TRACE_CFI(" %" B_PRIu64 " bytes of augmentation data\n", length);
if (dataReader.HasOverflow())
if (remaining != 0 || dataReader.HasOverflow()) {
WARNING("Error while reading CIE Augmentation\n");
return B_BAD_DATA;
}
return B_OK;
}
@ -335,21 +340,28 @@ struct DwarfFile::CIEAugmentation {
return (fFlags & CFI_AUGMENTATION_ADDRESS_POINTER_FORMAT) != 0;
}
target_addr_t FDEAddressOffset(ElfFile* file) const
target_addr_t FDEAddressOffset(ElfFile* file,
ElfSection* debugFrameSection) const
{
switch (FDEAddressType()) {
// function relative is currently equivalent to absolute
// in all the cases in which it gets generated
case CFI_ADDRESS_FORMAT_ABSOLUTE:
TRACE_CFI("FDE address format: absolute, ");
return 0;
case CFI_ADDRESS_TYPE_PC_RELATIVE:
TRACE_CFI("FDE address format: PC relative, ");
return debugFrameSection->LoadAddress();
case CFI_ADDRESS_TYPE_FUNCTION_RELATIVE:
TRACE_CFI("FDE address format: function relative, ");
return 0;
case CFI_ADDRESS_TYPE_TEXT_RELATIVE:
TRACE_CFI("FDE address format: text relative, ");
return file->TextSegment()->LoadAddress();
case CFI_ADDRESS_TYPE_DATA_RELATIVE:
TRACE_CFI("FDE address format: data relative, ");
return file->DataSegment()->LoadAddress();
case CFI_ADDRESS_TYPE_ALIGNED:
case CFI_ADDRESS_TYPE_INDIRECT:
TRACE_CFI("FDE address format: UNIMPLEMENTED, ");
// TODO: implement
// -- note: type indirect is currently not generated
return 0;
@ -358,9 +370,9 @@ struct DwarfFile::CIEAugmentation {
return 0;
}
int8 FDEAddressSize(CompilationUnit* unit) const
int8 EncodedAddressSize(char encoding, CompilationUnit* unit) const
{
switch (fAddressEncoding & 0x07) {
switch (encoding & 0x07) {
case CFI_ADDRESS_FORMAT_ABSOLUTE:
return unit->AddressSize();
case CFI_ADDRESS_FORMAT_UNSIGNED_16:
@ -382,36 +394,47 @@ struct DwarfFile::CIEAugmentation {
}
target_addr_t ReadEncodedAddress(DataReader &reader,
ElfFile* file) const
ElfFile* file, ElfSection* debugFrameSection,
bool valueOnly = false) const
{
target_addr_t address = FDEAddressOffset(file);
target_addr_t address = valueOnly ? 0 : FDEAddressOffset(file,
debugFrameSection);
switch (fAddressEncoding & 0x0f) {
case CFI_ADDRESS_FORMAT_ABSOLUTE:
address += reader.ReadAddress(0);
TRACE_CFI(" target address: %" B_PRId64 "\n", address);
break;
case CFI_ADDRESS_FORMAT_UNSIGNED_LEB128:
address += reader.ReadUnsignedLEB128(0);
TRACE_CFI(" unsigned LEB128: %" B_PRId64 "\n", address);
break;
case CFI_ADDRESS_FORMAT_SIGNED_LEB128:
address += reader.ReadSignedLEB128(0);
TRACE_CFI(" signed LEB128: %" B_PRId64 "\n", address);
break;
case CFI_ADDRESS_FORMAT_UNSIGNED_16:
address += reader.Read<uint16>(0);
TRACE_CFI(" unsigned 16-bit: %" B_PRId64 "\n", address);
break;
case CFI_ADDRESS_FORMAT_SIGNED_16:
address += reader.Read<int16>(0);
TRACE_CFI(" signed 16-bit: %" B_PRId64 "\n", address);
break;
case CFI_ADDRESS_FORMAT_UNSIGNED_32:
address += reader.Read<uint32>(0);
TRACE_CFI(" unsigned 32-bit: %" B_PRId64 "\n", address);
break;
case CFI_ADDRESS_FORMAT_SIGNED_32:
address += reader.Read<int32>(0);
TRACE_CFI(" signed 32-bit: %" B_PRId64 "\n", address);
break;
case CFI_ADDRESS_FORMAT_UNSIGNED_64:
address += reader.Read<uint64>(0);
TRACE_CFI(" unsigned 64-bit: %" B_PRId64 "\n", address);
break;
case CFI_ADDRESS_FORMAT_SIGNED_64:
address += reader.Read<int64>(0);
TRACE_CFI(" signed 64-bit: %" B_PRId64 "\n", address);
break;
}
@ -725,14 +748,15 @@ DwarfFile::UnwindCallFrame(CompilationUnit* unit, uint8 addressSize,
status_t
DwarfFile::EvaluateExpression(CompilationUnit* unit,
DwarfFile::EvaluateExpression(CompilationUnit* unit, uint8 addressSize,
DIESubprogram* subprogramEntry, const void* expression,
off_t expressionLength, const DwarfTargetInterface* targetInterface,
target_addr_t instructionPointer, target_addr_t framePointer,
target_addr_t valueToPush, bool pushValue, target_addr_t& _result)
{
ExpressionEvaluationContext context(this, unit, subprogramEntry,
targetInterface, instructionPointer, 0, false, framePointer, 0);
ExpressionEvaluationContext context(this, unit, addressSize,
subprogramEntry, targetInterface, instructionPointer, 0, false,
framePointer, 0);
DwarfExpressionEvaluator evaluator(&context);
if (pushValue && evaluator.Push(valueToPush) != B_OK)
@ -743,7 +767,7 @@ DwarfFile::EvaluateExpression(CompilationUnit* unit,
status_t
DwarfFile::ResolveLocation(CompilationUnit* unit,
DwarfFile::ResolveLocation(CompilationUnit* unit, uint8 addressSize,
DIESubprogram* subprogramEntry, const LocationDescription* location,
const DwarfTargetInterface* targetInterface,
target_addr_t instructionPointer, target_addr_t objectPointer,
@ -759,9 +783,9 @@ DwarfFile::ResolveLocation(CompilationUnit* unit,
return error;
// evaluate it
ExpressionEvaluationContext context(this, unit, subprogramEntry,
targetInterface, instructionPointer, objectPointer, hasObjectPointer,
framePointer, relocationDelta);
ExpressionEvaluationContext context(this, unit, addressSize,
subprogramEntry, targetInterface, instructionPointer, objectPointer,
hasObjectPointer, framePointer, relocationDelta);
DwarfExpressionEvaluator evaluator(&context);
return evaluator.EvaluateLocation(expression, expressionLength,
_result);
@ -769,7 +793,7 @@ DwarfFile::ResolveLocation(CompilationUnit* unit,
status_t
DwarfFile::EvaluateConstantValue(CompilationUnit* unit,
DwarfFile::EvaluateConstantValue(CompilationUnit* unit, uint8 addressSize,
DIESubprogram* subprogramEntry, const ConstantAttributeValue* value,
const DwarfTargetInterface* targetInterface,
target_addr_t instructionPointer, target_addr_t framePointer,
@ -788,9 +812,10 @@ DwarfFile::EvaluateConstantValue(CompilationUnit* unit,
case ATTRIBUTE_CLASS_BLOCK:
{
target_addr_t result;
status_t error = EvaluateExpression(unit, subprogramEntry,
value->block.data, value->block.length, targetInterface,
instructionPointer, framePointer, 0, false, result);
status_t error = EvaluateExpression(unit, addressSize,
subprogramEntry, value->block.data, value->block.length,
targetInterface, instructionPointer, framePointer, 0, false,
result);
if (error != B_OK)
return error;
@ -804,7 +829,7 @@ DwarfFile::EvaluateConstantValue(CompilationUnit* unit,
status_t
DwarfFile::EvaluateDynamicValue(CompilationUnit* unit,
DwarfFile::EvaluateDynamicValue(CompilationUnit* unit, uint8 addressSize,
DIESubprogram* subprogramEntry, const DynamicAttributeValue* value,
const DwarfTargetInterface* targetInterface,
target_addr_t instructionPointer, target_addr_t framePointer,
@ -887,9 +912,9 @@ DwarfFile::EvaluateDynamicValue(CompilationUnit* unit,
if (constantValue == NULL || !constantValue->IsValid())
return B_BAD_VALUE;
status_t error = EvaluateConstantValue(unit, subprogramEntry,
constantValue, targetInterface, instructionPointer,
framePointer, _result);
status_t error = EvaluateConstantValue(unit, addressSize,
subprogramEntry, constantValue, targetInterface,
instructionPointer, framePointer, _result);
if (error != B_OK)
return error;
@ -900,9 +925,10 @@ DwarfFile::EvaluateDynamicValue(CompilationUnit* unit,
case ATTRIBUTE_CLASS_BLOCK:
{
target_addr_t result;
status_t error = EvaluateExpression(unit, subprogramEntry,
value->block.data, value->block.length, targetInterface,
instructionPointer, framePointer, 0, false, result);
status_t error = EvaluateExpression(unit, addressSize,
subprogramEntry, value->block.data, value->block.length,
targetInterface, instructionPointer, framePointer, 0, false,
result);
if (error != B_OK)
return error;
@ -1540,28 +1566,18 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
return B_BAD_DATA;
target_addr_t initialLocation = cieAugmentation.ReadEncodedAddress(
dataReader, fElfFile);
target_size_t addressRange = cieAugmentation.ReadEncodedAddress(
dataReader, fElfFile);
dataReader, fElfFile, currentFrameSection);
target_addr_t addressRange = cieAugmentation.ReadEncodedAddress(
dataReader, fElfFile, currentFrameSection, true);
if (dataReader.HasOverflow())
return B_BAD_DATA;
// In the GCC 4 .eh_frame initialLocation is relative to the offset
// of the address.
if (usingEHFrameSection && gcc4EHFrameSection) {
// Note: We need to cast to the exact address width, since the
// initialLocation value can be (and likely is) negative.
if (dwarf64) {
initialLocation = (uint64)currentFrameSection
->LoadAddress() + (uint64)initialLocationOffset
+ (uint64)initialLocation;
} else {
initialLocation = (uint32)currentFrameSection
->LoadAddress() + (uint32)initialLocationOffset
+ (uint32)initialLocation;
}
if ((cieAugmentation.FDEAddressType()
& CFI_ADDRESS_TYPE_PC_RELATIVE) != 0) {
initialLocation += initialLocationOffset;
}
// TODO: For GCC 2 .eh_frame sections things work differently: The
// initial locations are relocated by the runtime loader and
// afterwards point to the absolute addresses. Fortunately the
@ -1599,7 +1615,7 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
// process the CIE's frame info instructions
cieReader = cieReader.RestrictedReader(cieRemaining);
error = _ParseFrameInfoInstructions(unit, context,
cieReader);
cieReader, cieAugmentation);
if (error != B_OK)
return error;
@ -1623,7 +1639,7 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
DataReader restrictedReader =
dataReader.RestrictedReader(remaining);
error = _ParseFrameInfoInstructions(unit, context,
restrictedReader);
restrictedReader, cieAugmentation);
if (error != B_OK)
return error;
@ -1647,7 +1663,8 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
}
case CFA_CFA_RULE_EXPRESSION:
{
error = EvaluateExpression(unit, subprogramEntry,
error = EvaluateExpression(unit, addressSize,
subprogramEntry,
cfaCfaRule->Expression().block,
cfaCfaRule->Expression().size,
inputInterface, location, 0, 0, false,
@ -1721,7 +1738,8 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
TRACE_CFI(" -> CFA_RULE_LOCATION_EXPRESSION\n");
target_addr_t address;
error = EvaluateExpression(unit, subprogramEntry,
error = EvaluateExpression(unit, addressSize,
subprogramEntry,
rule->Expression().block,
rule->Expression().size,
inputInterface, location, frameAddress,
@ -1739,7 +1757,8 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
TRACE_CFI(" -> CFA_RULE_VALUE_EXPRESSION\n");
target_addr_t value;
error = EvaluateExpression(unit, subprogramEntry,
error = EvaluateExpression(unit, addressSize,
subprogramEntry,
rule->Expression().block,
rule->Expression().size,
inputInterface, location, frameAddress,
@ -1847,7 +1866,7 @@ DwarfFile::_ParseCIEHeader(ElfSection* debugFrameSection,
status_t
DwarfFile::_ParseFrameInfoInstructions(CompilationUnit* unit,
CfaContext& context, DataReader& dataReader)
CfaContext& context, DataReader& dataReader, CIEAugmentation& augmentation)
{
while (dataReader.BytesRemaining() > 0) {
TRACE_CFI(" [%2" B_PRId64 "]", dataReader.BytesRemaining());
@ -1898,7 +1917,8 @@ DwarfFile::_ParseFrameInfoInstructions(CompilationUnit* unit,
}
case DW_CFA_set_loc:
{
target_addr_t location = dataReader.ReadAddress(0);
target_addr_t location = augmentation.ReadEncodedAddress(
dataReader, fElfFile, fDebugFrameSection);
TRACE_CFI(" DW_CFA_set_loc: %#" B_PRIx64 "\n", location);

View File

@ -56,6 +56,7 @@ public:
target_addr_t& _framePointer);
status_t EvaluateExpression(CompilationUnit* unit,
uint8 addressSize,
DIESubprogram* subprogramEntry,
const void* expression,
off_t expressionLength,
@ -65,6 +66,7 @@ public:
target_addr_t valueToPush, bool pushValue,
target_addr_t& _result);
status_t ResolveLocation(CompilationUnit* unit,
uint8 addressSize,
DIESubprogram* subprogramEntry,
const LocationDescription* location,
const DwarfTargetInterface* targetInterface,
@ -79,13 +81,14 @@ public:
// bit offsets/sizes (cf. bit pieces).
status_t EvaluateConstantValue(CompilationUnit* unit,
uint8 addressSize,
DIESubprogram* subprogramEntry,
const ConstantAttributeValue* value,
const DwarfTargetInterface* targetInterface,
target_addr_t instructionPointer,
target_addr_t framePointer,
BVariant& _result);
status_t EvaluateDynamicValue(CompilationUnit* unit,
status_t EvaluateDynamicValue(CompilationUnit* unit, uint8 addressSize,
DIESubprogram* subprogramEntry,
const DynamicAttributeValue* value,
const DwarfTargetInterface* targetInterface,
@ -133,7 +136,8 @@ private:
off_t& _cieRemaining);
status_t _ParseFrameInfoInstructions(
CompilationUnit* unit, CfaContext& context,
DataReader& dataReader);
DataReader& dataReader,
CIEAugmentation& cieAugmentation);
status_t _ParsePublicTypesInfo();
status_t _ParsePublicTypesInfo(DataReader& dataReader,