Skip to content

Commit ab6ce22

Browse files
seehearfeeljpoimboe
authored andcommitted
objtool: Handle various symbol types of rodata
In the relocation section ".rela.rodata" of each .o file compiled with LoongArch toolchain, there are various symbol types such as STT_NOTYPE, STT_OBJECT, STT_FUNC in addition to the usual STT_SECTION, it needs to use reloc symbol offset instead of reloc addend to find the destination instruction in find_jump_table() and add_jump_table(). For the most part, an absolute relocation type is used for rodata. In the case of STT_SECTION, reloc->sym->offset is always zero, and for the other symbol types, reloc_addend(reloc) is always zero, thus it can use a simple statement "reloc->sym->offset + reloc_addend(reloc)" to obtain the symbol offset for various symbol types. Signed-off-by: Tiezhu Yang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Huacai Chen <[email protected]> Signed-off-by: Josh Poimboeuf <[email protected]>
1 parent bf71940 commit ab6ce22

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

tools/objtool/check.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1954,6 +1954,7 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
19541954
unsigned int prev_offset = 0;
19551955
struct reloc *reloc = table;
19561956
struct alternative *alt;
1957+
unsigned long sym_offset;
19571958

19581959
/*
19591960
* Each @reloc is a switch table relocation which points to the target
@@ -1971,20 +1972,21 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
19711972
if (prev_offset && reloc_offset(reloc) != prev_offset + 8)
19721973
break;
19731974

1975+
sym_offset = reloc->sym->offset + reloc_addend(reloc);
1976+
19741977
/* Detect function pointers from contiguous objects: */
1975-
if (reloc->sym->sec == pfunc->sec &&
1976-
reloc_addend(reloc) == pfunc->offset)
1978+
if (reloc->sym->sec == pfunc->sec && sym_offset == pfunc->offset)
19771979
break;
19781980

19791981
/*
19801982
* Clang sometimes leaves dangling unused jump table entries
19811983
* which point to the end of the function. Ignore them.
19821984
*/
19831985
if (reloc->sym->sec == pfunc->sec &&
1984-
reloc_addend(reloc) == pfunc->offset + pfunc->len)
1986+
sym_offset == pfunc->offset + pfunc->len)
19851987
goto next;
19861988

1987-
dest_insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc));
1989+
dest_insn = find_insn(file, reloc->sym->sec, sym_offset);
19881990
if (!dest_insn)
19891991
break;
19901992

@@ -2023,6 +2025,7 @@ static void find_jump_table(struct objtool_file *file, struct symbol *func,
20232025
struct reloc *table_reloc;
20242026
struct instruction *dest_insn, *orig_insn = insn;
20252027
unsigned long table_size;
2028+
unsigned long sym_offset;
20262029

20272030
/*
20282031
* Backward search using the @first_jump_src links, these help avoid
@@ -2046,7 +2049,10 @@ static void find_jump_table(struct objtool_file *file, struct symbol *func,
20462049
table_reloc = arch_find_switch_table(file, insn, &table_size);
20472050
if (!table_reloc)
20482051
continue;
2049-
dest_insn = find_insn(file, table_reloc->sym->sec, reloc_addend(table_reloc));
2052+
2053+
sym_offset = table_reloc->sym->offset + reloc_addend(table_reloc);
2054+
2055+
dest_insn = find_insn(file, table_reloc->sym->sec, sym_offset);
20502056
if (!dest_insn || !insn_func(dest_insn) || insn_func(dest_insn)->pfunc != func)
20512057
continue;
20522058

0 commit comments

Comments
 (0)