summaryrefslogtreecommitdiff
path: root/tools/objtool/elf.c
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2022-10-28 15:49:26 +0200
committerPeter Zijlstra <peterz@infradead.org>2022-11-01 13:44:08 +0100
commit4c91be8e926c6b3734d59b9348e305431484d42b (patch)
tree0115efd918c1fcda3db338e068d1e2bdeb98d838 /tools/objtool/elf.c
parent5ebddd7c4951c50142bcb239d4c6a82eff15759e (diff)
objtool: Slice up elf_create_section_symbol()
In order to facilitate creation of more symbol types, slice up elf_create_section_symbol() to extract a generic helper that deals with adding ELF symbols. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Tested-by: Yujie Liu <yujie.liu@intel.com> Link: https://lkml.kernel.org/r/20221028194453.396634875@infradead.org
Diffstat (limited to 'tools/objtool/elf.c')
-rw-r--r--tools/objtool/elf.c56
1 files changed, 35 insertions, 21 deletions
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 89b37cd4ab1d..3ad89d963e59 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -717,11 +717,11 @@ static int elf_update_symbol(struct elf *elf, struct section *symtab,
}
static struct symbol *
-elf_create_section_symbol(struct elf *elf, struct section *sec)
+__elf_create_symbol(struct elf *elf, struct symbol *sym)
{
struct section *symtab, *symtab_shndx;
Elf32_Word first_non_local, new_idx;
- struct symbol *sym, *old;
+ struct symbol *old;
symtab = find_section_by_name(elf, ".symtab");
if (symtab) {
@@ -731,27 +731,16 @@ elf_create_section_symbol(struct elf *elf, struct section *sec)
return NULL;
}
- sym = calloc(1, sizeof(*sym));
- if (!sym) {
- perror("malloc");
- return NULL;
- }
-
- sym->name = sec->name;
- sym->sec = sec;
+ new_idx = symtab->sh.sh_size / symtab->sh.sh_entsize;
- // st_name 0
- sym->sym.st_info = GELF_ST_INFO(STB_LOCAL, STT_SECTION);
- // st_other 0
- // st_value 0
- // st_size 0
+ if (GELF_ST_BIND(sym->sym.st_info) != STB_LOCAL)
+ goto non_local;
/*
* Move the first global symbol, as per sh_info, into a new, higher
* symbol index. This fees up a spot for a new local symbol.
*/
first_non_local = symtab->sh.sh_info;
- new_idx = symtab->sh.sh_size / symtab->sh.sh_entsize;
old = find_symbol_by_index(elf, first_non_local);
if (old) {
old->idx = new_idx;
@@ -769,18 +758,43 @@ elf_create_section_symbol(struct elf *elf, struct section *sec)
new_idx = first_non_local;
}
+ /*
+ * Either way, we will add a LOCAL symbol.
+ */
+ symtab->sh.sh_info += 1;
+
+non_local:
sym->idx = new_idx;
if (elf_update_symbol(elf, symtab, symtab_shndx, sym)) {
WARN("elf_update_symbol");
return NULL;
}
- /*
- * Either way, we added a LOCAL symbol.
- */
- symtab->sh.sh_info += 1;
+ return sym;
+}
+
+static struct symbol *
+elf_create_section_symbol(struct elf *elf, struct section *sec)
+{
+ struct symbol *sym = calloc(1, sizeof(*sym));
+
+ if (!sym) {
+ perror("malloc");
+ return NULL;
+ }
- elf_add_symbol(elf, sym);
+ sym->name = sec->name;
+ sym->sec = sec;
+
+ // st_name 0
+ sym->sym.st_info = GELF_ST_INFO(STB_LOCAL, STT_SECTION);
+ // st_other 0
+ // st_value 0
+ // st_size 0
+
+ sym = __elf_create_symbol(elf, sym);
+ if (sym)
+ elf_add_symbol(elf, sym);
return sym;
}