Live-Patching Archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v1 10/23] objtool: LoongArch: Implement decoder
@ 2023-06-20  7:50 Youling Tang
  2023-06-20  7:50 ` [RFC PATCH v1 11/23] objtool: Add annotate_reachable() for objtools Youling Tang
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Youling Tang @ 2023-06-20  7:50 UTC (permalink / raw
  To: Josh Poimboeuf, Peter Zijlstra, Huacai Chen, madvenka
  Cc: chenzhongjin, WANG Xuerui, Xi Ruoyao, live-patching, linux-kernel,
	loongarch, tangyouling00, youling.tang, Jinyang He

Implement arch_decode_instruction() for LoongArch.

Add the decoding of the following part of the instruction,

Instructions that affect the SP:
  - Add instruction:
    addi.d
  - Load-Store instructions:
    st.d/ld.d
    stptr.d/ldptr.d

Instructions that affect control flow:
  - Branch and Jump instructions:
    beq/bne/blt/bge/bltu/bgeu/beqz/bnez/b
    jirl
  - Call instructions:
    bl
  - Return instructions:
    jr ra

Miscellaneous instructions:
  - Break instructionw:
    break
  - Nop instruction:
    nop
  - System instruction:
    ertn

Co-developed-by: Jinyang He <hejinyang@loongson.cn>
Signed-off-by: Jinyang He <hejinyang@loongson.cn>
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
 tools/arch/loongarch/include/asm/inst.h |   1 +
 tools/include/linux/bitops.h            |  10 ++
 tools/objtool/arch/loongarch/decode.c   | 136 ++++++++++++++++++++++++
 3 files changed, 147 insertions(+)

diff --git a/tools/arch/loongarch/include/asm/inst.h b/tools/arch/loongarch/include/asm/inst.h
index f0533fbc1e63..23d041cd76bf 100644
--- a/tools/arch/loongarch/include/asm/inst.h
+++ b/tools/arch/loongarch/include/asm/inst.h
@@ -56,6 +56,7 @@ enum reg2_op {
 	revbd_op	= 0x0f,
 	revh2w_op	= 0x10,
 	revhd_op	= 0x11,
+	ertn_op		= 0x1920e,
 };
 
 enum reg2i5_op {
diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h
index f18683b95ea6..d81b52c070f5 100644
--- a/tools/include/linux/bitops.h
+++ b/tools/include/linux/bitops.h
@@ -87,4 +87,14 @@ static inline __u32 rol32(__u32 word, unsigned int shift)
 	return (word << shift) | (word >> ((-shift) & 31));
 }
 
+/**
+ * sign_extend64 - sign extend a 64-bit value using specified bit as sign-bit
+ * @value: value to sign extend
+ * @index: 0 based bit index (0<=index<64) to sign bit
+ */
+static __always_inline __s64 sign_extend64(__u64 value, int index)
+{
+	__u8 shift = 63 - index;
+	return (__s64)(value << shift) >> shift;
+}
 #endif
diff --git a/tools/objtool/arch/loongarch/decode.c b/tools/objtool/arch/loongarch/decode.c
index 3f795f57e914..fc24efd6dba2 100644
--- a/tools/objtool/arch/loongarch/decode.c
+++ b/tools/objtool/arch/loongarch/decode.c
@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <linux/bitops.h>
 #include <asm/inst.h>
 
 #include <objtool/check.h>
@@ -13,6 +14,8 @@
 #include <objtool/endianness.h>
 #include <arch/cfi_regs.h>
 
+#define to_cfi_reg(reg) (reg)
+
 int arch_ftrace_match(char *name)
 {
 	return !strcmp(name, "_mcount");
@@ -74,11 +77,18 @@ const char *arch_ret_insn(int len)
 	return (const char *)&ret;
 }
 
+#define ADD_OP(op) \
+	if (!(op = calloc(1, sizeof(*op)))) \
+		return -1; \
+	else for (*ops_list = op, ops_list = &op->next; op; op = NULL)
+
 int arch_decode_instruction(struct objtool_file *file, const struct section *sec,
 			    unsigned long offset, unsigned int maxlen,
 			    struct instruction *insn)
 {
+	struct stack_op **ops_list = &insn->stack_ops;
 	const struct elf *elf = file->elf;
+	struct stack_op *op = NULL;
 	union loongarch_instruction inst;
 
 	if (!is_loongarch(elf))
@@ -97,6 +107,132 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
 	if (inst.word == 0)
 		insn->type = INSN_NOP;
 
+	switch (inst.reg2i12_format.opcode) {
+	case addid_op:
+		if ((inst.reg2i12_format.rj == CFI_SP) || (inst.reg2i12_format.rd == CFI_SP)) {
+			/* addi.d reg1,reg2,imm */
+			insn->immediate = sign_extend64(inst.reg2i12_format.immediate, 11);
+			ADD_OP(op) {
+				op->src.type = OP_SRC_ADD;
+				op->src.reg = to_cfi_reg(inst.reg2i12_format.rj);
+				op->src.offset = insn->immediate;
+				op->dest.type = OP_DEST_REG;
+				op->dest.reg = to_cfi_reg(inst.reg2i12_format.rd);
+			}
+		}
+		break;
+	case std_op:
+		if (inst.reg2i12_format.rj == CFI_SP) {
+			/* st.d reg,sp,imm */
+			insn->immediate = sign_extend64(inst.reg2i12_format.immediate, 11);
+			ADD_OP(op) {
+				op->src.type = OP_SRC_REG;
+				op->src.reg = to_cfi_reg(inst.reg2i12_format.rd);
+				op->dest.type = OP_DEST_REG_INDIRECT;
+				op->dest.reg = CFI_SP;
+				op->dest.offset = insn->immediate;
+			}
+		}
+		break;
+	case ldd_op:
+		if (inst.reg2i12_format.rj == CFI_SP) {
+			/* ld.d reg,sp,imm */
+			insn->immediate = sign_extend64(inst.reg2i12_format.immediate, 11);
+			ADD_OP(op) {
+				op->src.type = OP_SRC_REG_INDIRECT;
+				op->src.reg = CFI_SP;
+				op->src.offset = insn->immediate;
+				op->dest.type = OP_DEST_REG;
+				op->dest.reg = to_cfi_reg(inst.reg2i12_format.rd);
+			}
+		}
+		break;
+	case andi_op:
+		if (inst.reg2i12_format.immediate == 0 &&
+		     inst.reg2i12_format.rj == 0 &&
+		     inst.reg2i12_format.rd == 0)
+			/* nop */
+			insn->type = INSN_NOP;
+		break;
+	default:
+		switch (inst.reg2i16_format.opcode) {
+		case jirl_op:
+			if (inst.reg2i16_format.rj == CFI_RA &&
+			     inst.reg2i16_format.rd == 0) {
+				/* jr ra */
+				insn->type = INSN_RETURN;
+			} else if (inst.reg2i16_format.rd == CFI_RA) {
+				/* jalr reg */
+				insn->type = INSN_CALL_DYNAMIC;
+			} else if (inst.reg2i16_format.rd == 0) {
+				/* jr reg */
+				insn->type = INSN_JUMP_DYNAMIC;
+			} else if (!inst.reg2i16_format.immediate) {
+				/* jirl  */
+				insn->immediate = sign_extend64(inst.reg2i16_format.immediate, 15);
+				insn->type = INSN_JUMP_UNCONDITIONAL;
+			}
+			break;
+		case beq_op:
+		case bne_op:
+		case blt_op:
+		case bge_op:
+		case bltu_op:
+		case bgeu_op:
+			insn->immediate = sign_extend64(inst.reg2i16_format.immediate, 15);
+			insn->type = INSN_JUMP_CONDITIONAL;
+			break;
+		case beqz_op:
+		case bnez_op:
+			insn->immediate = sign_extend64(inst.reg1i21_format.immediate_h << 16 |
+					     inst.reg1i21_format.immediate_l, 20);
+			insn->type = INSN_JUMP_CONDITIONAL;
+			break;
+		case bl_op:
+			insn->immediate = sign_extend64(inst.reg0i26_format.immediate_h << 16 |
+					     inst.reg0i26_format.immediate_l, 25);
+			insn->type = INSN_CALL;
+			break;
+		case b_op:
+			insn->immediate = sign_extend64(inst.reg0i26_format.immediate_h << 16 |
+					     inst.reg0i26_format.immediate_l, 25);
+			insn->type = INSN_JUMP_UNCONDITIONAL;
+			break;
+		default:
+			if (inst.reg2i14_format.opcode == stptrd_op &&
+				inst.reg2i14_format.rj == CFI_SP) {
+				/* stptr.d reg,sp,imm */
+				insn->immediate = sign_extend64(inst.reg2i14_format.immediate, 13);
+				ADD_OP(op) {
+					op->src.type = OP_SRC_REG;
+					op->src.reg = to_cfi_reg(inst.reg2i14_format.rd);
+					op->dest.type = OP_DEST_REG_INDIRECT;
+					op->dest.reg = CFI_SP;
+					op->dest.offset = insn->immediate;
+				}
+			} else if (inst.reg2i14_format.opcode == ldptrd_op &&
+				inst.reg2i14_format.rj == CFI_SP) {
+				/* ldptr.d reg,sp,imm */
+				insn->immediate = sign_extend64(inst.reg2i14_format.immediate, 13);
+				ADD_OP(op) {
+					op->src.type = OP_SRC_REG_INDIRECT;
+					op->src.reg = CFI_SP;
+					op->src.offset = insn->immediate;
+					op->dest.type = OP_DEST_REG;
+					op->dest.reg = to_cfi_reg(inst.reg2i14_format.rd);
+				}
+			} else if (inst.reg0i15_format.opcode == break_op) {
+				/* break */
+				insn->type = INSN_BUG;
+			} else if (inst.reg2_format.opcode == ertn_op) {
+				/* ertn */
+				insn->type = INSN_RETURN;
+			}
+			break;
+		}
+		break;
+	}
+
 	return 0;
 }
 
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC PATCH v1 11/23] objtool: Add annotate_reachable() for objtools
  2023-06-20  7:50 [RFC PATCH v1 10/23] objtool: LoongArch: Implement decoder Youling Tang
@ 2023-06-20  7:50 ` Youling Tang
  2023-06-20  7:50 ` [RFC PATCH v1 12/23] LoongArch: bug: Add reachable annotation to warning macros Youling Tang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Youling Tang @ 2023-06-20  7:50 UTC (permalink / raw
  To: Josh Poimboeuf, Peter Zijlstra, Huacai Chen, madvenka
  Cc: chenzhongjin, WANG Xuerui, Xi Ruoyao, live-patching, linux-kernel,
	loongarch, tangyouling00, youling.tang

x86 removed annotate_reachable and replaced it with ASM_REACHABLE
which is not suitable for LoongArch micro.

Re-add annotation_reachable() for LoongArch.

Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
 include/linux/compiler.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 947a60b801db..6b33de8bf7c3 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -117,6 +117,14 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
  */
 #define __stringify_label(n) #n
 
+#define __annotate_reachable(c) ({					\
+	asm volatile(__stringify_label(c) ":\n\t"			\
+			".pushsection .discard.reachable\n\t"		\
+			".long " __stringify_label(c) "b - .\n\t"	\
+			".popsection\n\t");				\
+})
+#define annotate_reachable() __annotate_reachable(__COUNTER__)
+
 #define __annotate_unreachable(c) ({					\
 	asm volatile(__stringify_label(c) ":\n\t"			\
 		     ".pushsection .discard.unreachable\n\t"		\
@@ -129,6 +137,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
 #define __annotate_jump_table __section(".rodata..c_jump_table")
 
 #else /* !CONFIG_OBJTOOL */
+#define annotate_reachable()
 #define annotate_unreachable()
 #define __annotate_jump_table
 #endif /* CONFIG_OBJTOOL */
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC PATCH v1 12/23] LoongArch: bug: Add reachable annotation to warning macros
  2023-06-20  7:50 [RFC PATCH v1 10/23] objtool: LoongArch: Implement decoder Youling Tang
  2023-06-20  7:50 ` [RFC PATCH v1 11/23] objtool: Add annotate_reachable() for objtools Youling Tang
