Merge branch 'master' into sam460ex

This commit is contained in:
François Revol
2013-01-02 01:55:03 +01:00
31 changed files with 804 additions and 157 deletions
@@ -11,9 +11,9 @@ KernelAddon intel_extreme :
driver.cpp
device.cpp
intel_extreme.cpp
power.cpp
kernel_cpp.cpp
: libgraphicscommon.a
;
@@ -10,16 +10,16 @@
#include "intel_extreme.h"
#include "AreaKeeper.h"
#include "driver.h"
#include "utility.h"
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <driver_settings.h>
#include <util/kernel_cpp.h>
#include "utility.h"
#include "driver.h"
#include "power.h"
#define TRACE_INTELEXTREME
@@ -296,38 +296,11 @@ intel_extreme_init(intel_info &info)
primary.offset = (addr_t)primary.base - info.aperture_base;
}
// Clock gating
// Fix some problems on certain chips (taken from X driver)
// TODO: clean this up
if (info.pci->device_id == 0x2a02 || info.pci->device_id == 0x2a12) {
TRACE("i965GM/i965GME quirk\n");
write32(info, 0x6204, (1L << 29));
} else if (info.device_type.InGroup(INTEL_TYPE_SNB)) {
TRACE("SandyBridge clock gating\n");
write32(info, 0x42020, (1L << 28) | (1L << 7) | (1L << 5));
} else if (info.device_type.InGroup(INTEL_TYPE_IVB)) {
TRACE("IvyBridge clock gating\n");
write32(info, 0x42020, (1L << 28));
} else if (info.device_type.InGroup(INTEL_TYPE_ILK)) {
TRACE("IronLake clock gating\n");
write32(info, 0x42020, (1L << 7) | (1L << 5));
} else if (info.device_type.InGroup(INTEL_TYPE_G4x)) {
TRACE("G4x clock gating\n");
write32(info, 0x6204, 0);
write32(info, 0x6208, (1L << 9) | (1L << 7) | (1L << 6));
write32(info, 0x6210, 0);
// Enable clock gating
intel_en_gating(info);
uint32 gateValue = (1L << 28) | (1L << 3) | (1L << 2);
if ((info.device_type.type & INTEL_TYPE_MOBILE) == INTEL_TYPE_MOBILE) {
TRACE("G4x mobile clock gating\n");
gateValue |= 1L << 18;
}
write32(info, 0x6200, gateValue);
} else {
TRACE("i965 quirk\n");
write32(info, 0x6204, (1L << 29) | (1L << 23));
}
write32(info, 0x7408, 0x10);
// Enable automatic gpu downclocking if we can to save power
intel_en_downclock(info);
// no errors, so keep areas and mappings
sharedCreator.Detach();
@@ -0,0 +1,175 @@
/*
* Copyright 2012-2013, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Alexander von Gluck IV, [email protected]
*/
#include "power.h"
#undef TRACE
#define TRACE_POWER
#ifdef TRACE_POWER
# define TRACE(x...) dprintf("intel_extreme:" x)
#else
# define TRACE(x...)
#endif
#define ERROR(x...) dprintf("intel_extreme: " x)
#define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
status_t
intel_en_gating(intel_info &info)
{
CALLED();
// Fix some problems on certain chips (taken from X driver)
// TODO: clean this up
if (info.pci->device_id == 0x2a02 || info.pci->device_id == 0x2a12) {
TRACE("i965GM/i965GME quirk\n");
write32(info, 0x6204, (1L << 29));
} else if (info.device_type.InGroup(INTEL_TYPE_SNB)) {
TRACE("SandyBridge clock gating\n");
write32(info, 0x42020, (1L << 28) | (1L << 7) | (1L << 5));
} else if (info.device_type.InGroup(INTEL_TYPE_IVB)) {
TRACE("IvyBridge clock gating\n");
write32(info, 0x42020, (1L << 28));
} else if (info.device_type.InGroup(INTEL_TYPE_ILK)) {
TRACE("IronLake clock gating\n");
write32(info, 0x42020, (1L << 7) | (1L << 5));
} else if (info.device_type.InGroup(INTEL_TYPE_G4x)) {
TRACE("G4x clock gating\n");
write32(info, 0x6204, 0);
write32(info, 0x6208, (1L << 9) | (1L << 7) | (1L << 6));
write32(info, 0x6210, 0);
uint32 gateValue = (1L << 28) | (1L << 3) | (1L << 2);
if ((info.device_type.type & INTEL_TYPE_MOBILE) == INTEL_TYPE_MOBILE) {
TRACE("G4x mobile clock gating\n");
gateValue |= 1L << 18;
}
write32(info, 0x6200, gateValue);
} else {
TRACE("i965 quirk\n");
write32(info, 0x6204, (1L << 29) | (1L << 23));
}
write32(info, 0x7408, 0x10);
return B_OK;
}
status_t
intel_en_downclock(intel_info &info)
{
CALLED();
if (!info.device_type.InGroup(INTEL_TYPE_SNB)
&& !info.device_type.InGroup(INTEL_TYPE_IVB)) {
TRACE("%s: Downclocking not supported on this chipset.\n", __func__);
return B_NOT_ALLOWED;
}
if((info.device_type.type & INTEL_TYPE_MOBILE) == 0) {
// I don't see a point enabling auto-downclocking on non-mobile devices.
TRACE("%s: Skip GPU downclocking on non-mobile device.\n", __func__);
return B_NOT_ALLOWED;
}
// TODO: Check for deep RC6
// IvyBridge, SandyBridge, and Haswell can do depth 1 atm
// Some chipsets can go deeper... but this is safe for now
// Haswell should *NOT* do over depth 1;
int depth = 1;
// Lets always print this for now incase it causes regressions for someone.
ERROR("%s: Enabling Intel GPU auto downclocking depth %d\n", __func__,
depth);
/* Magical sequence of register writes to enable
* downclocking from the fine folks at Xorg
*/
write32(info, INTEL6_RC_STATE, 0);
uint32 rpStateCapacity = read32(info, INTEL6_RP_STATE_CAP);
uint32 gtPerfStatus = read32(info, INTEL6_GT_PERF_STATUS);
uint8 maxDelay = rpStateCapacity & 0xff;
uint8 minDelay = (rpStateCapacity & 0xff0000) >> 16;
write32(info, INTEL6_RC_CONTROL, 0);
write32(info, INTEL6_RC1_WAKE_RATE_LIMIT, 1000 << 16);
write32(info, INTEL6_RC6_WAKE_RATE_LIMIT, 40 << 16 | 30);
write32(info, INTEL6_RC6pp_WAKE_RATE_LIMIT, 30);
write32(info, INTEL6_RC_EVALUATION_INTERVAL, 125000);
write32(info, INTEL6_RC_IDLE_HYSTERSIS, 25);
// TODO: Idle each ring
write32(info, INTEL6_RC_SLEEP, 0);
write32(info, INTEL6_RC1e_THRESHOLD, 1000);
write32(info, INTEL6_RC6_THRESHOLD, 50000);
write32(info, INTEL6_RC6p_THRESHOLD, 100000);
write32(info, INTEL6_RC6pp_THRESHOLD, 64000);
uint32 rc6Mask = INTEL6_RC_CTL_RC6_ENABLE;
if (depth > 1)
rc6Mask |= INTEL6_RC_CTL_RC6p_ENABLE;
if (depth > 2)
rc6Mask |= INTEL6_RC_CTL_RC6pp_ENABLE;
write32(info, INTEL6_RC_CONTROL, rc6Mask | INTEL6_RC_CTL_EI_MODE(1)
| INTEL6_RC_CTL_HW_ENABLE);
write32(info, INTEL6_RPNSWREQ, INTEL6_FREQUENCY(10) | INTEL6_OFFSET(0)
| INTEL6_AGGRESSIVE_TURBO);
write32(info, INTEL6_RC_VIDEO_FREQ, INTEL6_FREQUENCY(12));
write32(info, INTEL6_RP_DOWN_TIMEOUT, 1000000);
write32(info, INTEL6_RP_INTERRUPT_LIMITS, maxDelay << 24 | minDelay << 16);
write32(info, INTEL6_RP_UP_THRESHOLD, 59400);
write32(info, INTEL6_RP_DOWN_THRESHOLD, 245000);
write32(info, INTEL6_RP_UP_EI, 66000);
write32(info, INTEL6_RP_DOWN_EI, 350000);
write32(info, INTEL6_RP_IDLE_HYSTERSIS, 10);
write32(info, INTEL6_RP_CONTROL, INTEL6_RP_MEDIA_TURBO
| INTEL6_RP_MEDIA_HW_NORMAL_MODE | INTEL6_RP_MEDIA_IS_GFX
| INTEL6_RP_ENABLE | INTEL6_RP_UP_BUSY_AVG
| INTEL6_RP_DOWN_IDLE_CONT);
// TODO: | (HASWELL ? GEN7_RP_DOWN_IDLE_AVG : INTEL6_RP_DOWN_IDLE_CONT));
// TODO: wait for (read32(INTEL6_PCODE_MAILBOX) & INTEL6_PCODE_READY)
write32(info, INTEL6_PCODE_DATA, 0);
write32(info, INTEL6_PCODE_MAILBOX, INTEL6_PCODE_READY
| INTEL6_PCODE_WRITE_MIN_FREQ_TABLE);
// TODO: wait for (read32(INTEL6_PCODE_MAILBOX) & INTEL6_PCODE_READY)
// TODO: check for overclock support and set.
// Calculate limits and enforce them
uint8 gtPerfShift = (gtPerfStatus & 0xff00) >> 8;
if (gtPerfShift >= maxDelay)
gtPerfShift = maxDelay;
uint32 limits = maxDelay << 24;
if (gtPerfShift <= minDelay) {
gtPerfShift = minDelay;
limits |= minDelay << 16;
}
write32(info, INTEL6_RP_INTERRUPT_LIMITS, limits);
write32(info, INTEL6_RPNSWREQ, INTEL6_FREQUENCY(gtPerfShift)
| INTEL6_OFFSET(0) | INTEL6_AGGRESSIVE_TURBO);
// Requires MSI to be enabled.
write32(info, INTEL6_PMIER, INTEL6_PM_DEFERRED_EVENTS);
// TODO: Review need for spin lock irq rps here?
write32(info, INTEL6_PMIMR, 0);
// TODO: Review need for spin unlock irq rps here?
write32(info, INTEL6_PMINTRMSK, 0);
return B_OK;
}
@@ -0,0 +1,121 @@
/*
* Copyright 2012-2013, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Alexander von Gluck IV, [email protected]
*/
#ifndef _INTEL_POWER_H_
#define _INTEL_POWER_H_
#include <string.h>
#include "driver.h"
// Clocking configuration
#define INTEL6_GT_THREAD_STATUS_REG 0x13805c
#define INTEL6_GT_THREAD_STATUS_CORE_MASK 0x7
#define INTEL6_GT_THREAD_STATUS_CORE_MASK_HSW (0x7 | (0x07 << 16))
#define INTEL6_GT_PERF_STATUS 0x145948
#define INTEL6_RP_STATE_LIMITS 0x145994
#define INTEL6_RP_STATE_CAP 0x145998
#define INTEL6_RPNSWREQ 0xA008
#define INTEL6_TURBO_DISABLE (1<<31)
#define INTEL6_FREQUENCY(x) ((x)<<25)
#define INTEL6_OFFSET(x) ((x)<<19)
#define INTEL6_AGGRESSIVE_TURBO (0<<15)
#define INTEL6_RC_VIDEO_FREQ 0xA00C
#define INTEL6_RC_CONTROL 0xA090
#define INTEL6_RC_CTL_RC6pp_ENABLE (1<<16)
#define INTEL6_RC_CTL_RC6p_ENABLE (1<<17)
#define INTEL6_RC_CTL_RC6_ENABLE (1<<18)
#define INTEL6_RC_CTL_RC1e_ENABLE (1<<20)
#define INTEL6_RC_CTL_RC7_ENABLE (1<<22)
#define INTEL6_RC_CTL_EI_MODE(x) ((x)<<27)
#define INTEL6_RC_CTL_HW_ENABLE (1<<31)
#define INTEL6_RP_DOWN_TIMEOUT 0xA010
#define INTEL6_RP_INTERRUPT_LIMITS 0xA014
#define INTEL6_RPSTAT1 0xA01C
#define INTEL6_CAGF_SHIFT 8
#define INTEL6_CAGF_MASK (0x7f << INTEL6_CAGF_SHIFT)
#define INTEL6_RP_CONTROL 0xA024
#define INTEL6_RP_MEDIA_TURBO (1<<11)
#define INTEL6_RP_MEDIA_MODE_MASK (3<<9)
#define INTEL6_RP_MEDIA_HW_TURBO_MODE (3<<9)
#define INTEL6_RP_MEDIA_HW_NORMAL_MODE (2<<9)
#define INTEL6_RP_MEDIA_HW_MODE (1<<9)
#define INTEL6_RP_MEDIA_SW_MODE (0<<9)
#define INTEL6_RP_MEDIA_IS_GFX (1<<8)
#define INTEL6_RP_ENABLE (1<<7)
#define INTEL6_RP_UP_IDLE_MIN (0x1<<3)
#define INTEL6_RP_UP_BUSY_AVG (0x2<<3)
#define INTEL6_RP_UP_BUSY_CONT (0x4<<3)
#define GEN7_RP_DOWN_IDLE_AVG (0x2<<0)
#define INTEL6_RP_DOWN_IDLE_CONT (0x1<<0)
#define INTEL6_RP_UP_THRESHOLD 0xA02C
#define INTEL6_RP_DOWN_THRESHOLD 0xA030
#define INTEL6_RP_CUR_UP_EI 0xA050
#define INTEL6_CURICONT_MASK 0xffffff
#define INTEL6_RP_CUR_UP 0xA054
#define INTEL6_CURBSYTAVG_MASK 0xffffff
#define INTEL6_RP_PREV_UP 0xA058
#define INTEL6_RP_CUR_DOWN_EI 0xA05C
#define INTEL6_CURIAVG_MASK 0xffffff
#define INTEL6_RP_CUR_DOWN 0xA060
#define INTEL6_RP_PREV_DOWN 0xA064
#define INTEL6_RP_UP_EI 0xA068
#define INTEL6_RP_DOWN_EI 0xA06C
#define INTEL6_RP_IDLE_HYSTERSIS 0xA070
#define INTEL6_RC_STATE 0xA094
#define INTEL6_RC1_WAKE_RATE_LIMIT 0xA098
#define INTEL6_RC6_WAKE_RATE_LIMIT 0xA09C
#define INTEL6_RC6pp_WAKE_RATE_LIMIT 0xA0A0
#define INTEL6_RC_EVALUATION_INTERVAL 0xA0A8
#define INTEL6_RC_IDLE_HYSTERSIS 0xA0AC
#define INTEL6_RC_SLEEP 0xA0B0
#define INTEL6_RC1e_THRESHOLD 0xA0B4
#define INTEL6_RC6_THRESHOLD 0xA0B8
#define INTEL6_RC6p_THRESHOLD 0xA0BC
#define INTEL6_RC6pp_THRESHOLD 0xA0C0
#define INTEL6_PMINTRMSK 0xA168
#define INTEL6_PMISR 0x44020
#define INTEL6_PMIMR 0x44024 /* rps_lock */
#define INTEL6_PMIIR 0x44028
#define INTEL6_PMIER 0x4402C
#define INTEL6_PM_MBOX_EVENT (1<<25)
#define INTEL6_PM_THERMAL_EVENT (1<<24)
#define INTEL6_PM_RP_DOWN_TIMEOUT (1<<6)
#define INTEL6_PM_RP_UP_THRESHOLD (1<<5)
#define INTEL6_PM_RP_DOWN_THRESHOLD (1<<4)
#define INTEL6_PM_RP_UP_EI_EXPIRED (1<<2)
#define INTEL6_PM_RP_DOWN_EI_EXPIRED (1<<1)
#define INTEL6_PM_DEFERRED_EVENTS (INTEL6_PM_RP_UP_THRESHOLD \
| INTEL6_PM_RP_DOWN_THRESHOLD \
| INTEL6_PM_RP_DOWN_TIMEOUT)
#define INTEL6_GT_GFX_RC6_LOCKED 0x138104
#define INTEL6_GT_GFX_RC6 0x138108
#define INTEL6_GT_GFX_RC6p 0x13810C
#define INTEL6_GT_GFX_RC6pp 0x138110
#define INTEL6_PCODE_MAILBOX 0x138124
#define INTEL6_PCODE_READY (1<<31)
#define INTEL6_READ_OC_PARAMS 0xc
#define INTEL6_PCODE_WRITE_MIN_FREQ_TABLE 0x8
#define INTEL6_PCODE_READ_MIN_FREQ_TABLE 0x9
#define INTEL6_PCODE_DATA 0x138128
#define INTEL6_PCODE_FREQ_IA_RATIO_SHIFT 8
#define INTEL6_GT_CORE_STATUS 0x138060
#define INTEL6_CORE_CPD_STATE_MASK (7<<4)
#define INTEL6_RCn_MASK 7
#define INTEL6_RC0 0
#define INTEL6_RC3 2
#define INTEL6_RC6 3
#define INTEL6_RC7 4
status_t intel_en_gating(intel_info &info);
status_t intel_en_downclock(intel_info &info);
#endif /* _INTEL_POWER_H_ */
+2 -1
View File
@@ -124,9 +124,10 @@ Application Debugger :
# ids
FunctionID.cpp
FunctionParameterID.cpp
LocalVariableID.cpp
ObjectID.cpp
FunctionParameterID.cpp
ReturnValueID.cpp
# jobs
GetCPUStateJob.cpp
+4 -3
View File
@@ -94,8 +94,8 @@ Architecture::InitRegisterRules(CfaContext& context) const
status_t
Architecture::CreateStackTrace(Team* team,
ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState,
StackTrace*& _stackTrace, int32 maxStackDepth, bool useExistingTrace,
bool getFullFrameInfo)
StackTrace*& _stackTrace, target_addr_t returnFunctionAddress,
int32 maxStackDepth, bool useExistingTrace, bool getFullFrameInfo)
{
BReference<CpuState> cpuStateReference(cpuState);
@@ -163,7 +163,8 @@ Architecture::CreateStackTrace(Team* team,
if (function != NULL) {
status_t error = functionDebugInfo->GetSpecificImageDebugInfo()
->CreateFrame(image, function, cpuState, getFullFrameInfo,
frame, previousCpuState);
nextFrame == NULL ? returnFunctionAddress : 0, frame,
previousCpuState);
if (error != B_OK && error != B_UNSUPPORTED)
break;
}
+8 -1
View File
@@ -30,6 +30,7 @@ class StackTrace;
class Statement;
class Team;
class TeamMemory;
class ValueLocation;
enum {
@@ -102,12 +103,14 @@ public:
target_addr_t address,
Statement*& _statement) = 0;
virtual status_t GetInstructionInfo(target_addr_t address,
InstructionInfo& _info) = 0;
InstructionInfo& _info,
CpuState* state) = 0;
status_t CreateStackTrace(Team* team,
ImageDebugInfoProvider* imageInfoProvider,
CpuState* cpuState,
StackTrace*& _stackTrace,
target_addr_t returnFunctionAddress,
int32 maxStackDepth = -1,
bool useExistingTrace = false,
bool getFullFrameInfo = true);
@@ -118,6 +121,10 @@ public:
int32& _maxBytesPerRegister,
uint8& _watchpointCapabilityFlags) = 0;
virtual status_t GetReturnAddressLocation(
StackFrame* frame, target_size_t valueSize,
ValueLocation*& _location) = 0;
protected:
TeamMemory* fTeamMemory;
+7 -3
View File
@@ -9,6 +9,7 @@
InstructionInfo::InstructionInfo()
:
fAddress(0),
fTargetAddress(0),
fSize(0),
fType(INSTRUCTION_TYPE_OTHER),
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,
const BString& disassembledLine)
:
fAddress(address),
fTargetAddress(targetAddress),
fSize(size),
fType(type),
fBreakpointAllowed(breakpointAllowed),
@@ -31,11 +34,12 @@ InstructionInfo::InstructionInfo(target_addr_t address, target_size_t size,
bool
InstructionInfo::SetTo(target_addr_t address, target_size_t size,
instruction_type type, bool breakpointAllowed,
InstructionInfo::SetTo(target_addr_t address, target_addr_t targetAddress,
target_size_t size, instruction_type type, bool breakpointAllowed,
const BString& disassembledLine)
{
fAddress = address;
fTargetAddress = targetAddress;
fSize = size;
fType = type;
fBreakpointAllowed = breakpointAllowed;
+8 -1
View File
@@ -12,6 +12,7 @@
enum instruction_type {
INSTRUCTION_TYPE_SUBROUTINE_CALL,
INSTRUCTION_TYPE_JUMP,
INSTRUCTION_TYPE_OTHER
};
@@ -20,16 +21,21 @@ class InstructionInfo {
public:
InstructionInfo();
InstructionInfo(target_addr_t address,
target_addr_t targetAddress,
target_size_t size, instruction_type type,
bool breakpointAllowed,
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,
bool breakpointAllowed,
const BString& disassembledLine);
target_addr_t Address() const { return fAddress; }
target_addr_t TargetAddress() const
{ return fTargetAddress; }
target_size_t Size() const { return fSize; }
instruction_type Type() const { return fType; }
bool IsBreakpointAllowed() const
@@ -40,6 +46,7 @@ public:
private:
target_addr_t fAddress;
target_addr_t fTargetAddress;
target_size_t fSize;
instruction_type fType;
bool fBreakpointAllowed;
+51 -33
View File
@@ -23,6 +23,7 @@
#include "StackFrame.h"
#include "Statement.h"
#include "TeamMemory.h"
#include "ValueLocation.h"
#include "X86AssemblyLanguage.h"
#include "disasm/DisassemblerX86.h"
@@ -560,7 +561,7 @@ ArchitectureX86::GetStatement(FunctionDebugInfo* function,
// TODO: This is not architecture dependent anymore!
// get the instruction info
InstructionInfo info;
status_t error = GetInstructionInfo(address, info);
status_t error = GetInstructionInfo(address, info, NULL);
if (error != B_OK)
return error;
@@ -577,11 +578,10 @@ ArchitectureX86::GetStatement(FunctionDebugInfo* function,
status_t
ArchitectureX86::GetInstructionInfo(target_addr_t address,
InstructionInfo& _info)
InstructionInfo& _info, CpuState* state)
{
// read the code
// read the code - maximum x86{-64} instruction size = 15 bytes
uint8 buffer[16];
// TODO: What's the maximum instruction size?
ssize_t bytesRead = fTeamMemory->ReadMemory(address, buffer,
sizeof(buffer));
if (bytesRead < 0)
@@ -593,35 +593,7 @@ ArchitectureX86::GetInstructionInfo(target_addr_t address,
if (error != B_OK)
return error;
// disassemble the instruction
BString line;
target_addr_t instructionAddress;
target_size_t instructionSize;
bool breakpointAllowed;
error = disassembler.GetNextInstruction(line, instructionAddress,
instructionSize, breakpointAllowed);
if (error != B_OK)
return error;
instruction_type instructionType = INSTRUCTION_TYPE_OTHER;
if (buffer[0] == 0xff && (buffer[1] & 0x34) == 0x10) {
// absolute call with r/m32
instructionType = INSTRUCTION_TYPE_SUBROUTINE_CALL;
} else if (buffer[0] == 0xe8 && instructionSize == 5) {
// 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
if (buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0
|| buffer[4] != 0) {
instructionType = INSTRUCTION_TYPE_SUBROUTINE_CALL;
}
}
if (!_info.SetTo(instructionAddress, instructionSize, instructionType,
breakpointAllowed, line)) {
return B_NO_MEMORY;
}
return B_OK;
return disassembler.GetNextInstructionInfo(_info, state);
}
@@ -643,6 +615,52 @@ ArchitectureX86::GetWatchpointDebugCapabilities(int32& _maxRegisterCount,
}
status_t
ArchitectureX86::GetReturnAddressLocation(StackFrame* frame,
target_size_t valueSize, ValueLocation*& _location)
{
// for the calling conventions currently in use on Haiku,
// the x86 rules for how values are returned are as follows:
//
// - 32 bits or smaller values are returned directly in EAX.
// - 32-64 bit values are returned across EAX:EDX.
// - > 64 bit values are returned on the stack.
ValueLocation* location = new(std::nothrow) ValueLocation(
IsBigEndian());
if (location == NULL)
return B_NO_MEMORY;
BReference<ValueLocation> locationReference(location,
true);
if (valueSize <= 4) {
ValuePieceLocation piece;
piece.SetSize(valueSize);
piece.SetToRegister(X86_REGISTER_EAX);
if (!location->AddPiece(piece))
return B_NO_MEMORY;
} else if (valueSize <= 8) {
ValuePieceLocation piece;
piece.SetSize(4);
piece.SetToRegister(X86_REGISTER_EAX);
if (!location->AddPiece(piece))
return B_NO_MEMORY;
piece.SetToRegister(X86_REGISTER_EDX);
piece.SetSize(valueSize - 4);
if (!location->AddPiece(piece))
return B_NO_MEMORY;
} else {
ValuePieceLocation piece;
piece.SetToMemory(frame->GetCpuState()->StackPointer());
piece.SetSize(valueSize);
if (!location->AddPiece(piece))
return B_NO_MEMORY;
}
_location = locationReference.Detach();
return B_OK;
}
void
ArchitectureX86::_AddRegister(int32 index, const char* name,
uint32 bitSize, uint32 valueType, register_type type, bool calleePreserved)
+6 -1
View File
@@ -59,13 +59,18 @@ public:
target_addr_t address,
Statement*& _statement);
virtual status_t GetInstructionInfo(target_addr_t address,
InstructionInfo& _info);
InstructionInfo& _info, CpuState* state);
virtual status_t GetWatchpointDebugCapabilities(
int32& _maxRegisterCount,
int32& _maxBytesPerRegister,
uint8& _watchpointCapabilityFlags);
virtual status_t GetReturnAddressLocation(
StackFrame* frame, target_size_t valueSize,
ValueLocation*& _location);
private:
struct ToDwarfRegisterMap;
struct FromDwarfRegisterMap;
@@ -12,6 +12,36 @@
#include <OS.h>
#include "CpuStateX86.h"
#include "InstructionInfo.h"
static uint8 RegisterNumberFromUdisIndex(int32 udisIndex)
{
switch (udisIndex) {
case UD_R_RIP: return X86_REGISTER_EIP;
case UD_R_ESP: return X86_REGISTER_ESP;
case UD_R_EBP: return X86_REGISTER_EBP;
case UD_R_EAX: return X86_REGISTER_EAX;
case UD_R_EBX: return X86_REGISTER_EBX;
case UD_R_ECX: return X86_REGISTER_ECX;
case UD_R_EDX: return X86_REGISTER_EDX;
case UD_R_ESI: return X86_REGISTER_ESI;
case UD_R_EDI: return X86_REGISTER_EDI;
case UD_R_CS: return X86_REGISTER_CS;
case UD_R_DS: return X86_REGISTER_DS;
case UD_R_ES: return X86_REGISTER_ES;
case UD_R_FS: return X86_REGISTER_FS;
case UD_R_GS: return X86_REGISTER_GS;
case UD_R_SS: return X86_REGISTER_SS;
}
return X86_INT_REGISTER_END;
}
struct DisassemblerX86::UdisData : ud_t {
};
@@ -108,3 +138,85 @@ DisassemblerX86::GetPreviousInstruction(target_addr_t nextAddress,
}
}
}
status_t
DisassemblerX86::GetNextInstructionInfo(InstructionInfo& _info,
CpuState* state)
{
unsigned int size = ud_disassemble(fUdisData);
if (size < 1)
return B_ENTRY_NOT_FOUND;
uint32 address = (uint32)ud_insn_off(fUdisData);
instruction_type type = INSTRUCTION_TYPE_OTHER;
target_addr_t targetAddress = 0;
if (fUdisData->mnemonic == UD_Icall)
type = INSTRUCTION_TYPE_SUBROUTINE_CALL;
else if (fUdisData->mnemonic == UD_Ijmp)
type = INSTRUCTION_TYPE_JUMP;
if (state != NULL)
targetAddress = GetInstructionTargetAddress(state);
char buffer[256];
snprintf(buffer, sizeof(buffer), "0x%08" B_PRIx32 ": %16.16s %s", address,
ud_insn_hex(fUdisData), ud_insn_asm(fUdisData));
// TODO: Resolve symbols!
if (!_info.SetTo(address, targetAddress, size, type, true, buffer))
return B_NO_MEMORY;
return B_OK;
}
target_addr_t
DisassemblerX86::GetInstructionTargetAddress(CpuState* state) const
{
if (fUdisData->mnemonic != UD_Icall && fUdisData->mnemonic != UD_Ijmp)
return 0;
CpuStateX86* x86State = dynamic_cast<CpuStateX86*>(state);
if (x86State == NULL)
return 0;
target_addr_t targetAddress = 0;
switch (fUdisData->operand[0].type) {
case UD_OP_REG:
{
targetAddress = x86State->IntRegisterValue(
RegisterNumberFromUdisIndex(fUdisData->operand[0].base));
targetAddress += fUdisData->operand[0].offset;
}
break;
case UD_OP_MEM:
{
targetAddress = x86State->IntRegisterValue(
RegisterNumberFromUdisIndex(fUdisData->operand[0].base));
targetAddress += x86State->IntRegisterValue(
RegisterNumberFromUdisIndex(fUdisData->operand[0].index))
* fUdisData->operand[0].scale;
}
break;
case UD_OP_JIMM:
{
targetAddress = ud_insn_off(fUdisData)
+ fUdisData->operand[0].lval.sdword + ud_insn_len(fUdisData);
}
break;
case UD_OP_IMM:
case UD_OP_CONST:
{
targetAddress = fUdisData->operand[0].lval.udword;
}
break;
default:
break;
}
return targetAddress;
}
@@ -10,6 +10,10 @@
#include "Types.h"
class CpuState;
class InstructionInfo;
class DisassemblerX86 {
public:
DisassemblerX86();
@@ -27,6 +31,14 @@ public:
target_addr_t& _address,
target_size_t& _size);
virtual status_t GetNextInstructionInfo(
InstructionInfo& _info,
CpuState* state);
private:
target_addr_t GetInstructionTargetAddress(
CpuState* state) const;
private:
struct UdisData;
@@ -3,9 +3,12 @@ SubDir HAIKU_TOP src apps debugger arch x86 disasm ;
CCFLAGS += -Werror ;
C++FLAGS += -Werror ;
UsePrivateHeaders shared ;
UseHeaders [ LibraryHeaders udis86 ] ;
UseHeaders [ LibraryHeaders [ FDirName udis86 libudis86 ] ] ;
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ;
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ;
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) $(DOTDOT) types ] ;
@@ -451,7 +451,7 @@ ArchitectureX8664::GetStatement(FunctionDebugInfo* function,
// TODO: This is not architecture dependent anymore!
// get the instruction info
InstructionInfo info;
status_t error = GetInstructionInfo(address, info);
status_t error = GetInstructionInfo(address, info, NULL);
if (error != B_OK)
return error;
@@ -468,7 +468,7 @@ ArchitectureX8664::GetStatement(FunctionDebugInfo* function,
status_t
ArchitectureX8664::GetInstructionInfo(target_addr_t address,
InstructionInfo& _info)
InstructionInfo& _info, CpuState* state)
{
// read the code
uint8 buffer[16];
@@ -487,6 +487,7 @@ ArchitectureX8664::GetInstructionInfo(target_addr_t address,
// disassemble the instruction
BString line;
target_addr_t instructionAddress;
target_addr_t targetAddress = 0;
target_size_t instructionSize;
bool breakpointAllowed;
error = disassembler.GetNextInstruction(line, instructionAddress,
@@ -508,8 +509,8 @@ ArchitectureX8664::GetInstructionInfo(target_addr_t address,
}
}
if (!_info.SetTo(instructionAddress, instructionSize, instructionType,
breakpointAllowed, line)) {
if (!_info.SetTo(instructionAddress, targetAddress, instructionSize,
instructionType, breakpointAllowed, line)) {
return B_NO_MEMORY;
}
@@ -534,6 +535,13 @@ ArchitectureX8664::GetWatchpointDebugCapabilities(int32& _maxRegisterCount,
}
status_t
ArchitectureX8664::GetReturnAddressLocation(StackFrame* frame,
target_size_t valueSize, ValueLocation*& _location) {
return B_NOT_SUPPORTED;
}
void
ArchitectureX8664::_AddRegister(int32 index, const char* name,
uint32 bitSize, uint32 valueType, register_type type, bool calleePreserved)
@@ -60,13 +60,17 @@ public:
target_addr_t address,
Statement*& _statement);
virtual status_t GetInstructionInfo(target_addr_t address,
InstructionInfo& _info);
InstructionInfo& _info, CpuState* state);
virtual status_t GetWatchpointDebugCapabilities(
int32& _maxRegisterCount,
int32& _maxBytesPerRegister,
uint8& _watchpointCapabilityFlags);
virtual status_t GetReturnAddressLocation(
StackFrame* frame, target_size_t valueSize,
ValueLocation*& _location);
private:
struct ToDwarfRegisterMap;
struct FromDwarfRegisterMap;
+28 -11
View File
@@ -253,8 +253,8 @@ ThreadHandler::HandleThreadAction(uint32 action)
if (stackTrace == NULL && cpuState != NULL) {
if (fDebuggerInterface->GetArchitecture()->CreateStackTrace(
fThread->GetTeam(), this, cpuState, stackTrace, 1, false,
false) == B_OK) {
fThread->GetTeam(), this, cpuState, stackTrace, 0, 1,
false, false) == B_OK) {
stackTraceReference.SetTo(stackTrace, true);
}
}
@@ -469,7 +469,7 @@ ThreadHandler::_DoStepOver(CpuState* cpuState)
// just single-step, otherwise we set a breakpoint after the instruction.
InstructionInfo info;
if (fDebuggerInterface->GetArchitecture()->GetInstructionInfo(
cpuState->InstructionPointer(), info) != B_OK) {
cpuState->InstructionPointer(), info, cpuState) != B_OK) {
TRACE_CONTROL(" failed to get instruction info\n");
return false;
}
@@ -484,6 +484,7 @@ ThreadHandler::_DoStepOver(CpuState* cpuState)
TRACE_CONTROL(" subroutine call -- installing breakpoint at address "
"%#" B_PRIx64 "\n", info.Address() + info.Size());
fThread->SetExecutedSubroutine(info.TargetAddress());
if (_InstallTemporaryBreakpoint(info.Address() + info.Size()) != B_OK)
return false;
@@ -565,9 +566,8 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState)
if (stackTrace == NULL && cpuState != NULL) {
if (fDebuggerInterface->GetArchitecture()->CreateStackTrace(
fThread->GetTeam(), this, cpuState, stackTrace, 1,
false, false)
== B_OK) {
fThread->GetTeam(), this, cpuState, stackTrace, 0, 1,
false, false) == B_OK) {
stackTraceReference.SetTo(stackTrace, true);
}
}
@@ -576,7 +576,7 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState)
// If we're not in the same frame we started in,
// keep executing.
if (frame != NULL && fPreviousFrameAddress
!= stackTrace->FrameAt(0)->FrameAddress()) {
!= frame->FrameAddress()) {
status_t error = _InstallTemporaryBreakpoint(
cpuState->InstructionPointer());
if (error != B_OK)
@@ -608,6 +608,7 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState)
// That's the return address, so we're done in theory,
// unless we're a recursive function. Check if we've actually
// exited the previous stack frame or not.
fThread->SetExecutedSubroutine(cpuState->InstructionPointer());
target_addr_t framePointer = cpuState->StackFramePointer();
bool hasExitedFrame = fDebuggerInterface->GetArchitecture()
->StackGrowthDirection() == STACK_GROWTH_DIRECTION_POSITIVE
@@ -652,9 +653,8 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
if (stackTrace == NULL && cpuState != NULL) {
if (fDebuggerInterface->GetArchitecture()->CreateStackTrace(
fThread->GetTeam(), this, cpuState, stackTrace, 1,
false, false)
== B_OK) {
fThread->GetTeam(), this, cpuState, stackTrace, 0, 1,
false, false) == B_OK) {
stackTraceReference.SetTo(stackTrace, true);
}
}
@@ -680,8 +680,25 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
case STEP_OVER:
{
// If we have stepped out of the statement, we're done.
if (!fStepStatement->ContainsAddress(cpuState->InstructionPointer()))
if (!fStepStatement->ContainsAddress(cpuState->InstructionPointer())) {
StackTrace* stackTrace = fThread->GetStackTrace();
BReference<StackTrace> stackTraceReference(stackTrace);
if (stackTrace == NULL && cpuState != NULL) {
if (fDebuggerInterface->GetArchitecture()->CreateStackTrace(
fThread->GetTeam(), this, cpuState, stackTrace, 0,
1, false, false) == B_OK) {
stackTraceReference.SetTo(stackTrace, true);
}
}
if (stackTrace != NULL && stackTrace->FrameAt(0)
->FrameAddress() != fPreviousFrameAddress) {
fThread->SetExecutedSubroutine(
cpuState->InstructionPointer());
}
return false;
}
return _DoStepOver(cpuState);
}
@@ -68,8 +68,8 @@ DebuggerImageDebugInfo::GetAddressSectionType(target_addr_t address)
status_t
DebuggerImageDebugInfo::CreateFrame(Image* image,
FunctionInstance* functionInstance, CpuState* cpuState,
bool getFullFrameInfo, StackFrame*& _previousFrame,
CpuState*& _previousCpuState)
bool getFullFrameInfo, target_addr_t returnFunctionAddress,
StackFrame*& _previousFrame, CpuState*& _previousCpuState)
{
return B_UNSUPPORTED;
}
@@ -36,6 +36,7 @@ public:
FunctionInstance* functionInstance,
CpuState* cpuState,
bool getFullFrameInfo,
target_addr_t returnFunctionAddress,
StackFrame*& _previousFrame,
CpuState*& _previousCpuState);
virtual status_t GetStatement(FunctionDebugInfo* function,
@@ -41,6 +41,8 @@
#include "FunctionID.h"
#include "FunctionInstance.h"
#include "GlobalTypeLookup.h"
#include "Image.h"
#include "ImageDebugInfo.h"
#include "InstructionInfo.h"
#include "LocatableFile.h"
#include "Register.h"
@@ -51,11 +53,13 @@
#include "StringUtils.h"
#include "SymbolInfo.h"
#include "TargetAddressRangeList.h"
#include "Team.h"
#include "TeamMemory.h"
#include "Tracing.h"
#include "TypeLookupConstraints.h"
#include "UnsupportedLanguage.h"
#include "Variable.h"
#include "ValueLocation.h"
namespace {
@@ -518,7 +522,8 @@ DwarfImageDebugInfo::GetAddressSectionType(target_addr_t address)
status_t
DwarfImageDebugInfo::CreateFrame(Image* image,
FunctionInstance* functionInstance, CpuState* cpuState,
bool getFullFrameInfo, StackFrame*& _frame, CpuState*& _previousCpuState)
bool getFullFrameInfo, target_addr_t returnFunctionAddress,
StackFrame*& _frame, CpuState*& _previousCpuState)
{
DwarfFunctionDebugInfo* function = dynamic_cast<DwarfFunctionDebugInfo*>(
functionInstance->GetFunctionDebugInfo());
@@ -668,13 +673,14 @@ DwarfImageDebugInfo::CreateFrame(Image* image,
instructionPointer, functionInstance->Address() - fRelocationDelta,
subprogramEntry->Variables(), subprogramEntry->Blocks());
// determine if the previously executed instruction was a function
// call to see if we need to potentially retrieve a return value
// as well
if (instructionPointer > functionInstance->Address() - fRelocationDelta) {
_CreateReturnValue(functionInstance, function, frame,
*stackFrameDebugInfo, instructionPointer);
// TODO: re-enable once PIC and false positive issues
// are properly dealt with
#if 0
if (returnFunctionAddress != 0) {
_CreateReturnValue(returnFunctionAddress, image, frame,
*stackFrameDebugInfo);
}
#endif
}
_frame = frameReference.Detach();
@@ -1084,43 +1090,73 @@ DwarfImageDebugInfo::_CreateLocalVariables(CompilationUnit* unit,
status_t
DwarfImageDebugInfo::_CreateReturnValue(FunctionInstance* functionInstance,
DwarfFunctionDebugInfo* function, StackFrame* frame,
DwarfStackFrameDebugInfo& factory, target_addr_t instructionPointer)
DwarfImageDebugInfo::_CreateReturnValue(target_addr_t returnFunctionAddress,
Image* image, StackFrame* frame, DwarfStackFrameDebugInfo& factory)
{
DisassembledCode* sourceCode = NULL;
target_size_t bufferSize = std::min(functionInstance->Size(),
(target_size_t)64 * 1024);
void* buffer = malloc(bufferSize);
if (buffer == NULL)
return B_NO_MEMORY;
MemoryDeleter bufferDeleter(buffer);
ssize_t bytesRead = function->GetSpecificImageDebugInfo()
->ReadCode(functionInstance->Address(), buffer, bufferSize);
if (bytesRead < 0)
return bytesRead;
if (!image->ContainsAddress(returnFunctionAddress)) {
// our current image doesn't contain the target function,
// locate the one which does.
image = image->GetTeam()->ImageByAddress(returnFunctionAddress);
if (image == NULL)
return B_BAD_VALUE;
}
status_t result = fArchitecture->DisassembleCode(function, buffer,
bytesRead, sourceCode);
if (result != B_OK)
return result;
status_t result = B_OK;
FunctionInstance* targetFunction;
if (returnFunctionAddress >= fPLTSectionStart
&& returnFunctionAddress < fPLTSectionEnd) {
// TODO: handle resolving PLT entries
// to their target function
return B_UNSUPPORTED;
}
BReference<DisassembledCode> sourceCodeReference(sourceCode, true);
target_addr_t previousStatementAddress = instructionPointer + fRelocationDelta - 1;
Statement* statement = sourceCode->StatementAtAddress(
previousStatementAddress);
if (statement == NULL)
return B_BAD_VALUE;
ImageDebugInfo* imageInfo = image->GetImageDebugInfo();
targetFunction = imageInfo->FunctionAtAddress(returnFunctionAddress);
if (targetFunction != NULL) {
DwarfFunctionDebugInfo* targetInfo =
dynamic_cast<DwarfFunctionDebugInfo*>(
targetFunction->GetFunctionDebugInfo());
if (targetInfo != NULL) {
DIESubprogram* subProgram = targetInfo->SubprogramEntry();
DIEType* returnType = subProgram->ReturnType();
if (returnType == NULL) {
// check if we have a specification, and if so, if that has
// a return type
subProgram = dynamic_cast<DIESubprogram*>(subProgram->Specification());
if (subProgram != NULL)
returnType = subProgram->ReturnType();
TargetAddressRange range = statement->CoveringAddressRange();
InstructionInfo info;
if (fArchitecture->GetInstructionInfo(range.Start(), info) == B_OK
&& info.Type() == INSTRUCTION_TYPE_SUBROUTINE_CALL) {
// TODO: determine where the previous instruction actually jumps to,
// retrieve that function (could potentially be in another image),
// and use its return type to retrieve the return value (will need
// architecture support since function return value passing convention
// is arch-dependent).
// function doesn't return a value, we're done.
if (returnType == NULL)
return B_OK;
}
uint32 byteSize = 0;
if (returnType->ByteSize() == NULL) {
if (dynamic_cast<DIEAddressingType*>(returnType) != NULL)
byteSize = fArchitecture->AddressSize();
} else
byteSize = returnType->ByteSize()->constant;
ValueLocation* location;
result = fArchitecture->GetReturnAddressLocation(frame,
byteSize, location);
if (result != B_OK)
return result;
BReference<ValueLocation> locationReference(location, true);
Variable* variable = NULL;
BReference<FunctionID> idReference(
targetFunction->GetFunctionID(), true);
result = factory.CreateReturnValue(idReference, returnType,
location, variable);
if (result != B_OK)
return result;
BReference<Variable> variableReference(variable, true);
if (!frame->AddLocalVariable(variable))
return B_NO_MEMORY;
}
}
return B_OK;
@@ -64,6 +64,7 @@ public:
FunctionInstance* functionInstance,
CpuState* cpuState,
bool getFullFrameInfo,
target_addr_t returnFunctionAddress,
StackFrame*& _frame,
CpuState*& _previousCpuState);
virtual status_t GetStatement(FunctionDebugInfo* function,
@@ -103,11 +104,11 @@ private:
const EntryListWrapper& variableEntries,
const EntryListWrapper& blockEntries);
status_t _CreateReturnValue(FunctionInstance* instance,
DwarfFunctionDebugInfo* info,
status_t _CreateReturnValue(
target_addr_t returnFunctionAddress,
Image* image,
StackFrame* frame,
DwarfStackFrameDebugInfo& factory,
target_addr_t instructionPointer);
DwarfStackFrameDebugInfo& factory);
bool _EvaluateBaseTypeConstraints(DIEType* type,
const TypeLookupConstraints& constraints);
@@ -1,4 +1,5 @@
/*
* Copyright 2012, Rene Gollent, rene@gollent.com.
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
@@ -23,6 +24,7 @@
#include "LocalVariableID.h"
#include "Register.h"
#include "RegisterMap.h"
#include "ReturnValueID.h"
#include "StringUtils.h"
#include "Tracing.h"
#include "ValueLocation.h"
@@ -117,6 +119,47 @@ private:
};
// #pragma mark - DwarfReturnValueID
struct DwarfStackFrameDebugInfo::DwarfReturnValueID
: public ReturnValueID {
DwarfReturnValueID(FunctionID* functionID)
:
fFunctionID(functionID),
fName("(returned)")
{
fFunctionID->AcquireReference();
}
virtual ~DwarfReturnValueID()
{
fFunctionID->ReleaseReference();
}
virtual bool operator==(const ObjectID& other) const
{
const DwarfReturnValueID* returnValueID
= dynamic_cast<const DwarfReturnValueID*>(&other);
return returnValueID != NULL
&& *fFunctionID == *returnValueID->fFunctionID
&& fName == returnValueID->fName;
}
protected:
virtual uint32 ComputeHashValue() const
{
uint32 hash = fFunctionID->HashValue();
return hash * 25 + StringUtils::HashValue(fName);
}
private:
FunctionID* fFunctionID;
const BString fName;
};
// #pragma mark - DwarfStackFrameDebugInfo
@@ -234,6 +277,39 @@ DwarfStackFrameDebugInfo::CreateLocalVariable(FunctionID* functionID,
}
status_t
DwarfStackFrameDebugInfo::CreateReturnValue(FunctionID* functionID,
DIEType* returnType, ValueLocation* location, Variable*& _variable)
{
if (returnType == NULL)
return B_BAD_VALUE;
// create the type
DwarfType* type;
status_t error = fTypeFactory->CreateType(returnType, type);
if (error != B_OK)
return error;
BReference<DwarfType> typeReference(type, true);
DwarfReturnValueID* id = new(std::nothrow) DwarfReturnValueID(
functionID);
if (id == NULL)
return B_NO_MEMORY;
BString name;
name.SetToFormat("%s returned", functionID->FunctionName().String());
Variable* variable = new(std::nothrow) Variable(id, name,
type, location);
if (variable == NULL)
return B_NO_MEMORY;
_variable = variable;
return B_OK;
}
status_t
DwarfStackFrameDebugInfo::_CreateVariable(ObjectID* id, const BString& name,
DIEType* typeEntry, LocationDescription* locationDescription,
@@ -1,4 +1,5 @@
/*
* Copyright 2012, Rene Gollent, rene@gollent.com.
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
@@ -56,10 +57,16 @@ public:
DIEVariable* variableEntry,
Variable*& _variable);
// returns reference
status_t CreateReturnValue(FunctionID* functionID,
DIEType* returnType,
ValueLocation* location,
Variable*& _variable);
// returns reference
private:
struct DwarfFunctionParameterID;
struct DwarfLocalVariableID;
struct DwarfReturnValueID;
private:
status_t _CreateVariable(ObjectID* id,
@@ -56,6 +56,7 @@ public:
FunctionInstance* functionInstance,
CpuState* cpuState,
bool getFullFrameInfo,
target_addr_t returnFunctionAddress,
StackFrame*& _Frame,
CpuState*& _previousCpuState) = 0;
// returns reference to previous frame
+13
View File
@@ -0,0 +1,13 @@
/*
* Copyright 2012, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#include "ReturnValueID.h"
ReturnValueID::~ReturnValueID()
{
}
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright 2012, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef RETURN_VALUE_ID_H
#define RETURN_VALUE_ID_H
#include "ObjectID.h"
class ReturnValueID : public ObjectID {
public:
virtual ~ReturnValueID();
};
#endif // RETURN_VALUE_ID_H
+2 -1
View File
@@ -58,7 +58,8 @@ GetStackTraceJob::Do()
// get the stack trace
StackTrace* stackTrace;
status_t error = fArchitecture->CreateStackTrace(fThread->GetTeam(), this,
fCpuState, stackTrace);
fCpuState, stackTrace, fThread->ExecutedSubroutine()
? fThread->SubroutineAddress() : 0);
if (error != B_OK)
return error;
BReference<StackTrace> stackTraceReference(stackTrace, true);
+13
View File
@@ -17,6 +17,8 @@ Thread::Thread(Team* team, thread_id threadID)
fTeam(team),
fID(threadID),
fState(THREAD_STATE_UNKNOWN),
fExecutedSubroutine(false),
fSubroutineAddress(0),
fStoppedReason(THREAD_STOPPED_UNKNOWN),
fCpuState(NULL),
fStackTrace(NULL)
@@ -68,6 +70,8 @@ Thread::SetState(uint32 state, uint32 reason, const BString& info)
if (fState != THREAD_STATE_STOPPED) {
SetCpuState(NULL);
SetStackTrace(NULL);
fExecutedSubroutine = false;
fSubroutineAddress = 0;
}
fTeam->NotifyThreadStateChanged(this);
@@ -108,3 +112,12 @@ Thread::SetStackTrace(StackTrace* trace)
fTeam->NotifyThreadStackTraceChanged(this);
}
void
Thread::SetExecutedSubroutine(target_addr_t address)
{
fExecutedSubroutine = true;
fSubroutineAddress = address;
}
+10
View File
@@ -11,6 +11,8 @@
#include <Referenceable.h>
#include <util/DoublyLinkedList.h>
#include "types/Types.h"
class CpuState;
class StackTrace;
@@ -67,11 +69,19 @@ public:
StackTrace* GetStackTrace() const { return fStackTrace; }
void SetStackTrace(StackTrace* trace);
bool ExecutedSubroutine() const
{ return fExecutedSubroutine; }
target_addr_t SubroutineAddress() const
{ return fSubroutineAddress; }
void SetExecutedSubroutine(target_addr_t address);
private:
Team* fTeam;
thread_id fID;
BString fName;
uint32 fState;
bool fExecutedSubroutine;
target_addr_t fSubroutineAddress;
uint32 fStoppedReason;
BString fStoppedReasonInfo;
CpuState* fCpuState;
+2
View File
@@ -302,6 +302,8 @@ TBarApp::InitSettings()
theDir.CreateFile(settingsFileName, fSettingsFile);
}
filePath = dirPath;
filePath.Append(clockSettingsFileName);
fClockSettingsFile = new BFile(filePath.Path(), O_RDWR);
if (fClockSettingsFile->InitCheck() != B_OK) {
BDirectory theDir(dirPath.Path());
+15 -15
View File
@@ -21,9 +21,9 @@
#include "AntialiasingSettingsView.h"
#include "APRView.h"
#include "LookAndFeelSettingsView.h"
#include "defs.h"
#include "FontView.h"
#include "LookAndFeelSettingsView.h"
#undef B_TRANSLATION_CONTEXT
@@ -50,19 +50,19 @@ APRWindow::APRWindow(BRect frame)
BTabView* tabView = new BTabView("tabview", B_WIDTH_FROM_LABEL);
fLookAndFeelSettings = new LookAndFeelSettingsView(
B_TRANSLATE("Look and feel"));
fFontSettings = new FontView(B_TRANSLATE("Fonts"));
fColorsView = new APRView(B_TRANSLATE("Colors"));
fLookAndFeelSettings = new LookAndFeelSettingsView(
B_TRANSLATE("Look and feel"));
fAntialiasingSettings = new AntialiasingSettingsView(
B_TRANSLATE("Antialiasing"));
tabView->AddTab(fLookAndFeelSettings);
tabView->AddTab(fFontSettings);
tabView->AddTab(fColorsView);
tabView->AddTab(fLookAndFeelSettings);
tabView->AddTab(fAntialiasingSettings);
_UpdateButtons();
@@ -91,8 +91,8 @@ APRWindow::MessageReceived(BMessage *message)
case kMsgSetDefaults:
fFontSettings->SetDefaults();
fColorsView->SetDefaults();
fAntialiasingSettings->SetDefaults();
fLookAndFeelSettings->SetDefaults();
fAntialiasingSettings->SetDefaults();
_UpdateButtons();
break;
@@ -100,8 +100,8 @@ APRWindow::MessageReceived(BMessage *message)
case kMsgRevert:
fColorsView->Revert();
fAntialiasingSettings->Revert();
fFontSettings->Revert();
fLookAndFeelSettings->Revert();
fFontSettings->Revert();
_UpdateButtons();
break;
@@ -128,10 +128,10 @@ APRWindow::_IsDefaultable() const
// printf("colors defaultable: %d\n", fColorsView->IsDefaultable());
// printf("AA defaultable: %d\n", fAntialiasingSettings->IsDefaultable());
// printf("decor defaultable: %d\n", fLookAndFeelSettings->IsDefaultable());
return fColorsView->IsDefaultable()
|| fFontSettings->IsDefaultable()
|| fAntialiasingSettings->IsDefaultable()
|| fLookAndFeelSettings->IsDefaultable();
return fFontSettings->IsDefaultable()
|| fColorsView->IsDefaultable()
|| fLookAndFeelSettings->IsDefaultable()
|| fAntialiasingSettings->IsDefaultable();
}
@@ -142,8 +142,8 @@ APRWindow::_IsRevertable() const
// printf("colors revertable: %d\n", fColorsView->IsRevertable());
// printf("AA revertable: %d\n", fAntialiasingSettings->IsRevertable());
// printf("decor revertable: %d\n", fLookAndFeelSettings->IsRevertable());
return fColorsView->IsRevertable()
|| fFontSettings->IsRevertable()
|| fAntialiasingSettings->IsRevertable()
|| fLookAndFeelSettings->IsRevertable();
return fFontSettings->IsRevertable()
|| fColorsView->IsRevertable()
|| fLookAndFeelSettings->IsRevertable()
|| fAntialiasingSettings->IsRevertable();
}