2023-06-20 08:12:18

by Youling Tang

[permalink] [raw]
Subject: [RFC PATCH v1 00/23] LoongArch: Add objtool and ORC unwinder support

This series of patches adds objtool and ORC unwinder support for
LoongArch.

Patch 01 - 07 are from "Madhavan T. Venkataraman" [1] with minor
code tweaks. The "objtool: Reorganize ORC types" patch was not
added, because LoongArch cannot share `strcut orc_entry`, it also
needs to include ra_offset and ra_reg.

Since the changes in Patch 01 - 08 in [1] are architecture-independent,
it might be better if they could be separated separately from the series
of patches.

ORC unwinder can get a reliable stack trace, which provides a prerequisite
for the subsequent addition of livepatch support.


Instruction decoder
===================

To do this, an instruction decoder needs to be implemented. I have implemented
a simple, table-driven decoder for LoongArch. Only a subset of the instructions
needs to be fully decoded for this purpose:

- Load-Store instructions
- Add instructions
- Branch instructions
- Call instructions
- Return instructions
- Stack pointer authentication instruction


Unwind hints
============

Unwind hints are collected in a special section. Objtool converts unwind hints
to ORC data. The unwinder processes unwind hints to handle special cases
mentioned above.


ORC unwinder
============

Before vmlinux created, we check all metadata, find the stack operation,
note stack state and create orc data. Objtool insert two sections into
vmlinux. '.orc_unwind_ip' and '.orc_unwind'. (For modules, insert
'.rela.orc_unwind_ip' to relocate '.orc_unwind_ip'.) Each insn has only
one stack state in .orc_unwind and orc_unwind_ip hint its pc address.
Through unwinding orc data, we can get stack info both kernel and module.


This is a series of RFC patches, which may require long-term discussions
and revisions. It is not based on the latest code but based on 6.3-rc3.
Any ideas or suggestions are welcome.

base-commit: e8d018dd0257f744ca50a729e3d042cf2ec9da65 (Linux 6.3-rc3)

Link:
[1]: https://lore.kernel.org/lkml/[email protected]/#r

Madhavan T. Venkataraman (7):
objtool: Reorganize CFI code
objtool: Reorganize instruction-related code
objtool: Move decode_instructions() to a separate file
objtool: Reorganize Unwind hint code
objtool: Reorganize ORC code
objtool: Reorganize ORC kernel code
objtool: Introduce STATIC_CHECK

Youling Tang (16):
tools: LoongArch: Copy inst.h and asm.h to tools
objtool: LoongArch: Add base definition for LoongArch
objtool: LoongArch: Implement decoder
objtool: Add annotate_reachable() for objtools
LoongArch: bug: Add reachable annotation to warning macros
objtool: Add next member in struct reloc
objtool: Add orc_print_dump() package
objtool: Add ORC support for LoongArch
LoongArch: Add ORC unwinder support
LoongArch: Support R_LARCH_32_PCREL relocation type in kernel module
LoongArch: Fix fpu.S objtool warning
LoongArch: Annotate unwind_hint
LoongArch: Move some data definitions into the .data section
objtool: Add arch-specific "noreturn" function handling
objtool: Make update_cfi_state() arch-specific function
LoongArch: objtool: Mark non-standard object files and directories