@ 2023-06-20  7:50 ` Youling Tang
  2023-06-20  7:50 ` [RFC PATCH v1 13/23] objtool: Add next member in struct reloc Youling Tang
  2023-06-20  7:50 ` [RFC PATCH v1 14/23] objtool: Add orc_print_dump() package Youling Tang
  3 siblings, 0 replies; 6+ messages in thread
From: Youling Tang @ 2023-06-20  7:50 UTC (permalink / raw
  To: Josh Poimboeuf, Peter Zijlstra, Huacai Chen, madvenka
  Cc: chenzhongjin, WANG Xuerui, Xi Ruoyao, live-patching, linux-kernel,
	loongarch, tangyouling00, youling.tang

WARN* and BUG* both use `break 0x1` opcodes and the distinction is
provided by the contents of the bug table. This table is not accessible
to objtool, so add an annotation to WARN* macros to let objtool know
that break handler will return an resume the execution of the instructions
following the WARN's break.

Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
 arch/loongarch/include/asm/bug.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/loongarch/include/asm/bug.h b/arch/loongarch/include/asm/bug.h
index d4ca3ba25418..08388876ade4 100644
--- a/arch/loongarch/include/asm/bug.h
+++ b/arch/loongarch/include/asm/bug.h
@@ -44,6 +44,7 @@
 do {								\
 	instrumentation_begin();				\
 	__BUG_FLAGS(BUGFLAG_WARNING|(flags));			\
+	annotate_reachable();					\
 	instrumentation_end();					\
 } while (0)
 
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC PATCH v1 13/23] objtool: Add next member in struct reloc
  2023-06-20  7:50 [RFC PATCH v1 10/23] objtool: LoongArch: Implement decoder Youling Tang
  2023-06-20  7:50 ` [RFC PATCH v1 11/23] objtool: Add annotate_reachable() for objtools Youling Tang
  2023-06-20  7:50 ` [RFC PATCH v1 12/23] LoongArch: bug: Add reachable annotation to warning macros Youling Tang
@ 2023-06-20  7:50 ` Youling Tang
  2023-06-20  8:57   ` Peter Zijlstra
  2023-06-20  7:50 ` [RFC PATCH v1 14/23] objtool: Add orc_print_dump() package Youling Tang
  3 siblings, 1 reply; 6+ messages in thread
