]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
objtool: Decode unwind hint register depending on architecture
authorJulien Thierry <jthierry@redhat.com>
Fri, 4 Sep 2020 15:30:28 +0000 (16:30 +0100)
committerJosh Poimboeuf <jpoimboe@redhat.com>
Thu, 10 Sep 2020 15:43:13 +0000 (10:43 -0500)
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>
tools/objtool/arch.h
tools/objtool/arch/x86/decode.c
tools/objtool/check.c

index b18c5f61d42d1211a6335b99c9da6d4a67b17637..4a84c3081b8e131572b32c9e02a7dfbcf8c40068 100644 (file)
@@ -88,4 +88,6 @@ unsigned long arch_dest_reloc_offset(int addend);
 
 const char *arch_nop_insn(int len);
 
+int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg);
+
 #endif /* _ARCH_H */
index 1967370440b30136ac9947789a510ec41f023b34..cde9c36e40ae0ccff941a22b07f8cc7d1313ac54 100644 (file)
@@ -15,6 +15,7 @@
 #include "../../elf.h"
 #include "../../arch.h"
 #include "../../warn.h"
+#include <asm/orc_types.h>
 
 static unsigned char op_to_cfi_reg[][2] = {
        {CFI_AX, CFI_R8},
@@ -583,3 +584,39 @@ const char *arch_nop_insn(int len)
 
        return nops[len-1];
 }
+
+int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg)
+{
+       struct cfi_reg *cfa = &insn->cfi.cfa;
+
+       switch (sp_reg) {
+       case ORC_REG_UNDEFINED:
+               cfa->base = CFI_UNDEFINED;
+               break;
+       case ORC_REG_SP:
+               cfa->base = CFI_SP;
+               break;
+       case ORC_REG_BP:
+               cfa->base = CFI_BP;
+               break;
+       case ORC_REG_SP_INDIRECT:
+               cfa->base = CFI_SP_INDIRECT;
+               break;
+       case ORC_REG_R10:
+               cfa->base = CFI_R10;
+               break;
+       case ORC_REG_R13:
+               cfa->base = CFI_R13;
+               break;
+       case ORC_REG_DI:
+               cfa->base = CFI_DI;
+               break;
+       case ORC_REG_DX:
+               cfa->base = CFI_DX;
+               break;
+       default:
+               return -1;
+       }
+
+       return 0;
+}
index 95c6e0d31c0ad73a642d4e527abe5b23d9fb4625..4e2f703b6a25b648815de7af1b5e85064cba9846 100644 (file)
@@ -1367,32 +1367,7 @@ static int read_unwind_hints(struct objtool_file *file)
 
                insn->hint = true;
 
-               switch (hint->sp_reg) {
-               case ORC_REG_UNDEFINED:
-                       cfa->base = CFI_UNDEFINED;
-                       break;
-               case ORC_REG_SP:
-                       cfa->base = CFI_SP;
-                       break;
-               case ORC_REG_BP:
-                       cfa->base = CFI_BP;
-                       break;
-               case ORC_REG_SP_INDIRECT:
-                       cfa->base = CFI_SP_INDIRECT;
-                       break;
-               case ORC_REG_R10:
-                       cfa->base = CFI_R10;
-                       break;
-               case ORC_REG_R13:
-                       cfa->base = CFI_R13;
-                       break;
-               case ORC_REG_DI:
-                       cfa->base = CFI_DI;
-                       break;
-               case ORC_REG_DX:
-                       cfa->base = CFI_DX;
-                       break;
-               default:
+               if (arch_decode_hint_reg(insn, hint->sp_reg)) {
                        WARN_FUNC("unsupported unwind_hint sp base reg %d",
                                  insn->sec, insn->offset, hint->sp_reg);
                        return -1;