arch/loongarch/Kconfig | 2 +
arch/loongarch/Kconfig.debug | 11 +
arch/loongarch/Makefile | 4 +
arch/loongarch/include/asm/bug.h | 1 +
arch/loongarch/include/asm/module.h | 7 +
arch/loongarch/include/asm/orc_types.h | 58 ++
arch/loongarch/include/asm/stackframe.h | 3 +
arch/loongarch/include/asm/unwind.h | 17 +-
arch/loongarch/include/asm/unwind_hints.h | 110 +++
arch/loongarch/kernel/Makefile | 3 +
arch/loongarch/kernel/entry.S | 2 +
arch/loongarch/kernel/fpu.S | 11 +-
arch/loongarch/kernel/genex.S | 2 +
arch/loongarch/kernel/head.S | 1 +
arch/loongarch/kernel/module.c | 21 +-
arch/loongarch/kernel/relocate_kernel.S | 12 +-
arch/loongarch/kernel/setup.c | 2 +
arch/loongarch/kernel/stacktrace.c | 1 +
arch/loongarch/kernel/unwind_orc.c | 301 +++++++++
arch/loongarch/kernel/vmlinux.lds.S | 3 +
arch/loongarch/power/Makefile | 2 +
arch/loongarch/vdso/Makefile | 2 +
arch/x86/include/asm/unwind.h | 5 -
arch/x86/include/asm/unwind_hints.h | 86 +++
arch/x86/kernel/module.c | 7 +-
arch/x86/kernel/unwind_orc.c | 268 +-------
arch/x86/kernel/vmlinux.lds.S | 2 +-
.../asm => include/asm-generic}/orc_lookup.h | 43 ++
include/linux/compiler.h | 9 +
include/linux/objtool.h | 70 --
kernel/Makefile | 2 +
kernel/orc_lookup.c | 261 ++++++++
scripts/Makefile | 5 +-
tools/arch/loongarch/include/asm/asm.h | 201 ++++++
tools/arch/loongarch/include/asm/inst.h | 629 ++++++++++++++++++
tools/arch/loongarch/include/asm/orc_types.h | 58 ++
.../arch/loongarch/include/asm/unwind_hints.h | 110 +++
tools/arch/x86/include/asm/unwind_hints.h | 160 +++++
tools/include/linux/bitops.h | 10 +
tools/include/linux/objtool.h | 70 --
tools/objtool/Build | 8 +-
tools/objtool/Makefile | 9 +-
tools/objtool/arch/loongarch/Build | 3 +
tools/objtool/arch/loongarch/decode.c | 352 ++++++++++
.../arch/loongarch/include/arch/cfi_regs.h | 14 +
.../objtool/arch/loongarch/include/arch/elf.h | 15 +
.../arch/loongarch/include/arch/special.h | 21 +
tools/objtool/arch/loongarch/orc.c | 155 +++++
tools/objtool/arch/loongarch/special.c | 25 +
tools/objtool/arch/powerpc/special.c | 3 +
tools/objtool/arch/x86/Build | 1 +
tools/objtool/arch/x86/include/arch/elf.h | 1 +
tools/objtool/arch/x86/orc.c | 164 +++++
tools/objtool/arch/x86/special.c | 4 +
tools/objtool/cfi.c | 108 +++
tools/objtool/check.c | 568 +---------------
tools/objtool/decode.c | 136 ++++
tools/objtool/elf.c | 11 +-
tools/objtool/include/objtool/arch.h | 3 +
tools/objtool/include/objtool/cfi.h | 12 +
tools/objtool/include/objtool/check.h | 97 +--
tools/objtool/include/objtool/elf.h | 1 +
tools/objtool/include/objtool/insn.h | 166 +++++
tools/objtool/include/objtool/objtool.h | 3 +
tools/objtool/include/objtool/orc.h | 15 +
tools/objtool/include/objtool/special.h | 3 +
tools/objtool/insn.c | 195 ++++++
tools/objtool/orc_dump.c | 67 +-
tools/objtool/orc_gen.c | 79 +--
tools/objtool/sync-check.sh | 9 +
tools/objtool/unwind_hints.c | 107 +++
71 files changed, 3721 insertions(+), 1206 deletions(-)
create mode 100644 arch/loongarch/include/asm/orc_types.h
create mode 100644 arch/loongarch/include/asm/unwind_hints.h
create mode 100644 arch/loongarch/kernel/unwind_orc.c
rename {arch/x86/include/asm => include/asm-generic}/orc_lookup.h (50%)
create mode 100644 kernel/orc_lookup.c
create mode 100644 tools/arch/loongarch/include/asm/asm.h
create mode 100644 tools/arch/loongarch/include/asm/inst.h
create mode 100644 tools/arch/loongarch/include/asm/orc_types.h
create mode 100644 tools/arch/loongarch/include/asm/unwind_hints.h
create mode 100644 tools/arch/x86/include/asm/unwind_hints.h
create mode 100644 tools/objtool/arch/loongarch/Build
create mode 100644 tools/objtool/arch/loongarch/decode.c
create mode 100644 tools/objtool/arch/loongarch/include/arch/cfi_regs.h
create mode 100644 tools/objtool/arch/loongarch/include/arch/elf.h
create mode 100644 tools/objtool/arch/loongarch/include/arch/special.h
create mode 100644 tools/objtool/arch/loongarch/orc.c
create mode 100644 tools/objtool/arch/loongarch/special.c
create mode 100644 tools/objtool/arch/x86/orc.c
create mode 100644 tools/objtool/cfi.c
create mode 100644 tools/objtool/decode.c
create mode 100644 tools/objtool/include/objtool/insn.h
create mode 100644 tools/objtool/include/objtool/orc.h
create mode 100644 tools/objtool/insn.c
create mode 100644 tools/objtool/unwind_hints.c

--
2.39.2



2023-06-20 08:23:01

by Youling Tang

[permalink] [raw]
Subject: [RFC PATCH v1 01/23] objtool: Reorganize CFI code

From: "Madhavan T. Venkataraman" <[email protected]>

check.c implements static stack validation. But the CFI code that it
contains can be shared with other types of validation. E.g., dynamic FP
validation. Move the CFI code to its own files - cfi.h and cfi.c.

Signed-off-by: Madhavan T. Venkataraman <[email protected]>
---
tools/objtool/Build | 1 +
tools/objtool/cfi.c | 108 ++++++++++++++++++++++++++++
tools/objtool/check.c | 96 -------------------------
tools/objtool/include/objtool/cfi.h | 12 ++++
4 files changed, 121 insertions(+), 96 deletions(-)
create mode 100644 tools/objtool/cfi.c

diff --git a/tools/objtool/Build b/tools/objtool/Build
index a3cdf8af6635..9f23d1f4c716 100644
--- a/tools/objtool/Build
+++ b/tools/objtool/Build
@@ -5,6 +5,7 @@ objtool-y += weak.o
objtool-y += check.o
objtool-y += special.o
objtool-y += builtin-check.o
+objtool-y += cfi.o
objtool-y += elf.o
objtool-y += objtool.o