From: Youling Tang @ 2023-06-20  7:50 UTC (permalink / raw
  To: Josh Poimboeuf, Peter Zijlstra, Huacai Chen, madvenka
  Cc: chenzhongjin, WANG Xuerui, Xi Ruoyao, live-patching, linux-kernel,
	loongarch, tangyouling00, youling.tang, Jinyang He

In LoongArch, there may be multiple relocation information in one location,
so the next member is added to handle this situation.

The following warning appears when the next member is not added,
warning: objtool: unexpected relocation symbol type in .rela.discard.unreachable

Relocation section '.rela.discard.unreachable' at offset 0x1a58 contains 4 entries:
    Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
0000000000000000  0000000200000032 R_LARCH_ADD32          0000000000000000 .text + 354
0000000000000000  0000000900000037 R_LARCH_SUB32          0000000000000000 L0^A + 0

Co-developed-by: Jinyang He <hejinyang@loongson.cn>
Signed-off-by: Jinyang He <hejinyang@loongson.cn>
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
 tools/objtool/elf.c                 | 11 ++++++++++-
 tools/objtool/include/objtool/elf.h |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 6806ce01d933..d345300d269b 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -895,7 +895,7 @@ static int read_relocs(struct elf *elf)
 {
 	unsigned long nr_reloc, max_reloc = 0, tot_reloc = 0;
 	struct section *sec;
-	struct reloc *reloc;
+	struct reloc *reloc, *next_reloc;
 	unsigned int symndx;
 	struct symbol *sym;
 	int i;
@@ -915,6 +915,7 @@ static int read_relocs(struct elf *elf)
 			return -1;
 		}
 
+		next_reloc = NULL;
 		sec->base->reloc = sec;
 
 		nr_reloc = 0;
@@ -946,6 +947,14 @@ static int read_relocs(struct elf *elf)
 				return -1;
 			}
 
