Compare commits

...

3 Commits

4 changed files with 43 additions and 20 deletions

View File

@ -73,10 +73,12 @@ struct ViewAssemblyOptions
Promotion PCAddr_to_Location = Promote;
/* In a read with a know location, promote address to pointed value */
Promotion ReadLocation_to_Constant = Promote;
/* Promote an integer to a binary object's name */
Promotion Constant_to_ObjectName = Promote;
/* Promote an integer to a syscall number (if no name is available) */
/* Promote an integer to a syscall number */
Promotion Constant_to_SyscallNumber = Promote;
/* Promote an integer (not a syscall) to a binary object's name */
Promotion Constant_to_ObjectName = Promote;
/* Promote a syscall number to a binary object's name */
Promotion SyscallNumber_to_ObjectName = Append;
} promotions;
/* Binary to get symbols from */

View File

@ -172,7 +172,8 @@ struct Superblock
};
// TODO: Unclear what the exit status of the superblock is in case of error
static Superblock exploreSuperblock(Function &function, u32 entry, bool *error)
static Superblock exploreSuperblock(Function &function,
std::vector<Superblock> const &blocks, u32 entry, bool *error)
{
Superblock sb;
sb.addresses.reserve(32);
@ -182,6 +183,7 @@ static Superblock exploreSuperblock(Function &function, u32 entry, bool *error)
VirtualSpace &vspace = function.parentBinary().vspace();
bool inDelaySlot = false;
bool terminatorFound = false;
bool ranIntoAnotherBlock = false;
u32 pc = entry;
/* Determine how much space the vspace covers at this address to know if we
@ -195,7 +197,11 @@ static Superblock exploreSuperblock(Function &function, u32 entry, bool *error)
return sb;
}
while(!terminatorFound || inDelaySlot) {
/* Break after either finding a terminator or finding an instruction
already explored as part of another superblock, unless we are in a delay
slot, because (1) delay slots go with terminators, (2) if another block
starts at the delay slot there will be trouble, so duplicate it. */
while((!terminatorFound && !ranIntoAnotherBlock) || inDelaySlot) {
sb.addresses.push_back(pc);
/* Read the next instruction from memory */
@ -238,6 +244,13 @@ static Superblock exploreSuperblock(Function &function, u32 entry, bool *error)
terminatorFound = terminatorFound || opcode.isBlockTerminator();
inDelaySlot = !inDelaySlot && opcode.hasDelaySlot();
pc += 2;
for(auto const &other: blocks) {
if(other.addresses[0] == pc) {
ranIntoAnotherBlock = true;
break;
}
}
}
if(*error)
@ -289,7 +302,7 @@ bool Function::exploreFunctionAt(u32 functionAddress)
continue;
bool error = false;
Superblock sb = exploreSuperblock(*this, entry, &error);
Superblock sb = exploreSuperblock(*this, blocks, entry, &error);
if(error)
return false;

View File

@ -96,18 +96,6 @@ static void renderOperand(AsmOperand const &op, u32 pc, int opsize,
type = Constant;
}
/* Promote to object name first if available... */
if(type == Constant && hasValue && opts.binary) {
auto p = opts.promotions.Constant_to_ObjectName;
BinaryObject *obj = opts.binary->objectAt(value);
if(obj) {
if(output(out, p, {}, obj->name()))
return;
type = ObjectName;
}
}
/* ... or, as a default, a syscall number */
if(type == Constant && hasValue && os) {
int syscall_id = os->find_syscall(value);
if(syscall_id >= 0) {
@ -117,6 +105,25 @@ static void renderOperand(AsmOperand const &op, u32 pc, int opsize,
type = SyscallNumber;
}
}
if(type == Constant && hasValue && opts.binary) {
auto p = opts.promotions.Constant_to_ObjectName;
BinaryObject *obj = opts.binary->objectAt(value);
if(obj) {
if(output(out, p, {}, obj->name()))
return;
type = ObjectName;
}
}
if(type == SyscallNumber && hasValue && opts.binary) {
auto p = opts.promotions.SyscallNumber_to_ObjectName;
BinaryObject *obj = opts.binary->objectAt(value);
if(obj) {
if(output(out, p, {}, obj->name()))
return;
type = ObjectName;
}
}
}
//=== Legacy-style instruction printer ===//

View File

@ -115,7 +115,7 @@ static void af_analyze(Session &session, Binary &binary, _af_args const &args)
std::set<u32> TEST_knownErrors;
int done = 0, successes = 0, skipped = 0, errors = 0;
int done = 0, created = 0, successes = 0, skipped = 0, errors = 0;
int total = functionQueue.size();
int unresolvedCalls = 0;
@ -144,6 +144,7 @@ static void af_analyze(Session &session, Binary &binary, _af_args const &args)
binary.addObject(std::move(f));
existing = binary.functionAt(entry);
successes++;
created++;
}
else {
FxOS_log(ERR, "... while analyzing 0x%08x", entry);
@ -175,7 +176,7 @@ static void af_analyze(Session &session, Binary &binary, _af_args const &args)
if(args.recursive)
printf("There were %d unresolved call sites.\n", unresolvedCalls);
if(successes > 0)
if(created > 0)
session.project().setDirty();
// _af_consistency(binary);