Instead of manually calling elf_rebuild_reloc_section() on sections
we've called elf_add_reloc() on, have elf_write() DTRT.

This makes it easier to add random relocations in places without
carefully tracking when we're done and need to flush what section.

Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org>
---
 tools/objtool/check.c               |    3 ---
 tools/objtool/elf.c                 |   13 ++++++++++++-
 tools/objtool/include/objtool/elf.h |    2 +-
 tools/objtool/orc_gen.c             |    3 ---
 4 files changed, 13 insertions(+), 8 deletions(-)

--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -542,9 +542,6 @@ static int create_static_call_sections(s
                idx++;
        }
 
-       if (elf_rebuild_reloc_section(file->elf, reloc_sec))
-               return -1;
-
        return 0;
 }
 
--- 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;
 }
 
 static int read_rel_reloc(struct section *sec, int i, struct reloc *reloc, 
unsigned int *symndx)
@@ -558,7 +560,9 @@ static int read_relocs(struct elf *elf)
                                return -1;
                        }
 
-                       elf_add_reloc(elf, reloc);
+                       list_add_tail(&reloc->list, &sec->reloc_list);
+                       elf_hash_add(elf->reloc_hash, &reloc->hash, 
reloc_hash(reloc));
+
                        nr_reloc++;
                }
                max_reloc = max(max_reloc, nr_reloc);
@@ -890,6 +894,8 @@ int elf_rebuild_reloc_section(struct elf
        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,
@@ -944,6 +950,11 @@ 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: */
        list_for_each_entry(sec, &elf->sections, list) {
                if (sec->changed) {
--- 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;
+       bool changed, text, rodata, noinstr, rereloc;
 };
 
 struct symbol {
--- a/tools/objtool/orc_gen.c
+++ b/tools/objtool/orc_gen.c
@@ -254,8 +254,5 @@ int orc_create(struct objtool_file *file
                        return -1;
        }
 
-       if (elf_rebuild_reloc_section(file->elf, ip_rsec))
-               return -1;
-
        return 0;
 }


Reply via email to