diff --git a/tools/objtool/cfi.c b/tools/objtool/cfi.c
new file mode 100644
index 000000000000..18b460e066c8
--- /dev/null
+++ b/tools/objtool/cfi.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2015-2017 Josh Poimboeuf <[email protected]>
+ */
+
+#include <stdlib.h>
+#include <sys/mman.h>
+
+#include <objtool/cfi.h>
+#include <objtool/builtin.h>
+#include <objtool/warn.h>
+
+unsigned long nr_cfi, nr_cfi_reused, nr_cfi_cache;
+
+struct cfi_init_state initial_func_cfi;
+struct cfi_state init_cfi;
+struct cfi_state func_cfi;
+
+void init_cfi_state(struct cfi_state *cfi)
+{
+ int i;
+
+ for (i = 0; i < CFI_NUM_REGS; i++) {
+ cfi->regs[i].base = CFI_UNDEFINED;
+ cfi->vals[i].base = CFI_UNDEFINED;
+ }
+ cfi->cfa.base = CFI_UNDEFINED;
+ cfi->drap_reg = CFI_UNDEFINED;
+ cfi->drap_offset = -1;
+}
+
+static struct cfi_state *cfi_alloc(void)
+{
+ struct cfi_state *cfi = calloc(sizeof(struct cfi_state), 1);
+
+ if (!cfi) {
+ WARN("calloc failed");
+ exit(1);
+ }
+ nr_cfi++;
+ return cfi;
+}
+
+static int cfi_bits;
+static struct hlist_head *cfi_hash;
+
+inline bool cficmp(struct cfi_state *cfi1, struct cfi_state *cfi2)
+{
+ return memcmp((void *)cfi1 + sizeof(cfi1->hash),
+ (void *)cfi2 + sizeof(cfi2->hash),
+ sizeof(struct cfi_state) - sizeof(struct hlist_node));
+}
+
+static inline u32 cfi_key(struct cfi_state *cfi)
+{
+ return jhash((void *)cfi + sizeof(cfi->hash),
+ sizeof(*cfi) - sizeof(cfi->hash), 0);
+}
+
+struct cfi_state *cfi_hash_find_or_add(struct cfi_state *cfi)
+{
+ struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)];
+ struct cfi_state *obj;
+
+ hlist_for_each_entry(obj, head, hash) {
+ if (!cficmp(cfi, obj)) {
+ nr_cfi_cache++;
+ return obj;
+ }
+ }
+
+ obj = cfi_alloc();
+ *obj = *cfi;
+ hlist_add_head(&obj->hash, head);
+
+ return obj;
+}
+
+void cfi_hash_add(struct cfi_state *cfi)
+{
+ struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)];
+
+ hlist_add_head(&cfi->hash, head);
+}
+
+void *cfi_hash_alloc(unsigned long size)
+{
+ cfi_bits = max(10, ilog2(size));
+ cfi_hash = mmap(NULL, sizeof(struct hlist_head) << cfi_bits,
+ PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANON, -1, 0);
+ if (cfi_hash == (void *)-1L) {
+ WARN("mmap fail cfi_hash");
+ cfi_hash = NULL;
+ } else if (opts.stats) {
+ printf("cfi_bits: %d\n", cfi_bits);
+ }
+
+ return cfi_hash;
+}
+
+void set_func_state(struct cfi_state *state)
+{
+ state->cfa = initial_func_cfi.cfa;
+ memcpy(&state->regs, &initial_func_cfi.regs,
+ CFI_NUM_REGS * sizeof(struct cfi_reg));
+ state->stack_size = initial_func_cfi.cfa.offset;
+}
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index f937be1afe65..803764f4d4d8 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -28,12 +28,6 @@ struct alternative {
bool skip_orig;
};

-static unsigned long nr_cfi, nr_cfi_reused, nr_cfi_cache;
-
-static struct cfi_init_state initial_func_cfi;
-static struct cfi_state init_cfi;
-static struct cfi_state func_cfi;
-
struct instruction *find_insn(struct objtool_file *file,
struct section *sec, unsigned long offset)
{
@@ -288,19 +282,6 @@ static bool dead_end_function(struct objtool_file *file, struct symbol *func)
return __dead_end_function(file, func, 0);
}

-static void init_cfi_state(struct cfi_state *cfi)
-{
- int i;
-
- for (i = 0; i < CFI_NUM_REGS; i++) {
- cfi->regs[i].base = CFI_UNDEFINED;
- cfi->vals[i].base = CFI_UNDEFINED;
- }
- cfi->cfa.base = CFI_UNDEFINED;
- cfi->drap_reg = CFI_UNDEFINED;
- cfi->drap_offset = -1;
-}
-
static void init_insn_state(struct objtool_file *file, struct insn_state *state,
struct section *sec)
{
@@ -316,75 +297,6 @@ static void init_insn_state(struct objtool_file *file, struct insn_state *state,
state->noinstr = sec->noinstr;
}

-static struct cfi_state *cfi_alloc(void)
-{
- struct cfi_state *cfi = calloc(sizeof(struct cfi_state), 1);
- if (!cfi) {
- WARN("calloc failed");
- exit(1);
- }
- nr_cfi++;
- return cfi;
-}
-
-static int cfi_bits;
-static struct hlist_head *cfi_hash;
-
-static inline bool cficmp(struct cfi_state *cfi1, struct cfi_state *cfi2)
-{
- return memcmp((void *)cfi1 + sizeof(cfi1->hash),
- (void *)cfi2 + sizeof(cfi2->hash),
- sizeof(struct cfi_state) - sizeof(struct hlist_node));
-}
-
-static inline u32 cfi_key(struct cfi_state *cfi)
-{
- return jhash((void *)cfi + sizeof(cfi->hash),
- sizeof(*cfi) - sizeof(cfi->hash), 0);
-}
-
-static struct cfi_state *cfi_hash_find_or_add(struct cfi_state *cfi)
-{
- struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)];
- struct cfi_state *obj;
-
- hlist_for_each_entry(obj, head, hash) {
- if (!cficmp(cfi, obj)) {
- nr_cfi_cache++;
- return obj;
- }
- }
-
- obj = cfi_alloc();
- *obj = *cfi;
- hlist_add_head(&obj->hash, head);
-
- return obj;
-}
-
-static void cfi_hash_add(struct cfi_state *cfi)
-{
- struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)];
-
- hlist_add_head(&cfi->hash, head);
-}
-
-static void *cfi_hash_alloc(unsigned long size)
-{
- cfi_bits = max(10, ilog2(size));
- cfi_hash = mmap(NULL, sizeof(struct hlist_head) << cfi_bits,
- PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANON, -1, 0);
- if (cfi_hash == (void *)-1L) {
- WARN("mmap fail cfi_hash");
- cfi_hash = NULL;
- } else if (opts.stats) {
- printf("cfi_bits: %d\n", cfi_bits);
- }
-
- return cfi_hash;
-}
-
static unsigned long nr_insns;
static unsigned long nr_insns_visited;

