mirror of https://github.com/torvalds/linux.git
objtool: Add elf_create_data()
In preparation for the objtool klp diff subcommand, refactor elf_add_string() by adding a new elf_add_data() helper which allows the adding of arbitrary data to a section. Make both interfaces global so they can be used by the upcoming klp diff code. Acked-by: Petr Mladek <pmladek@suse.com> Tested-by: Joe Lawrence <joe.lawrence@redhat.com> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
This commit is contained in:
parent
243e963853
commit
431dbabf2d
|
|
@ -18,10 +18,11 @@
|
|||
#include <errno.h>
|
||||
#include <linux/interval_tree_generic.h>
|
||||
#include <objtool/builtin.h>
|
||||
|
||||
#include <objtool/elf.h>
|
||||
#include <objtool/warn.h>
|
||||
|
||||
#define ALIGN_UP(x, align_to) (((x) + ((align_to)-1)) & ~((align_to)-1))
|
||||
|
||||
static inline u32 str_hash(const char *str)
|
||||
{
|
||||
return jhash(str, strlen(str), 0);
|
||||
|
|
@ -763,8 +764,6 @@ static int elf_update_symbol(struct elf *elf, struct section *symtab,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int elf_add_string(struct elf *elf, struct section *strtab, const char *str);
|
||||
|
||||
struct symbol *elf_create_symbol(struct elf *elf, const char *name,
|
||||
struct section *sec, unsigned int bind,
|
||||
unsigned int type, unsigned long offset,
|
||||
|
|
@ -1100,11 +1099,9 @@ struct elf *elf_open_read(const char *name, int flags)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int elf_add_string(struct elf *elf, struct section *strtab, const char *str)
|
||||
unsigned int elf_add_string(struct elf *elf, struct section *strtab, const char *str)
|
||||
{
|
||||
Elf_Data *data;
|
||||
Elf_Scn *s;
|
||||
int len;
|
||||
unsigned int offset;
|
||||
|
||||
if (!strtab)
|
||||
strtab = find_section_by_name(elf, ".strtab");
|
||||
|
|
@ -1113,28 +1110,59 @@ static int elf_add_string(struct elf *elf, struct section *strtab, const char *s
|
|||
return -1;
|
||||
}
|
||||
|
||||
s = elf_getscn(elf->elf, strtab->idx);
|
||||
if (!strtab->sh.sh_addralign) {
|
||||
ERROR("'%s': invalid sh_addralign", strtab->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
offset = ALIGN_UP(strtab->sh.sh_size, strtab->sh.sh_addralign);
|
||||
|
||||
if (!elf_add_data(elf, strtab, str, strlen(str) + 1))
|
||||
return -1;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
void *elf_add_data(struct elf *elf, struct section *sec, const void *data, size_t size)
|
||||
{
|
||||
unsigned long offset;
|
||||
Elf_Scn *s;
|
||||
|
||||
if (!sec->sh.sh_addralign) {
|
||||
ERROR("'%s': invalid sh_addralign", sec->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s = elf_getscn(elf->elf, sec->idx);
|
||||
if (!s) {
|
||||
ERROR_ELF("elf_getscn");
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = elf_newdata(s);
|
||||
if (!data) {
|
||||
sec->data = elf_newdata(s);
|
||||
if (!sec->data) {
|
||||
ERROR_ELF("elf_newdata");
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data->d_buf = strdup(str);
|
||||
data->d_size = strlen(str) + 1;
|
||||
data->d_align = 1;
|
||||
sec->data->d_buf = calloc(1, size);
|
||||
if (!sec->data->d_buf) {
|
||||
ERROR_GLIBC("calloc");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = strtab->sh.sh_size;
|
||||
strtab->sh.sh_size += data->d_size;
|
||||
if (data)
|
||||
memcpy(sec->data->d_buf, data, size);
|
||||
|
||||
mark_sec_changed(elf, strtab, true);
|
||||
sec->data->d_size = size;
|
||||
sec->data->d_align = 1;
|
||||
|
||||
return len;
|
||||
offset = ALIGN_UP(sec->sh.sh_size, sec->sh.sh_addralign);
|
||||
sec->sh.sh_size = offset + size;
|
||||
|
||||
mark_sec_changed(elf, sec, true);
|
||||
|
||||
return sec->data->d_buf;
|
||||
}
|
||||
|
||||
struct section *elf_create_section(struct elf *elf, const char *name,
|
||||
|
|
|
|||
|
|
@ -135,6 +135,10 @@ struct symbol *elf_create_section_symbol(struct elf *elf, struct section *sec);
|
|||
struct symbol *elf_create_prefix_symbol(struct elf *elf, struct symbol *orig,
|
||||
size_t size);
|
||||
|
||||
void *elf_add_data(struct elf *elf, struct section *sec, const void *data,
|
||||
size_t size);
|
||||
|
||||
unsigned int elf_add_string(struct elf *elf, struct section *strtab, const char *str);
|
||||
|
||||
struct reloc *elf_init_reloc_text_sym(struct elf *elf, struct section *sec,
|
||||
unsigned long offset,
|
||||
|
|
@ -148,9 +152,9 @@ struct reloc *elf_init_reloc_data_sym(struct elf *elf, struct section *sec,
|
|||
struct symbol *sym,
|
||||
s64 addend);
|
||||
|
||||
int elf_write_insn(struct elf *elf, struct section *sec,
|
||||
unsigned long offset, unsigned int len,
|
||||
const char *insn);
|
||||
int elf_write_insn(struct elf *elf, struct section *sec, unsigned long offset,
|
||||
unsigned int len, const char *insn);
|
||||
|
||||
int elf_write(struct elf *elf);
|
||||
void elf_close(struct elf *elf);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue