aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRene Gollent <anevilyak@gmail.com>2012-07-11 21:56:15 -0400
committerRene Gollent <anevilyak@gmail.com>2012-07-11 21:56:15 -0400
commitc4120026a5c8c365a57917ea923779c07df9aea0 (patch)
treeb71468a387d337e64f3e835d6d65ebe05f0f6eb8
parentdfa21dfeabe22cd7df5de50e21bf1ad3678454b8 (diff)
Refactor previous commit.hrev44317
- Keep knowledge of the existence and need to search the different frame sections contained within DwarfFile.
-rw-r--r--src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp17
-rw-r--r--src/apps/debugger/dwarf/DwarfFile.cpp577
-rw-r--r--src/apps/debugger/dwarf/DwarfFile.h18
3 files changed, 311 insertions, 301 deletions
diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
index f24f9b1299..4a9b5c5af6 100644
--- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
+++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
@@ -555,21 +555,8 @@ DwarfImageDebugInfo::CreateFrame(Image* image,
= cpuState->InstructionPointer() - fRelocationDelta;
target_addr_t framePointer;
CompilationUnit* unit = function->GetCompilationUnit();
- // first try .debug_frame
- if (fFile->HasDebugFrameSection()) {
- error = fFile->UnwindCallFrame(false, unit,
- function->SubprogramEntry(), instructionPointer, inputInterface,
- outputInterface, framePointer);
- } else
- error = B_ENTRY_NOT_FOUND;
-
- // if that section isn't present, or we couldn't find a match,
- // try .eh_frame if possible.
- if (error == B_ENTRY_NOT_FOUND && fFile->HasEHFrameSection()) {
- error = fFile->UnwindCallFrame(true, unit,
- function->SubprogramEntry(), instructionPointer, inputInterface,
- outputInterface, framePointer);
- }
+ error = fFile->UnwindCallFrame(unit, function->SubprogramEntry(),
+ instructionPointer, inputInterface, outputInterface, framePointer);
if (error != B_OK) {
TRACE_CFI("Failed to unwind call frame: %s\n", strerror(error));
diff --git a/src/apps/debugger/dwarf/DwarfFile.cpp b/src/apps/debugger/dwarf/DwarfFile.cpp
index aee71b4ce9..f07f10ae2a 100644
--- a/src/apps/debugger/dwarf/DwarfFile.cpp
+++ b/src/apps/debugger/dwarf/DwarfFile.cpp
@@ -535,292 +535,27 @@ DwarfFile::ResolveRangeList(CompilationUnit* unit, uint64 offset) const
status_t
-DwarfFile::UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
+DwarfFile::UnwindCallFrame(CompilationUnit* unit,
DIESubprogram* subprogramEntry, target_addr_t location,
const DwarfTargetInterface* inputInterface,
DwarfTargetInterface* outputInterface, target_addr_t& _framePointer)
{
- ElfSection* currentFrameSection = (usingEHFrameSection)
- ? fEHFrameSection : fDebugFrameSection;
-
- if (currentFrameSection == NULL)
- return B_ENTRY_NOT_FOUND;
+ status_t result = B_ENTRY_NOT_FOUND;
- bool gcc4EHFrameSection = false;
- if (usingEHFrameSection) {
- gcc4EHFrameSection = !currentFrameSection->IsWritable();
- // Crude heuristic for recognizing GCC 4 (Itanium ABI) style
- // .eh_frame sections. The ones generated by GCC 2 are writable,
- // the ones generated by GCC 4 aren't.
+ // first try to find the FDE in .debug_frame
+ if (fDebugFrameSection != NULL) {
+ result = _UnwindCallFrame(false, unit, subprogramEntry, location,
+ inputInterface, outputInterface, _framePointer);
}
-
-
- TRACE_CFI("DwarfFile::UnwindCallFrame(%#llx)\n", location);
-
- DataReader dataReader((uint8*)currentFrameSection->Data(),
- currentFrameSection->Size(), unit->AddressSize());
-
- while (dataReader.BytesRemaining() > 0) {
- // length
- bool dwarf64;
- TRACE_CFI_ONLY(off_t entryOffset = dataReader.Offset();)
- uint64 length = dataReader.ReadInitialLength(dwarf64);
-
- TRACE_CFI("DwarfFile::UnwindCallFrame(): offset: %" B_PRIdOFF
- ", length: %" B_PRId64 "\n", entryOffset, length);
-
- if (length > (uint64)dataReader.BytesRemaining())
- return B_BAD_DATA;
- off_t lengthOffset = dataReader.Offset();
-
- // CIE ID/CIE pointer
- uint64 cieID = dwarf64
- ? dataReader.Read<uint64>(0) : dataReader.Read<uint32>(0);
-
- // In .debug_frame ~0 indicates a CIE, in .eh_frame 0 does.
- if (usingEHFrameSection
- ? cieID == 0
- : (dwarf64
- ? cieID == 0xffffffffffffffffULL
- : cieID == 0xffffffff)) {
- // this is a CIE -- skip it
- } else {
- // this is a FDE
- uint64 initialLocationOffset = dataReader.Offset();
- target_addr_t initialLocation = dataReader.ReadAddress(0);
- target_size_t addressRange = dataReader.ReadAddress(0);
-
- 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;
- }
- }
- // 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
- // relocations that always seem to be used are R_386_RELATIVE, so
- // that the value we read from the file is already absolute
- // (assuming an unchanged segment load address).
-
- TRACE_CFI("location: %" B_PRIx64 ", initial location: %" B_PRIx64
- ", address range: %" B_PRIx64 "\n", location, initialLocation,
- addressRange);
-
- if (location >= initialLocation
- && location < initialLocation + addressRange) {
- // This is the FDE we're looking for.
- off_t remaining = lengthOffset + length
- - dataReader.Offset();
- if (remaining < 0)
- return B_BAD_DATA;
-
- // In .eh_frame the CIE offset is a relative back offset.
- if (usingEHFrameSection) {
- if (cieID > (uint64)lengthOffset) {
- TRACE_CFI("Invalid CIE offset: %" B_PRIu64 ", max "
- "possible: %" B_PRIu64 "\n", cieID, lengthOffset);
- break;
- }
- // convert to a section relative offset
- cieID = lengthOffset - cieID;
- }
-
- TRACE_CFI(" found fde: length: %llu (%lld), CIE offset: %#llx, "
- "location: %#llx, range: %#llx\n", length, remaining, cieID,
- initialLocation, addressRange);
-
- CfaContext context(location, initialLocation);
- uint32 registerCount = outputInterface->CountRegisters();
- status_t error = context.Init(registerCount);
- if (error != B_OK)
- return error;
-
- error = outputInterface->InitRegisterRules(context);
- if (error != B_OK)
- return error;
-
- // process the CIE
- CIEAugmentation cieAugmentation;
- error = _ParseCIE(currentFrameSection, usingEHFrameSection,
- unit, context, cieID, cieAugmentation);
- if (error != B_OK)
- return error;
-
- // read the FDE augmentation data (if any)
- FDEAugmentation fdeAugmentation;
- error = cieAugmentation.ReadFDEData(dataReader,
- fdeAugmentation);
- if (error != B_OK) {
- TRACE_CFI(" failed to read FDE augmentation data!\n");
- return error;
- }
- // adjust remaining byte count to take augmentation bytes
- // (if any) into account.
- remaining = lengthOffset + length
- - dataReader.Offset();
-
- error = context.SaveInitialRuleSet();
- if (error != B_OK)
- return error;
-
- DataReader restrictedReader =
- dataReader.RestrictedReader(remaining);
- error = _ParseFrameInfoInstructions(unit, context,
- restrictedReader);
- if (error != B_OK)
- return error;
-
- TRACE_CFI(" found row!\n");
-
- // apply the rules of the final row
- // get the frameAddress first
- target_addr_t frameAddress;
- CfaCfaRule* cfaCfaRule = context.GetCfaCfaRule();
- switch (cfaCfaRule->Type()) {
- case CFA_CFA_RULE_REGISTER_OFFSET:
- {
- BVariant value;
- if (!inputInterface->GetRegisterValue(
- cfaCfaRule->Register(), value)
- || !value.IsNumber()) {
- return B_UNSUPPORTED;
- }
- frameAddress = value.ToUInt64() + cfaCfaRule->Offset();
- break;
- }
- case CFA_CFA_RULE_EXPRESSION:
- {
- error = EvaluateExpression(unit, subprogramEntry,
- cfaCfaRule->Expression().block,
- cfaCfaRule->Expression().size,
- inputInterface, location, 0, 0, false,
- frameAddress);
- if (error != B_OK)
- return error;
- break;
- }
- case CFA_CFA_RULE_UNDEFINED:
- default:
- return B_BAD_VALUE;
- }
-
- TRACE_CFI(" frame address: %#llx\n", frameAddress);
-
- // apply the register rules
- for (uint32 i = 0; i < registerCount; i++) {
- TRACE_CFI(" reg %lu\n", i);
-
- uint32 valueType = outputInterface->RegisterValueType(i);
- if (valueType == 0)
- continue;
-
- CfaRule* rule = context.RegisterRule(i);
- if (rule == NULL)
- continue;
-
- // apply the rule
- switch (rule->Type()) {
- case CFA_RULE_SAME_VALUE:
- {
- TRACE_CFI(" -> CFA_RULE_SAME_VALUE\n");
-
- BVariant value;
- if (inputInterface->GetRegisterValue(i, value))
- outputInterface->SetRegisterValue(i, value);
- break;
- }
- case CFA_RULE_LOCATION_OFFSET:
- {
- TRACE_CFI(" -> CFA_RULE_LOCATION_OFFSET: %lld\n",
- rule->Offset());
-
- BVariant value;
- if (inputInterface->ReadValueFromMemory(
- frameAddress + rule->Offset(), valueType,
- value)) {
- outputInterface->SetRegisterValue(i, value);
- }
- break;
- }
- case CFA_RULE_VALUE_OFFSET:
- TRACE_CFI(" -> CFA_RULE_VALUE_OFFSET\n");
-
- outputInterface->SetRegisterValue(i,
- frameAddress + rule->Offset());
- break;
- case CFA_RULE_REGISTER:
- {
- TRACE_CFI(" -> CFA_RULE_REGISTER\n");
-
- BVariant value;
- if (inputInterface->GetRegisterValue(
- rule->Register(), value)) {
- outputInterface->SetRegisterValue(i, value);
- }
- break;
- }
- case CFA_RULE_LOCATION_EXPRESSION:
- {
- TRACE_CFI(" -> CFA_RULE_LOCATION_EXPRESSION\n");
-
- target_addr_t address;
- error = EvaluateExpression(unit, subprogramEntry,
- rule->Expression().block,
- rule->Expression().size,
- inputInterface, location, frameAddress,
- frameAddress, true, address);
- BVariant value;
- if (error == B_OK
- && inputInterface->ReadValueFromMemory(address,
- valueType, value)) {
- outputInterface->SetRegisterValue(i, value);
- }
- break;
- }
- case CFA_RULE_VALUE_EXPRESSION:
- {
- TRACE_CFI(" -> CFA_RULE_VALUE_EXPRESSION\n");
-
- target_addr_t value;
- error = EvaluateExpression(unit, subprogramEntry,
- rule->Expression().block,
- rule->Expression().size,
- inputInterface, location, frameAddress,
- frameAddress, true, value);
- if (error == B_OK)
- outputInterface->SetRegisterValue(i, value);
- break;
- }
- case CFA_RULE_UNDEFINED:
- TRACE_CFI(" -> CFA_RULE_UNDEFINED\n");
- default:
- break;
- }
- }
-
- _framePointer = frameAddress;
- return B_OK;
- }
- }
-
- dataReader.SeekAbsolute(lengthOffset + length);
+ // if .debug_frame isn't present, or if the FDE wasn't found there,
+ // try .eh_frame
+ if (result == B_ENTRY_NOT_FOUND && fEHFrameSection != NULL) {
+ result = _UnwindCallFrame(true, unit, subprogramEntry, location,
+ inputInterface, outputInterface, _framePointer);
}
- return B_ENTRY_NOT_FOUND;
+ return result;
}
@@ -1550,6 +1285,294 @@ DwarfFile::_ParseLineInfo(CompilationUnit* unit)
status_t
+DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
+ DIESubprogram* subprogramEntry, target_addr_t location,
+ const DwarfTargetInterface* inputInterface,
+ DwarfTargetInterface* outputInterface, target_addr_t& _framePointer)
+{
+ ElfSection* currentFrameSection = (usingEHFrameSection)
+ ? fEHFrameSection : fDebugFrameSection;
+
+ if (currentFrameSection == NULL)
+ return B_ENTRY_NOT_FOUND;
+
+ bool gcc4EHFrameSection = false;
+ if (usingEHFrameSection) {
+ gcc4EHFrameSection = !currentFrameSection->IsWritable();
+ // Crude heuristic for recognizing GCC 4 (Itanium ABI) style
+ // .eh_frame sections. The ones generated by GCC 2 are writable,
+ // the ones generated by GCC 4 aren't.
+ }
+
+ TRACE_CFI("DwarfFile::_UnwindCallFrame(%#llx)\n", location);
+
+ DataReader dataReader((uint8*)currentFrameSection->Data(),
+ currentFrameSection->Size(), unit->AddressSize());
+
+ while (dataReader.BytesRemaining() > 0) {
+ // length
+ bool dwarf64;
+ TRACE_CFI_ONLY(off_t entryOffset = dataReader.Offset();)
+ uint64 length = dataReader.ReadInitialLength(dwarf64);
+
+ TRACE_CFI("DwarfFile::_UnwindCallFrame(): offset: %" B_PRIdOFF
+ ", length: %" B_PRId64 "\n", entryOffset, length);
+
+ if (length > (uint64)dataReader.BytesRemaining())
+ return B_BAD_DATA;
+ off_t lengthOffset = dataReader.Offset();
+
+ // CIE ID/CIE pointer
+ uint64 cieID = dwarf64
+ ? dataReader.Read<uint64>(0) : dataReader.Read<uint32>(0);
+
+ // In .debug_frame ~0 indicates a CIE, in .eh_frame 0 does.
+ if (usingEHFrameSection
+ ? cieID == 0
+ : (dwarf64
+ ? cieID == 0xffffffffffffffffULL
+ : cieID == 0xffffffff)) {
+ // this is a CIE -- skip it
+ } else {
+ // this is a FDE
+ uint64 initialLocationOffset = dataReader.Offset();
+ target_addr_t initialLocation = dataReader.ReadAddress(0);
+ target_size_t addressRange = dataReader.ReadAddress(0);
+
+ 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;
+ }
+ }
+ // 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
+ // relocations that always seem to be used are R_386_RELATIVE, so
+ // that the value we read from the file is already absolute
+ // (assuming an unchanged segment load address).
+
+ TRACE_CFI("location: %" B_PRIx64 ", initial location: %" B_PRIx64
+ ", address range: %" B_PRIx64 "\n", location, initialLocation,
+ addressRange);
+
+ if (location >= initialLocation
+ && location < initialLocation + addressRange) {
+ // This is the FDE we're looking for.
+ off_t remaining = lengthOffset + length
+ - dataReader.Offset();
+ if (remaining < 0)
+ return B_BAD_DATA;
+
+ // In .eh_frame the CIE offset is a relative back offset.
+ if (usingEHFrameSection) {
+ if (cieID > (uint64)lengthOffset) {
+ TRACE_CFI("Invalid CIE offset: %" B_PRIu64 ", max "
+ "possible: %" B_PRIu64 "\n", cieID, lengthOffset);
+ break;
+ }
+ // convert to a section relative offset
+ cieID = lengthOffset - cieID;
+ }
+
+ TRACE_CFI(" found fde: length: %llu (%lld), CIE offset: %#llx, "
+ "location: %#llx, range: %#llx\n", length, remaining, cieID,
+ initialLocation, addressRange);
+
+ CfaContext context(location, initialLocation);
+ uint32 registerCount = outputInterface->CountRegisters();
+ status_t error = context.Init(registerCount);
+ if (error != B_OK)
+ return error;
+
+ error = outputInterface->InitRegisterRules(context);
+ if (error != B_OK)
+ return error;
+
+ // process the CIE
+ CIEAugmentation cieAugmentation;
+ error = _ParseCIE(currentFrameSection, usingEHFrameSection,
+ unit, context, cieID, cieAugmentation);
+ if (error != B_OK)
+ return error;
+
+ // read the FDE augmentation data (if any)
+ FDEAugmentation fdeAugmentation;
+ error = cieAugmentation.ReadFDEData(dataReader,
+ fdeAugmentation);
+ if (error != B_OK) {
+ TRACE_CFI(" failed to read FDE augmentation data!\n");
+ return error;
+ }
+ // adjust remaining byte count to take augmentation bytes
+ // (if any) into account.
+ remaining = lengthOffset + length
+ - dataReader.Offset();
+
+ error = context.SaveInitialRuleSet();
+ if (error != B_OK)
+ return error;
+
+ DataReader restrictedReader =
+ dataReader.RestrictedReader(remaining);
+ error = _ParseFrameInfoInstructions(unit, context,
+ restrictedReader);
+ if (error != B_OK)
+ return error;
+
+ TRACE_CFI(" found row!\n");
+
+ // apply the rules of the final row
+ // get the frameAddress first
+ target_addr_t frameAddress;
+ CfaCfaRule* cfaCfaRule = context.GetCfaCfaRule();
+ switch (cfaCfaRule->Type()) {
+ case CFA_CFA_RULE_REGISTER_OFFSET:
+ {
+ BVariant value;
+ if (!inputInterface->GetRegisterValue(
+ cfaCfaRule->Register(), value)
+ || !value.IsNumber()) {
+ return B_UNSUPPORTED;
+ }
+ frameAddress = value.ToUInt64() + cfaCfaRule->Offset();
+ break;
+ }
+ case CFA_CFA_RULE_EXPRESSION:
+ {
+ error = EvaluateExpression(unit, subprogramEntry,
+ cfaCfaRule->Expression().block,
+ cfaCfaRule->Expression().size,
+ inputInterface, location, 0, 0, false,
+ frameAddress);
+ if (error != B_OK)
+ return error;
+ break;
+ }
+ case CFA_CFA_RULE_UNDEFINED:
+ default:
+ return B_BAD_VALUE;
+ }
+
+ TRACE_CFI(" frame address: %#llx\n", frameAddress);
+
+ // apply the register rules
+ for (uint32 i = 0; i < registerCount; i++) {
+ TRACE_CFI(" reg %lu\n", i);
+
+ uint32 valueType = outputInterface->RegisterValueType(i);
+ if (valueType == 0)
+ continue;
+
+ CfaRule* rule = context.RegisterRule(i);
+ if (rule == NULL)
+ continue;
+
+ // apply the rule
+ switch (rule->Type()) {
+ case CFA_RULE_SAME_VALUE:
+ {
+ TRACE_CFI(" -> CFA_RULE_SAME_VALUE\n");
+
+ BVariant value;
+ if (inputInterface->GetRegisterValue(i, value))
+ outputInterface->SetRegisterValue(i, value);
+ break;
+ }
+ case CFA_RULE_LOCATION_OFFSET:
+ {
+ TRACE_CFI(" -> CFA_RULE_LOCATION_OFFSET: %lld\n",
+ rule->Offset());
+
+ BVariant value;
+ if (inputInterface->ReadValueFromMemory(
+ frameAddress + rule->Offset(), valueType,
+ value)) {
+ outputInterface->SetRegisterValue(i, value);
+ }
+ break;
+ }
+ case CFA_RULE_VALUE_OFFSET:
+ TRACE_CFI(" -> CFA_RULE_VALUE_OFFSET\n");
+
+ outputInterface->SetRegisterValue(i,
+ frameAddress + rule->Offset());
+ break;
+ case CFA_RULE_REGISTER:
+ {
+ TRACE_CFI(" -> CFA_RULE_REGISTER\n");
+
+ BVariant value;
+ if (inputInterface->GetRegisterValue(
+ rule->Register(), value)) {
+ outputInterface->SetRegisterValue(i, value);
+ }
+ break;
+ }
+ case CFA_RULE_LOCATION_EXPRESSION:
+ {
+ TRACE_CFI(" -> CFA_RULE_LOCATION_EXPRESSION\n");
+
+ target_addr_t address;
+ error = EvaluateExpression(unit, subprogramEntry,
+ rule->Expression().block,
+ rule->Expression().size,
+ inputInterface, location, frameAddress,
+ frameAddress, true, address);
+ BVariant value;
+ if (error == B_OK
+ && inputInterface->ReadValueFromMemory(address,
+ valueType, value)) {
+ outputInterface->SetRegisterValue(i, value);
+ }
+ break;
+ }
+ case CFA_RULE_VALUE_EXPRESSION:
+ {
+ TRACE_CFI(" -> CFA_RULE_VALUE_EXPRESSION\n");
+
+ target_addr_t value;
+ error = EvaluateExpression(unit, subprogramEntry,
+ rule->Expression().block,
+ rule->Expression().size,
+ inputInterface, location, frameAddress,
+ frameAddress, true, value);
+ if (error == B_OK)
+ outputInterface->SetRegisterValue(i, value);
+ break;
+ }
+ case CFA_RULE_UNDEFINED:
+ TRACE_CFI(" -> CFA_RULE_UNDEFINED\n");
+ default:
+ break;
+ }
+ }
+
+ _framePointer = frameAddress;
+ return B_OK;
+ }
+ }
+
+ dataReader.SeekAbsolute(lengthOffset + length);
+ }
+
+ return B_ENTRY_NOT_FOUND;
+}
+
+
+status_t
DwarfFile::_ParseCIE(ElfSection* debugFrameSection, bool usingEHFrameSection,
CompilationUnit* unit, CfaContext& context, off_t cieOffset,
CIEAugmentation& cieAugmentation)
diff --git a/src/apps/debugger/dwarf/DwarfFile.h b/src/apps/debugger/dwarf/DwarfFile.h
index a7afede41f..b7d53b8351 100644
--- a/src/apps/debugger/dwarf/DwarfFile.h
+++ b/src/apps/debugger/dwarf/DwarfFile.h
@@ -39,13 +39,6 @@ public:
const char* Name() const { return fName; }
ElfFile* GetElfFile() const { return fElfFile; }
- bool HasDebugFrameSection() const {
- return fDebugFrameSection != NULL;
- }
- bool HasEHFrameSection() const {
- return fEHFrameSection != NULL;
- }
-
int32 CountCompilationUnits() const;
CompilationUnit* CompilationUnitAt(int32 index) const;
CompilationUnit* CompilationUnitForDIE(
@@ -54,8 +47,7 @@ public:
TargetAddressRangeList* ResolveRangeList(CompilationUnit* unit,
uint64 offset) const;
- status_t UnwindCallFrame(bool usingEHFrameSection,
- CompilationUnit* unit,
+ status_t UnwindCallFrame(CompilationUnit* unit,
DIESubprogram* subprogramEntry,
target_addr_t location,
const DwarfTargetInterface* inputInterface,
@@ -121,6 +113,14 @@ private:
status_t _ParseLineInfo(CompilationUnit* unit);
+ status_t _UnwindCallFrame(bool usingEHFrameSection,
+ CompilationUnit* unit,
+ DIESubprogram* subprogramEntry,
+ target_addr_t location,
+ const DwarfTargetInterface* inputInterface,
+ DwarfTargetInterface* outputInterface,
+ target_addr_t& _framePointer);
+
status_t _ParseCIE(ElfSection* debugFrameSection,
bool usingEHFrameSection,
CompilationUnit* unit,