+			if (next_reloc && reloc->offset == next_reloc->offset) {
+				next_reloc->next = reloc;
+				next_reloc = reloc;
+				continue;
+			}
+
+			next_reloc = reloc;
+
 			list_add_tail(&reloc->sym_reloc_entry, &sym->reloc_list);
 			list_add_tail(&reloc->list, &sec->reloc_list);
 			elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));
diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
index ad0024da262b..7877298fe401 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -68,6 +68,7 @@ struct symbol {
 struct reloc {
 	struct list_head list;
 	struct hlist_node hash;
+	struct reloc *next;
 	union {
 		GElf_Rela rela;
 		GElf_Rel  rel;
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC PATCH v1 14/23] objtool: Add orc_print_dump() package
  2023-06-20  7:50 [RFC PATCH v1 10/23] objtool: LoongArch: Implement decoder Youling Tang
                   ` (2 preceding siblings ...)
  2023-06-20  7:50 ` [RFC PATCH v1 13/23] objtool: Add next member in struct reloc Youling Tang
@ 2023-06-20  7:50 ` Youling Tang
  3 siblings, 0 replies; 6+ messages in thread
From: Youling Tang @ 2023-06-20  7:50 UTC (permalink / raw
  To: Josh Poimboeuf, Peter Zijlstra, Huacai Chen, madvenka
  Cc: chenzhongjin, WANG Xuerui, Xi Ruoyao, live-patching, linux-kernel,
	loongarch, tangyouling00, youling.tang

There is no functional change, only operations such as orc_print_{sp,fp}
are encapsulated into orc_print_dump(). It is convenient to add LoongArch
support later (because it needs to add orc_print_ra()).

Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
 tools/objtool/arch/x86/orc.c        | 23 ++++++++++++++++++-----
 tools/objtool/include/objtool/orc.h |  5 +----
 tools/objtool/orc_dump.c            | 12 +-----------
 3 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/tools/objtool/arch/x86/orc.c b/tools/objtool/arch/x86/orc.c
index a0c00e136089..cf546b274a79 100644
--- a/tools/objtool/arch/x86/orc.c
+++ b/tools/objtool/arch/x86/orc.c
@@ -114,7 +114,7 @@ static const char *reg_name(unsigned int reg)
 	}
 }
 
-const char *orc_type_name(unsigned int type)
+static const char *orc_type_name(unsigned int type)
 {
 	switch (type) {
 	case UNWIND_HINT_TYPE_CALL:
@@ -128,7 +128,7 @@ const char *orc_type_name(unsigned int type)
 	}
 }
 
-void orc_print_reg(unsigned int reg, int offset)
+static void orc_print_reg(unsigned int reg, int offset)
 {
 	if (reg == ORC_REG_BP_INDIRECT)
 		printf("(bp%+d)", offset);
@@ -140,12 +140,25 @@ void orc_print_reg(unsigned int reg, int offset)
 		printf("%s%+d", reg_name(reg), offset);
 }
 
-void orc_print_sp(void)
+static void orc_print_sp(void)
 {
 	printf(" sp:");
 }
-
-void orc_print_fp(void)
+static void orc_print_fp(void)
 {
 	printf(" bp:");
 }
+
+void orc_print_dump(struct elf *dummy_elf, struct orc_entry *orc, int i)
+{
+	orc_print_sp();
+
+	orc_print_reg(orc[i].sp_reg, bswap_if_needed(dummy_elf, orc[i].sp_offset));
+
+	orc_print_fp();
+
+	orc_print_reg(orc[i].bp_reg, bswap_if_needed(dummy_elf, orc[i].bp_offset));
+
+	printf(" type:%s signal:%d end:%d\n",
+	       orc_type_name(orc[i].type), orc[i].signal, orc[i].end);
+}
diff --git a/tools/objtool/include/objtool/orc.h b/tools/objtool/include/objtool/orc.h
index bf141134c56f..53a037bdfc35 100644
--- a/tools/objtool/include/objtool/orc.h
+++ b/tools/objtool/include/objtool/orc.h
@@ -10,9 +10,6 @@
 
 int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi,
 		   struct instruction *insn);
-const char *orc_type_name(unsigned int type);
-void orc_print_reg(unsigned int reg, int offset);
-void orc_print_sp(void);
-void orc_print_fp(void);
+void orc_print_dump(struct elf *dummy_elf, struct orc_entry *orc, int i);
 
 #endif /* _OBJTOOL_ORC_H */
diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c
index 82bdd33dbc39..c274c0577427 100644
--- a/tools/objtool/orc_dump.c
+++ b/tools/objtool/orc_dump.c
@@ -151,17 +151,7 @@ int orc_dump(const char *_objname)
 			printf("%llx:", (unsigned long long)(orc_ip_addr + (i * sizeof(int)) + orc_ip[i]));
 		}
 
-
-		orc_print_sp();
-
-		orc_print_reg(orc[i].sp_reg, bswap_if_needed(&dummy_elf, orc[i].sp_offset));
-
-		orc_print_fp();
-
-		orc_print_reg(orc[i].bp_reg, bswap_if_needed(&dummy_elf, orc[i].bp_offset));
-
-		printf(" type:%s signal:%d end:%d\n",
-		       orc_type_name(orc[i].type), orc[i].signal, orc[i].end);
+		orc_print_dump(&dummy_elf, orc, i);
 	}
 
 	elf_end(elf);
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [RFC PATCH v1 13/23] objtool: Add next member in struct reloc
  2023-06-20  7:50 ` [RFC PATCH v1 13/23] objtool: Add next member in struct reloc Youling Tang
@ 2023-06-20  8:57   ` Peter Zijlstra
  0 siblings, 0 replies; 6+ messages in thread
From: Peter Zijlstra @ 2023-06-20  8:57 UTC (permalink / raw
  To: Youling Tang
  Cc: Josh Poimboeuf, Huacai Chen, madvenka, chenzhongjin, WANG Xuerui,
	Xi Ruoyao, live-patching, linux-kernel, loongarch, tangyouling00,
	youling.tang, Jinyang He

On Tue, Jun 20, 2023 at 03:50:09PM +0800, Youling Tang wrote:
> In LoongArch, there may be multiple relocation information in one location,
> so the next member is added to handle this situation.

So Josh did a shrink on struct reloc because there are too many of them;
ideally we find another way to link them for the case where it is
needed.

> 
> The following warning appears when the next member is not added,
> warning: objtool: unexpected relocation symbol type in .rela.discard.unreachable
> 
> Relocation section '.rela.discard.unreachable' at offset 0x1a58 contains 4 entries:
>     Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
> 0000000000000000  0000000200000032 R_LARCH_ADD32          0000000000000000 .text + 354
> 0000000000000000  0000000900000037 R_LARCH_SUB32          0000000000000000 L0^A + 0
> 
> Co-developed-by: Jinyang He <hejinyang@loongson.cn>
> Signed-off-by: Jinyang He <hejinyang@loongson.cn>
> Signed-off-by: Youling Tang <tangyouling@loongson.cn>
> ---
>  tools/objtool/elf.c                 | 11 ++++++++++-
>  tools/objtool/include/objtool/elf.h |  1 +
>  2 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
> index 6806ce01d933..d345300d269b 100644
> --- a/tools/objtool/elf.c
> +++ b/tools/objtool/elf.c
> @@ -895,7 +895,7 @@ static int read_relocs(struct elf *elf)
>  {
>  	unsigned long nr_reloc, max_reloc = 0, tot_reloc = 0;
>  	struct section *sec;
> -	struct reloc *reloc;
> +	struct reloc *reloc, *next_reloc;
>  	unsigned int symndx;
>  	struct symbol *sym;
>  	int i;
> @@ -915,6 +915,7 @@ static int read_relocs(struct elf *elf)
>  			return -1;
>  		}
>  
> +		next_reloc = NULL;
>  		sec->base->reloc = sec;
>  
>  		nr_reloc = 0;
> @@ -946,6 +947,14 @@ static int read_relocs(struct elf *elf)
>  				return -1;
>  			}
>  
> +			if (next_reloc && reloc->offset == next_reloc->offset) {
> +				next_reloc->next = reloc;
> +				next_reloc = reloc;
> +				continue;
> +			}
> +
> +			next_reloc = reloc;

This seems to rely on 'linked' reloc being adjecent in the ELF tables;
is this required by the LoongArch ELF spec? If not, you really should
not rely on it.

> +
>  			list_add_tail(&reloc->sym_reloc_entry, &sym->reloc_list);
>  			list_add_tail(&reloc->list, &sec->reloc_list);
>  			elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));
> diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
> index ad0024da262b..7877298fe401 100644
> --- a/tools/objtool/include/objtool/elf.h
> +++ b/tools/objtool/include/objtool/elf.h
> @@ -68,6 +68,7 @@ struct symbol {
>  struct reloc {
>  	struct list_head list;
>  	struct hlist_node hash;
> +	struct reloc *next;
>  	union {
>  		GElf_Rela rela;
>  		GElf_Rel  rel;
> -- 
> 2.39.2
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-06-20  8:58 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-20  7:50 [RFC PATCH v1 10/23] objtool: LoongArch: Implement decoder Youling Tang
2023-06-20  7:50 ` [RFC PATCH v1 11/23] objtool: Add annotate_reachable() for objtools Youling Tang
2023-06-20  7:50 ` [RFC PATCH v1 12/23] LoongArch: bug: Add reachable annotation to warning macros Youling Tang
2023-06-20  7:50 ` [RFC PATCH v1 13/23] objtool: Add next member in struct reloc Youling Tang
2023-06-20  8:57   ` Peter Zijlstra
2023-06-20  7:50 ` [RFC PATCH v1 14/23] objtool: Add orc_print_dump() package Youling Tang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).