提交 8045b8f0 编写于 作者: T Thomas Weißschuh 提交者: Josh Poimboeuf

objtool: Allocate multiple structures with calloc()

By using calloc() instead of malloc() in a loop, libc does not have to
keep around bookkeeping information for each single structure.

This reduces maximum memory usage while processing vmlinux.o from
3153325 KB to 3035668 KB (-3.7%) on my notebooks "localmodconfig".

Note this introduces memory leaks, because some additional structs get
added to the lists later after reading the symbols and sections from the
original object.  Luckily we don't really care about memory leaks in
objtool.
Signed-off-by: NThomas Weißschuh <linux@weissschuh.net>
Link: https://lore.kernel.org/r/20221216-objtool-memory-v2-3-17968f85a464@weissschuh.netSigned-off-by: NJosh Poimboeuf <jpoimboe@kernel.org>
上级 cfd66e81
...@@ -284,13 +284,13 @@ static int read_sections(struct elf *elf) ...@@ -284,13 +284,13 @@ static int read_sections(struct elf *elf)
!elf_alloc_hash(section_name, sections_nr)) !elf_alloc_hash(section_name, sections_nr))
return -1; return -1;
elf->section_data = calloc(sections_nr, sizeof(*sec));
if (!elf->section_data) {
perror("calloc");
return -1;
}
for (i = 0; i < sections_nr; i++) { for (i = 0; i < sections_nr; i++) {
sec = malloc(sizeof(*sec)); sec = &elf->section_data[i];
if (!sec) {
perror("malloc");
return -1;
}
memset(sec, 0, sizeof(*sec));
INIT_LIST_HEAD(&sec->symbol_list); INIT_LIST_HEAD(&sec->symbol_list);
INIT_LIST_HEAD(&sec->reloc_list); INIT_LIST_HEAD(&sec->reloc_list);
...@@ -422,13 +422,13 @@ static int read_symbols(struct elf *elf) ...@@ -422,13 +422,13 @@ static int read_symbols(struct elf *elf)
!elf_alloc_hash(symbol_name, symbols_nr)) !elf_alloc_hash(symbol_name, symbols_nr))
return -1; return -1;
elf->symbol_data = calloc(symbols_nr, sizeof(*sym));
if (!elf->symbol_data) {
perror("calloc");
return -1;
}
for (i = 0; i < symbols_nr; i++) { for (i = 0; i < symbols_nr; i++) {
sym = malloc(sizeof(*sym)); sym = &elf->symbol_data[i];
if (!sym) {
perror("malloc");
return -1;
}
memset(sym, 0, sizeof(*sym));
sym->idx = i; sym->idx = i;
...@@ -918,13 +918,13 @@ static int read_relocs(struct elf *elf) ...@@ -918,13 +918,13 @@ static int read_relocs(struct elf *elf)
sec->base->reloc = sec; sec->base->reloc = sec;
nr_reloc = 0; nr_reloc = 0;
sec->reloc_data = calloc(sec->sh.sh_size / sec->sh.sh_entsize, sizeof(*reloc));
if (!sec->reloc_data) {
perror("calloc");
return -1;
}
for (i = 0; i < sec->sh.sh_size / sec->sh.sh_entsize; i++) { for (i = 0; i < sec->sh.sh_size / sec->sh.sh_entsize; i++) {
reloc = malloc(sizeof(*reloc)); reloc = &sec->reloc_data[i];
if (!reloc) {
perror("malloc");
return -1;
}
memset(reloc, 0, sizeof(*reloc));
switch (sec->sh.sh_type) { switch (sec->sh.sh_type) {
case SHT_REL: case SHT_REL:
if (read_rel_reloc(sec, i, reloc, &symndx)) if (read_rel_reloc(sec, i, reloc, &symndx))
...@@ -1453,16 +1453,16 @@ void elf_close(struct elf *elf) ...@@ -1453,16 +1453,16 @@ void elf_close(struct elf *elf)
list_for_each_entry_safe(sym, tmpsym, &sec->symbol_list, list) { list_for_each_entry_safe(sym, tmpsym, &sec->symbol_list, list) {
list_del(&sym->list); list_del(&sym->list);
hash_del(&sym->hash); hash_del(&sym->hash);
free(sym);
} }
list_for_each_entry_safe(reloc, tmpreloc, &sec->reloc_list, list) { list_for_each_entry_safe(reloc, tmpreloc, &sec->reloc_list, list) {
list_del(&reloc->list); list_del(&reloc->list);
hash_del(&reloc->hash); hash_del(&reloc->hash);
free(reloc);
} }
list_del(&sec->list); list_del(&sec->list);
free(sec); free(sec->reloc_data);
} }
free(elf->symbol_data);
free(elf->section_data);
free(elf); free(elf);
} }
...@@ -39,6 +39,7 @@ struct section { ...@@ -39,6 +39,7 @@ struct section {
char *name; char *name;
int idx; int idx;
bool changed, text, rodata, noinstr, init, truncate; bool changed, text, rodata, noinstr, init, truncate;
struct reloc *reloc_data;
}; };
struct symbol { struct symbol {
...@@ -104,6 +105,9 @@ struct elf { ...@@ -104,6 +105,9 @@ struct elf {
struct hlist_head *section_hash; struct hlist_head *section_hash;
struct hlist_head *section_name_hash; struct hlist_head *section_name_hash;
struct hlist_head *reloc_hash; struct hlist_head *reloc_hash;
struct section *section_data;
struct symbol *symbol_data;
}; };
#define OFFSET_STRIDE_BITS 4 #define OFFSET_STRIDE_BITS 4
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册