Previously ORC_REG_SP and ORC_REG_PREV_SP will depend on kernel version
for their value, however this is fragile since distributions will
backport the upstream patch to a lower kernel version, thus break the
version assumption.
This patch fixes by checking the value of ORC_REG_PREV_SP, which can be
get from orc_fp_entry. ORC_REG_PREV_SP's value can work as the indicator
of whether the current kernel have applied the upstream patch 1735858caa4b
("objtool/x86: Reorder ORC register numbering").
Fixes: d0ee428664f9 ("x86_64: Fix "bt" command to use correct ORC register
values on Linux 7.1 and later")
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
x86_64.c | 31 +++++++++++++++++++++++--------
1 file changed, 23 insertions(+), 8 deletions(-)
diff --git a/x86_64.c b/x86_64.c
index 55648697baf3..10e06b942d53 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -6661,6 +6661,9 @@ x86_64_ORC_init(void)
NULL
};
struct ORC_data *orc;
+ struct gnu_request request, *req;
+ req = &request;
+ ulong value = 0;
MEMBER_OFFSET_INIT(inactive_task_frame_bp, "inactive_task_frame",
"bp");
MEMBER_OFFSET_INIT(inactive_task_frame_ret_addr, "inactive_task_frame",
"ret_addr");
@@ -6736,14 +6739,26 @@ x86_64_ORC_init(void)
if (orc->has_signal && !orc->has_end)
machdep->flags |= ORC_6_4;
- /* See kernel commit 1735858caa4b */
- if (THIS_KERNEL_VERSION >= LINUX(7,1,0)) {
- ORC_REG_SP = 3;
- ORC_REG_PREV_SP = 8;
- } else {
- ORC_REG_SP = 5;
- ORC_REG_PREV_SP = 1;
- }
+ /* Try get ORC_REG_(PREV)_SP */
+ ORC_REG_SP = 5;
+ ORC_REG_PREV_SP = 1;
+
+ if (kernel_symbol_exists("orc_fp_entry") &&
+ get_symbol_type("orc_fp_entry", "bp_reg", req) == TYPE_CODE_INT)
{
+ get_symbol_data("orc_fp_entry", sizeof(ulong), &value);
+ /*
+ * orc_fp_entry.bp_reg = ORC_REG_PREV_SP
+ * See kernel commit 1735858caa4b. Use ORC_REG_PREV_SP as the
+ * indicator of the commit.
+ */
+ value >>= req->member_offset;
+ value &= ((1UL << req->member_length) - 1);
+ if (value == 8) {
+ ORC_REG_SP = 3;
+ ORC_REG_PREV_SP = 8;
+ }
+ } else
+ error(WARNING, "Cannot get orc_fp_entry info");
machdep->flags |= ORC;
}
--
2.54.0