lkml.org 
[lkml]   [2020]   [Jul]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH v6 10/17] x86/static_call: Add inline static call implementation for x86-64
    On Fri, 10 Jul 2020 15:38:41 +0200
    Peter Zijlstra <peterz@infradead.org> wrote:
    > --- a/tools/objtool/check.c
    > +++ b/tools/objtool/check.c
    > @@ -16,6 +16,7 @@
    >
    > #include <linux/hashtable.h>
    > #include <linux/kernel.h>
    > +#include <linux/static_call_types.h>
    >
    > #define FAKE_JUMP_OFFSET -1
    >
    > @@ -433,6 +434,99 @@ static int add_dead_ends(struct objtool_
    > return 0;
    > }
    >
    > +static int create_static_call_sections(struct objtool_file *file)
    > +{
    > + struct section *sec, *reloc_sec;
    > + struct reloc *reloc;
    > + struct static_call_site *site;
    > + struct instruction *insn;
    > + struct symbol *key_sym;
    > + char *key_name, *tmp;
    > + int idx;
    > +
    > + sec = find_section_by_name(file->elf, ".static_call_sites");
    > + if (sec) {
    > + INIT_LIST_HEAD(&file->static_call_list);
    > + WARN("file already has .static_call_sites section, skipping");
    > + return 0;
    > + }
    > +
    > + if (list_empty(&file->static_call_list))
    > + return 0;
    > +
    > + idx = 0;
    > + list_for_each_entry(insn, &file->static_call_list, static_call_node)
    > + idx++;
    > +
    > + sec = elf_create_section(file->elf, ".static_call_sites", SHF_WRITE,
    > + sizeof(struct static_call_site), idx);
    > + if (!sec)
    > + return -1;
    > +
    > + reloc_sec = elf_create_reloc_section(file->elf, sec, SHT_RELA);
    > + if (!reloc_sec)
    > + return -1;
    > +
    > + idx = 0;
    > + list_for_each_entry(insn, &file->static_call_list, static_call_node) {
    > +
    > + site = (struct static_call_site *)sec->data->d_buf + idx;
    > + memset(site, 0, sizeof(struct static_call_site));
    > +
    > + /* populate reloc for 'addr' */
    > + reloc = malloc(sizeof(*reloc));
    > + if (!reloc) {
    > + perror("malloc");
    > + return -1;
    > + }
    > + memset(reloc, 0, sizeof(*reloc));
    > + reloc->sym = insn->sec->sym;
    > + reloc->addend = insn->offset;
    > + reloc->type = R_X86_64_PC32;
    > + reloc->offset = idx * sizeof(struct static_call_site);
    > + reloc->sec = reloc_sec;
    > + elf_add_reloc(file->elf, reloc);
    > +
    > + /* find key symbol */
    > + key_name = strdup(insn->call_dest->name);

    Should check for failed allocation of strdup().

    > + if (strncmp(key_name, STATIC_CALL_TRAMP_PREFIX_STR,
    > + strlen(STATIC_CALL_TRAMP_PREFIX_STR))) {
    > + WARN("static_call: trampoline name malformed: %s", key_name);
    > + return -1;
    > + }
    > + tmp = key_name + STATIC_CALL_TRAMP_PREFIX_LEN - STATIC_CALL_KEY_PREFIX_LEN;
    > + memcpy(tmp, STATIC_CALL_KEY_PREFIX_STR, STATIC_CALL_KEY_PREFIX_LEN);
    > +
    > + key_sym = find_symbol_by_name(file->elf, tmp);
    > + if (!key_sym) {
    > + WARN("static_call: can't find static_call_key symbol: %s", tmp);
    > + return -1;
    > + }
    > + free(key_name);
    > +
    > + /* populate reloc for 'key' */
    > + reloc = malloc(sizeof(*reloc));
    > + if (!reloc) {
    > + perror("malloc");
    > + return -1;
    > + }
    > + memset(reloc, 0, sizeof(*reloc));
    > + reloc->sym = key_sym;
    > + reloc->addend = 0;
    > + reloc->type = R_X86_64_PC32;

    How easy would this be for other architectures to implement this? That
    is how much of this function is x86 specific?


    -- Steve

    > + reloc->offset = idx * sizeof(struct static_call_site) + 4;
    > + reloc->sec = reloc_sec;
    > + elf_add_reloc(file->elf, reloc);
    > +
    > + idx++;
    > + }
    > +
    > + if (elf_rebuild_reloc_section(file->elf, reloc_sec))
    > + return -1;
    > +
    > + return 0;
    > +}
    > +

    \
     
     \ /
      Last update: 2020-07-11 00:32    [W:3.628 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site