lkml.org 
[lkml]   [2022]   [Sep]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH v3 30/59] objtool: Add .call_sites section
    From: Peter Zijlstra <peterz@infradead.org>

    In preparation for call depth tracking provide a section which collects all
    direct calls.

    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    ---
    arch/x86/kernel/vmlinux.lds.S | 7 ++++
    tools/objtool/check.c | 51 ++++++++++++++++++++++++++++++++
    tools/objtool/include/objtool/objtool.h | 1
    tools/objtool/objtool.c | 1
    4 files changed, 60 insertions(+)

    --- a/arch/x86/kernel/vmlinux.lds.S
    +++ b/arch/x86/kernel/vmlinux.lds.S
    @@ -291,6 +291,13 @@ SECTIONS
    *(.return_sites)
    __return_sites_end = .;
    }
    +
    + . = ALIGN(8);
    + .call_sites : AT(ADDR(.call_sites) - LOAD_OFFSET) {
    + __call_sites = .;
    + *(.call_sites)
    + __call_sites_end = .;
    + }
    #endif

    #ifdef CONFIG_X86_KERNEL_IBT
    --- a/tools/objtool/check.c
    +++ b/tools/objtool/check.c
    @@ -898,6 +898,49 @@ static int create_mcount_loc_sections(st
    return 0;
    }

    +static int create_direct_call_sections(struct objtool_file *file)
    +{
    + struct instruction *insn;
    + struct section *sec;
    + unsigned int *loc;
    + int idx;
    +
    + sec = find_section_by_name(file->elf, ".call_sites");
    + if (sec) {
    + INIT_LIST_HEAD(&file->call_list);
    + WARN("file already has .call_sites section, skipping");
    + return 0;
    + }
    +
    + if (list_empty(&file->call_list))
    + return 0;
    +
    + idx = 0;
    + list_for_each_entry(insn, &file->call_list, call_node)
    + idx++;
    +
    + sec = elf_create_section(file->elf, ".call_sites", 0, sizeof(unsigned int), idx);
    + if (!sec)
    + return -1;
    +
    + idx = 0;
    + list_for_each_entry(insn, &file->call_list, call_node) {
    +
    + loc = (unsigned int *)sec->data->d_buf + idx;
    + memset(loc, 0, sizeof(unsigned int));
    +
    + if (elf_add_reloc_to_insn(file->elf, sec,
    + idx * sizeof(unsigned int),
    + R_X86_64_PC32,
    + insn->sec, insn->offset))
    + return -1;
    +
    + idx++;
    + }
    +
    + return 0;
    +}
    +
    /*
    * Warnings shouldn't be reported for ignored functions.
    */
    @@ -1252,6 +1295,9 @@ static void annotate_call_site(struct ob
    return;
    }

    + if (insn->type == INSN_CALL && !insn->sec->init)
    + list_add_tail(&insn->call_node, &file->call_list);
    +
    if (!sibling && dead_end_function(file, sym))
    insn->dead_end = true;
    }
    @@ -4274,6 +4320,11 @@ int check(struct objtool_file *file)
    if (ret < 0)
    goto out;
    warnings += ret;
    +
    + ret = create_direct_call_sections(file);
    + if (ret < 0)
    + goto out;
    + warnings += ret;
    }

    if (opts.mcount) {
    --- a/tools/objtool/include/objtool/objtool.h
    +++ b/tools/objtool/include/objtool/objtool.h
    @@ -28,6 +28,7 @@ struct objtool_file {
    struct list_head static_call_list;
    struct list_head mcount_loc_list;
    struct list_head endbr_list;
    + struct list_head call_list;
    bool ignore_unreachables, hints, rodata;

    unsigned int nr_endbr;
    --- a/tools/objtool/objtool.c
    +++ b/tools/objtool/objtool.c
    @@ -106,6 +106,7 @@ struct objtool_file *objtool_open_read(c
    INIT_LIST_HEAD(&file.static_call_list);
    INIT_LIST_HEAD(&file.mcount_loc_list);
    INIT_LIST_HEAD(&file.endbr_list);
    + INIT_LIST_HEAD(&file.call_list);
    file.ignore_unreachables = opts.no_unreachable;
    file.hints = false;


    \
     
     \ /
      Last update: 2022-09-15 13:45    [W:4.036 / U:0.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site