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:
parent
3fbf5d6809
commit
16b8573bae
@ -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;
|
||||
|
@ -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(),
|
||||
|
@ -81,6 +81,7 @@ public:
|
||||
{ return fTargetInterface; }
|
||||
RegisterMap* FromDwarfRegisterMap() const
|
||||
{ return fFromDwarfRegisterMap; }
|
||||
uint8 AddressSize() const;
|
||||
|
||||
private:
|
||||
Architecture* fArchitecture;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user