Fix return value handling.

- In the case of position independent code, the initial call isn't to
  the function we want, but rather to a PLT slot which resolves the
  function's location. As such, find that slot and use it to determine
  the corresponding GOT offset for the function's real location.

Still need some further refactoring of return value handling to properly
handle the case of stepping over a single line that makes multiple calls,
but this fixes the basic case at least.
This commit is contained in:
Rene Gollent
2013-03-26 18:50:45 -04:00
parent 029fcc4ad6
commit 1efa0a42f6
@@ -674,14 +674,10 @@ DwarfImageDebugInfo::CreateFrame(Image* image,
instructionPointer, functionInstance->Address() - fRelocationDelta, instructionPointer, functionInstance->Address() - fRelocationDelta,
subprogramEntry->Variables(), subprogramEntry->Blocks()); subprogramEntry->Variables(), subprogramEntry->Blocks());
// TODO: re-enable once PIC and false positive issues
// are properly dealt with
#if 0
if (returnFunctionAddress != 0) { if (returnFunctionAddress != 0) {
_CreateReturnValue(returnFunctionAddress, image, frame, _CreateReturnValue(returnFunctionAddress, returnFunctionState,
*stackFrameDebugInfo); image, frame, *stackFrameDebugInfo);
} }
#endif
} }
_frame = frameReference.Detach(); _frame = frameReference.Detach();
@@ -1104,15 +1100,30 @@ DwarfImageDebugInfo::_CreateReturnValue(target_addr_t returnFunctionAddress,
} }
status_t result = B_OK; status_t result = B_OK;
ImageDebugInfo* imageInfo = image->GetImageDebugInfo();
FunctionInstance* targetFunction; FunctionInstance* targetFunction;
if (returnFunctionAddress >= fPLTSectionStart if (returnFunctionAddress >= fPLTSectionStart
&& returnFunctionAddress < fPLTSectionEnd) { && returnFunctionAddress < fPLTSectionEnd) {
// TODO: handle resolving PLT entries // if the function in question is position-independent, the call
// to their target function // will actually have taken us to its corresponding PLT slot.
return B_UNSUPPORTED; // in such a case, look at the disassembled jump to determine
// where to find the actual function address.
InstructionInfo info;
if (fDebuggerInterface->GetArchitecture()->GetInstructionInfo(
returnFunctionAddress, info, returnFunctionState) != B_OK) {
return B_BAD_VALUE;
} }
ImageDebugInfo* imageInfo = image->GetImageDebugInfo(); target_size_t addressSize = fDebuggerInterface->GetArchitecture()
->AddressSize();
ssize_t bytesRead = fDebuggerInterface->ReadMemory(info.TargetAddress(),
&returnFunctionAddress, addressSize);
if (bytesRead != addressSize)
return B_BAD_VALUE;
}
targetFunction = imageInfo->FunctionAtAddress(returnFunctionAddress); targetFunction = imageInfo->FunctionAtAddress(returnFunctionAddress);
if (targetFunction != NULL) { if (targetFunction != NULL) {
DwarfFunctionDebugInfo* targetInfo = DwarfFunctionDebugInfo* targetInfo =