Messages in this thread Patch in this message | | | From | Julien Thierry <> | Subject | [PATCH 4/4] objtool: orc_gen: Move orc_entry out of instruction structure | Date | Thu, 4 Jun 2020 17:39:38 +0100 |
| |
One orc_entry is associated with each instruction in the object file, but having the orc_entry contained by the instruction structure forces architectures not implementing the orc subcommands to provide a dummy definition of the orc_entry.
Avoid that by having orc_entries in a separate list, part of the objtool_file.
Signed-off-by: Julien Thierry <jthierry@redhat.com> --- tools/objtool/check.h | 1 - tools/objtool/objtool.c | 1 + tools/objtool/objtool.h | 1 + tools/objtool/orc_gen.c | 83 +++++++++++++++++++++++------------------ 4 files changed, 49 insertions(+), 37 deletions(-)
diff --git a/tools/objtool/check.h b/tools/objtool/check.h index 906b5210f7ca..49f9a5cc4228 100644 --- a/tools/objtool/check.h +++ b/tools/objtool/check.h @@ -42,7 +42,6 @@ struct instruction { struct symbol *func; struct list_head stack_ops; struct cfi_state cfi; - struct orc_entry orc; }; struct instruction *find_insn(struct objtool_file *file, diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c index 71c4122cf491..4b2e8013edb8 100644 --- a/tools/objtool/objtool.c +++ b/tools/objtool/objtool.c @@ -61,6 +61,7 @@ struct objtool_file *objtool_setup_file(const char *_objname, bool writable) INIT_LIST_HEAD(&file.insn_list); hash_init(file.insn_hash); + INIT_LIST_HEAD(&file.orc_data_list); file.c_file = find_section_by_name(file.elf, ".comment"); file.ignore_unreachables = no_unreachable; file.hints = false; diff --git a/tools/objtool/objtool.h b/tools/objtool/objtool.h index be526f3d294d..e782c4206cb2 100644 --- a/tools/objtool/objtool.h +++ b/tools/objtool/objtool.h @@ -16,6 +16,7 @@ struct objtool_file { struct elf *elf; struct list_head insn_list; DECLARE_HASHTABLE(insn_hash, 20); + struct list_head orc_data_list; bool ignore_unreachables, c_file, hints, rodata; }; diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c index e74578640705..b8d199682530 100644 --- a/tools/objtool/orc_gen.c +++ b/tools/objtool/orc_gen.c @@ -9,14 +9,32 @@ #include "check.h" #include "warn.h" +struct orc_data { + struct list_head list; + struct instruction *insn; + struct orc_entry orc; +}; + int create_orc(struct objtool_file *file) { struct instruction *insn; for_each_insn(file, insn) { - struct orc_entry *orc = &insn->orc; struct cfi_reg *cfa = &insn->cfi.cfa; struct cfi_reg *bp = &insn->cfi.regs[CFI_BP]; + struct orc_entry *orc; + struct orc_data *od; + + if (!insn->sec->text) + continue; + + od = calloc(1, sizeof(*od)); + if (!od) + return -1; + od->insn = insn; + list_add_tail(&od->list, &file->orc_data_list); + + orc = &od->orc; if (!insn->sec->text) continue; @@ -139,7 +157,7 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti int create_orc_sections(struct objtool_file *file) { - struct instruction *insn, *prev_insn; + struct orc_data *od, *prev_od; struct section *sec, *u_sec, *ip_relasec; unsigned int idx; @@ -157,23 +175,21 @@ int create_orc_sections(struct objtool_file *file) /* count the number of needed orcs */ idx = 0; - for_each_sec(file, sec) { - if (!sec->text) - continue; - - prev_insn = NULL; - sec_for_each_insn(file, sec, insn) { - if (!prev_insn || - memcmp(&insn->orc, &prev_insn->orc, - sizeof(struct orc_entry))) { - idx++; - } - prev_insn = insn; + prev_od = NULL; + list_for_each_entry(od, &file->orc_data_list, list) { + if (!prev_od || + memcmp(&od->orc, &prev_od->orc, sizeof(struct orc_entry))) { + idx++; } + prev_od = od; + /* section terminator */ - if (prev_insn) + if (list_is_last(&od->insn->list, &file->insn_list) || + list_next_entry(od->insn, list)->sec != od->insn->sec) { + prev_od = NULL; idx++; + } } if (!idx) return -1; @@ -194,33 +210,28 @@ int create_orc_sections(struct objtool_file *file) /* populate sections */ idx = 0; - for_each_sec(file, sec) { - if (!sec->text) - continue; - - prev_insn = NULL; - sec_for_each_insn(file, sec, insn) { - if (!prev_insn || memcmp(&insn->orc, &prev_insn->orc, - sizeof(struct orc_entry))) { - - if (create_orc_entry(file->elf, u_sec, ip_relasec, idx, - insn->sec, insn->offset, - &insn->orc)) - return -1; - - idx++; - } - prev_insn = insn; + prev_od = NULL; + list_for_each_entry(od, &file->orc_data_list, list) { + if (!prev_od || + memcmp(&od->orc, &prev_od->orc, sizeof(struct orc_entry))) { + if (create_orc_entry(file->elf, u_sec, ip_relasec, idx, + od->insn->sec, od->insn->offset, + &od->orc)) + return -1; + idx++; } + prev_od = od; + /* section terminator */ - if (prev_insn) { + if (list_is_last(&od->insn->list, &file->insn_list) || + list_next_entry(od->insn, list)->sec != od->insn->sec) { if (create_orc_entry(file->elf, u_sec, ip_relasec, idx, - prev_insn->sec, - prev_insn->offset + prev_insn->len, + prev_od->insn->sec, + prev_od->insn->offset + prev_od->insn->len, &empty)) return -1; - + prev_od = NULL; idx++; } } -- 2.21.1
| |