OSDN Git Service

objtool: Allocate relocs in advance for new rela sections
authorJosh Poimboeuf <jpoimboe@kernel.org>
Tue, 30 May 2023 17:21:03 +0000 (10:21 -0700)
committerJosh Poimboeuf <jpoimboe@kernel.org>
Wed, 7 Jun 2023 17:03:20 +0000 (10:03 -0700)
Similar to read_relocs(), allocate the reloc structs all together in an
array rather than allocating them one at a time.

Link: https://lore.kernel.org/r/5332d845c5a2d6c2d052075b381bfba8bcb67ed5.1685464332.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
tools/objtool/elf.c

index 8d53f18..5f69d45 100644 (file)
@@ -814,7 +814,7 @@ static struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec,
                                    unsigned long offset, struct symbol *sym,
                                    s64 addend, unsigned int type)
 {
-       struct reloc *reloc;
+       struct reloc *reloc, empty = { 0 };
 
        if (reloc_idx >= rsec->sh.sh_size / elf_rela_size(elf)) {
                WARN("%s: bad reloc_idx %u for %s with size 0x%lx",
@@ -822,12 +822,13 @@ static struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec,
                return NULL;
        }
 
-       reloc = malloc(sizeof(*reloc));
-       if (!reloc) {
-               perror("malloc");
+       reloc = &rsec->reloc_data[reloc_idx];
+
+       if (memcmp(reloc, &empty, sizeof(empty))) {
+               WARN("%s: %s: reloc %d already initialized!",
+                    __func__, rsec->name, reloc_idx);
                return NULL;
        }
-       memset(reloc, 0, sizeof(*reloc));
 
        reloc->idx = reloc_idx;
        reloc->sec = rsec;
@@ -1185,6 +1186,13 @@ static struct section *elf_create_rela_section(struct elf *elf,
        rsec->sh.sh_info = sec->idx;
        rsec->sh.sh_flags = SHF_INFO_LINK;
 
+       rsec->reloc_data = calloc(rsec->sh.sh_size / rsec->sh.sh_entsize,
+                                 sizeof(struct reloc));
+       if (!rsec->reloc_data) {
+               perror("calloc");
+               return NULL;
+       }
+
        sec->rsec = rsec;
        rsec->base = sec;