Skip to content

Commit edea9e6

Browse files
Julien Thierryjpoimboe
authored andcommitted
objtool: Decode unwind hint register depending on architecture
The set of registers that can be included in an unwind hint and their encoding will depend on the architecture. Have arch specific code to decode that register. Signed-off-by: Julien Thierry <jthierry@redhat.com> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
1 parent ee819ae commit edea9e6

3 files changed

Lines changed: 40 additions & 26 deletions

File tree

tools/objtool/arch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,6 @@ unsigned long arch_dest_reloc_offset(int addend);
8888

8989
const char *arch_nop_insn(int len);
9090

91+
int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg);
92+
9193
#endif /* _ARCH_H */

tools/objtool/arch/x86/decode.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "../../elf.h"
1616
#include "../../arch.h"
1717
#include "../../warn.h"
18+
#include <asm/orc_types.h>
1819

1920
static unsigned char op_to_cfi_reg[][2] = {
2021
{CFI_AX, CFI_R8},
@@ -583,3 +584,39 @@ const char *arch_nop_insn(int len)
583584

584585
return nops[len-1];
585586
}
587+
588+
int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg)
589+
{
590+
struct cfi_reg *cfa = &insn->cfi.cfa;
591+
592+
switch (sp_reg) {
593+
case ORC_REG_UNDEFINED:
594+
cfa->base = CFI_UNDEFINED;
595+
break;
596+
case ORC_REG_SP:
597+
cfa->base = CFI_SP;
598+
break;
599+
case ORC_REG_BP:
600+
cfa->base = CFI_BP;
601+
break;
602+
case ORC_REG_SP_INDIRECT:
603+
cfa->base = CFI_SP_INDIRECT;
604+
break;
605+
case ORC_REG_R10:
606+
cfa->base = CFI_R10;
607+
break;
608+
case ORC_REG_R13:
609+
cfa->base = CFI_R13;
610+
break;
611+
case ORC_REG_DI:
612+
cfa->base = CFI_DI;
613+
break;
614+
case ORC_REG_DX:
615+
cfa->base = CFI_DX;
616+
break;
617+
default:
618+
return -1;
619+
}
620+
621+
return 0;
622+
}

tools/objtool/check.c

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,32 +1367,7 @@ static int read_unwind_hints(struct objtool_file *file)
13671367

13681368
insn->hint = true;
13691369

1370-
switch (hint->sp_reg) {
1371-
case ORC_REG_UNDEFINED:
1372-
cfa->base = CFI_UNDEFINED;
1373-
break;
1374-
case ORC_REG_SP:
1375-
cfa->base = CFI_SP;
1376-
break;
1377-
case ORC_REG_BP:
1378-
cfa->base = CFI_BP;
1379-
break;
1380-
case ORC_REG_SP_INDIRECT:
1381-
cfa->base = CFI_SP_INDIRECT;
1382-
break;
1383-
case ORC_REG_R10:
1384-
cfa->base = CFI_R10;
1385-
break;
1386-
case ORC_REG_R13:
1387-
cfa->base = CFI_R13;
1388-
break;
1389-
case ORC_REG_DI:
1390-
cfa->base = CFI_DI;
1391-
break;
1392-
case ORC_REG_DX:
1393-
cfa->base = CFI_DX;
1394-
break;
1395-
default:
1370+
if (arch_decode_hint_reg(insn, hint->sp_reg)) {
13961371
WARN_FUNC("unsupported unwind_hint sp base reg %d",
13971372
insn->sec, insn->offset, hint->sp_reg);
13981373
return -1;

0 commit comments

Comments
 (0)