Debugger: Fix return value for PIC functions on x86-64.
- Add Architecture::ResolvePICFunctionAddress() and pull out the previous code in DwarfImageDebugInfo into the x86-specific implemementation. - PIC handling works a bit differently on x86-64 than it does on x86 since x86-64 is likely to use RIP-relative addressing. Implement ArchitectureX8664::ResolvePICFunctionAddress() accordingly.
This commit is contained in:
parent
0a1334de28
commit
aef9e4fce2
@ -106,6 +106,10 @@ public:
|
||||
virtual status_t GetInstructionInfo(target_addr_t address,
|
||||
InstructionInfo& _info,
|
||||
CpuState* state) = 0;
|
||||
virtual status_t ResolvePICFunctionAddress(target_addr_t
|
||||
instructionAddress,
|
||||
CpuState* state,
|
||||
target_addr_t& _targetAddress) = 0;
|
||||
|
||||
status_t CreateStackTrace(Team* team,
|
||||
ImageDebugInfoProvider* imageInfoProvider,
|
||||
|
@ -597,6 +597,32 @@ ArchitectureX86::GetInstructionInfo(target_addr_t address,
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ArchitectureX86::ResolvePICFunctionAddress(target_addr_t instructionAddress,
|
||||
CpuState* state, target_addr_t& _targetAddress)
|
||||
{
|
||||
// if the function in question is position-independent, the call
|
||||
// will actually have taken us to its corresponding PLT slot.
|
||||
// in such a case, look at the disassembled jump to determine
|
||||
// where to find the actual function address.
|
||||
state->SetInstructionPointer(instructionAddress);
|
||||
InstructionInfo info;
|
||||
if (GetInstructionInfo(instructionAddress, info, state) != B_OK) {
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
target_addr_t subroutineAddress = info.TargetAddress();
|
||||
|
||||
ssize_t bytesRead = fTeamMemory->ReadMemory(info.TargetAddress(),
|
||||
&subroutineAddress, fAddressSize);
|
||||
|
||||
if (bytesRead != fAddressSize)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
_targetAddress = subroutineAddress;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ArchitectureX86::GetWatchpointDebugCapabilities(int32& _maxRegisterCount,
|
||||
int32& _maxBytesPerRegister, uint8& _watchpointCapabilityFlags)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2011-2012, Rene Gollent, rene@gollent.com.
|
||||
* Copyright 2011-2013, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ARCHITECTURE_X86_H
|
||||
@ -60,6 +60,10 @@ public:
|
||||
Statement*& _statement);
|
||||
virtual status_t GetInstructionInfo(target_addr_t address,
|
||||
InstructionInfo& _info, CpuState* state);
|
||||
virtual status_t ResolvePICFunctionAddress(
|
||||
target_addr_t instructionAddress,
|
||||
CpuState* state,
|
||||
target_addr_t& _targetAddress);
|
||||
|
||||
virtual status_t GetWatchpointDebugCapabilities(
|
||||
int32& _maxRegisterCount,
|
||||
|
@ -621,6 +621,40 @@ ArchitectureX8664::GetInstructionInfo(target_addr_t address,
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ArchitectureX8664::ResolvePICFunctionAddress(target_addr_t instructionAddress,
|
||||
CpuState* state, target_addr_t& _targetAddress)
|
||||
{
|
||||
// if the function in question is position-independent, the call
|
||||
// will actually have taken us to its corresponding PLT slot.
|
||||
// in such a case, look at the disassembled jump to determine
|
||||
// where to find the actual function address.
|
||||
InstructionInfo info;
|
||||
if (GetInstructionInfo(instructionAddress, info, state) != B_OK)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// x86-64 is likely to use a RIP-relative jump here
|
||||
// as such, set our instruction pointer to the address
|
||||
// after this instruction (where it would be during actual
|
||||
// execution), and recalculate the target address of the jump
|
||||
state->SetInstructionPointer(info.Address() + info.Size());
|
||||
if (GetInstructionInfo(info.Address(), info, state) != B_OK)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
target_addr_t subroutineAddress;
|
||||
ssize_t bytesRead = fTeamMemory->ReadMemory(info.TargetAddress(),
|
||||
&subroutineAddress, fAddressSize);
|
||||
|
||||
if (bytesRead != fAddressSize)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
_targetAddress = subroutineAddress;
|
||||
return B_OK;
|
||||
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ArchitectureX8664::GetWatchpointDebugCapabilities(int32& _maxRegisterCount,
|
||||
int32& _maxBytesPerRegister, uint8& _watchpointCapabilityFlags)
|
||||
|
@ -61,6 +61,10 @@ public:
|
||||
Statement*& _statement);
|
||||
virtual status_t GetInstructionInfo(target_addr_t address,
|
||||
InstructionInfo& _info, CpuState* state);
|
||||
virtual status_t ResolvePICFunctionAddress(target_addr_t
|
||||
instructionAddress,
|
||||
CpuState* state,
|
||||
target_addr_t& _targetAddress);
|
||||
|
||||
virtual status_t GetWatchpointDebugCapabilities(
|
||||
int32& _maxRegisterCount,
|
||||
|
@ -1112,27 +1112,15 @@ DwarfImageDebugInfo::_CreateReturnValues(ReturnValueInfoList* returnValueInfos,
|
||||
}
|
||||
|
||||
status_t result = B_OK;
|
||||
ImageDebugInfo* imageInfo = image->GetImageDebugInfo();
|
||||
ImageDebugInfo* imageInfo = targetImage->GetImageDebugInfo();
|
||||
|
||||
FunctionInstance* targetFunction;
|
||||
target_size_t addressSize = fDebuggerInterface->GetArchitecture()
|
||||
->AddressSize();
|
||||
if (subroutineAddress >= fPLTSectionStart
|
||||
&& subroutineAddress < fPLTSectionEnd) {
|
||||
// if the function in question is position-independent, the call
|
||||
// will actually have taken us to its corresponding PLT slot.
|
||||
// in such a case, look at the disassembled jump to determine
|
||||
// where to find the actual function address.
|
||||
InstructionInfo info;
|
||||
if (fDebuggerInterface->GetArchitecture()->GetInstructionInfo(
|
||||
subroutineAddress, info, subroutineState) != B_OK) {
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
ssize_t bytesRead = fDebuggerInterface->ReadMemory(
|
||||
info.TargetAddress(), &subroutineAddress, addressSize);
|
||||
|
||||
if (bytesRead != (ssize_t)addressSize)
|
||||
return B_BAD_VALUE;
|
||||
if (imageInfo->GetAddressSectionType(subroutineAddress)
|
||||
== ADDRESS_SECTION_TYPE_PLT) {
|
||||
result = fArchitecture->ResolvePICFunctionAddress(
|
||||
subroutineAddress, subroutineState, subroutineAddress);
|
||||
if (result != B_OK)
|
||||
continue;
|
||||
}
|
||||
|
||||
targetFunction = imageInfo->FunctionAtAddress(subroutineAddress);
|
||||
@ -1166,7 +1154,7 @@ DwarfImageDebugInfo::_CreateReturnValues(ReturnValueInfoList* returnValueInfos,
|
||||
// if we were unable to determine a size for the type,
|
||||
// simply default to the architecture's register width.
|
||||
if (byteSize == 0)
|
||||
byteSize = addressSize;
|
||||
byteSize = fArchitecture->AddressSize();
|
||||
|
||||
ValueLocation* location;
|
||||
result = fArchitecture->GetReturnAddressLocation(frame,
|
||||
|
Loading…
Reference in New Issue
Block a user