@@ -2236,14 +2148,6 @@ static int add_jump_table_alts(struct objtool_file *file)
return 0;
}

-static void set_func_state(struct cfi_state *state)
-{
- state->cfa = initial_func_cfi.cfa;
- memcpy(&state->regs, &initial_func_cfi.regs,
- CFI_NUM_REGS * sizeof(struct cfi_reg));
- state->stack_size = initial_func_cfi.cfa.offset;
-}
-
static int read_unwind_hints(struct objtool_file *file)
{
struct cfi_state cfi = init_cfi;
diff --git a/tools/objtool/include/objtool/cfi.h b/tools/objtool/include/objtool/cfi.h
index b1258e79a1b7..28c70daa3965 100644
--- a/tools/objtool/include/objtool/cfi.h
+++ b/tools/objtool/include/objtool/cfi.h
@@ -38,4 +38,16 @@ struct cfi_state {
bool end;
};

+void init_cfi_state(struct cfi_state *cfi);
+bool cficmp(struct cfi_state *cfi1, struct cfi_state *cfi2);
+struct cfi_state *cfi_hash_find_or_add(struct cfi_state *cfi);
+void cfi_hash_add(struct cfi_state *cfi);
+void *cfi_hash_alloc(unsigned long size);
+void set_func_state(struct cfi_state *state);
+
+extern unsigned long nr_cfi, nr_cfi_reused, nr_cfi_cache;
+extern struct cfi_init_state initial_func_cfi;
+extern struct cfi_state init_cfi;
+extern struct cfi_state func_cfi;
+
#endif /* _OBJTOOL_CFI_H */
--
2.39.2


2023-06-20 08:50:24

by Youling Tang

[permalink] [raw]
Subject: Re: [RFC PATCH v1 00/23] LoongArch: Add objtool and ORC unwinder support

Hi, Ruoyao

On 06/20/2023 04:15 PM, Xi Ruoyao wrote:
> It looks like only 19 patches are successfully delivered, out of 23.
I'm sorry, somehow the patchset didn't reach the mailing list. Probably
due to the sending limit being reached.

>
> And AFAIK objtool needs libelf from elfutils, and the LoongArch support
> in elfutils is not complete (there are about ten failures in the test
> suite as at the latest 0.189 release). Do we need to add more LoongArch
> support into libelf and/or declare a minimal needed libelf version for
> LoongArch objtool?
After the following series of patches [1], the elfutils test results
are passed.

[1]: https://sourceware.org/pipermail/elfutils-devel/2023q2/006107.html

Thanks,
Youling
>
> On Tue, 2023-06-20 at 15:46 +0800, Youling Tang wrote:
>> This series of patches adds objtool and ORC unwinder support for
>> LoongArch.
>>
>> Patch 01 - 07 are from "Madhavan T. Venkataraman" [1] with minor
>> code tweaks. The "objtool: Reorganize ORC types" patch was not
>> added, because LoongArch cannot share `strcut orc_entry`, it also
>> needs to include ra_offset and ra_reg.
>>
>> Since the changes in Patch 01 - 08 in [1] are architecture-
>> independent,
>> it might be better if they could be separated separately from the
>> series
>> of patches.
>>
>> ORC unwinder can get a reliable stack trace, which provides a
>> prerequisite
>> for the subsequent addition of livepatch support.
>>
>>
>> Instruction decoder
>> ===================
>>
>> To do this, an instruction decoder needs to be implemented. I have
>> implemented
>> a simple, table-driven decoder for LoongArch. Only a subset of the
>> instructions
>> needs to be fully decoded for this purpose:
>>
>> - Load-Store instructions
>> - Add instructions
>> - Branch instructions
>> - Call instructions
>> - Return instructions
>> - Stack pointer authentication instruction
>>
>>
>> Unwind hints
>> ============
>>
>> Unwind hints are collected in a special section. Objtool converts
>> unwind hints
>> to ORC data. The unwinder processes unwind hints to handle special
>> cases
>> mentioned above.
>>
>>
>> ORC unwinder
>> ============
>>
>> Before vmlinux created, we check all metadata, find the stack
>> operation,
>> note stack state and create orc data. Objtool insert two sections into
>> vmlinux. '.orc_unwind_ip' and '.orc_unwind'. (For modules, insert
>> '.rela.orc_unwind_ip' to relocate '.orc_unwind_ip'.) Each insn has
>> only
>> one stack state in .orc_unwind and orc_unwind_ip hint its pc address.
>> Through unwinding orc data, we can get stack info both kernel and
>> module.
>>
>>
>> This is a series of RFC patches, which may require long-term
>> discussions
>> and revisions. It is not based on the latest code but based on 6.3-
>> rc3.
>> Any ideas or suggestions are welcome.
>>
>> base-commit: e8d018dd0257f744ca50a729e3d042cf2ec9da65 (Linux 6.3-rc3)
>>
>> Link:
>> [1]:
>> https://lore.kernel.org/lkml/[email protected]/#r
>>
>> Madhavan T. Venkataraman (7):
>> objtool: Reorganize CFI code
>> objtool: Reorganize instruction-related code
>> objtool: Move decode_instructions() to a separate file
>> objtool: Reorganize Unwind hint code
>> objtool: Reorganize ORC code
>> objtool: Reorganize ORC kernel code
>> objtool: Introduce STATIC_CHECK
>>
>> Youling Tang (16):
>> tools: LoongArch: Copy inst.h and asm.h to tools
>> objtool: LoongArch: Add base definition for LoongArch
>> objtool: LoongArch: Implement decoder
>> objtool: Add annotate_reachable() for objtools
>> LoongArch: bug: Add reachable annotation to warning macros
>> objtool: Add next member in struct reloc
>> objtool: Add orc_print_dump() package
>> objtool: Add ORC support for LoongArch
>> LoongArch: Add ORC unwinder support
>> LoongArch: Support R_LARCH_32_PCREL relocation type in kernel module
>> LoongArch: Fix fpu.S objtool warning
>> LoongArch: Annotate unwind_hint
>> LoongArch: Move some data definitions into the .data section
>> objtool: Add arch-specific "noreturn" function handling
>> objtool: Make update_cfi_state() arch-specific function
>> LoongArch: objtool: Mark non-standard object files and directories
>>
>> arch/loongarch/Kconfig | 2 +
>> arch/loongarch/Kconfig.debug | 11 +
>> arch/loongarch/Makefile | 4 +
>> arch/loongarch/include/asm/bug.h | 1 +
>> arch/loongarch/include/asm/module.h | 7 +
>> arch/loongarch/include/asm/orc_types.h | 58 ++
>> arch/loongarch/include/asm/stackframe.h | 3 +
>> arch/loongarch/include/asm/unwind.h | 17 +-
>> arch/loongarch/include/asm/unwind_hints.h | 110 +++
>> arch/loongarch/kernel/Makefile | 3 +
>> arch/loongarch/kernel/entry.S | 2 +
>> arch/loongarch/kernel/fpu.S | 11 +-
>> arch/loongarch/kernel/genex.S | 2 +
>> arch/loongarch/kernel/head.S | 1 +
>> arch/loongarch/kernel/module.c | 21 +-
>> arch/loongarch/kernel/relocate_kernel.S | 12 +-
>> arch/loongarch/kernel/setup.c | 2 +
>> arch/loongarch/kernel/stacktrace.c | 1 +
>> arch/loongarch/kernel/unwind_orc.c | 301 +++++++++
>> arch/loongarch/kernel/vmlinux.lds.S | 3 +
>> arch/loongarch/power/Makefile | 2 +
>> arch/loongarch/vdso/Makefile | 2 +
>> arch/x86/include/asm/unwind.h | 5 -
>> arch/x86/include/asm/unwind_hints.h | 86 +++
>> arch/x86/kernel/module.c | 7 +-
>> arch/x86/kernel/unwind_orc.c | 268 +-------
>> arch/x86/kernel/vmlinux.lds.S | 2 +-
>> .../asm => include/asm-generic}/orc_lookup.h | 43 ++
>> include/linux/compiler.h | 9 +
>> include/linux/objtool.h | 70 --
>> kernel/Makefile | 2 +
>> kernel/orc_lookup.c | 261 ++++++++
>> scripts/Makefile | 5 +-
>> tools/arch/loongarch/include/asm/asm.h | 201 ++++++
>> tools/arch/loongarch/include/asm/inst.h | 629
>> ++++++++++++++++++
>> tools/arch/loongarch/include/asm/orc_types.h | 58 ++
>> .../arch/loongarch/include/asm/unwind_hints.h | 110 +++
>> tools/arch/x86/include/asm/unwind_hints.h | 160 +++++
>> tools/include/linux/bitops.h | 10 +
>> tools/include/linux/objtool.h | 70 --
>> tools/objtool/Build | 8 +-
>> tools/objtool/Makefile | 9 +-
>> tools/objtool/arch/loongarch/Build | 3 +
>> tools/objtool/arch/loongarch/decode.c | 352 ++++++++++
>> .../arch/loongarch/include/arch/cfi_regs.h | 14 +
>> .../objtool/arch/loongarch/include/arch/elf.h | 15 +
>> .../arch/loongarch/include/arch/special.h | 21 +
>> tools/objtool/arch/loongarch/orc.c | 155 +++++
>> tools/objtool/arch/loongarch/special.c | 25 +
>> tools/objtool/arch/powerpc/special.c | 3 +
>> tools/objtool/arch/x86/Build | 1 +
>> tools/objtool/arch/x86/include/arch/elf.h | 1 +
>> tools/objtool/arch/x86/orc.c | 164 +++++
>> tools/objtool/arch/x86/special.c | 4 +
>> tools/objtool/cfi.c | 108 +++
>> tools/objtool/check.c | 568 +---------------
>> tools/objtool/decode.c | 136 ++++
>> tools/objtool/elf.c | 11 +-
>> tools/objtool/include/objtool/arch.h | 3 +
>> tools/objtool/include/objtool/cfi.h | 12 +
>> tools/objtool/include/objtool/check.h | 97 +--
>> tools/objtool/include/objtool/elf.h | 1 +
>> tools/objtool/include/objtool/insn.h | 166 +++++
>> tools/objtool/include/objtool/objtool.h | 3 +
>> tools/objtool/include/objtool/orc.h | 15 +
>> tools/objtool/include/objtool/special.h | 3 +
>> tools/objtool/insn.c | 195 ++++++
>> tools/objtool/orc_dump.c | 67 +-
>> tools/objtool/orc_gen.c | 79 +--
>> tools/objtool/sync-check.sh | 9 +
>> tools/objtool/unwind_hints.c | 107 +++
>> 71 files changed, 3721 insertions(+), 1206 deletions(-)
>> create mode 100644 arch/loongarch/include/asm/orc_types.h
>> create mode 100644 arch/loongarch/include/asm/unwind_hints.h
>> create mode 100644 arch/loongarch/kernel/unwind_orc.c
>> rename {arch/x86/include/asm => include/asm-generic}/orc_lookup.h
>> (50%)
>> create mode 100644 kernel/orc_lookup.c
>> create mode 100644 tools/arch/loongarch/include/asm/asm.h
>> create mode 100644 tools/arch/loongarch/include/asm/inst.h
>> create mode 100644 tools/arch/loongarch/include/asm/orc_types.h
>> create mode 100644 tools/arch/loongarch/include/asm/unwind_hints.h
>> create mode 100644 tools/arch/x86/include/asm/unwind_hints.h
>> create mode 100644 tools/objtool/arch/loongarch/Build
>> create mode 100644 tools/objtool/arch/loongarch/decode.c
>> create mode 100644
>> tools/objtool/arch/loongarch/include/arch/cfi_regs.h
>> create mode 100644 tools/objtool/arch/loongarch/include/arch/elf.h
>> create mode 100644
>> tools/objtool/arch/loongarch/include/arch/special.h
>> create mode 100644 tools/objtool/arch/loongarch/orc.c
>> create mode 100644 tools/objtool/arch/loongarch/special.c
>> create mode 100644 tools/objtool/arch/x86/orc.c
>> create mode 100644 tools/objtool/cfi.c
>> create mode 100644 tools/objtool/decode.c
>> create mode 100644 tools/objtool/include/objtool/insn.h
>> create mode 100644 tools/objtool/include/objtool/orc.h
>> create mode 100644 tools/objtool/insn.c
>> create mode 100644 tools/objtool/unwind_hints.c
>>
>


