The following commit has been merged into the x86/core branch of tip:

Commit-ID:     98ce4d014ad4c1c4afcc427fc3f0002674315cb9
Gitweb:        
https://git.kernel.org/tip/98ce4d014ad4c1c4afcc427fc3f0002674315cb9
Author:        Peter Zijlstra <pet...@infradead.org>
AuthorDate:    Fri, 26 Mar 2021 16:12:06 +01:00
Committer:     Borislav Petkov <b...@suse.de>
CommitterDate: Thu, 01 Apr 2021 12:51:35 +02:00

objtool: Rework rebuild_reloc logic

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>
Signed-off-by: Borislav Petkov <b...@suse.de>
Reviewed-by: Miroslav Benes <mbe...@suse.cz>
Link: https://lkml.kernel.org/r/20210326151259.754213...@infradead.org
---
 tools/objtool/check.c               |  6 ------
 tools/objtool/elf.c                 | 20 ++++++++++++++------
 tools/objtool/include/objtool/elf.h |  1 -
 tools/objtool/orc_gen.c             |  3 ---
 4 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 8618d03..1d0415b 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -542,9 +542,6 @@ static int create_static_call_sections(struct objtool_file 
*file)
                idx++;
        }
 
-       if (elf_rebuild_reloc_section(file->elf, reloc_sec))
-               return -1;
-
        return 0;
 }
 
@@ -614,9 +611,6 @@ static int create_mcount_loc_sections(struct objtool_file 
*file)
                idx++;
        }
 
-       if (elf_rebuild_reloc_section(file->elf, reloc_sec))
-               return -1;
-
        return 0;
 }
 
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 93fa833..374813e 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -479,6 +479,8 @@ 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->changed = 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);
@@ -873,14 +877,11 @@ static int elf_rebuild_rela_reloc_section(struct section 
*sec, int nr)
        return 0;
 }
 
-int elf_rebuild_reloc_section(struct elf *elf, struct section *sec)
+static 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++;
@@ -944,9 +945,15 @@ int elf_write(struct elf *elf)
        struct section *sec;
        Elf_Scn *s;
 
-       /* 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->base &&
+                           elf_rebuild_reloc_section(elf, sec)) {
+                               WARN("elf_rebuild_reloc_section");
+                               return -1;
+                       }
+
                        s = elf_getscn(elf->elf, sec->idx);
                        if (!s) {
                                WARN_ELF("elf_getscn");
@@ -958,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 e6890cc..fc576ed 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -142,7 +142,6 @@ struct reloc *find_reloc_by_dest_range(const struct elf 
*elf, struct section *se
 struct symbol *find_func_containing(struct section *sec, unsigned long offset);
 void insn_to_reloc_sym_addend(struct section *sec, unsigned long offset,
                              struct reloc *reloc);
-int elf_rebuild_reloc_section(struct elf *elf, struct section *sec);
 
 #define for_each_sec(file, sec)                                                
\
        list_for_each_entry(sec, &file->elf->sections, list)
diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c
index 738aa50..f534708 100644
--- 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