Merge tag 'objtool_urgent_for_v5.15_rc5' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 10 Oct 2021 17:05:39 +0000 (10:05 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 10 Oct 2021 17:05:39 +0000 (10:05 -0700)
Pull objtool fixes from Borislav Petkov:

 - Remove an extra section.len member in favour of section.sh_size

 - Align .altinstructions section creation with the kernel's by creating
   them with entry size of 0

 - Fix objtool to convert a reloc symbol to a section offset and not to
   not warn about not knowing how

* tag 'objtool_urgent_for_v5.15_rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  objtool: Remove redundant 'len' field from struct section
  objtool: Make .altinstructions section entry size consistent
  objtool: Remove reloc symbol type checks in get_alt_entry()

tools/objtool/arch/x86/decode.c
tools/objtool/check.c
tools/objtool/elf.c
tools/objtool/include/objtool/elf.h
tools/objtool/orc_gen.c
tools/objtool/special.c

index bc82105..0893436 100644 (file)
@@ -684,7 +684,7 @@ static int elf_add_alternative(struct elf *elf,
        sec = find_section_by_name(elf, ".altinstructions");
        if (!sec) {
                sec = elf_create_section(elf, ".altinstructions",
-                                        SHF_ALLOC, size, 0);
+                                        SHF_ALLOC, 0, 0);
 
                if (!sec) {
                        WARN_ELF("elf_create_section");
index e5947fb..06b5c16 100644 (file)
@@ -292,7 +292,7 @@ static int decode_instructions(struct objtool_file *file)
                    !strcmp(sec->name, ".entry.text"))
                        sec->noinstr = true;
 
-               for (offset = 0; offset < sec->len; offset += insn->len) {
+               for (offset = 0; offset < sec->sh.sh_size; offset += insn->len) {
                        insn = malloc(sizeof(*insn));
                        if (!insn) {
                                WARN("malloc failed");
@@ -307,7 +307,7 @@ static int decode_instructions(struct objtool_file *file)
                        insn->offset = offset;
 
                        ret = arch_decode_instruction(file->elf, sec, offset,
-                                                     sec->len - offset,
+                                                     sec->sh.sh_size - offset,
                                                      &insn->len, &insn->type,
                                                      &insn->immediate,
                                                      &insn->stack_ops);
@@ -349,9 +349,9 @@ static struct instruction *find_last_insn(struct objtool_file *file,
 {
        struct instruction *insn = NULL;
        unsigned int offset;
-       unsigned int end = (sec->len > 10) ? sec->len - 10 : 0;
+       unsigned int end = (sec->sh.sh_size > 10) ? sec->sh.sh_size - 10 : 0;
 
-       for (offset = sec->len - 1; offset >= end && !insn; offset--)
+       for (offset = sec->sh.sh_size - 1; offset >= end && !insn; offset--)
                insn = find_insn(file, sec, offset);
 
        return insn;
@@ -389,7 +389,7 @@ static int add_dead_ends(struct objtool_file *file)
                insn = find_insn(file, reloc->sym->sec, reloc->addend);
                if (insn)
                        insn = list_prev_entry(insn, list);
-               else if (reloc->addend == reloc->sym->sec->len) {
+               else if (reloc->addend == reloc->sym->sec->sh.sh_size) {
                        insn = find_last_insn(file, reloc->sym->sec);
                        if (!insn) {
                                WARN("can't find unreachable insn at %s+0x%x",
@@ -424,7 +424,7 @@ reachable:
                insn = find_insn(file, reloc->sym->sec, reloc->addend);
                if (insn)
                        insn = list_prev_entry(insn, list);
-               else if (reloc->addend == reloc->sym->sec->len) {
+               else if (reloc->addend == reloc->sym->sec->sh.sh_size) {
                        insn = find_last_insn(file, reloc->sym->sec);
                        if (!insn) {
                                WARN("can't find reachable insn at %s+0x%x",
@@ -1561,14 +1561,14 @@ static int read_unwind_hints(struct objtool_file *file)
                return -1;
        }
 
-       if (sec->len % sizeof(struct unwind_hint)) {
+       if (sec->sh.sh_size % sizeof(struct unwind_hint)) {
                WARN("struct unwind_hint size mismatch");
                return -1;
        }
 
        file->hints = true;
 
-       for (i = 0; i < sec->len / sizeof(struct unwind_hint); i++) {
+       for (i = 0; i < sec->sh.sh_size / sizeof(struct unwind_hint); i++) {
                hint = (struct unwind_hint *)sec->data->d_buf + i;
 
                reloc = find_reloc_by_dest(file->elf, sec, i * sizeof(*hint));
index 8676c75..b18f005 100644 (file)
@@ -286,10 +286,9 @@ static int read_sections(struct elf *elf)
                                return -1;
                        }
                }
-               sec->len = sec->sh.sh_size;
 
                if (sec->sh.sh_flags & SHF_EXECINSTR)
-                       elf->text_size += sec->len;
+                       elf->text_size += sec->sh.sh_size;
 
                list_add_tail(&sec->list, &elf->sections);
                elf_hash_add(section, &sec->hash, sec->idx);
@@ -734,8 +733,8 @@ static int elf_add_string(struct elf *elf, struct section *strtab, char *str)
        data->d_size = strlen(str) + 1;
        data->d_align = 1;
 
-       len = strtab->len;
-       strtab->len += data->d_size;
+       len = strtab->sh.sh_size;
+       strtab->sh.sh_size += data->d_size;
        strtab->changed = true;
 
        return len;
@@ -790,9 +789,9 @@ struct symbol *elf_create_undef_symbol(struct elf *elf, const char *name)
        data->d_align = 1;
        data->d_type = ELF_T_SYM;
 
-       sym->idx = symtab->len / sizeof(sym->sym);
+       sym->idx = symtab->sh.sh_size / sizeof(sym->sym);
 
-       symtab->len += data->d_size;
+       symtab->sh.sh_size += data->d_size;
        symtab->changed = true;
 
        symtab_shndx = find_section_by_name(elf, ".symtab_shndx");
@@ -814,7 +813,7 @@ struct symbol *elf_create_undef_symbol(struct elf *elf, const char *name)
                data->d_align = 4;
                data->d_type = ELF_T_WORD;
 
-               symtab_shndx->len += 4;
+               symtab_shndx->sh.sh_size += 4;
                symtab_shndx->changed = true;
        }
 
@@ -855,7 +854,6 @@ struct section *elf_create_section(struct elf *elf, const char *name,
        }
 
        sec->idx = elf_ndxscn(s);
-       sec->len = size;
        sec->changed = true;
 
        sec->data = elf_newdata(s);
index e343950..075d829 100644 (file)
@@ -38,7 +38,6 @@ struct section {
        Elf_Data *data;
        char *name;
        int idx;
-       unsigned int len;
        bool changed, text, rodata, noinstr;
 };
 
index dc9b7dd..b5865e2 100644 (file)
@@ -204,7 +204,7 @@ int orc_create(struct objtool_file *file)
 
                /* Add a section terminator */
                if (!empty) {
-                       orc_list_add(&orc_list, &null, sec, sec->len);
+                       orc_list_add(&orc_list, &null, sec, sec->sh.sh_size);
                        nr++;
                }
        }
index f1428e3..06c3eac 100644 (file)
@@ -58,22 +58,11 @@ void __weak arch_handle_alternative(unsigned short feature, struct special_alt *
 {
 }
 
-static bool reloc2sec_off(struct reloc *reloc, struct section **sec, unsigned long *off)
+static void reloc_to_sec_off(struct reloc *reloc, struct section **sec,
+                            unsigned long *off)
 {
-       switch (reloc->sym->type) {
-       case STT_FUNC:
-               *sec = reloc->sym->sec;
-               *off = reloc->sym->offset + reloc->addend;
-               return true;
-
-       case STT_SECTION:
-               *sec = reloc->sym->sec;
-               *off = reloc->addend;
-               return true;
-
-       default:
-               return false;
-       }
+       *sec = reloc->sym->sec;
+       *off = reloc->sym->offset + reloc->addend;
 }
 
 static int get_alt_entry(struct elf *elf, struct special_entry *entry,
@@ -109,13 +98,8 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry,
                WARN_FUNC("can't find orig reloc", sec, offset + entry->orig);
                return -1;
        }
-       if (!reloc2sec_off(orig_reloc, &alt->orig_sec, &alt->orig_off)) {
-               WARN_FUNC("don't know how to handle reloc symbol type %d: %s",
-                          sec, offset + entry->orig,
-                          orig_reloc->sym->type,
-                          orig_reloc->sym->name);
-               return -1;
-       }
+
+       reloc_to_sec_off(orig_reloc, &alt->orig_sec, &alt->orig_off);
 
        if (!entry->group || alt->new_len) {
                new_reloc = find_reloc_by_dest(elf, sec, offset + entry->new);
@@ -133,13 +117,7 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry,
                if (arch_is_retpoline(new_reloc->sym))
                        return 1;
 
-               if (!reloc2sec_off(new_reloc, &alt->new_sec, &alt->new_off)) {
-                       WARN_FUNC("don't know how to handle reloc symbol type %d: %s",
-                                 sec, offset + entry->new,
-                                 new_reloc->sym->type,
-                                 new_reloc->sym->name);
-                       return -1;
-               }
+               reloc_to_sec_off(new_reloc, &alt->new_sec, &alt->new_off);
 
                /* _ASM_EXTABLE_EX hack */
                if (alt->new_off >= 0x7ffffff0)
@@ -181,13 +159,13 @@ int special_get_alts(struct elf *elf, struct list_head *alts)
                if (!sec)
                        continue;
 
-               if (sec->len % entry->size != 0) {
+               if (sec->sh.sh_size % entry->size != 0) {
                        WARN("%s size not a multiple of %d",
                             sec->name, entry->size);
                        return -1;
                }
 
-               nr_entries = sec->len / entry->size;
+               nr_entries = sec->sh.sh_size / entry->size;
 
                for (idx = 0; idx < nr_entries; idx++) {
                        alt = malloc(sizeof(*alt));