if (const MCSymbolRefExpr *A = Target.getSymA()) {
const MCSymbol &Sym = A->getSymbol();
bool valid;
if (Sym.isDefined()) {
Value += Layout.getSymbolOffset(Sym, valid);
if (!valid) {
KsError = KS_ERR_ASM_FIXUP_INVALID;
return false;
}
} else {
// a missing symbol. is there any resolver registered?
if (KsSymResolver) {
uint64_t imm;
ks_sym_resolver resolver = (ks_sym_resolver)KsSymResolver;
if (resolver(Sym.getName().str().c_str(), &imm)) {
// resolver handled this symbol
Value = imm;
IsResolved = true;
} else {
// resolver did not handle this symbol
KsError = KS_ERR_ASM_SYMBOL_MISSING;
return false;
}
} else {
// no resolver registered
KsError = KS_ERR_ASM_SYMBOL_MISSING;
return false;
}
}
}
after resolver finding the address, it assign the imm to Value directly. but the other branch where symbol is not missing, it will do "Value += Layout.getSymbolOffset(Sym, valid);", this is where the difference is. maybe it should be "Value += imm" when using resolver?
I tried recompile keystone with the patch, and now it gives ('\xe9\xa8\xde\x00\x00', 1L) as result, which is "jmp 0xdead".
to testing sym_resolver interface, I wrote the following script:
while we want is "jmp 0xdead", current keystone engine will give "\xe9\xac\xde\x00\x00" as result, which is "jmp 0xdeb1". this is not what we want, I think the cause is in https://github.com/keystone-engine/keystone/blob/master/llvm/lib/MC/MCAssembler.cpp
after resolver finding the address, it assign the imm to Value directly. but the other branch where symbol is not missing, it will do "Value += Layout.getSymbolOffset(Sym, valid);", this is where the difference is. maybe it should be "Value += imm" when using resolver?
I tried recompile keystone with the patch, and now it gives ('\xe9\xa8\xde\x00\x00', 1L) as result, which is "jmp 0xdead".
maybe a fix?