On Fri, Mar 12, 2021 at 06:16:18PM +0100, Peter Zijlstra wrote:
> --- a/tools/objtool/elf.c
> +++ b/tools/objtool/elf.c
> @@ -479,6 +479,8 @@ void elf_add_reloc(struct elf *elf, stru
>  
>       list_add_tail(&reloc->list, &sec->reloc_list);
>       elf_hash_add(elf->reloc_hash, &reloc->hash, reloc_hash(reloc));
> +
> +     sec->rereloc = true;
>  }

Can we just reuse sec->changed for this?  Something like this on top
(untested of course):

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index addcec88ac9f..b9cb74a54681 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -480,7 +480,7 @@ void elf_add_reloc(struct elf *elf, struct reloc *reloc)
        list_add_tail(&reloc->list, &sec->reloc_list);
        elf_hash_add(elf->reloc_hash, &reloc->hash, reloc_hash(reloc));
 
-       sec->rereloc = true;
+       sec->changed = true;
 }
 
 static int read_rel_reloc(struct section *sec, int i, struct reloc *reloc, 
unsigned int *symndx)
@@ -882,9 +882,6 @@ int elf_rebuild_reloc_section(struct elf *elf, struct 
section *sec)
        struct reloc *reloc;
        int nr;
 
-       sec->changed = true;
-       elf->changed = true;
-
        nr = 0;
        list_for_each_entry(reloc, &sec->reloc_list, list)
                nr++;
@@ -894,8 +891,6 @@ int elf_rebuild_reloc_section(struct elf *elf, struct 
section *sec)
        case SHT_RELA: return elf_rebuild_rela_reloc_section(sec, nr);
        default:       return -1;
        }
-
-       sec->rereloc = false;
 }
 
 int elf_write_insn(struct elf *elf, struct section *sec,
@@ -950,14 +945,15 @@ int elf_write(struct elf *elf)
        struct section *sec;
        Elf_Scn *s;
 
-       list_for_each_entry(sec, &elf->sections, list) {
-               if (sec->reloc && sec->reloc->rereloc)
-                       elf_rebuild_reloc_section(elf, sec->reloc);
-       }
-
-       /* Update section headers for changed sections: */
+       /* Update changed relocation sections and section headers: */
        list_for_each_entry(sec, &elf->sections, list) {
                if (sec->changed) {
+                       if (sec->reloc &&
+                           elf_rebuild_reloc_section(elf, sec->reloc)) {
+                               WARN_ELF("elf_rebuild_reloc_section");
+                               return -1;
+                       }
+
                        s = elf_getscn(elf->elf, sec->idx);
                        if (!s) {
                                WARN_ELF("elf_getscn");
@@ -969,6 +965,7 @@ int elf_write(struct elf *elf)
                        }
 
                        sec->changed = false;
+                       elf->changed = true;
                }
        }
 
diff --git a/tools/objtool/include/objtool/elf.h 
b/tools/objtool/include/objtool/elf.h
index 9fdd4c5f9f32..e6890cc70a25 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -39,7 +39,7 @@ struct section {
        char *name;
        int idx;
        unsigned int len;
-       bool changed, text, rodata, noinstr, rereloc;
+       bool changed, text, rodata, noinstr;
 };
 
 struct symbol {

Reply via email to