Scanner now picks up restgprlr calls.
This commit is contained in:
parent
1dc356cb4d
commit
e2e2a392ee
|
@ -12,6 +12,7 @@
|
||||||
#include <alloy/frontend/tracing.h>
|
#include <alloy/frontend/tracing.h>
|
||||||
#include <alloy/frontend/ppc/ppc_frontend.h>
|
#include <alloy/frontend/ppc/ppc_frontend.h>
|
||||||
#include <alloy/frontend/ppc/ppc_instr.h>
|
#include <alloy/frontend/ppc/ppc_instr.h>
|
||||||
|
#include <alloy/runtime/runtime.h>
|
||||||
|
|
||||||
using namespace alloy;
|
using namespace alloy;
|
||||||
using namespace alloy::frontend;
|
using namespace alloy::frontend;
|
||||||
|
@ -27,10 +28,11 @@ PPCScanner::~PPCScanner() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCScanner::IsRestGprLr(uint64_t address) {
|
bool PPCScanner::IsRestGprLr(uint64_t address) {
|
||||||
// TODO(benvanik): detect type.
|
FunctionInfo* symbol_info;
|
||||||
/*FunctionSymbol* fn = GetFunction(addr);
|
if (frontend_->runtime()->LookupFunctionInfo(address, &symbol_info)) {
|
||||||
return fn && (fn->flags & FunctionSymbol::kFlagRestGprLr);*/
|
return false;
|
||||||
return false;
|
}
|
||||||
|
return symbol_info->behavior() == FunctionInfo::BEHAVIOR_EPILOG_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
|
@ -136,7 +138,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
// (Indirect branches may still go beyond, but no way of knowing).
|
// (Indirect branches may still go beyond, but no way of knowing).
|
||||||
if (target >= start_address &&
|
if (target >= start_address &&
|
||||||
target < address && furthest_target <= address) {
|
target < address && furthest_target <= address) {
|
||||||
XELOGSDB("function end %.8X (back b)", addr);
|
XELOGSDB("function end %.8X (back b)", address);
|
||||||
ends_fn = true;
|
ends_fn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +146,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
// address it's definitely a tail call.
|
// address it's definitely a tail call.
|
||||||
if (!ends_fn &&
|
if (!ends_fn &&
|
||||||
target < start_address && furthest_target <= address) {
|
target < start_address && furthest_target <= address) {
|
||||||
XELOGSDB("function end %.8X (back b before addr)", addr);
|
XELOGSDB("function end %.8X (back b before addr)", address);
|
||||||
ends_fn = true;
|
ends_fn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +157,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
if (!ends_fn &&
|
if (!ends_fn &&
|
||||||
furthest_target <= address &&
|
furthest_target <= address &&
|
||||||
IsRestGprLr(target)) {
|
IsRestGprLr(target)) {
|
||||||
XELOGSDB("function end %.8X (__restgprlr_*)", addr);
|
XELOGSDB("function end %.8X (__restgprlr_*)", address);
|
||||||
ends_fn = true;
|
ends_fn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,17 +226,17 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
|
||||||
} else if (i.type->opcode == 0x4C000020) {
|
} else if (i.type->opcode == 0x4C000020) {
|
||||||
// bclr/bclrl
|
// bclr/bclrl
|
||||||
if (i.XL.LK) {
|
if (i.XL.LK) {
|
||||||
XELOGSDB("bclrl %.8X", addr);
|
XELOGSDB("bclrl %.8X", address);
|
||||||
} else {
|
} else {
|
||||||
XELOGSDB("bclr %.8X", addr);
|
XELOGSDB("bclr %.8X", address);
|
||||||
}
|
}
|
||||||
ends_block = true;
|
ends_block = true;
|
||||||
} else if (i.type->opcode == 0x4C000420) {
|
} else if (i.type->opcode == 0x4C000420) {
|
||||||
// bcctr/bcctrl
|
// bcctr/bcctrl
|
||||||
if (i.XL.LK) {
|
if (i.XL.LK) {
|
||||||
XELOGSDB("bcctrl %.8X", addr);
|
XELOGSDB("bcctrl %.8X", address);
|
||||||
} else {
|
} else {
|
||||||
XELOGSDB("bcctr %.8X", addr);
|
XELOGSDB("bcctr %.8X", address);
|
||||||
}
|
}
|
||||||
ends_block = true;
|
ends_block = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ SymbolInfo::~SymbolInfo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionInfo::FunctionInfo(Module* module, uint64_t address) :
|
FunctionInfo::FunctionInfo(Module* module, uint64_t address) :
|
||||||
end_address_(0), function_(0),
|
end_address_(0), behavior_(BEHAVIOR_DEFAULT), function_(0),
|
||||||
SymbolInfo(SymbolInfo::TYPE_FUNCTION, module, address) {
|
SymbolInfo(SymbolInfo::TYPE_FUNCTION, module, address) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,14 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
class FunctionInfo : public SymbolInfo {
|
class FunctionInfo : public SymbolInfo {
|
||||||
|
public:
|
||||||
|
enum Behavior {
|
||||||
|
BEHAVIOR_DEFAULT = 0,
|
||||||
|
BEHAVIOR_PROLOG,
|
||||||
|
BEHAVIOR_EPILOG,
|
||||||
|
BEHAVIOR_EPILOG_RETURN,
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FunctionInfo(Module* module, uint64_t address);
|
FunctionInfo(Module* module, uint64_t address);
|
||||||
virtual ~FunctionInfo();
|
virtual ~FunctionInfo();
|
||||||
|
@ -60,11 +68,15 @@ public:
|
||||||
uint64_t end_address() const { return end_address_; }
|
uint64_t end_address() const { return end_address_; }
|
||||||
void set_end_address(uint64_t value) { end_address_ = value; }
|
void set_end_address(uint64_t value) { end_address_ = value; }
|
||||||
|
|
||||||
|
Behavior behavior() const { return behavior_; }
|
||||||
|
void set_behavior(Behavior value) { behavior_ = value; }
|
||||||
|
|
||||||
Function* function() const { return function_; }
|
Function* function() const { return function_; }
|
||||||
void set_function(Function* value) { function_ = value; }
|
void set_function(Function* value) { function_ = value; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t end_address_;
|
uint64_t end_address_;
|
||||||
|
Behavior behavior_;
|
||||||
Function* function_;
|
Function* function_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -390,6 +390,7 @@ int XexModule::FindSaveRest() {
|
||||||
// TODO(benvanik): set name
|
// TODO(benvanik): set name
|
||||||
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
||||||
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagSaveGprLr;
|
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagSaveGprLr;
|
||||||
|
symbol_info->set_behavior(FunctionInfo::BEHAVIOR_PROLOG);
|
||||||
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
||||||
address += 4;
|
address += 4;
|
||||||
}
|
}
|
||||||
|
@ -402,6 +403,7 @@ int XexModule::FindSaveRest() {
|
||||||
// TODO(benvanik): set name
|
// TODO(benvanik): set name
|
||||||
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
||||||
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagRestGprLr;
|
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagRestGprLr;
|
||||||
|
symbol_info->set_behavior(FunctionInfo::BEHAVIOR_EPILOG_RETURN);
|
||||||
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
||||||
address += 4;
|
address += 4;
|
||||||
}
|
}
|
||||||
|
@ -416,6 +418,7 @@ int XexModule::FindSaveRest() {
|
||||||
// TODO(benvanik): set name
|
// TODO(benvanik): set name
|
||||||
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
||||||
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagSaveFpr;
|
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagSaveFpr;
|
||||||
|
symbol_info->set_behavior(FunctionInfo::BEHAVIOR_PROLOG);
|
||||||
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
||||||
address += 4;
|
address += 4;
|
||||||
}
|
}
|
||||||
|
@ -428,6 +431,7 @@ int XexModule::FindSaveRest() {
|
||||||
// TODO(benvanik): set name
|
// TODO(benvanik): set name
|
||||||
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
||||||
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagRestFpr;
|
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagRestFpr;
|
||||||
|
symbol_info->set_behavior(FunctionInfo::BEHAVIOR_EPILOG);
|
||||||
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
||||||
address += 4;
|
address += 4;
|
||||||
}
|
}
|
||||||
|
@ -446,6 +450,7 @@ int XexModule::FindSaveRest() {
|
||||||
// TODO(benvanik): set name
|
// TODO(benvanik): set name
|
||||||
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
||||||
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagSaveVmx;
|
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagSaveVmx;
|
||||||
|
symbol_info->set_behavior(FunctionInfo::BEHAVIOR_PROLOG);
|
||||||
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
||||||
address += 2 * 4;
|
address += 2 * 4;
|
||||||
}
|
}
|
||||||
|
@ -457,6 +462,7 @@ int XexModule::FindSaveRest() {
|
||||||
// TODO(benvanik): set name
|
// TODO(benvanik): set name
|
||||||
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
||||||
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagSaveVmx;
|
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagSaveVmx;
|
||||||
|
symbol_info->set_behavior(FunctionInfo::BEHAVIOR_PROLOG);
|
||||||
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
||||||
address += 2 * 4;
|
address += 2 * 4;
|
||||||
}
|
}
|
||||||
|
@ -468,6 +474,7 @@ int XexModule::FindSaveRest() {
|
||||||
// TODO(benvanik): set name
|
// TODO(benvanik): set name
|
||||||
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
||||||
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagRestVmx;
|
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagRestVmx;
|
||||||
|
symbol_info->set_behavior(FunctionInfo::BEHAVIOR_EPILOG);
|
||||||
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
||||||
address += 2 * 4;
|
address += 2 * 4;
|
||||||
}
|
}
|
||||||
|
@ -479,6 +486,7 @@ int XexModule::FindSaveRest() {
|
||||||
// TODO(benvanik): set name
|
// TODO(benvanik): set name
|
||||||
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
// TODO(benvanik): set type fn->type = FunctionSymbol::User;
|
||||||
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagRestVmx;
|
// TODO(benvanik): set flags fn->flags |= FunctionSymbol::kFlagRestVmx;
|
||||||
|
symbol_info->set_behavior(FunctionInfo::BEHAVIOR_EPILOG);
|
||||||
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
||||||
address += 2 * 4;
|
address += 2 * 4;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue