Compare commits
3 Commits
51ee6fd6ff
...
0ffc5f38f6
Author | SHA1 | Date |
---|---|---|
Lephenixnoir | 0ffc5f38f6 | |
Lephenixnoir | 10e7334524 | |
Lephenixnoir | 593d486185 |
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ===//
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue