Allow objtool to create undefined symbols; this allows creating relocations to symbols not currently in the symbol table.
Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org> --- tools/objtool/elf.c | 63 ++++++++++++++++++++++++++++++++++++ tools/objtool/include/objtool/elf.h | 1 2 files changed, 64 insertions(+) --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -724,6 +724,69 @@ static int elf_strtab_concat(struct elf return len; } +struct symbol *elf_create_undef_symbol(struct elf *elf, const char *name) +{ + struct section *symtab; + struct symbol *sym; + Elf_Data *data; + Elf_Scn *s; + + sym = malloc(sizeof(*sym)); + if (!sym) { + perror("malloc"); + return NULL; + } + memset(sym, 0, sizeof(*sym)); + + sym->name = strdup(name); + + sym->sym.st_name = elf_strtab_concat(elf, sym->name, NULL); + if (sym->sym.st_name == -1) + return NULL; + + sym->sym.st_info = 0x10; /* STB_GLOBAL, STT_NOTYPE */ + // st_other 0 + // st_shndx 0 + // st_value 0 + // st_size 0 + + symtab = find_section_by_name(elf, ".symtab"); + if (!symtab) { + WARN("can't find .symtab"); + return NULL; + } + + s = elf_getscn(elf->elf, symtab->idx); + if (!s) { + WARN_ELF("elf_getscn"); + return NULL; + } + + data = elf_newdata(s); + if (!data) { + WARN_ELF("elf_newdata"); + return NULL; + } + + data->d_buf = &sym->sym; + data->d_size = sizeof(sym->sym); + data->d_align = 1; + + sym->idx = symtab->len / sizeof(sym->sym); + + symtab->len += data->d_size; + symtab->changed = true; + + sym->sec = find_section_by_index(elf, 0); + + if (!elf_symbol_add(elf, sym)) { + WARN("elf_symbol_add"); + return NULL; + } + + return sym; +} + struct section *elf_create_section(struct elf *elf, const char *name, unsigned int sh_flags, size_t entsize, int nr) { --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -136,6 +136,7 @@ int elf_write_insn(struct elf *elf, stru unsigned long offset, unsigned int len, const char *insn); int elf_write_reloc(struct elf *elf, struct reloc *reloc); +struct symbol *elf_create_undef_symbol(struct elf *elf, const char *name); int elf_write(struct elf *elf); void elf_close(struct elf *elf);