// This method does plain instruction decoding, no frills. // It may be called before the binutils disassembler kicks in // to handle special cases the binutils disassembler does not. // Instruction address, comments, and the like have to be output by caller.
address Disassembler::decode_instruction0(address here, outputStream * st, address virtual_begin) { if (is_abstract()) { // The disassembler library was not loaded (yet), // use AbstractDisassembler's decode-method. return decode_instruction_abstract(here, st, Assembler::instr_len(here), Assembler::instr_maxlen());
}
// Currently, "special decoding" doesn't work when decoding error files. // When decoding an instruction from a hs_err file, the given // instruction address 'start' points to the instruction's virtual address // which is not equal to the address where the instruction is located. // Therefore, we will either crash or decode garbage. if (is_decode_error_file()) { return here;
}
if (Assembler::is_z_nop((long)instruction_2bytes)) { #if1
st->print("nop "); // fill up to operand column, leads to better code comment alignment
next = here + 2; #else // Compact disassembler output. Does not work the easy way. // Currently unusable, search does not terminate, risk of crash. // TODO: rework required. // Terminate search loop when reaching CodeEntryAlignment-aligned offset // or, at the latest, when reaching the next page boundary. int n_nops = 0; while(is_same_page(here, here+2*n_nops) && Assembler::is_z_nop((long)instruction_2bytes)) {
n_nops++;
instruction_2bytes = *(uint16_t*)(here+2*n_nops);
} if (n_nops <= 4) { // do not group few subsequent nops
st->print("nop "); // fill up to operand column, leads to better code comment alignment
next = here + 2;
} else {
st->print("nop count=%d", n_nops);
next = here + 2*n_nops;
} #endif
} elseif (Assembler::is_z_sync((long)instruction_2bytes)) { // Specific names. Make use of lightweight sync.
st->print("sync "); if (Assembler::is_z_sync_full((long)instruction_2bytes) ) st->print("heavyweight"); if (Assembler::is_z_sync_light((long)instruction_2bytes)) st->print("lightweight");
next = here + 2;
} elseif (instruction_2bytes == 0x0000) { #if1
st->print("illtrap .nodata");
next = here + 2; #else // Compact disassembler output. Does not work the easy way. // Currently unusable, search does not terminate, risk of crash. // TODO: rework required. // Terminate search loop when reaching CodeEntryAlignment-aligned offset // or, at the latest, when reaching the next page boundary. int n_traps = 0; while(is_same_page(here, here+2*n_nops) && (instruction_2bytes == 0x0000)) {
n_traps++;
instruction_2bytes = *(uint16_t*)(here+2*n_traps);
} if (n_traps <= 4) { // do not group few subsequent illtraps
st->print("illtrap .nodata");
next = here + 2;
} else {
st->print("illtrap .nodata count=%d", n_traps);
next = here + 2*n_traps;
} #endif
} elseif ((instruction_2bytes & 0xff00) == 0x0000) {
st->print("illtrap .data 0x%2.2x", instruction_2bytes & 0x00ff);
next = here + 2;
} else {
next = here;
} return next;
}
// Print annotations (value of loaded constant) void Disassembler::annotate(address here, outputStream* st) { // Currently, annotation doesn't work when decoding error files. // When decoding an instruction from a hs_err file, the given // instruction address 'start' points to the instruction's virtual address // which is not equal to the address where the instruction is located. // Therefore, we will either crash or decode garbage. if (is_decode_error_file()) { return;
}
if (MacroAssembler::is_load_const(here)) { long value = MacroAssembler::get_const(here); constint tsize = 8;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.