Extend InstructionInfo for subroutines.

- InstructionInfo now also stores the destination address of subroutine
  call instructions.
- Adjust callers.
This commit is contained in:
Rene Gollent
2012-12-31 20:25:09 -05:00
parent 9ede3c06e8
commit 84ea02a0f4
4 changed files with 24 additions and 8 deletions
+7 -3
View File
@@ -9,6 +9,7 @@
InstructionInfo::InstructionInfo() InstructionInfo::InstructionInfo()
: :
fAddress(0), fAddress(0),
fTargetAddress(0),
fSize(0), fSize(0),
fType(INSTRUCTION_TYPE_OTHER), fType(INSTRUCTION_TYPE_OTHER),
fBreakpointAllowed(false), fBreakpointAllowed(false),
@@ -17,11 +18,13 @@ InstructionInfo::InstructionInfo()
} }
InstructionInfo::InstructionInfo(target_addr_t address, target_size_t size, InstructionInfo::InstructionInfo(target_addr_t address,
target_addr_t targetAddress, target_size_t size,
instruction_type type, bool breakpointAllowed, instruction_type type, bool breakpointAllowed,
const BString& disassembledLine) const BString& disassembledLine)
: :
fAddress(address), fAddress(address),
fTargetAddress(targetAddress),
fSize(size), fSize(size),
fType(type), fType(type),
fBreakpointAllowed(breakpointAllowed), fBreakpointAllowed(breakpointAllowed),
@@ -31,11 +34,12 @@ InstructionInfo::InstructionInfo(target_addr_t address, target_size_t size,
bool bool
InstructionInfo::SetTo(target_addr_t address, target_size_t size, InstructionInfo::SetTo(target_addr_t address, target_addr_t targetAddress,
instruction_type type, bool breakpointAllowed, target_size_t size, instruction_type type, bool breakpointAllowed,
const BString& disassembledLine) const BString& disassembledLine)
{ {
fAddress = address; fAddress = address;
fTargetAddress = targetAddress;
fSize = size; fSize = size;
fType = type; fType = type;
fBreakpointAllowed = breakpointAllowed; fBreakpointAllowed = breakpointAllowed;
+7 -1
View File
@@ -20,16 +20,21 @@ class InstructionInfo {
public: public:
InstructionInfo(); InstructionInfo();
InstructionInfo(target_addr_t address, InstructionInfo(target_addr_t address,
target_addr_t targetAddress,
target_size_t size, instruction_type type, target_size_t size, instruction_type type,
bool breakpointAllowed, bool breakpointAllowed,
const BString& disassembledLine); const BString& disassembledLine);
bool SetTo(target_addr_t address, target_size_t size, bool SetTo(target_addr_t address,
target_addr_t targetAddress,
target_size_t size,
instruction_type type, instruction_type type,
bool breakpointAllowed, bool breakpointAllowed,
const BString& disassembledLine); const BString& disassembledLine);
target_addr_t Address() const { return fAddress; } target_addr_t Address() const { return fAddress; }
target_addr_t TargetAddress() const
{ return fTargetAddress; }
target_size_t Size() const { return fSize; } target_size_t Size() const { return fSize; }
instruction_type Type() const { return fType; } instruction_type Type() const { return fType; }
bool IsBreakpointAllowed() const bool IsBreakpointAllowed() const
@@ -40,6 +45,7 @@ public:
private: private:
target_addr_t fAddress; target_addr_t fAddress;
target_addr_t fTargetAddress;
target_size_t fSize; target_size_t fSize;
instruction_type fType; instruction_type fType;
bool fBreakpointAllowed; bool fBreakpointAllowed;
@@ -596,6 +596,7 @@ ArchitectureX86::GetInstructionInfo(target_addr_t address,
// disassemble the instruction // disassemble the instruction
BString line; BString line;
target_addr_t instructionAddress; target_addr_t instructionAddress;
target_addr_t targetAddress = 0;
target_size_t instructionSize; target_size_t instructionSize;
bool breakpointAllowed; bool breakpointAllowed;
error = disassembler.GetNextInstruction(line, instructionAddress, error = disassembler.GetNextInstruction(line, instructionAddress,
@@ -607,17 +608,21 @@ ArchitectureX86::GetInstructionInfo(target_addr_t address,
if (buffer[0] == 0xff && (buffer[1] & 0x34) == 0x10) { if (buffer[0] == 0xff && (buffer[1] & 0x34) == 0x10) {
// absolute call with r/m32 // absolute call with r/m32
instructionType = INSTRUCTION_TYPE_SUBROUTINE_CALL; instructionType = INSTRUCTION_TYPE_SUBROUTINE_CALL;
// TODO: retrieve target address (might be in a register)
} else if (buffer[0] == 0xe8 && instructionSize == 5) { } else if (buffer[0] == 0xe8 && instructionSize == 5) {
// relative call with rel32 -- don't categorize the call with 0 as // relative call with rel32 -- don't categorize the call with 0 as
// subroutine call, since it is only used to get the address of the GOT // subroutine call, since it is only used to get the address of the GOT
if (buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0 if (buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0
|| buffer[4] != 0) { || buffer[4] != 0) {
instructionType = INSTRUCTION_TYPE_SUBROUTINE_CALL; instructionType = INSTRUCTION_TYPE_SUBROUTINE_CALL;
int32 offset;
memcpy(&offset, &buffer[1], 4);
targetAddress = instructionAddress + instructionSize + offset;
} }
} }
if (!_info.SetTo(instructionAddress, instructionSize, instructionType, if (!_info.SetTo(instructionAddress, targetAddress, instructionSize,
breakpointAllowed, line)) { instructionType, breakpointAllowed, line)) {
return B_NO_MEMORY; return B_NO_MEMORY;
} }
@@ -487,6 +487,7 @@ ArchitectureX8664::GetInstructionInfo(target_addr_t address,
// disassemble the instruction // disassemble the instruction
BString line; BString line;
target_addr_t instructionAddress; target_addr_t instructionAddress;
target_addr_t targetAddress = 0;
target_size_t instructionSize; target_size_t instructionSize;
bool breakpointAllowed; bool breakpointAllowed;
error = disassembler.GetNextInstruction(line, instructionAddress, error = disassembler.GetNextInstruction(line, instructionAddress,
@@ -508,8 +509,8 @@ ArchitectureX8664::GetInstructionInfo(target_addr_t address,
} }
} }
if (!_info.SetTo(instructionAddress, instructionSize, instructionType, if (!_info.SetTo(instructionAddress, targetAddress, instructionSize,
breakpointAllowed, line)) { instructionType, breakpointAllowed, line)) {
return B_NO_MEMORY; return B_NO_MEMORY;
} }