2023-06-20 08:50:58

by Xi Ruoyao

[permalink] [raw]
Subject: Re: [RFC PATCH v1 00/23] LoongArch: Add objtool and ORC unwinder support

It looks like only 19 patches are successfully delivered, out of 23.

And AFAIK objtool needs libelf from elfutils, and the LoongArch support
in elfutils is not complete (there are about ten failures in the test
suite as at the latest 0.189 release). Do we need to add more LoongArch
support into libelf and/or declare a minimal needed libelf version for
LoongArch objtool?

On Tue, 2023-06-20 at 15:46 +0800, Youling Tang wrote:
> This series of patches adds objtool and ORC unwinder support for
> LoongArch.
>
> Patch 01 - 07 are from "Madhavan T. Venkataraman" [1] with minor
> code tweaks. The "objtool: Reorganize ORC types" patch was not
> added, because LoongArch cannot share `strcut orc_entry`, it also
> needs to include ra_offset and ra_reg.
>
> Since the changes in Patch 01 - 08 in [1] are architecture-
> independent,
> it might be better if they could be separated separately from the
> series
> of patches.
>
> ORC unwinder can get a reliable stack trace, which provides a
> prerequisite
> for the subsequent addition of livepatch support.
>
>
> Instruction decoder
> ===================
>
> To do this, an instruction decoder needs to be implemented. I have
> implemented
> a simple, table-driven decoder for LoongArch. Only a subset of the
> instructions
> needs to be fully decoded for this purpose:
>
>         - Load-Store instructions
>         - Add instructions
>         - Branch instructions
>         - Call instructions
>         - Return instructions
>         - Stack pointer authentication instruction
>
>
> Unwind hints
> ============
>
> Unwind hints are collected in a special section. Objtool converts
> unwind hints
> to ORC data. The unwinder processes unwind hints to handle special
> cases
> mentioned above.
>
>
> ORC unwinder
> ============
>
> Before vmlinux created, we check all metadata, find the stack
> operation,
> note stack state and create orc data. Objtool insert two sections into
> vmlinux. '.orc_unwind_ip' and '.orc_unwind'. (For modules, insert
> '.rela.orc_unwind_ip' to relocate '.orc_unwind_ip'.) Each insn has
> only
> one stack state in .orc_unwind and orc_unwind_ip hint its pc address.
> Through unwinding orc data, we can get stack info both kernel and
> module.
>
>
> This is a series of RFC patches, which may require long-term
> discussions
> and revisions. It is not based on the latest code but based on 6.3-
> rc3.
> Any ideas or suggestions are welcome.
>
> base-commit: e8d018dd0257f744ca50a729e3d042cf2ec9da65 (Linux 6.3-rc3)
>
> Link:
> [1]:
> https://lore.kernel.org/lkml/[email protected]/#r
>
> Madhavan T. Venkataraman (7):
>   objtool: Reorganize CFI code
>   objtool: Reorganize instruction-related code
>   objtool: Move decode_instructions() to a separate file
>   objtool: Reorganize Unwind hint code
>   objtool: Reorganize ORC code
>   objtool: Reorganize ORC kernel code
>   objtool: Introduce STATIC_CHECK
>
> Youling Tang (16):
>   tools: LoongArch: Copy inst.h and asm.h to tools
>   objtool: LoongArch: Add base definition for LoongArch
>   objtool: LoongArch: Implement decoder
>   objtool: Add annotate_reachable() for objtools
>   LoongArch: bug: Add reachable annotation to warning macros
>   objtool: Add next member in struct reloc
>   objtool: Add orc_print_dump() package
>   objtool: Add ORC support for LoongArch
>   LoongArch: Add ORC unwinder support
>   LoongArch: Support R_LARCH_32_PCREL relocation type in kernel module
>   LoongArch: Fix fpu.S objtool warning
>   LoongArch: Annotate unwind_hint
>   LoongArch: Move some data definitions into the .data section
>   objtool: Add arch-specific "noreturn" function handling
>   objtool: Make update_cfi_state() arch-specific function
>   LoongArch: objtool: Mark non-standard object files and directories
>
>  arch/loongarch/Kconfig                        |   2 +
>  arch/loongarch/Kconfig.debug                  |  11 +
>  arch/loongarch/Makefile                       |   4 +
>  arch/loongarch/include/asm/bug.h              |   1 +
>  arch/loongarch/include/asm/module.h           |   7 +
>  arch/loongarch/include/asm/orc_types.h        |  58 ++
>  arch/loongarch/include/asm/stackframe.h       |   3 +
>  arch/loongarch/include/asm/unwind.h           |  17 +-
>  arch/loongarch/include/asm/unwind_hints.h     | 110 +++
>  arch/loongarch/kernel/Makefile                |   3 +
>  arch/loongarch/kernel/entry.S                 |   2 +
>  arch/loongarch/kernel/fpu.S                   |  11 +-
>  arch/loongarch/kernel/genex.S                 |   2 +
>  arch/loongarch/kernel/head.S                  |   1 +
>  arch/loongarch/kernel/module.c                |  21 +-
>  arch/loongarch/kernel/relocate_kernel.S       |  12 +-
>  arch/loongarch/kernel/setup.c                 |   2 +
>  arch/loongarch/kernel/stacktrace.c            |   1 +
>  arch/loongarch/kernel/unwind_orc.c            | 301 +++++++++
>  arch/loongarch/kernel/vmlinux.lds.S           |   3 +
>  arch/loongarch/power/Makefile                 |   2 +
>  arch/loongarch/vdso/Makefile                  |   2 +
>  arch/x86/include/asm/unwind.h                 |   5 -
>  arch/x86/include/asm/unwind_hints.h           |  86 +++
>  arch/x86/kernel/module.c                      |   7 +-
>  arch/x86/kernel/unwind_orc.c                  | 268 +-------
>  arch/x86/kernel/vmlinux.lds.S                 |   2 +-
>  .../asm => include/asm-generic}/orc_lookup.h  |  43 ++
>  include/linux/compiler.h                      |   9 +
>  include/linux/objtool.h                       |  70 --
>  kernel/Makefile                               |   2 +
>  kernel/orc_lookup.c                           | 261 ++++++++
>  scripts/Makefile                              |   5 +-
>  tools/arch/loongarch/include/asm/asm.h        | 201 ++++++
>  tools/arch/loongarch/include/asm/inst.h       | 629
> ++++++++++++++++++
>  tools/arch/loongarch/include/asm/orc_types.h  |  58 ++
>  .../arch/loongarch/include/asm/unwind_hints.h | 110 +++
>  tools/arch/x86/include/asm/unwind_hints.h     | 160 +++++
>  tools/include/linux/bitops.h                  |  10 +
>  tools/include/linux/objtool.h                 |  70 --
>  tools/objtool/Build                           |   8 +-
>  tools/objtool/Makefile                        |   9 +-
>  tools/objtool/arch/loongarch/Build            |   3 +
>  tools/objtool/arch/loongarch/decode.c         | 352 ++++++++++
>  .../arch/loongarch/include/arch/cfi_regs.h    |  14 +
>  .../objtool/arch/loongarch/include/arch/elf.h |  15 +
>  .../arch/loongarch/include/arch/special.h     |  21 +
>  tools/objtool/arch/loongarch/orc.c            | 155 +++++
>  tools/objtool/arch/loongarch/special.c        |  25 +
>  tools/objtool/arch/powerpc/special.c          |   3 +
>  tools/objtool/arch/x86/Build                  |   1 +
>  tools/objtool/arch/x86/include/arch/elf.h     |   1 +
>  tools/objtool/arch/x86/orc.c                  | 164 +++++
>  tools/objtool/arch/x86/special.c              |   4 +
>  tools/objtool/cfi.c                           | 108 +++
>  tools/objtool/check.c                         | 568 +---------------
>  tools/objtool/decode.c                        | 136 ++++
>  tools/objtool/elf.c                           |  11 +-
>  tools/objtool/include/objtool/arch.h          |   3 +
>  tools/objtool/include/objtool/cfi.h           |  12 +
>  tools/objtool/include/objtool/check.h         |  97 +--
>  tools/objtool/include/objtool/elf.h           |   1 +
>  tools/objtool/include/objtool/insn.h          | 166 +++++
>  tools/objtool/include/objtool/objtool.h       |   3 +
>  tools/objtool/include/objtool/orc.h           |  15 +
>  tools/objtool/include/objtool/special.h       |   3 +
>  tools/objtool/insn.c                          | 195 ++++++
>  tools/objtool/orc_dump.c                      |  67 +-
>  tools/objtool/orc_gen.c                       |  79 +--
>  tools/objtool/sync-check.sh                   |   9 +
>  tools/objtool/unwind_hints.c                  | 107 +++
>  71 files changed, 3721 insertions(+), 1206 deletions(-)
>  create mode 100644 arch/loongarch/include/asm/orc_types.h
>  create mode 100644 arch/loongarch/include/asm/unwind_hints.h
>  create mode 100644 arch/loongarch/kernel/unwind_orc.c
>  rename {arch/x86/include/asm => include/asm-generic}/orc_lookup.h
> (50%)
>  create mode 100644 kernel/orc_lookup.c
>  create mode 100644 tools/arch/loongarch/include/asm/asm.h
>  create mode 100644 tools/arch/loongarch/include/asm/inst.h
>  create mode 100644 tools/arch/loongarch/include/asm/orc_types.h
>  create mode 100644 tools/arch/loongarch/include/asm/unwind_hints.h
>  create mode 100644 tools/arch/x86/include/asm/unwind_hints.h
>  create mode 100644 tools/objtool/arch/loongarch/Build
>  create mode 100644 tools/objtool/arch/loongarch/decode.c
>  create mode 100644
> tools/objtool/arch/loongarch/include/arch/cfi_regs.h
>  create mode 100644 tools/objtool/arch/loongarch/include/arch/elf.h
>  create mode 100644
> tools/objtool/arch/loongarch/include/arch/special.h
>  create mode 100644 tools/objtool/arch/loongarch/orc.c
>  create mode 100644 tools/objtool/arch/loongarch/special.c
>  create mode 100644 tools/objtool/arch/x86/orc.c
>  create mode 100644 tools/objtool/cfi.c
>  create mode 100644 tools/objtool/decode.c
>  create mode 100644 tools/objtool/include/objtool/insn.h
>  create mode 100644 tools/objtool/include/objtool/orc.h
>  create mode 100644 tools/objtool/insn.c
>  create mode 100644 tools/objtool/unwind_hints.c
>

