2021-02-19 21:12:25

by Peter Zijlstra

[permalink] [raw]
Subject: [RFC][PATCH 3/6] 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) <[email protected]>
---
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;
}