@@ -146,12 +146,11 @@ static bool has_notrack_prefix(struct insn *insn)
146
146
147
147
int arch_decode_instruction (struct objtool_file * file , const struct section * sec ,
148
148
unsigned long offset , unsigned int maxlen ,
149
- unsigned int * len , enum insn_type * type ,
150
- unsigned long * immediate ,
151
- struct list_head * ops_list )
149
+ struct instruction * insn )
152
150
{
151
+ struct list_head * ops_list = & insn -> stack_ops ;
153
152
const struct elf * elf = file -> elf ;
154
- struct insn insn ;
153
+ struct insn ins ;
155
154
int x86_64 , ret ;
156
155
unsigned char op1 , op2 , op3 , prefix ,
157
156
rex = 0 , rex_b = 0 , rex_r = 0 , rex_w = 0 , rex_x = 0 ,
@@ -165,42 +164,42 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
165
164
if (x86_64 == -1 )
166
165
return -1 ;
167
166
168
- ret = insn_decode (& insn , sec -> data -> d_buf + offset , maxlen ,
167
+ ret = insn_decode (& ins , sec -> data -> d_buf + offset , maxlen ,
169
168
x86_64 ? INSN_MODE_64 : INSN_MODE_32 );
170
169
if (ret < 0 ) {
171
170
WARN ("can't decode instruction at %s:0x%lx" , sec -> name , offset );
172
171
return -1 ;
173
172
}
174
173
175
- * len = insn .length ;
176
- * type = INSN_OTHER ;
174
+ insn -> len = ins .length ;
175
+ insn -> type = INSN_OTHER ;
177
176
178
- if (insn .vex_prefix .nbytes )
177
+ if (ins .vex_prefix .nbytes )
179
178
return 0 ;
180
179
181
- prefix = insn .prefixes .bytes [0 ];
180
+ prefix = ins .prefixes .bytes [0 ];
182
181
183
- op1 = insn .opcode .bytes [0 ];
184
- op2 = insn .opcode .bytes [1 ];
185
- op3 = insn .opcode .bytes [2 ];
182
+ op1 = ins .opcode .bytes [0 ];
183
+ op2 = ins .opcode .bytes [1 ];
184
+ op3 = ins .opcode .bytes [2 ];
186
185
187
- if (insn .rex_prefix .nbytes ) {
188
- rex = insn .rex_prefix .bytes [0 ];
186
+ if (ins .rex_prefix .nbytes ) {
187
+ rex = ins .rex_prefix .bytes [0 ];
189
188
rex_w = X86_REX_W (rex ) >> 3 ;
190
189
rex_r = X86_REX_R (rex ) >> 2 ;
191
190
rex_x = X86_REX_X (rex ) >> 1 ;
192
191
rex_b = X86_REX_B (rex );
193
192
}
194
193
195
- if (insn .modrm .nbytes ) {
196
- modrm = insn .modrm .bytes [0 ];
194
+ if (ins .modrm .nbytes ) {
195
+ modrm = ins .modrm .bytes [0 ];
197
196
modrm_mod = X86_MODRM_MOD (modrm );
198
197
modrm_reg = X86_MODRM_REG (modrm ) + 8 * rex_r ;
199
198
modrm_rm = X86_MODRM_RM (modrm ) + 8 * rex_b ;
200
199
}
201
200
202
- if (insn .sib .nbytes ) {
203
- sib = insn .sib .bytes [0 ];
201
+ if (ins .sib .nbytes ) {
202
+ sib = ins .sib .bytes [0 ];
204
203
/* sib_scale = X86_SIB_SCALE(sib); */
205
204
sib_index = X86_SIB_INDEX (sib ) + 8 * rex_x ;
206
205
sib_base = X86_SIB_BASE (sib ) + 8 * rex_b ;
@@ -254,7 +253,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
254
253
break ;
255
254
256
255
case 0x70 ... 0x7f :
257
- * type = INSN_JUMP_CONDITIONAL ;
256
+ insn -> type = INSN_JUMP_CONDITIONAL ;
258
257
break ;
259
258
260
259
case 0x80 ... 0x83 :
@@ -278,7 +277,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
278
277
if (!rm_is_reg (CFI_SP ))
279
278
break ;
280
279
281
- imm = insn .immediate .value ;
280
+ imm = ins .immediate .value ;
282
281
if (op1 & 2 ) { /* sign extend */
283
282
if (op1 & 1 ) { /* imm32 */
284
283
imm <<= 32 ;
@@ -309,7 +308,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
309
308
ADD_OP (op ) {
310
309
op -> src .type = OP_SRC_AND ;
311
310
op -> src .reg = CFI_SP ;
312
- op -> src .offset = insn .immediate .value ;
311
+ op -> src .offset = ins .immediate .value ;
313
312
op -> dest .type = OP_DEST_REG ;
314
313
op -> dest .reg = CFI_SP ;
315
314
}
@@ -356,7 +355,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
356
355
op -> src .reg = CFI_SP ;
357
356
op -> dest .type = OP_DEST_REG_INDIRECT ;
358
357
op -> dest .reg = modrm_rm ;
359
- op -> dest .offset = insn .displacement .value ;
358
+ op -> dest .offset = ins .displacement .value ;
360
359
}
361
360
break ;
362
361
}
@@ -389,7 +388,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
389
388
op -> src .reg = modrm_reg ;
390
389
op -> dest .type = OP_DEST_REG_INDIRECT ;
391
390
op -> dest .reg = CFI_BP ;
392
- op -> dest .offset = insn .displacement .value ;
391
+ op -> dest .offset = ins .displacement .value ;
393
392
}
394
393
break ;
395
394
}
@@ -402,7 +401,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
402
401
op -> src .reg = modrm_reg ;
403
402
op -> dest .type = OP_DEST_REG_INDIRECT ;
404
403
op -> dest .reg = CFI_SP ;
405
- op -> dest .offset = insn .displacement .value ;
404
+ op -> dest .offset = ins .displacement .value ;
406
405
}
407
406
break ;
408
407
}
@@ -419,7 +418,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
419
418
ADD_OP (op ) {
420
419
op -> src .type = OP_SRC_REG_INDIRECT ;
421
420
op -> src .reg = CFI_BP ;
422
- op -> src .offset = insn .displacement .value ;
421
+ op -> src .offset = ins .displacement .value ;
423
422
op -> dest .type = OP_DEST_REG ;
424
423
op -> dest .reg = modrm_reg ;
425
424
}
@@ -432,7 +431,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
432
431
ADD_OP (op ) {
433
432
op -> src .type = OP_SRC_REG_INDIRECT ;
434
433
op -> src .reg = CFI_SP ;
435
- op -> src .offset = insn .displacement .value ;
434
+ op -> src .offset = ins .displacement .value ;
436
435
op -> dest .type = OP_DEST_REG ;
437
436
op -> dest .reg = modrm_reg ;
438
437
}
@@ -464,7 +463,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
464
463
465
464
/* lea disp(%src), %dst */
466
465
ADD_OP (op ) {
467
- op -> src .offset = insn .displacement .value ;
466
+ op -> src .offset = ins .displacement .value ;
468
467
if (!op -> src .offset ) {
469
468
/* lea (%src), %dst */
470
469
op -> src .type = OP_SRC_REG ;
@@ -487,7 +486,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
487
486
break ;
488
487
489
488
case 0x90 :
490
- * type = INSN_NOP ;
489
+ insn -> type = INSN_NOP ;
491
490
break ;
492
491
493
492
case 0x9c :
@@ -511,39 +510,39 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
511
510
if (op2 == 0x01 ) {
512
511
513
512
if (modrm == 0xca )
514
- * type = INSN_CLAC ;
513
+ insn -> type = INSN_CLAC ;
515
514
else if (modrm == 0xcb )
516
- * type = INSN_STAC ;
515
+ insn -> type = INSN_STAC ;
517
516
518
517
} else if (op2 >= 0x80 && op2 <= 0x8f ) {
519
518
520
- * type = INSN_JUMP_CONDITIONAL ;
519
+ insn -> type = INSN_JUMP_CONDITIONAL ;
521
520
522
521
} else if (op2 == 0x05 || op2 == 0x07 || op2 == 0x34 ||
523
522
op2 == 0x35 ) {
524
523
525
524
/* sysenter, sysret */
526
- * type = INSN_CONTEXT_SWITCH ;
525
+ insn -> type = INSN_CONTEXT_SWITCH ;
527
526
528
527
} else if (op2 == 0x0b || op2 == 0xb9 ) {
529
528
530
529
/* ud2 */
531
- * type = INSN_BUG ;
530
+ insn -> type = INSN_BUG ;
532
531
533
532
} else if (op2 == 0x0d || op2 == 0x1f ) {
534
533
535
534
/* nopl/nopw */
536
- * type = INSN_NOP ;
535
+ insn -> type = INSN_NOP ;
537
536
538
537
} else if (op2 == 0x1e ) {
539
538
540
539
if (prefix == 0xf3 && (modrm == 0xfa || modrm == 0xfb ))
541
- * type = INSN_ENDBR ;
540
+ insn -> type = INSN_ENDBR ;
542
541
543
542
544
543
} else if (op2 == 0x38 && op3 == 0xf8 ) {
545
- if (insn .prefixes .nbytes == 1 &&
546
- insn .prefixes .bytes [0 ] == 0xf2 ) {
544
+ if (ins .prefixes .nbytes == 1 &&
545
+ ins .prefixes .bytes [0 ] == 0xf2 ) {
547
546
/* ENQCMD cannot be used in the kernel. */
548
547
WARN ("ENQCMD instruction at %s:%lx" , sec -> name ,
549
548
offset );
@@ -591,29 +590,29 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
591
590
592
591
case 0xcc :
593
592
/* int3 */
594
- * type = INSN_TRAP ;
593
+ insn -> type = INSN_TRAP ;
595
594
break ;
596
595
597
596
case 0xe3 :
598
597
/* jecxz/jrcxz */
599
- * type = INSN_JUMP_CONDITIONAL ;
598
+ insn -> type = INSN_JUMP_CONDITIONAL ;
600
599
break ;
601
600
602
601
case 0xe9 :
603
602
case 0xeb :
604
- * type = INSN_JUMP_UNCONDITIONAL ;
603
+ insn -> type = INSN_JUMP_UNCONDITIONAL ;
605
604
break ;
606
605
607
606
case 0xc2 :
608
607
case 0xc3 :
609
- * type = INSN_RETURN ;
608
+ insn -> type = INSN_RETURN ;
610
609
break ;
611
610
612
611
case 0xc7 : /* mov imm, r/m */
613
612
if (!opts .noinstr )
614
613
break ;
615
614
616
- if (insn .length == 3 + 4 + 4 && !strncmp (sec -> name , ".init.text" , 10 )) {
615
+ if (ins .length == 3 + 4 + 4 && !strncmp (sec -> name , ".init.text" , 10 )) {
617
616
struct reloc * immr , * disp ;
618
617
struct symbol * func ;
619
618
int idx ;
@@ -661,17 +660,17 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
661
660
662
661
case 0xca : /* retf */
663
662
case 0xcb : /* retf */
664
- * type = INSN_CONTEXT_SWITCH ;
663
+ insn -> type = INSN_CONTEXT_SWITCH ;
665
664
break ;
666
665
667
666
case 0xe0 : /* loopne */
668
667
case 0xe1 : /* loope */
669
668
case 0xe2 : /* loop */
670
- * type = INSN_JUMP_CONDITIONAL ;
669
+ insn -> type = INSN_JUMP_CONDITIONAL ;
671
670
break ;
672
671
673
672
case 0xe8 :
674
- * type = INSN_CALL ;
673
+ insn -> type = INSN_CALL ;
675
674
/*
676
675
* For the impact on the stack, a CALL behaves like
677
676
* a PUSH of an immediate value (the return address).
@@ -683,30 +682,30 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
683
682
break ;
684
683
685
684
case 0xfc :
686
- * type = INSN_CLD ;
685
+ insn -> type = INSN_CLD ;
687
686
break ;
688
687
689
688
case 0xfd :
690
- * type = INSN_STD ;
689
+ insn -> type = INSN_STD ;
691
690
break ;
692
691
693
692
case 0xff :
694
693
if (modrm_reg == 2 || modrm_reg == 3 ) {
695
694
696
- * type = INSN_CALL_DYNAMIC ;
697
- if (has_notrack_prefix (& insn ))
695
+ insn -> type = INSN_CALL_DYNAMIC ;
696
+ if (has_notrack_prefix (& ins ))
698
697
WARN ("notrack prefix found at %s:0x%lx" , sec -> name , offset );
699
698
700
699
} else if (modrm_reg == 4 ) {
701
700
702
- * type = INSN_JUMP_DYNAMIC ;
703
- if (has_notrack_prefix (& insn ))
701
+ insn -> type = INSN_JUMP_DYNAMIC ;
702
+ if (has_notrack_prefix (& ins ))
704
703
WARN ("notrack prefix found at %s:0x%lx" , sec -> name , offset );
705
704
706
705
} else if (modrm_reg == 5 ) {
707
706
708
707
/* jmpf */
709
- * type = INSN_CONTEXT_SWITCH ;
708
+ insn -> type = INSN_CONTEXT_SWITCH ;
710
709
711
710
} else if (modrm_reg == 6 ) {
712
711
@@ -723,7 +722,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
723
722
break ;
724
723
}
725
724
726
- * immediate = insn .immediate .nbytes ? insn .immediate .value : 0 ;
725
+ insn -> immediate = ins .immediate .nbytes ? ins .immediate .value : 0 ;
727
726
728
727
return 0 ;
729
728
}
0 commit comments