修订版 | 1d772dc70c3a8d2225d219e9be5be7ccc05dcdd6 (tree) |
---|---|
时间 | 2020-02-23 15:25:57 |
作者 | Richard Henderson <richard.henderson@lina...> |
Commiter | Yoshinori Sato |
target/rx: Collect all bytes during disassembly
Collected, to be used in the next patch.
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
Message-Id: <20190607091116.49044-23-ysato@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
@@ -25,43 +25,59 @@ typedef struct DisasContext { | ||
25 | 25 | disassemble_info *dis; |
26 | 26 | uint32_t addr; |
27 | 27 | uint32_t pc; |
28 | + uint8_t len; | |
29 | + uint8_t bytes[8]; | |
28 | 30 | } DisasContext; |
29 | 31 | |
30 | 32 | |
31 | 33 | static uint32_t decode_load_bytes(DisasContext *ctx, uint32_t insn, |
32 | - int i, int n) | |
34 | + int i, int n) | |
33 | 35 | { |
34 | - bfd_byte buf; | |
36 | + uint32_t addr = ctx->addr; | |
37 | + | |
38 | + g_assert(ctx->len == i); | |
39 | + g_assert(n <= ARRAY_SIZE(ctx->bytes)); | |
40 | + | |
35 | 41 | while (++i <= n) { |
36 | - ctx->dis->read_memory_func(ctx->addr++, &buf, 1, ctx->dis); | |
37 | - insn |= buf << (32 - i * 8); | |
42 | + ctx->dis->read_memory_func(addr++, &ctx->bytes[i - 1], 1, ctx->dis); | |
43 | + insn |= ctx->bytes[i - 1] << (32 - i * 8); | |
38 | 44 | } |
45 | + ctx->addr = addr; | |
46 | + ctx->len = n; | |
47 | + | |
39 | 48 | return insn; |
40 | 49 | } |
41 | 50 | |
42 | 51 | static int32_t li(DisasContext *ctx, int sz) |
43 | 52 | { |
44 | - int32_t addr; | |
45 | - bfd_byte buf[4]; | |
46 | - addr = ctx->addr; | |
53 | + uint32_t addr = ctx->addr; | |
54 | + uintptr_t len = ctx->len; | |
47 | 55 | |
48 | 56 | switch (sz) { |
49 | 57 | case 1: |
58 | + g_assert(len + 1 <= ARRAY_SIZE(ctx->bytes)); | |
50 | 59 | ctx->addr += 1; |
51 | - ctx->dis->read_memory_func(addr, buf, 1, ctx->dis); | |
52 | - return (int8_t)buf[0]; | |
60 | + ctx->len += 1; | |
61 | + ctx->dis->read_memory_func(addr, ctx->bytes + len, 1, ctx->dis); | |
62 | + return (int8_t)ctx->bytes[len]; | |
53 | 63 | case 2: |
64 | + g_assert(len + 2 <= ARRAY_SIZE(ctx->bytes)); | |
54 | 65 | ctx->addr += 2; |
55 | - ctx->dis->read_memory_func(addr, buf, 2, ctx->dis); | |
56 | - return ldsw_le_p(buf); | |
66 | + ctx->len += 2; | |
67 | + ctx->dis->read_memory_func(addr, ctx->bytes + len, 2, ctx->dis); | |
68 | + return ldsw_le_p(ctx->bytes + len); | |
57 | 69 | case 3: |
70 | + g_assert(len + 3 <= ARRAY_SIZE(ctx->bytes)); | |
58 | 71 | ctx->addr += 3; |
59 | - ctx->dis->read_memory_func(addr, buf, 3, ctx->dis); | |
60 | - return (int8_t)buf[2] << 16 | lduw_le_p(buf); | |
72 | + ctx->len += 3; | |
73 | + ctx->dis->read_memory_func(addr, ctx->bytes + len, 3, ctx->dis); | |
74 | + return (int8_t)ctx->bytes[len + 2] << 16 | lduw_le_p(ctx->bytes + len); | |
61 | 75 | case 0: |
76 | + g_assert(len + 4 <= ARRAY_SIZE(ctx->bytes)); | |
62 | 77 | ctx->addr += 4; |
63 | - ctx->dis->read_memory_func(addr, buf, 4, ctx->dis); | |
64 | - return ldl_le_p(buf); | |
78 | + ctx->len += 4; | |
79 | + ctx->dis->read_memory_func(addr, ctx->bytes + len, 4, ctx->dis); | |
80 | + return ldl_le_p(ctx->bytes + len); | |
65 | 81 | default: |
66 | 82 | g_assert_not_reached(); |
67 | 83 | } |
@@ -110,7 +126,7 @@ static const char psw[] = { | ||
110 | 126 | static void rx_index_addr(DisasContext *ctx, char out[8], int ld, int mi) |
111 | 127 | { |
112 | 128 | uint32_t addr = ctx->addr; |
113 | - uint8_t buf[2]; | |
129 | + uintptr_t len = ctx->len; | |
114 | 130 | uint16_t dsp; |
115 | 131 | |
116 | 132 | switch (ld) { |
@@ -119,14 +135,18 @@ static void rx_index_addr(DisasContext *ctx, char out[8], int ld, int mi) | ||
119 | 135 | out[0] = '\0'; |
120 | 136 | return; |
121 | 137 | case 1: |
138 | + g_assert(len + 1 <= ARRAY_SIZE(ctx->bytes)); | |
122 | 139 | ctx->addr += 1; |
123 | - ctx->dis->read_memory_func(addr, buf, 1, ctx->dis); | |
124 | - dsp = buf[0]; | |
140 | + ctx->len += 1; | |
141 | + ctx->dis->read_memory_func(addr, ctx->bytes + len, 1, ctx->dis); | |
142 | + dsp = ctx->bytes[len]; | |
125 | 143 | break; |
126 | 144 | case 2: |
145 | + g_assert(len + 2 <= ARRAY_SIZE(ctx->bytes)); | |
127 | 146 | ctx->addr += 2; |
128 | - ctx->dis->read_memory_func(addr, buf, 2, ctx->dis); | |
129 | - dsp = lduw_le_p(buf); | |
147 | + ctx->len += 2; | |
148 | + ctx->dis->read_memory_func(addr, ctx->bytes + len, 2, ctx->dis); | |
149 | + dsp = lduw_le_p(ctx->bytes + len); | |
130 | 150 | break; |
131 | 151 | default: |
132 | 152 | g_assert_not_reached(); |
@@ -1392,8 +1412,10 @@ int print_insn_rx(bfd_vma addr, disassemble_info *dis) | ||
1392 | 1412 | DisasContext ctx; |
1393 | 1413 | uint32_t insn; |
1394 | 1414 | int i; |
1415 | + | |
1395 | 1416 | ctx.dis = dis; |
1396 | 1417 | ctx.pc = ctx.addr = addr; |
1418 | + ctx.len = 0; | |
1397 | 1419 | |
1398 | 1420 | insn = decode_load(&ctx); |
1399 | 1421 | if (!decode(&ctx, insn)) { |