objtool: Slice up elf_create_section_symbol()
authorPeter Zijlstra <peterz@infradead.org>
Fri, 28 Oct 2022 13:49:26 +0000 (15:49 +0200)
committerPeter Zijlstra <peterz@infradead.org>
Tue, 1 Nov 2022 12:44:08 +0000 (13:44 +0100)
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
tools/objtool/elf.c

index 89b37cd4ab1dcc38c39c2126fb67029971221ee8..3ad89d963e593acacdd37cf988586b33d0faf3b8 100644 (file)
@@ -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;
 }