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:
@@ -625,8 +625,9 @@ DwarfTypeFactory::_CreatePrimitiveType(const BString& name,
|
|||||||
if (byteSizeValue->IsValid()) {
|
if (byteSizeValue->IsValid()) {
|
||||||
BVariant value;
|
BVariant value;
|
||||||
status_t error = fTypeContext->File()->EvaluateDynamicValue(
|
status_t error = fTypeContext->File()->EvaluateDynamicValue(
|
||||||
fTypeContext->GetCompilationUnit(), fTypeContext->SubprogramEntry(),
|
fTypeContext->GetCompilationUnit(), fTypeContext->AddressSize(),
|
||||||
byteSizeValue, fTypeContext->TargetInterface(),
|
fTypeContext->SubprogramEntry(), byteSizeValue,
|
||||||
|
fTypeContext->TargetInterface(),
|
||||||
fTypeContext->InstructionPointer(), fTypeContext->FramePointer(),
|
fTypeContext->InstructionPointer(), fTypeContext->FramePointer(),
|
||||||
value);
|
value);
|
||||||
if (error == B_OK && value.IsInteger())
|
if (error == B_OK && value.IsInteger())
|
||||||
@@ -634,8 +635,9 @@ DwarfTypeFactory::_CreatePrimitiveType(const BString& name,
|
|||||||
} else if (bitSizeValue->IsValid()) {
|
} else if (bitSizeValue->IsValid()) {
|
||||||
BVariant value;
|
BVariant value;
|
||||||
status_t error = fTypeContext->File()->EvaluateDynamicValue(
|
status_t error = fTypeContext->File()->EvaluateDynamicValue(
|
||||||
fTypeContext->GetCompilationUnit(), fTypeContext->SubprogramEntry(),
|
fTypeContext->GetCompilationUnit(), fTypeContext->AddressSize(),
|
||||||
bitSizeValue, fTypeContext->TargetInterface(),
|
fTypeContext->SubprogramEntry(), bitSizeValue,
|
||||||
|
fTypeContext->TargetInterface(),
|
||||||
fTypeContext->InstructionPointer(), fTypeContext->FramePointer(),
|
fTypeContext->InstructionPointer(), fTypeContext->FramePointer(),
|
||||||
value);
|
value);
|
||||||
if (error == B_OK && value.IsInteger())
|
if (error == B_OK && value.IsInteger())
|
||||||
@@ -973,6 +975,7 @@ DwarfTypeFactory::_CreateEnumerationType(const BString& name,
|
|||||||
BVariant value;
|
BVariant value;
|
||||||
status_t error = fTypeContext->File()->EvaluateConstantValue(
|
status_t error = fTypeContext->File()->EvaluateConstantValue(
|
||||||
fTypeContext->GetCompilationUnit(),
|
fTypeContext->GetCompilationUnit(),
|
||||||
|
fTypeContext->AddressSize(),
|
||||||
fTypeContext->SubprogramEntry(), enumeratorEntry->ConstValue(),
|
fTypeContext->SubprogramEntry(), enumeratorEntry->ConstValue(),
|
||||||
fTypeContext->TargetInterface(),
|
fTypeContext->TargetInterface(),
|
||||||
fTypeContext->InstructionPointer(),
|
fTypeContext->InstructionPointer(),
|
||||||
@@ -1019,10 +1022,12 @@ DwarfTypeFactory::_CreateSubrangeType(const BString& name,
|
|||||||
// evaluate it
|
// evaluate it
|
||||||
DIEType* valueType;
|
DIEType* valueType;
|
||||||
status_t error = fTypeContext->File()->EvaluateDynamicValue(
|
status_t error = fTypeContext->File()->EvaluateDynamicValue(
|
||||||
fTypeContext->GetCompilationUnit(), fTypeContext->SubprogramEntry(),
|
fTypeContext->GetCompilationUnit(), fTypeContext->AddressSize(),
|
||||||
lowerBoundOwnerEntry->LowerBound(), fTypeContext->TargetInterface(),
|
fTypeContext->SubprogramEntry(),
|
||||||
fTypeContext->InstructionPointer(), fTypeContext->FramePointer(),
|
lowerBoundOwnerEntry->LowerBound(),
|
||||||
lowerBound, &valueType);
|
fTypeContext->TargetInterface(),
|
||||||
|
fTypeContext->InstructionPointer(),
|
||||||
|
fTypeContext->FramePointer(), lowerBound, &valueType);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
WARNING(" failed to evaluate lower bound: %s\n", strerror(error));
|
WARNING(" failed to evaluate lower bound: %s\n", strerror(error));
|
||||||
return error;
|
return error;
|
||||||
@@ -1046,8 +1051,10 @@ DwarfTypeFactory::_CreateSubrangeType(const BString& name,
|
|||||||
// evaluate it
|
// evaluate it
|
||||||
DIEType* valueType;
|
DIEType* valueType;
|
||||||
status_t error = fTypeContext->File()->EvaluateDynamicValue(
|
status_t error = fTypeContext->File()->EvaluateDynamicValue(
|
||||||
fTypeContext->GetCompilationUnit(), fTypeContext->SubprogramEntry(),
|
fTypeContext->GetCompilationUnit(), fTypeContext->AddressSize(),
|
||||||
upperBoundOwnerEntry->UpperBound(), fTypeContext->TargetInterface(),
|
fTypeContext->SubprogramEntry(),
|
||||||
|
upperBoundOwnerEntry->UpperBound(),
|
||||||
|
fTypeContext->TargetInterface(),
|
||||||
fTypeContext->InstructionPointer(), fTypeContext->FramePointer(),
|
fTypeContext->InstructionPointer(), fTypeContext->FramePointer(),
|
||||||
upperBound, &valueType);
|
upperBound, &valueType);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
@@ -1069,10 +1076,10 @@ DwarfTypeFactory::_CreateSubrangeType(const BString& name,
|
|||||||
DIEType* valueType;
|
DIEType* valueType;
|
||||||
status_t error = fTypeContext->File()->EvaluateDynamicValue(
|
status_t error = fTypeContext->File()->EvaluateDynamicValue(
|
||||||
fTypeContext->GetCompilationUnit(),
|
fTypeContext->GetCompilationUnit(),
|
||||||
fTypeContext->SubprogramEntry(), countOwnerEntry->Count(),
|
fTypeContext->AddressSize(), fTypeContext->SubprogramEntry(),
|
||||||
fTypeContext->TargetInterface(),
|
countOwnerEntry->Count(), fTypeContext->TargetInterface(),
|
||||||
fTypeContext->InstructionPointer(), fTypeContext->FramePointer(),
|
fTypeContext->InstructionPointer(),
|
||||||
count, &valueType);
|
fTypeContext->FramePointer(), count, &valueType);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
WARNING(" failed to evaluate count: %s\n", strerror(error));
|
WARNING(" failed to evaluate count: %s\n", strerror(error));
|
||||||
return error;
|
return error;
|
||||||
@@ -1375,9 +1382,10 @@ DwarfTypeFactory::_ResolveTypeByteSize(DIEType* typeEntry,
|
|||||||
// get the actual value
|
// get the actual value
|
||||||
BVariant size;
|
BVariant size;
|
||||||
status_t error = fTypeContext->File()->EvaluateDynamicValue(
|
status_t error = fTypeContext->File()->EvaluateDynamicValue(
|
||||||
fTypeContext->GetCompilationUnit(), fTypeContext->SubprogramEntry(),
|
fTypeContext->GetCompilationUnit(), fTypeContext->AddressSize(),
|
||||||
sizeValue, fTypeContext->TargetInterface(),
|
fTypeContext->SubprogramEntry(), sizeValue,
|
||||||
fTypeContext->InstructionPointer(), fTypeContext->FramePointer(), size);
|
fTypeContext->TargetInterface(), fTypeContext->InstructionPointer(),
|
||||||
|
fTypeContext->FramePointer(), size);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
TRACE_LOCALS(" failed to resolve attribute: %s\n", strerror(error));
|
TRACE_LOCALS(" failed to resolve attribute: %s\n", strerror(error));
|
||||||
return error;
|
return error;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "Architecture.h"
|
#include "Architecture.h"
|
||||||
#include "ArrayIndexPath.h"
|
#include "ArrayIndexPath.h"
|
||||||
|
#include "CompilationUnit.h"
|
||||||
#include "Dwarf.h"
|
#include "Dwarf.h"
|
||||||
#include "DwarfFile.h"
|
#include "DwarfFile.h"
|
||||||
#include "DwarfTargetInterface.h"
|
#include "DwarfTargetInterface.h"
|
||||||
@@ -162,6 +163,14 @@ DwarfTypeContext::~DwarfTypeContext()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8
|
||||||
|
DwarfTypeContext::AddressSize() const
|
||||||
|
{
|
||||||
|
return fCompilationUnit != NULL ? fCompilationUnit->AddressSize()
|
||||||
|
: fArchitecture->AddressSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - DwarfType
|
// #pragma mark - DwarfType
|
||||||
|
|
||||||
|
|
||||||
@@ -310,11 +319,11 @@ DwarfType::ResolveLocation(DwarfTypeContext* typeContext,
|
|||||||
bool hasObjectAddress, ValueLocation& _location)
|
bool hasObjectAddress, ValueLocation& _location)
|
||||||
{
|
{
|
||||||
status_t error = typeContext->File()->ResolveLocation(
|
status_t error = typeContext->File()->ResolveLocation(
|
||||||
typeContext->GetCompilationUnit(), typeContext->SubprogramEntry(),
|
typeContext->GetCompilationUnit(), typeContext->AddressSize(),
|
||||||
description, typeContext->TargetInterface(),
|
typeContext->SubprogramEntry(), description,
|
||||||
typeContext->InstructionPointer(), objectAddress, hasObjectAddress,
|
typeContext->TargetInterface(), typeContext->InstructionPointer(),
|
||||||
typeContext->FramePointer(), typeContext->RelocationDelta(),
|
objectAddress, hasObjectAddress, typeContext->FramePointer(),
|
||||||
_location);
|
typeContext->RelocationDelta(), _location);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
@@ -707,10 +716,10 @@ DwarfCompoundType::ResolveDataMemberLocation(DataMember* _member,
|
|||||||
if (memberEntry->ByteSize()->IsValid()) {
|
if (memberEntry->ByteSize()->IsValid()) {
|
||||||
BVariant value;
|
BVariant value;
|
||||||
error = typeContext->File()->EvaluateDynamicValue(
|
error = typeContext->File()->EvaluateDynamicValue(
|
||||||
typeContext->GetCompilationUnit(), typeContext->SubprogramEntry(),
|
typeContext->GetCompilationUnit(), typeContext->AddressSize(),
|
||||||
memberEntry->ByteSize(), typeContext->TargetInterface(),
|
typeContext->SubprogramEntry(), memberEntry->ByteSize(),
|
||||||
typeContext->InstructionPointer(), typeContext->FramePointer(),
|
typeContext->TargetInterface(), typeContext->InstructionPointer(),
|
||||||
value);
|
typeContext->FramePointer(), value);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
byteSize = value.ToUInt64();
|
byteSize = value.ToUInt64();
|
||||||
@@ -722,10 +731,10 @@ DwarfCompoundType::ResolveDataMemberLocation(DataMember* _member,
|
|||||||
if (memberEntry->BitOffset()->IsValid()) {
|
if (memberEntry->BitOffset()->IsValid()) {
|
||||||
BVariant value;
|
BVariant value;
|
||||||
error = typeContext->File()->EvaluateDynamicValue(
|
error = typeContext->File()->EvaluateDynamicValue(
|
||||||
typeContext->GetCompilationUnit(), typeContext->SubprogramEntry(),
|
typeContext->GetCompilationUnit(), typeContext->AddressSize(),
|
||||||
memberEntry->BitOffset(), typeContext->TargetInterface(),
|
typeContext->SubprogramEntry(), memberEntry->BitOffset(),
|
||||||
typeContext->InstructionPointer(), typeContext->FramePointer(),
|
typeContext->TargetInterface(), typeContext->InstructionPointer(),
|
||||||
value);
|
typeContext->FramePointer(), value);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
bitOffset = value.ToUInt64();
|
bitOffset = value.ToUInt64();
|
||||||
@@ -736,10 +745,10 @@ DwarfCompoundType::ResolveDataMemberLocation(DataMember* _member,
|
|||||||
if (memberEntry->BitSize()->IsValid()) {
|
if (memberEntry->BitSize()->IsValid()) {
|
||||||
BVariant value;
|
BVariant value;
|
||||||
error = typeContext->File()->EvaluateDynamicValue(
|
error = typeContext->File()->EvaluateDynamicValue(
|
||||||
typeContext->GetCompilationUnit(), typeContext->SubprogramEntry(),
|
typeContext->GetCompilationUnit(), typeContext->AddressSize(),
|
||||||
memberEntry->BitSize(), typeContext->TargetInterface(),
|
typeContext->SubprogramEntry(), memberEntry->BitSize(),
|
||||||
typeContext->InstructionPointer(), typeContext->FramePointer(),
|
typeContext->TargetInterface(), typeContext->InstructionPointer(),
|
||||||
value);
|
typeContext->FramePointer(), value);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
bitSize = value.ToUInt64();
|
bitSize = value.ToUInt64();
|
||||||
@@ -944,10 +953,10 @@ DwarfArrayType::ResolveElementLocation(const ArrayIndexPath& indexPath,
|
|||||||
fEntry, HasBitStridePredicate<DIEArrayType>())) {
|
fEntry, HasBitStridePredicate<DIEArrayType>())) {
|
||||||
BVariant value;
|
BVariant value;
|
||||||
status_t error = typeContext->File()->EvaluateDynamicValue(
|
status_t error = typeContext->File()->EvaluateDynamicValue(
|
||||||
typeContext->GetCompilationUnit(), typeContext->SubprogramEntry(),
|
typeContext->GetCompilationUnit(), typeContext->AddressSize(),
|
||||||
bitStrideOwnerEntry->BitStride(), typeContext->TargetInterface(),
|
typeContext->SubprogramEntry(), bitStrideOwnerEntry->BitStride(),
|
||||||
typeContext->InstructionPointer(), typeContext->FramePointer(),
|
typeContext->TargetInterface(), typeContext->InstructionPointer(),
|
||||||
value);
|
typeContext->FramePointer(), value);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
if (!value.IsInteger())
|
if (!value.IsInteger())
|
||||||
@@ -980,6 +989,7 @@ DwarfArrayType::ResolveElementLocation(const ArrayIndexPath& indexPath,
|
|||||||
BVariant value;
|
BVariant value;
|
||||||
status_t error = typeContext->File()->EvaluateDynamicValue(
|
status_t error = typeContext->File()->EvaluateDynamicValue(
|
||||||
typeContext->GetCompilationUnit(),
|
typeContext->GetCompilationUnit(),
|
||||||
|
typeContext->AddressSize(),
|
||||||
typeContext->SubprogramEntry(),
|
typeContext->SubprogramEntry(),
|
||||||
bitStrideOwnerEntry->BitStride(),
|
bitStrideOwnerEntry->BitStride(),
|
||||||
typeContext->TargetInterface(),
|
typeContext->TargetInterface(),
|
||||||
@@ -998,6 +1008,7 @@ DwarfArrayType::ResolveElementLocation(const ArrayIndexPath& indexPath,
|
|||||||
BVariant value;
|
BVariant value;
|
||||||
status_t error = typeContext->File()->EvaluateDynamicValue(
|
status_t error = typeContext->File()->EvaluateDynamicValue(
|
||||||
typeContext->GetCompilationUnit(),
|
typeContext->GetCompilationUnit(),
|
||||||
|
typeContext->AddressSize(),
|
||||||
typeContext->SubprogramEntry(),
|
typeContext->SubprogramEntry(),
|
||||||
byteStrideOwnerEntry->ByteStride(),
|
byteStrideOwnerEntry->ByteStride(),
|
||||||
typeContext->TargetInterface(),
|
typeContext->TargetInterface(),
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ public:
|
|||||||
{ return fTargetInterface; }
|
{ return fTargetInterface; }
|
||||||
RegisterMap* FromDwarfRegisterMap() const
|
RegisterMap* FromDwarfRegisterMap() const
|
||||||
{ return fFromDwarfRegisterMap; }
|
{ return fFromDwarfRegisterMap; }
|
||||||
|
uint8 AddressSize() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Architecture* fArchitecture;
|
Architecture* fArchitecture;
|
||||||
|
|||||||
@@ -61,13 +61,13 @@ struct DwarfFile::ExpressionEvaluationContext
|
|||||||
: DwarfExpressionEvaluationContext {
|
: DwarfExpressionEvaluationContext {
|
||||||
public:
|
public:
|
||||||
ExpressionEvaluationContext(DwarfFile* file, CompilationUnit* unit,
|
ExpressionEvaluationContext(DwarfFile* file, CompilationUnit* unit,
|
||||||
DIESubprogram* subprogramEntry,
|
uint8 addressSize, DIESubprogram* subprogramEntry,
|
||||||
const DwarfTargetInterface* targetInterface,
|
const DwarfTargetInterface* targetInterface,
|
||||||
target_addr_t instructionPointer, target_addr_t objectPointer,
|
target_addr_t instructionPointer, target_addr_t objectPointer,
|
||||||
bool hasObjectPointer, target_addr_t framePointer,
|
bool hasObjectPointer, target_addr_t framePointer,
|
||||||
target_addr_t relocationDelta)
|
target_addr_t relocationDelta)
|
||||||
:
|
:
|
||||||
DwarfExpressionEvaluationContext(targetInterface, unit->AddressSize(),
|
DwarfExpressionEvaluationContext(targetInterface, addressSize,
|
||||||
relocationDelta),
|
relocationDelta),
|
||||||
fFile(file),
|
fFile(file),
|
||||||
fUnit(unit),
|
fUnit(unit),
|
||||||
@@ -254,9 +254,13 @@ struct DwarfFile::CIEAugmentation {
|
|||||||
fFlags |= CFI_AUGMENTATION_DATA;
|
fFlags |= CFI_AUGMENTATION_DATA;
|
||||||
const char* string = fString + 1;
|
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 length = dataReader.ReadUnsignedLEB128(0);
|
||||||
uint64 remaining = length;
|
uint64 remaining = length;
|
||||||
// let's see what data we have to expect
|
// let's see what data we have to expect
|
||||||
|
|
||||||
|
TRACE_CFI(" %" B_PRIu64 " bytes of augmentation data\n", length);
|
||||||
while (*string != '\0') {
|
while (*string != '\0') {
|
||||||
switch (*string) {
|
switch (*string) {
|
||||||
case 'L':
|
case 'L':
|
||||||
@@ -265,10 +269,14 @@ struct DwarfFile::CIEAugmentation {
|
|||||||
--remaining;
|
--remaining;
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
fFlags |= CFI_AUGMENTATION_PERSONALITY;
|
{
|
||||||
dataReader.Read<char>(0);
|
char personalityEncoding = dataReader.Read<char>(0);
|
||||||
--remaining;
|
uint8 addressSize = EncodedAddressSize(
|
||||||
|
personalityEncoding, NULL);
|
||||||
|
dataReader.Skip(addressSize);
|
||||||
|
remaining -= addressSize + 1;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'R':
|
case 'R':
|
||||||
fFlags |= CFI_AUGMENTATION_ADDRESS_POINTER_FORMAT;
|
fFlags |= CFI_AUGMENTATION_ADDRESS_POINTER_FORMAT;
|
||||||
fAddressEncoding = dataReader.Read<char>(0);
|
fAddressEncoding = dataReader.Read<char>(0);
|
||||||
@@ -280,14 +288,11 @@ struct DwarfFile::CIEAugmentation {
|
|||||||
string++;
|
string++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the augmentation data block -- it is preceeded by an
|
|
||||||
// LEB128 indicating the length of the data block
|
|
||||||
dataReader.Skip(remaining);
|
dataReader.Skip(remaining);
|
||||||
|
if (remaining != 0 || dataReader.HasOverflow()) {
|
||||||
TRACE_CFI(" %" B_PRIu64 " bytes of augmentation data\n", length);
|
WARNING("Error while reading CIE Augmentation\n");
|
||||||
|
|
||||||
if (dataReader.HasOverflow())
|
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -335,21 +340,28 @@ struct DwarfFile::CIEAugmentation {
|
|||||||
return (fFlags & CFI_AUGMENTATION_ADDRESS_POINTER_FORMAT) != 0;
|
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()) {
|
switch (FDEAddressType()) {
|
||||||
// function relative is currently equivalent to absolute
|
|
||||||
// in all the cases in which it gets generated
|
|
||||||
case CFI_ADDRESS_FORMAT_ABSOLUTE:
|
case CFI_ADDRESS_FORMAT_ABSOLUTE:
|
||||||
|
TRACE_CFI("FDE address format: absolute, ");
|
||||||
|
return 0;
|
||||||
case CFI_ADDRESS_TYPE_PC_RELATIVE:
|
case CFI_ADDRESS_TYPE_PC_RELATIVE:
|
||||||
|
TRACE_CFI("FDE address format: PC relative, ");
|
||||||
|
return debugFrameSection->LoadAddress();
|
||||||
case CFI_ADDRESS_TYPE_FUNCTION_RELATIVE:
|
case CFI_ADDRESS_TYPE_FUNCTION_RELATIVE:
|
||||||
|
TRACE_CFI("FDE address format: function relative, ");
|
||||||
return 0;
|
return 0;
|
||||||
case CFI_ADDRESS_TYPE_TEXT_RELATIVE:
|
case CFI_ADDRESS_TYPE_TEXT_RELATIVE:
|
||||||
|
TRACE_CFI("FDE address format: text relative, ");
|
||||||
return file->TextSegment()->LoadAddress();
|
return file->TextSegment()->LoadAddress();
|
||||||
case CFI_ADDRESS_TYPE_DATA_RELATIVE:
|
case CFI_ADDRESS_TYPE_DATA_RELATIVE:
|
||||||
|
TRACE_CFI("FDE address format: data relative, ");
|
||||||
return file->DataSegment()->LoadAddress();
|
return file->DataSegment()->LoadAddress();
|
||||||
case CFI_ADDRESS_TYPE_ALIGNED:
|
case CFI_ADDRESS_TYPE_ALIGNED:
|
||||||
case CFI_ADDRESS_TYPE_INDIRECT:
|
case CFI_ADDRESS_TYPE_INDIRECT:
|
||||||
|
TRACE_CFI("FDE address format: UNIMPLEMENTED, ");
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
// -- note: type indirect is currently not generated
|
// -- note: type indirect is currently not generated
|
||||||
return 0;
|
return 0;
|
||||||
@@ -358,9 +370,9 @@ struct DwarfFile::CIEAugmentation {
|
|||||||
return 0;
|
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:
|
case CFI_ADDRESS_FORMAT_ABSOLUTE:
|
||||||
return unit->AddressSize();
|
return unit->AddressSize();
|
||||||
case CFI_ADDRESS_FORMAT_UNSIGNED_16:
|
case CFI_ADDRESS_FORMAT_UNSIGNED_16:
|
||||||
@@ -382,36 +394,47 @@ struct DwarfFile::CIEAugmentation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
target_addr_t ReadEncodedAddress(DataReader &reader,
|
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) {
|
switch (fAddressEncoding & 0x0f) {
|
||||||
case CFI_ADDRESS_FORMAT_ABSOLUTE:
|
case CFI_ADDRESS_FORMAT_ABSOLUTE:
|
||||||
address += reader.ReadAddress(0);
|
address += reader.ReadAddress(0);
|
||||||
|
TRACE_CFI(" target address: %" B_PRId64 "\n", address);
|
||||||
break;
|
break;
|
||||||
case CFI_ADDRESS_FORMAT_UNSIGNED_LEB128:
|
case CFI_ADDRESS_FORMAT_UNSIGNED_LEB128:
|
||||||
address += reader.ReadUnsignedLEB128(0);
|
address += reader.ReadUnsignedLEB128(0);
|
||||||
|
TRACE_CFI(" unsigned LEB128: %" B_PRId64 "\n", address);
|
||||||
break;
|
break;
|
||||||
case CFI_ADDRESS_FORMAT_SIGNED_LEB128:
|
case CFI_ADDRESS_FORMAT_SIGNED_LEB128:
|
||||||
address += reader.ReadSignedLEB128(0);
|
address += reader.ReadSignedLEB128(0);
|
||||||
|
TRACE_CFI(" signed LEB128: %" B_PRId64 "\n", address);
|
||||||
break;
|
break;
|
||||||
case CFI_ADDRESS_FORMAT_UNSIGNED_16:
|
case CFI_ADDRESS_FORMAT_UNSIGNED_16:
|
||||||
address += reader.Read<uint16>(0);
|
address += reader.Read<uint16>(0);
|
||||||
|
TRACE_CFI(" unsigned 16-bit: %" B_PRId64 "\n", address);
|
||||||
break;
|
break;
|
||||||
case CFI_ADDRESS_FORMAT_SIGNED_16:
|
case CFI_ADDRESS_FORMAT_SIGNED_16:
|
||||||
address += reader.Read<int16>(0);
|
address += reader.Read<int16>(0);
|
||||||
|
TRACE_CFI(" signed 16-bit: %" B_PRId64 "\n", address);
|
||||||
break;
|
break;
|
||||||
case CFI_ADDRESS_FORMAT_UNSIGNED_32:
|
case CFI_ADDRESS_FORMAT_UNSIGNED_32:
|
||||||
address += reader.Read<uint32>(0);
|
address += reader.Read<uint32>(0);
|
||||||
|
TRACE_CFI(" unsigned 32-bit: %" B_PRId64 "\n", address);
|
||||||
break;
|
break;
|
||||||
case CFI_ADDRESS_FORMAT_SIGNED_32:
|
case CFI_ADDRESS_FORMAT_SIGNED_32:
|
||||||
address += reader.Read<int32>(0);
|
address += reader.Read<int32>(0);
|
||||||
|
TRACE_CFI(" signed 32-bit: %" B_PRId64 "\n", address);
|
||||||
break;
|
break;
|
||||||
case CFI_ADDRESS_FORMAT_UNSIGNED_64:
|
case CFI_ADDRESS_FORMAT_UNSIGNED_64:
|
||||||
address += reader.Read<uint64>(0);
|
address += reader.Read<uint64>(0);
|
||||||
|
TRACE_CFI(" unsigned 64-bit: %" B_PRId64 "\n", address);
|
||||||
break;
|
break;
|
||||||
case CFI_ADDRESS_FORMAT_SIGNED_64:
|
case CFI_ADDRESS_FORMAT_SIGNED_64:
|
||||||
address += reader.Read<int64>(0);
|
address += reader.Read<int64>(0);
|
||||||
|
TRACE_CFI(" signed 64-bit: %" B_PRId64 "\n", address);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,14 +748,15 @@ DwarfFile::UnwindCallFrame(CompilationUnit* unit, uint8 addressSize,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DwarfFile::EvaluateExpression(CompilationUnit* unit,
|
DwarfFile::EvaluateExpression(CompilationUnit* unit, uint8 addressSize,
|
||||||
DIESubprogram* subprogramEntry, const void* expression,
|
DIESubprogram* subprogramEntry, const void* expression,
|
||||||
off_t expressionLength, const DwarfTargetInterface* targetInterface,
|
off_t expressionLength, const DwarfTargetInterface* targetInterface,
|
||||||
target_addr_t instructionPointer, target_addr_t framePointer,
|
target_addr_t instructionPointer, target_addr_t framePointer,
|
||||||
target_addr_t valueToPush, bool pushValue, target_addr_t& _result)
|
target_addr_t valueToPush, bool pushValue, target_addr_t& _result)
|
||||||
{
|
{
|
||||||
ExpressionEvaluationContext context(this, unit, subprogramEntry,
|
ExpressionEvaluationContext context(this, unit, addressSize,
|
||||||
targetInterface, instructionPointer, 0, false, framePointer, 0);
|
subprogramEntry, targetInterface, instructionPointer, 0, false,
|
||||||
|
framePointer, 0);
|
||||||
DwarfExpressionEvaluator evaluator(&context);
|
DwarfExpressionEvaluator evaluator(&context);
|
||||||
|
|
||||||
if (pushValue && evaluator.Push(valueToPush) != B_OK)
|
if (pushValue && evaluator.Push(valueToPush) != B_OK)
|
||||||
@@ -743,7 +767,7 @@ DwarfFile::EvaluateExpression(CompilationUnit* unit,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DwarfFile::ResolveLocation(CompilationUnit* unit,
|
DwarfFile::ResolveLocation(CompilationUnit* unit, uint8 addressSize,
|
||||||
DIESubprogram* subprogramEntry, const LocationDescription* location,
|
DIESubprogram* subprogramEntry, const LocationDescription* location,
|
||||||
const DwarfTargetInterface* targetInterface,
|
const DwarfTargetInterface* targetInterface,
|
||||||
target_addr_t instructionPointer, target_addr_t objectPointer,
|
target_addr_t instructionPointer, target_addr_t objectPointer,
|
||||||
@@ -759,9 +783,9 @@ DwarfFile::ResolveLocation(CompilationUnit* unit,
|
|||||||
return error;
|
return error;
|
||||||
|
|
||||||
// evaluate it
|
// evaluate it
|
||||||
ExpressionEvaluationContext context(this, unit, subprogramEntry,
|
ExpressionEvaluationContext context(this, unit, addressSize,
|
||||||
targetInterface, instructionPointer, objectPointer, hasObjectPointer,
|
subprogramEntry, targetInterface, instructionPointer, objectPointer,
|
||||||
framePointer, relocationDelta);
|
hasObjectPointer, framePointer, relocationDelta);
|
||||||
DwarfExpressionEvaluator evaluator(&context);
|
DwarfExpressionEvaluator evaluator(&context);
|
||||||
return evaluator.EvaluateLocation(expression, expressionLength,
|
return evaluator.EvaluateLocation(expression, expressionLength,
|
||||||
_result);
|
_result);
|
||||||
@@ -769,7 +793,7 @@ DwarfFile::ResolveLocation(CompilationUnit* unit,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DwarfFile::EvaluateConstantValue(CompilationUnit* unit,
|
DwarfFile::EvaluateConstantValue(CompilationUnit* unit, uint8 addressSize,
|
||||||
DIESubprogram* subprogramEntry, const ConstantAttributeValue* value,
|
DIESubprogram* subprogramEntry, const ConstantAttributeValue* value,
|
||||||
const DwarfTargetInterface* targetInterface,
|
const DwarfTargetInterface* targetInterface,
|
||||||
target_addr_t instructionPointer, target_addr_t framePointer,
|
target_addr_t instructionPointer, target_addr_t framePointer,
|
||||||
@@ -788,9 +812,10 @@ DwarfFile::EvaluateConstantValue(CompilationUnit* unit,
|
|||||||
case ATTRIBUTE_CLASS_BLOCK:
|
case ATTRIBUTE_CLASS_BLOCK:
|
||||||
{
|
{
|
||||||
target_addr_t result;
|
target_addr_t result;
|
||||||
status_t error = EvaluateExpression(unit, subprogramEntry,
|
status_t error = EvaluateExpression(unit, addressSize,
|
||||||
value->block.data, value->block.length, targetInterface,
|
subprogramEntry, value->block.data, value->block.length,
|
||||||
instructionPointer, framePointer, 0, false, result);
|
targetInterface, instructionPointer, framePointer, 0, false,
|
||||||
|
result);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
@@ -804,7 +829,7 @@ DwarfFile::EvaluateConstantValue(CompilationUnit* unit,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DwarfFile::EvaluateDynamicValue(CompilationUnit* unit,
|
DwarfFile::EvaluateDynamicValue(CompilationUnit* unit, uint8 addressSize,
|
||||||
DIESubprogram* subprogramEntry, const DynamicAttributeValue* value,
|
DIESubprogram* subprogramEntry, const DynamicAttributeValue* value,
|
||||||
const DwarfTargetInterface* targetInterface,
|
const DwarfTargetInterface* targetInterface,
|
||||||
target_addr_t instructionPointer, target_addr_t framePointer,
|
target_addr_t instructionPointer, target_addr_t framePointer,
|
||||||
@@ -887,9 +912,9 @@ DwarfFile::EvaluateDynamicValue(CompilationUnit* unit,
|
|||||||
if (constantValue == NULL || !constantValue->IsValid())
|
if (constantValue == NULL || !constantValue->IsValid())
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
status_t error = EvaluateConstantValue(unit, subprogramEntry,
|
status_t error = EvaluateConstantValue(unit, addressSize,
|
||||||
constantValue, targetInterface, instructionPointer,
|
subprogramEntry, constantValue, targetInterface,
|
||||||
framePointer, _result);
|
instructionPointer, framePointer, _result);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
@@ -900,9 +925,10 @@ DwarfFile::EvaluateDynamicValue(CompilationUnit* unit,
|
|||||||
case ATTRIBUTE_CLASS_BLOCK:
|
case ATTRIBUTE_CLASS_BLOCK:
|
||||||
{
|
{
|
||||||
target_addr_t result;
|
target_addr_t result;
|
||||||
status_t error = EvaluateExpression(unit, subprogramEntry,
|
status_t error = EvaluateExpression(unit, addressSize,
|
||||||
value->block.data, value->block.length, targetInterface,
|
subprogramEntry, value->block.data, value->block.length,
|
||||||
instructionPointer, framePointer, 0, false, result);
|
targetInterface, instructionPointer, framePointer, 0, false,
|
||||||
|
result);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
@@ -1540,28 +1566,18 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
|
|||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
target_addr_t initialLocation = cieAugmentation.ReadEncodedAddress(
|
target_addr_t initialLocation = cieAugmentation.ReadEncodedAddress(
|
||||||
dataReader, fElfFile);
|
dataReader, fElfFile, currentFrameSection);
|
||||||
target_size_t addressRange = cieAugmentation.ReadEncodedAddress(
|
target_addr_t addressRange = cieAugmentation.ReadEncodedAddress(
|
||||||
dataReader, fElfFile);
|
dataReader, fElfFile, currentFrameSection, true);
|
||||||
|
|
||||||
if (dataReader.HasOverflow())
|
if (dataReader.HasOverflow())
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
// In the GCC 4 .eh_frame initialLocation is relative to the offset
|
if ((cieAugmentation.FDEAddressType()
|
||||||
// of the address.
|
& CFI_ADDRESS_TYPE_PC_RELATIVE) != 0) {
|
||||||
if (usingEHFrameSection && gcc4EHFrameSection) {
|
initialLocation += initialLocationOffset;
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: For GCC 2 .eh_frame sections things work differently: The
|
// TODO: For GCC 2 .eh_frame sections things work differently: The
|
||||||
// initial locations are relocated by the runtime loader and
|
// initial locations are relocated by the runtime loader and
|
||||||
// afterwards point to the absolute addresses. Fortunately the
|
// 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
|
// process the CIE's frame info instructions
|
||||||
cieReader = cieReader.RestrictedReader(cieRemaining);
|
cieReader = cieReader.RestrictedReader(cieRemaining);
|
||||||
error = _ParseFrameInfoInstructions(unit, context,
|
error = _ParseFrameInfoInstructions(unit, context,
|
||||||
cieReader);
|
cieReader, cieAugmentation);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
@@ -1623,7 +1639,7 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
|
|||||||
DataReader restrictedReader =
|
DataReader restrictedReader =
|
||||||
dataReader.RestrictedReader(remaining);
|
dataReader.RestrictedReader(remaining);
|
||||||
error = _ParseFrameInfoInstructions(unit, context,
|
error = _ParseFrameInfoInstructions(unit, context,
|
||||||
restrictedReader);
|
restrictedReader, cieAugmentation);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
@@ -1647,7 +1663,8 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
|
|||||||
}
|
}
|
||||||
case CFA_CFA_RULE_EXPRESSION:
|
case CFA_CFA_RULE_EXPRESSION:
|
||||||
{
|
{
|
||||||
error = EvaluateExpression(unit, subprogramEntry,
|
error = EvaluateExpression(unit, addressSize,
|
||||||
|
subprogramEntry,
|
||||||
cfaCfaRule->Expression().block,
|
cfaCfaRule->Expression().block,
|
||||||
cfaCfaRule->Expression().size,
|
cfaCfaRule->Expression().size,
|
||||||
inputInterface, location, 0, 0, false,
|
inputInterface, location, 0, 0, false,
|
||||||
@@ -1721,7 +1738,8 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
|
|||||||
TRACE_CFI(" -> CFA_RULE_LOCATION_EXPRESSION\n");
|
TRACE_CFI(" -> CFA_RULE_LOCATION_EXPRESSION\n");
|
||||||
|
|
||||||
target_addr_t address;
|
target_addr_t address;
|
||||||
error = EvaluateExpression(unit, subprogramEntry,
|
error = EvaluateExpression(unit, addressSize,
|
||||||
|
subprogramEntry,
|
||||||
rule->Expression().block,
|
rule->Expression().block,
|
||||||
rule->Expression().size,
|
rule->Expression().size,
|
||||||
inputInterface, location, frameAddress,
|
inputInterface, location, frameAddress,
|
||||||
@@ -1739,7 +1757,8 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
|
|||||||
TRACE_CFI(" -> CFA_RULE_VALUE_EXPRESSION\n");
|
TRACE_CFI(" -> CFA_RULE_VALUE_EXPRESSION\n");
|
||||||
|
|
||||||
target_addr_t value;
|
target_addr_t value;
|
||||||
error = EvaluateExpression(unit, subprogramEntry,
|
error = EvaluateExpression(unit, addressSize,
|
||||||
|
subprogramEntry,
|
||||||
rule->Expression().block,
|
rule->Expression().block,
|
||||||
rule->Expression().size,
|
rule->Expression().size,
|
||||||
inputInterface, location, frameAddress,
|
inputInterface, location, frameAddress,
|
||||||
@@ -1847,7 +1866,7 @@ DwarfFile::_ParseCIEHeader(ElfSection* debugFrameSection,
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
DwarfFile::_ParseFrameInfoInstructions(CompilationUnit* unit,
|
DwarfFile::_ParseFrameInfoInstructions(CompilationUnit* unit,
|
||||||
CfaContext& context, DataReader& dataReader)
|
CfaContext& context, DataReader& dataReader, CIEAugmentation& augmentation)
|
||||||
{
|
{
|
||||||
while (dataReader.BytesRemaining() > 0) {
|
while (dataReader.BytesRemaining() > 0) {
|
||||||
TRACE_CFI(" [%2" B_PRId64 "]", dataReader.BytesRemaining());
|
TRACE_CFI(" [%2" B_PRId64 "]", dataReader.BytesRemaining());
|
||||||
@@ -1898,7 +1917,8 @@ DwarfFile::_ParseFrameInfoInstructions(CompilationUnit* unit,
|
|||||||
}
|
}
|
||||||
case DW_CFA_set_loc:
|
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);
|
TRACE_CFI(" DW_CFA_set_loc: %#" B_PRIx64 "\n", location);
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ public:
|
|||||||
target_addr_t& _framePointer);
|
target_addr_t& _framePointer);
|
||||||
|
|
||||||
status_t EvaluateExpression(CompilationUnit* unit,
|
status_t EvaluateExpression(CompilationUnit* unit,
|
||||||
|
uint8 addressSize,
|
||||||
DIESubprogram* subprogramEntry,
|
DIESubprogram* subprogramEntry,
|
||||||
const void* expression,
|
const void* expression,
|
||||||
off_t expressionLength,
|
off_t expressionLength,
|
||||||
@@ -65,6 +66,7 @@ public:
|
|||||||
target_addr_t valueToPush, bool pushValue,
|
target_addr_t valueToPush, bool pushValue,
|
||||||
target_addr_t& _result);
|
target_addr_t& _result);
|
||||||
status_t ResolveLocation(CompilationUnit* unit,
|
status_t ResolveLocation(CompilationUnit* unit,
|
||||||
|
uint8 addressSize,
|
||||||
DIESubprogram* subprogramEntry,
|
DIESubprogram* subprogramEntry,
|
||||||
const LocationDescription* location,
|
const LocationDescription* location,
|
||||||
const DwarfTargetInterface* targetInterface,
|
const DwarfTargetInterface* targetInterface,
|
||||||
@@ -79,13 +81,14 @@ public:
|
|||||||
// bit offsets/sizes (cf. bit pieces).
|
// bit offsets/sizes (cf. bit pieces).
|
||||||
|
|
||||||
status_t EvaluateConstantValue(CompilationUnit* unit,
|
status_t EvaluateConstantValue(CompilationUnit* unit,
|
||||||
|
uint8 addressSize,
|
||||||
DIESubprogram* subprogramEntry,
|
DIESubprogram* subprogramEntry,
|
||||||
const ConstantAttributeValue* value,
|
const ConstantAttributeValue* value,
|
||||||
const DwarfTargetInterface* targetInterface,
|
const DwarfTargetInterface* targetInterface,
|
||||||
target_addr_t instructionPointer,
|
target_addr_t instructionPointer,
|
||||||
target_addr_t framePointer,
|
target_addr_t framePointer,
|
||||||
BVariant& _result);
|
BVariant& _result);
|
||||||
status_t EvaluateDynamicValue(CompilationUnit* unit,
|
status_t EvaluateDynamicValue(CompilationUnit* unit, uint8 addressSize,
|
||||||
DIESubprogram* subprogramEntry,
|
DIESubprogram* subprogramEntry,
|
||||||
const DynamicAttributeValue* value,
|
const DynamicAttributeValue* value,
|
||||||
const DwarfTargetInterface* targetInterface,
|
const DwarfTargetInterface* targetInterface,
|
||||||
@@ -133,7 +136,8 @@ private:
|
|||||||
off_t& _cieRemaining);
|
off_t& _cieRemaining);
|
||||||
status_t _ParseFrameInfoInstructions(
|
status_t _ParseFrameInfoInstructions(
|
||||||
CompilationUnit* unit, CfaContext& context,
|
CompilationUnit* unit, CfaContext& context,
|
||||||
DataReader& dataReader);
|
DataReader& dataReader,
|
||||||
|
CIEAugmentation& cieAugmentation);
|
||||||
|
|
||||||
status_t _ParsePublicTypesInfo();
|
status_t _ParsePublicTypesInfo();
|
||||||
status_t _ParsePublicTypesInfo(DataReader& dataReader,
|
status_t _ParsePublicTypesInfo(DataReader& dataReader,
|
||||||
|
|||||||
Reference in New Issue
Block a user