From 16b8573bae88a4ceabff6ba49db3357fd4e0a1da Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sun, 23 Dec 2012 16:30:51 -0500 Subject: [PATCH] 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. --- .../debugger/debug_info/DwarfTypeFactory.cpp | 42 +++--- src/apps/debugger/debug_info/DwarfTypes.cpp | 53 ++++--- src/apps/debugger/debug_info/DwarfTypes.h | 1 + src/apps/debugger/dwarf/DwarfFile.cpp | 142 ++++++++++-------- src/apps/debugger/dwarf/DwarfFile.h | 8 +- 5 files changed, 145 insertions(+), 101 deletions(-) diff --git a/src/apps/debugger/debug_info/DwarfTypeFactory.cpp b/src/apps/debugger/debug_info/DwarfTypeFactory.cpp index 76d2e163b9b..527e500d0a2 100644 --- a/src/apps/debugger/debug_info/DwarfTypeFactory.cpp +++ b/src/apps/debugger/debug_info/DwarfTypeFactory.cpp @@ -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; diff --git a/src/apps/debugger/debug_info/DwarfTypes.cpp b/src/apps/debugger/debug_info/DwarfTypes.cpp index 3c85e4b0ec0..20c52de259b 100644 --- a/src/apps/debugger/debug_info/DwarfTypes.cpp +++ b/src/apps/debugger/debug_info/DwarfTypes.cpp @@ -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())) { 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(), diff --git a/src/apps/debugger/debug_info/DwarfTypes.h b/src/apps/debugger/debug_info/DwarfTypes.h index 50983cc49d3..628bae54160 100644 --- a/src/apps/debugger/debug_info/DwarfTypes.h +++ b/src/apps/debugger/debug_info/DwarfTypes.h @@ -81,6 +81,7 @@ class DwarfTypeContext : public BReferenceable { { return fTargetInterface; } RegisterMap* FromDwarfRegisterMap() const { return fFromDwarfRegisterMap; } + uint8 AddressSize() const; private: Architecture* fArchitecture; diff --git a/src/apps/debugger/dwarf/DwarfFile.cpp b/src/apps/debugger/dwarf/DwarfFile.cpp index d076eb0c455..7c71714295b 100644 --- a/src/apps/debugger/dwarf/DwarfFile.cpp +++ b/src/apps/debugger/dwarf/DwarfFile.cpp @@ -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(0); - --remaining; - break; + { + char personalityEncoding = dataReader.Read(0); + uint8 addressSize = EncodedAddressSize( + personalityEncoding, NULL); + dataReader.Skip(addressSize); + remaining -= addressSize + 1; + break; + } case 'R': fFlags |= CFI_AUGMENTATION_ADDRESS_POINTER_FORMAT; fAddressEncoding = dataReader.Read(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(0); + TRACE_CFI(" unsigned 16-bit: %" B_PRId64 "\n", address); break; case CFI_ADDRESS_FORMAT_SIGNED_16: address += reader.Read(0); + TRACE_CFI(" signed 16-bit: %" B_PRId64 "\n", address); break; case CFI_ADDRESS_FORMAT_UNSIGNED_32: address += reader.Read(0); + TRACE_CFI(" unsigned 32-bit: %" B_PRId64 "\n", address); break; case CFI_ADDRESS_FORMAT_SIGNED_32: address += reader.Read(0); + TRACE_CFI(" signed 32-bit: %" B_PRId64 "\n", address); break; case CFI_ADDRESS_FORMAT_UNSIGNED_64: address += reader.Read(0); + TRACE_CFI(" unsigned 64-bit: %" B_PRId64 "\n", address); break; case CFI_ADDRESS_FORMAT_SIGNED_64: address += reader.Read(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); diff --git a/src/apps/debugger/dwarf/DwarfFile.h b/src/apps/debugger/dwarf/DwarfFile.h index 848720f27e6..458180c8f5b 100644 --- a/src/apps/debugger/dwarf/DwarfFile.h +++ b/src/apps/debugger/dwarf/DwarfFile.h @@ -56,6 +56,7 @@ class DwarfFile : public BReferenceable, target_addr_t& _framePointer); status_t EvaluateExpression(CompilationUnit* unit, + uint8 addressSize, DIESubprogram* subprogramEntry, const void* expression, off_t expressionLength, @@ -65,6 +66,7 @@ class DwarfFile : public BReferenceable, 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 @@ class DwarfFile : public BReferenceable, // 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 @@ class DwarfFile : public BReferenceable, off_t& _cieRemaining); status_t _ParseFrameInfoInstructions( CompilationUnit* unit, CfaContext& context, - DataReader& dataReader); + DataReader& dataReader, + CIEAugmentation& cieAugmentation); status_t _ParsePublicTypesInfo(); status_t _ParsePublicTypesInfo(DataReader& dataReader,