--
Xi Ruoyao <[email protected]>
School of Aerospace Science and Technology, Xidian University

2023-06-20 08:53:39

by Xi Ruoyao

[permalink] [raw]
Subject: Re: [RFC PATCH v1 00/23] LoongArch: Add objtool and ORC unwinder support

On Tue, 2023-06-20 at 16:29 +0800, Youling Tang wrote:
> Hi, Ruoyao
>
> On 06/20/2023 04:15 PM, Xi Ruoyao wrote:
> > It looks like only 19 patches are successfully delivered, out of 23.
> I'm sorry, somehow the patchset didn't reach the mailing list. Probably
> due to the sending limit being reached.

They've reached now. Thanks!

> > And AFAIK objtool needs libelf from elfutils, and the LoongArch support
> > in elfutils is not complete (there are about ten failures in the test
> > suite as at the latest 0.189 release).  Do we need to add more LoongArch
> > support into libelf and/or declare a minimal needed libelf version for
> > LoongArch objtool?

> After the following series of patches [1], the elfutils test results
> are passed.
>
> [1]: https://sourceware.org/pipermail/elfutils-devel/2023q2/006107.html

Wow thanks, I'll add them into my build. But I'm not sure if we need a
libelf version check or something in the kernel building system.

--
Xi Ruoyao <[email protected]>
School of Aerospace Science and Technology, Xidian University

