1 #include <linux/kernel.h>
3 static const char jumplen
[256] = {[0x0f] = 5, /* je */
21 [0xe8] = 4, /* call */
25 /* Various efficient no-op patterns for aligning code labels.
26 Note: Don't try to assemble the instructions in the comments.
27 0L and 0w are not legal. */
29 #define NUM_NOPS (sizeof(nops) / sizeof(nops[0]))
37 .len = sizeof((unsigned char []){__VA_ARGS__}), \
38 .data = ((unsigned char []){__VA_ARGS__}), \
40 static struct insn nops
[] = {
41 /* GNU assembler no-op patterns from
42 binutils-2.17/gas/config/tc-i386.c line 500 */
44 I(0x89, 0xf6), /* movl %esi,%esi */
45 I(0x8d, 0x76, 0x00), /* leal 0(%esi),%esi */
46 I(0x8d, 0x74, 0x26, 0x00), /* leal 0(%esi,1),%esi */
48 0x8d, 0x74, 0x26, 0x00), /* leal 0(%esi,1),%esi */
49 I(0x8d, 0xb6, 0x00, 0x00, 0x00, 0x00), /* leal 0L(%esi),%esi */
50 I(0x8d, 0xb4, 0x26, 0x00, 0x00, 0x00, 0x00), /* leal 0L(%esi,1),%esi */
52 0x8d, 0xb4, 0x26, 0x00, 0x00, 0x00, 0x00), /* leal 0L(%esi,1),%esi */
53 I(0x89, 0xf6, /* movl %esi,%esi */
54 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00), /* leal 0L(%edi,1),%edi */
55 I(0x8d, 0x76, 0x00, /* leal 0(%esi),%esi */
56 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00), /* leal 0L(%edi,1),%edi */
57 I(0x8d, 0x74, 0x26, 0x00, /* leal 0(%esi,1),%esi */
58 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00), /* leal 0L(%edi,1),%edi */
59 I(0x8d, 0xb6, 0x00, 0x00, 0x00, 0x00, /* leal 0L(%esi),%esi */
60 0x8d, 0xbf, 0x00, 0x00, 0x00, 0x00), /* leal 0L(%edi),%edi */
61 I(0x8d, 0xb6, 0x00, 0x00, 0x00, 0x00, /* leal 0L(%esi),%esi */
62 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00), /* leal 0L(%edi,1),%edi */
63 I(0x8d, 0xb4, 0x26, 0x00, 0x00, 0x00, 0x00, /* leal 0L(%esi,1),%esi */
64 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00), /* leal 0L(%edi,1),%edi */
65 I(0xeb, 0x0d, 0x90, 0x90, 0x90, 0x90, 0x90, /* jmp .+15; lotsa nops */
66 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90),
68 /* binutils-2.17/gas/config/tc-i386.c line 570 */
69 I(0x66, 0x90), /* xchg %ax,%ax */
71 0x66, 0x90), /* xchg %ax,%ax */
74 0x66, 0x90), /* xchg %ax,%ax */
78 0x66, 0x90), /* xchg %ax,%ax */
80 /* binutils-2.18/gas/config/tc-i386.c line 572 */
81 I(0x0f, 0x1f, 0x00), /* nopl (%[re]ax) */
82 I(0x0f, 0x1f, 0x40, 0x00), /* nopl 0(%[re]ax) */
83 I(0x0f, 0x1f, 0x44, 0x00, 0x00), /* nopl 0(%[re]ax,%[re]ax,1) */
84 I(0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00), /* nopw 0(%[re]ax,%[re]ax,1) */
85 I(0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00),
86 /* nopw 0(%[re]ax,%[re]ax,1) */
87 I(0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00),
88 /* nopl 0L(%[re]ax,%[re]ax,1) */
89 I(0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00),
90 /* nopw 0L(%[re]ax,%[re]ax,1) */
91 I(0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00),
92 /* nopw %cs:0L(%[re]ax,%[re]ax,1) */
94 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00),
95 /* nopw %cs:0L(%[re]ax,%[re]ax,1) */
98 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00),
99 /* nopw %cs:0L(%[re]ax,%[re]ax,1) */
103 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00),
104 /* nopw %cs:0L(%[re]ax,%[re]ax,1) */
109 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00),
110 /* nopw %cs:0L(%[re]ax,%[re]ax,1) */
116 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00),
117 /* nopw %cs:0L(%[re]ax,%[re]ax,1) */
123 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00),
124 /* nopw %cs:0L(%[re]ax,%[re]ax,1) */
125 I(0x0f, 0x1f, 0x44, 0x00, 0x00, /* nopl 0(%[re]ax,%[re]ax,1) */
126 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00), /* nopw 0(%[re]ax,%[re]ax,1) */
127 I(0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00, /* nopw 0(%[re]ax,%[re]ax,1) */
128 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00), /* nopw 0(%[re]ax,%[re]ax,1) */
129 I(0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00, /* nopw 0(%[re]ax,%[re]ax,1) */
130 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00), /* nopl 0L(%[re]ax) */
131 I(0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, /* nopl 0L(%[re]ax) */
132 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00), /* nopl 0L(%[re]ax) */
133 I(0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, /* nopl 0L(%[re]ax) */
134 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00),
135 /* nopl 0L(%[re]ax,%[re]ax,1) */
139 static int match_nop(long addr
, int *o
);
141 static int run_pre_cmp(struct module_pack
*pack
, long run_addr
, long pre_addr
,
144 int run_o
= 0, pre_o
= 0, lenient
= 0;
145 unsigned char run
, pre
;
146 struct reloc_addrmap
*map
;
151 while (run_o
< size
&& pre_o
< size
) {
155 if (!virtual_address_mapped(run_addr
+ run_o
))
158 map
= find_addrmap(pack
, pre_addr
+ pre_o
);
160 if (handle_myst_reloc
161 (pre_addr
, &pre_o
, run_addr
, &run_o
, map
,
167 if (match_nop(run_addr
, &run_o
) || match_nop(pre_addr
, &pre_o
))
170 run
= *(unsigned char *)(run_addr
+ run_o
);
171 pre
= *(unsigned char *)(pre_addr
+ pre_o
);
174 printk("%02x/%02x ", run
, pre
);
178 lenient
= max(jumplen
[pre
] + 1, lenient
);
183 if (jumplen
[run
] && jumplen
[pre
]) {
184 run_o
+= 1 + jumplen
[run
];
185 pre_o
+= 1 + jumplen
[pre
];
193 printk("[p_o=%08x] ! %02x/%02x %02x/%02x",
195 *(unsigned char *)(run_addr
+ run_o
+ 1),
196 *(unsigned char *)(pre_addr
+ pre_o
+ 1),
197 *(unsigned char *)(run_addr
+ run_o
+ 2),
198 *(unsigned char *)(pre_addr
+ pre_o
+ 2));
204 static int match_nop(long addr
, int *o
)
208 for (i
= NUM_NOPS
- 1; i
>= 0; i
--) {
210 for (j
= 0; j
< nop
->len
; j
++) {
211 if (!virtual_address_mapped(addr
+ *o
+ j
))
213 if (*(unsigned char *)(addr
+ *o
+ j
) != nop
->data
[j
])