diff options
author | Jens Remus <jremus@linux.ibm.com> | 2023-11-29 21:44:34 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2023-12-04 17:13:33 +0000 |
commit | c5306fed7d40717d9866524fb346ac2599f9769d (patch) | |
tree | 7ccf62c167807ced69a27aae18df57e1408b7610 /opcodes | |
parent | 86b775c51597816dcab29dd37522b505d043dc51 (diff) | |
download | binutils-c5306fed7d40717d9866524fb346ac2599f9769d.zip binutils-c5306fed7d40717d9866524fb346ac2599f9769d.tar.gz binutils-c5306fed7d40717d9866524fb346ac2599f9769d.tar.bz2 |
s390: Support for jump visualization in disassembly
Add support for jump visualization for the s390 architecture in
disassembly:
objdump -d --visualize-jumps ...
Annotate the (conditional) jump and branch relative instructions with
information required for jump visualization:
- jump: Unconditional jump / branch relative.
- condjump: Conditional jump / branch relative.
- jumpsr: Jump / branch relative to subroutine.
Unconditional jump and branch relative instructions are annotated as
jump.
Conditional jump and branch relative instructions, jump / branch
relative on count/index, and compare and jump / branch relative
instructions are annotated as condjump.
Jump and save (jas, jasl) and branch relative and save (bras, brasl)
instructions are annotated as jumpsr (jump to subroutine).
Provide instruction information required for jump visualization during
disassembly.
The instruction type is provided after determining the opcode.
For non-code it is set to dis_noninsn. Otherwise it defaults to
dis_nonbranch. No annotation is done for data reference instructions
(i.e. instruction types dis_dref and dis_dref2). Note that the
instruction type needs to be provided before printing of the
instruction, as it is used in print_address_func() to translate the
argument value into an address if it is assumed to be a PC-relative
offset. Note that this is never the case on s390, as
print_address_func() is only called with addresses and never with
offsets.
The target of the (conditional) jump and branch relative instructions
is provided during print, when the PC relative operand is decoded.
include/
* opcode/s390.h: Define opcode flags to annotate instruction
class information for jump visualization:
S390_INSTR_FLAG_CLASS_BRANCH, S390_INSTR_FLAG_CLASS_RELATIVE,
S390_INSTR_FLAG_CLASS_CONDITIONAL, and
S390_INSTR_FLAG_CLASS_SUBROUTINE.
Define opcode flags mask S390_INSTR_FLAG_CLASS_MASK for above
instruction class information.
Define helpers for common instruction class flag combinations:
S390_INSTR_FLAGS_CLASS_JUMP, S390_INSTR_FLAGS_CLASS_CONDJUMP,
and S390_INSTR_FLAGS_CLASS_JUMPSR.
opcodes/
* s390-mkopc.c: Add opcode flags to annotate information
for jump visualization: jump, condjump, and jumpsr.
* s390-opc.txt: Annotate (conditional) jump and branch relative
instructions with information for jump visualization.
* s390-dis.c (print_insn_s390, s390_print_insn_with_opcode):
Provide instruction information for jump visualization.
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Andreas Krebbel <krebbel@linux.ibm.com>
Diffstat (limited to 'opcodes')
-rw-r--r-- | opcodes/s390-dis.c | 36 | ||||
-rw-r--r-- | opcodes/s390-mkopc.c | 12 | ||||
-rw-r--r-- | opcodes/s390-opc.txt | 82 |
3 files changed, 88 insertions, 42 deletions
diff --git a/opcodes/s390-dis.c b/opcodes/s390-dis.c index 2a3b4c2..8c8a98c 100644 --- a/opcodes/s390-dis.c +++ b/opcodes/s390-dis.c @@ -26,6 +26,7 @@ #include "opintl.h" #include "opcode/s390.h" #include "libiberty.h" +#include "dis-asm.h" static int opc_index[256]; static int current_arch_mask = 0; @@ -259,9 +260,14 @@ s390_print_insn_with_opcode (bfd_vma memaddr, } else if (flags & S390_OPERAND_PCREL) { + bfd_vma target = memaddr + val.i + val.i; + + /* Provide info for jump visualization. May be evaluated by p_a_f(). */ + info->target = target; + info->fprintf_styled_func (info->stream, dis_style_text, "%c", separator); - info->print_address_func (memaddr + val.i + val.i, info); + info->print_address_func (target, info); } else if (flags & S390_OPERAND_SIGNED) { @@ -332,6 +338,14 @@ print_insn_s390 (bfd_vma memaddr, struct disassemble_info *info) /* The output looks better if we put 6 bytes on a line. */ info->bytes_per_line = 6; + /* Set some defaults for the insn info. */ + info->insn_info_valid = 0; + info->branch_delay_insns = 0; + info->data_size = 0; + info->insn_type = dis_nonbranch; + info->target = 0; + info->target2 = 0; + /* Every S390 instruction is max 6 bytes long. */ memset (buffer, 0, 6); status = info->read_memory_func (memaddr, buffer, 6, info); @@ -373,6 +387,23 @@ print_insn_s390 (bfd_vma memaddr, struct disassemble_info *info) if (opcode != NULL) { + /* Provide info for jump visualization. Must be done before print. */ + switch (opcode->flags & S390_INSTR_FLAG_CLASS_MASK) + { + case S390_INSTR_FLAGS_CLASS_JUMP: + info->insn_type = dis_branch; + break; + case S390_INSTR_FLAGS_CLASS_CONDJUMP: + info->insn_type = dis_condbranch; + break; + case S390_INSTR_FLAGS_CLASS_JUMPSR: + info->insn_type = dis_jsr; + break; + default: + info->insn_type = dis_nonbranch; + } + info->insn_info_valid = 1; + /* The instruction is valid. Print it and return its size. */ s390_print_insn_with_opcode (memaddr, info, buffer, opcode); return opsize; @@ -394,6 +425,9 @@ print_insn_s390 (bfd_vma memaddr, struct disassemble_info *info) if (bytes_to_dump == 0) return 0; + info->insn_type = dis_noninsn; + info->insn_info_valid = 1; + /* Fall back to hex print. */ switch (bytes_to_dump) { diff --git a/opcodes/s390-mkopc.c b/opcodes/s390-mkopc.c index 48b1c1e..5f921ee 100644 --- a/opcodes/s390-mkopc.c +++ b/opcodes/s390-mkopc.c @@ -431,6 +431,18 @@ main (void) && (str[2] == 0 || str[2] == ',')) { flag_bits |= S390_INSTR_FLAG_VX; str += 2; + } else if (strncmp (str, "jump", 7) == 0 + && (str[4] == 0 || str[4] == ',')) { + flag_bits |= S390_INSTR_FLAGS_CLASS_JUMP; + str += 4; + } else if (strncmp (str, "condjump", 7) == 0 + && (str[8] == 0 || str[8] == ',')) { + flag_bits |= S390_INSTR_FLAGS_CLASS_CONDJUMP; + str += 8; + } else if (strncmp (str, "jumpsr", 7) == 0 + && (str[6] == 0 || str[6] == ',')) { + flag_bits |= S390_INSTR_FLAGS_CLASS_JUMPSR; + str += 6; } else { fprintf (stderr, "Couldn't parse flags string %s\n", flags_string); diff --git a/opcodes/s390-opc.txt b/opcodes/s390-opc.txt index 853758b..0fd04ee 100644 --- a/opcodes/s390-opc.txt +++ b/opcodes/s390-opc.txt @@ -245,15 +245,15 @@ d7 xc SS_L0RDRD "exclusive OR" g5 esa,zarch 17 xr RR_RR "exclusive OR" g5 esa,zarch f8 zap SS_LLRDRD "zero and add" g5 esa,zarch a70a ahi RI_RI "add halfword immediate" g5 esa,zarch -84 brxh RSI_RRP "branch relative on index high" g5 esa,zarch -84 jxh RSI_RRP "branch relative on index high" g5 esa,zarch -85 brxle RSI_RRP "branch relative on index low or equal" g5 esa,zarch -85 jxle RSI_RRP "branch relative on index low or equal" g5 esa,zarch -a705 bras RI_RP "branch relative and save" g5 esa,zarch -a705 jas RI_RP "branch relative and save" g5 esa,zarch -a704 brc RI_UP "branch relative on condition" g5 esa,zarch -a706 brct RI_RP "branch relative on count" g5 esa,zarch -a706 jct RI_RP "branch relative on count" g5 esa,zarch +84 brxh RSI_RRP "branch relative on index high" g5 esa,zarch condjump +84 jxh RSI_RRP "branch relative on index high" g5 esa,zarch condjump +85 brxle RSI_RRP "branch relative on index low or equal" g5 esa,zarch condjump +85 jxle RSI_RRP "branch relative on index low or equal" g5 esa,zarch condjump +a705 bras RI_RP "branch relative and save" g5 esa,zarch jumpsr +a705 jas RI_RP "branch relative and save" g5 esa,zarch jumpsr +a704 brc RI_UP "branch relative on condition" g5 esa,zarch condjump +a706 brct RI_RP "branch relative on count" g5 esa,zarch condjump +a706 jct RI_RP "branch relative on count" g5 esa,zarch condjump b241 cksm RRE_RR "checksum" g5 esa,zarch a70e chi RI_RI "compare halfword immediate" g5 esa,zarch a9 clcle RS_RRRD "compare logical long extended" g5 esa,zarch @@ -272,12 +272,12 @@ a701 tml RI_RU "test under mask low" g5 esa,zarch 4700 nop RX_0RRD "no operation" g5 esa,zarch optparm 4700 b*8 RX_0RRD "conditional branch" g5 esa,zarch 47f0 b RX_0RRD "unconditional branch" g5 esa,zarch -a704 jc RI_UP "conditional jump" g5 esa,zarch +a704 jc RI_UP "conditional jump" g5 esa,zarch condjump a704 jnop RI_0P "nop jump" g5 esa,zarch -a704 j*8 RI_0P "conditional jump" g5 esa,zarch -a704 br*8 RI_0P "conditional jump" g5 esa,zarch -a7f4 j RI_0P "unconditional jump" g5 esa,zarch -a7f4 bru RI_0P "unconditional jump" g5 esa,zarch +a704 j*8 RI_0P "conditional jump" g5 esa,zarch condjump +a704 br*8 RI_0P "conditional jump" g5 esa,zarch condjump +a7f4 j RI_0P "unconditional jump" g5 esa,zarch jump +a7f4 bru RI_0P "unconditional jump" g5 esa,zarch jump b34a axbr RRE_FEFE "add extended bfp" g5 esa,zarch b31a adbr RRE_FF "add long bfp" g5 esa,zarch ed000000001a adb RXE_FRRD "add long bfp" g5 esa,zarch @@ -446,10 +446,10 @@ e3000000000b slg RXE_RRRD "subtract logical 64" z900 zarch e3000000001b slgf RXE_RRRD "subtract logical 64<32" z900 zarch e3000000000c msg RXE_RRRD "multiply single 64" z900 zarch e3000000001c msgf RXE_RRRD "multiply single 64<32" z900 zarch -ec0000000044 brxhg RIE_RRP "branch relative on index high 64" z900 zarch -ec0000000044 jxhg RIE_RRP "branch relative on index high 64" z900 zarch -ec0000000045 brxlg RIE_RRP "branch relative on index low or equal 64" z900 zarch -ec0000000045 jxleg RIE_RRP "branch relative on index low or equal 64" z900 zarch +ec0000000044 brxhg RIE_RRP "branch relative on index high 64" z900 zarch condjump +ec0000000044 jxhg RIE_RRP "branch relative on index high 64" z900 zarch condjump +ec0000000045 brxlg RIE_RRP "branch relative on index low or equal 64" z900 zarch condjump +ec0000000045 jxleg RIE_RRP "branch relative on index low or equal 64" z900 zarch condjump eb0000000044 bxhg RSE_RRRD "branch on index high 64" z900 zarch eb0000000045 bxleg RSE_RRRD "branch on index low or equal 64" z900 zarch eb000000000c srlg RSE_RRRD "shift right single logical 64" z900 zarch @@ -473,18 +473,18 @@ eb000000002c stcmh RSE_RURD "store characters under mask high" z900 zarch eb0000000080 icmh RSE_RURD "insert characters under mask high" z900 zarch a702 tmhh RI_RU "test under mask high high" z900 zarch a703 tmhl RI_RU "test under mask high low" z900 zarch -c004 brcl RIL_UP "branch relative on condition long" z900 esa,zarch +c004 brcl RIL_UP "branch relative on condition long" z900 esa,zarch condjump # jlc omitted due to missing jl* (see jl*8) and not added as non-standard jgc c004 jgnop RIL_0P "nop jump long" z900 esa,zarch -c004 jg*8 RIL_0P "conditional jump long" z900 esa,zarch +c004 jg*8 RIL_0P "conditional jump long" z900 esa,zarch condjump # jl*8 omitted due to clash with non-standard j*8 flavors jle and jlh; exists as non-standard jg*8 instead -c004 br*8l RIL_0P "conditional jump long" z900 esa,zarch -c0f4 jg RIL_0P "unconditional jump long" z900 esa,zarch -c0f4 brul RIL_0P "unconditional jump long" z900 esa,zarch -c005 brasl RIL_RP "branch relative and save long" z900 esa,zarch -c005 jasl RIL_RP "branch relative and save long" z900 esa,zarch -a707 brctg RI_RP "branch relative on count 64" z900 zarch -a707 jctg RI_RP "branch relative on count 64" z900 zarch +c004 br*8l RIL_0P "conditional jump long" z900 esa,zarch condjump +c0f4 jg RIL_0P "unconditional jump long" z900 esa,zarch jump +c0f4 brul RIL_0P "unconditional jump long" z900 esa,zarch jump +c005 brasl RIL_RP "branch relative and save long" z900 esa,zarch jumpsr +c005 jasl RIL_RP "branch relative and save long" z900 esa,zarch jumpsr +a707 brctg RI_RP "branch relative on count 64" z900 zarch condjump +a707 jctg RI_RP "branch relative on count 64" z900 zarch condjump a709 lghi RI_RI "load halfword immediate 64" z900 zarch a70b aghi RI_RI "add halfword immediate 64" z900 zarch a70d mghi RI_RI "multiply halfword immediate 64" z900 zarch @@ -896,18 +896,18 @@ ec00000000f6 crb$32 RRS_RRRD0 "compare and branch (32)" z10 zarch ec00000000f6 crb RRS_RRRDU "compare and branch (32)" z10 zarch ec00000000e4 cgrb$32 RRS_RRRD0 "compare and branch (64)" z10 zarch ec00000000e4 cgrb RRS_RRRDU "compare and branch (64)" z10 zarch -ec0000000076 crj$32 RIE_RRP0 "compare and branch relative (32)" z10 zarch -ec0000000076 crj RIE_RRPU "compare and branch relative (32)" z10 zarch -ec0000000064 cgrj$32 RIE_RRP0 "compare and branch relative (64)" z10 zarch -ec0000000064 cgrj RIE_RRPU "compare and branch relative (64)" z10 zarch +ec0000000076 crj$32 RIE_RRP0 "compare and branch relative (32)" z10 zarch condjump +ec0000000076 crj RIE_RRPU "compare and branch relative (32)" z10 zarch condjump +ec0000000064 cgrj$32 RIE_RRP0 "compare and branch relative (64)" z10 zarch condjump +ec0000000064 cgrj RIE_RRPU "compare and branch relative (64)" z10 zarch condjump ec00000000fe cib$12 RIS_R0RDI "compare immediate and branch (32<8)" z10 zarch ec00000000fe cib RIS_RURDI "compare immediate and branch (32<8)" z10 zarch ec00000000fc cgib$12 RIS_R0RDI "compare immediate and branch (64<8)" z10 zarch ec00000000fc cgib RIS_RURDI "compare immediate and branch (64<8)" z10 zarch -ec000000007e cij$12 RIE_R0PI "compare immediate and branch relative (32<8)" z10 zarch -ec000000007e cij RIE_RUPI "compare immediate and branch relative (32<8)" z10 zarch -ec000000007c cgij$12 RIE_R0PI "compare immediate and branch relative (64<8)" z10 zarch -ec000000007c cgij RIE_RUPI "compare immediate and branch relative (64<8)" z10 zarch +ec000000007e cij$12 RIE_R0PI "compare immediate and branch relative (32<8)" z10 zarch condjump +ec000000007e cij RIE_RUPI "compare immediate and branch relative (32<8)" z10 zarch condjump +ec000000007c cgij$12 RIE_R0PI "compare immediate and branch relative (64<8)" z10 zarch condjump +ec000000007c cgij RIE_RUPI "compare immediate and branch relative (64<8)" z10 zarch condjump b9720000 crt$16 RRF_00RR "compare and trap" z10 zarch b972 crt RRF_U0RR "compare and trap" z10 zarch b9600000 cgrt$16 RRF_00RR "compare and trap 64" z10 zarch @@ -934,10 +934,10 @@ ec00000000f7 clrb$32 RRS_RRRD0 "compare logical and branch (32)" z10 zarch ec00000000f7 clrb RRS_RRRDU "compare logical and branch (32)" z10 zarch ec00000000e5 clgrb$32 RRS_RRRD0 "compare logical and branch (64)" z10 zarch ec00000000e5 clgrb RRS_RRRDU "compare logical and branch (64)" z10 zarch -ec0000000077 clrj$32 RIE_RRP0 "compare logical and branch relative (32)" z10 zarch -ec0000000077 clrj RIE_RRPU "compare logical and branch relative (32)" z10 zarch -ec0000000065 clgrj$32 RIE_RRP0 "compare logical and branch relative (64)" z10 zarch -ec0000000065 clgrj RIE_RRPU "compare logical and branch relative (64)" z10 zarch +ec0000000077 clrj$32 RIE_RRP0 "compare logical and branch relative (32)" z10 zarch condjump +ec0000000077 clrj RIE_RRPU "compare logical and branch relative (32)" z10 zarch condjump +ec0000000065 clgrj$32 RIE_RRP0 "compare logical and branch relative (64)" z10 zarch condjump +ec0000000065 clgrj RIE_RRPU "compare logical and branch relative (64)" z10 zarch condjump ec00000000ff clib$12 RIS_R0RDU "compare logical immediate and branch (32<8)" z10 zarch ec00000000ff clib RIS_RURDU "compare logical immediate and branch (32<8)" z10 zarch ec00000000fd clgib$12 RIS_R0RDU "compare logical immediate and branch (64<8)" z10 zarch @@ -1011,8 +1011,8 @@ b9ca alhhhr RRF_R0RR2 "add logical high high" z196 zarch b9da alhhlr RRF_R0RR2 "add logical high low" z196 zarch cc0a alsih RIL_RI "add logical with signed immediate high with cc" z196 zarch cc0b alsihn RIL_RI "add logical with signed immediate high no cc" z196 zarch -cc06 brcth RIL_RP "branch relative on count high" z196 zarch -cc06 jcth RIL_RP "jump on count high" z196 zarch +cc06 brcth RIL_RP "branch relative on count high" z196 zarch condjump +cc06 jcth RIL_RP "jump on count high" z196 zarch condjump b9cd chhr RRE_RR "compare high high" z196 zarch b9dd chlr RRE_RR "compare high low" z196 zarch e300000000cd chf RXY_RRRD "compare high" z196 zarch |