2023-06-20 09:08:54

by Youling Tang

[permalink] [raw]
Subject: Re: [RFC PATCH v1 00/23] LoongArch: Add objtool and ORC unwinder support

Hi, Peter

On 06/20/2023 04:38 PM, Peter Zijlstra wrote:
> On Tue, Jun 20, 2023 at 04:29:12PM +0800, Youling Tang wrote:
>> Hi, Ruoyao
>>
>> On 06/20/2023 04:15 PM, Xi Ruoyao wrote:
>>> It looks like only 19 patches are successfully delivered, out of 23.
>> I'm sorry, somehow the patchset didn't reach the mailing list. Probably
>> due to the sending limit being reached.
>
> I got all the patches, but their threading is broken, they come in
> chunks of 5 or :/

Yes, due to the limitation of the mailbox, only 5 patches can be sent
at a time (the number of patches multiplied by the number of people
sent), so the thread was interrupted, which caused inconvenience to the
review code, I am very sorry.

Thanks,
Youling


2023-06-20 09:09:12

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [RFC PATCH v1 00/23] LoongArch: Add objtool and ORC unwinder support

On Tue, Jun 20, 2023 at 03:46:26PM +0800, Youling Tang wrote:
> This series of patches adds objtool and ORC unwinder support for
> LoongArch.
>
> Patch 01 - 07 are from "Madhavan T. Venkataraman" [1] with minor
> code tweaks. The "objtool: Reorganize ORC types" patch was not
> added, because LoongArch cannot share `strcut orc_entry`, it also
> needs to include ra_offset and ra_reg.

Yeah, I wish you would not have done that :-( I really don't like those
patches. I just don't much believe in that dynamic validation thing, and
doubly not for the patches you did pick not including any actual
rationale for it.


Also, the patches very much do not apply to tip/objtool/core,
specifically Josh recently reworked the reloc stuff quite dramatically.

2023-06-20 09:09:13

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [RFC PATCH v1 00/23] LoongArch: Add objtool and ORC unwinder support

On Tue, Jun 20, 2023 at 04:29:12PM +0800, Youling Tang wrote:
> Hi, Ruoyao
>
> On 06/20/2023 04:15 PM, Xi Ruoyao wrote:
> > It looks like only 19 patches are successfully delivered, out of 23.
> I'm sorry, somehow the patchset didn't reach the mailing list. Probably
> due to the sending limit being reached.

I got all the patches, but their threading is broken, they come in
chunks of 5 or :/

2023-06-20 09:12:37

by Xi Ruoyao

[permalink] [raw]
Subject: Re: [RFC PATCH v1 00/23] LoongArch: Add objtool and ORC unwinder support

On Tue, 2023-06-20 at 10:38 +0200, Peter Zijlstra wrote:
> On Tue, Jun 20, 2023 at 04:29:12PM +0800, Youling Tang wrote:
> > Hi, Ruoyao
> >
> > On 06/20/2023 04:15 PM, Xi Ruoyao wrote:
> > > It looks like only 19 patches are successfully delivered, out of 23.
> > I'm sorry, somehow the patchset didn't reach the mailing list. Probably
> > due to the sending limit being reached.
>
> I got all the patches, but their threading is broken, they come in
> chunks of 5 or :/

Youling: when you need to resend a part of the series next time, you can
use the "--in-reply-to=" option of git send-email to avoid such an
issue. See the man page of git send-email for details :).

--
Xi Ruoyao <[email protected]>
School of Aerospace Science and Technology, Xidian University