ko kallsyms

ko kallsyms

在layout_symtab()里确认哪些symbol(symbol包括函数与变量)是属于core_layout里的,将这些属于core_layout的symbol的string长度累加起来,然后会将这个累加长度加到core_layout.size,到时也给它分配内存空间。

static void layout_symtab(struct module *mod, struct load_info *info)
{
    Elf_Shdr *symsect = info->sechdrs + info->index.sym;
    Elf_Shdr *strsect = info->sechdrs + info->index.str;
    const Elf_Sym *src;
    unsigned int i, nsrc, ndst, strtab_size = 0;

    /* Put symbol section at end of init part of module. */
    symsect->sh_flags |= SHF_ALLOC;
    symsect->sh_entsize = get_offset(mod, &mod->init_layout.size, symsect,
                     info->index.sym) | INIT_OFFSET_MASK;
    pr_debug("	%s
", info->secstrings + symsect->sh_name);

    src = (void *)info->hdr + symsect->sh_offset;
    nsrc = symsect->sh_size / sizeof(*src);

    /* Compute total space required for the core symbols' strtab. */
    for (ndst = i = 0; i < nsrc; i++) {
        if (i == 0 || is_livepatch_module(mod) ||
            is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum,
                   info->index.pcpu)) {
            strtab_size += strlen(&info->strtab[src[i].st_name])+1;
            ndst++;
        }
    }

    /* Append room for core symbols at end of core part. */
    info->symoffs = ALIGN(mod->core_layout.size, symsect->sh_addralign ?: 1);
    info->stroffs = mod->core_layout.size = info->symoffs + ndst * sizeof(Elf_Sym);
    mod->core_layout.size += strtab_size;
    mod->core_layout.size = debug_align(mod->core_layout.size);

    /* Put string table section at end of init part of module. */
    strsect->sh_flags |= SHF_ALLOC;
    strsect->sh_entsize = get_offset(mod, &mod->init_layout.size, strsect,
                     info->index.str) | INIT_OFFSET_MASK;
    pr_debug("	%s
", info->secstrings + strsect->sh_name);

    /* We'll tack temporary mod_kallsyms on the end. */
    mod->init_layout.size = ALIGN(mod->init_layout.size,
                      __alignof__(struct mod_kallsyms));
    info->mod_kallsyms_init_off = mod->init_layout.size;
    mod->init_layout.size += sizeof(struct mod_kallsyms);
    mod->init_layout.size = debug_align(mod->init_layout.size);
}

 其中,如果CONFIG_KALLSYMS_ALL没有define时,变量将不会加到core_layout,只有函数会加到core_layout,为什么呢,请看如下函数,变量是不会有SHF_EXECINSTR flag的,只有函数才会有此flag,此flag表示可执行,当此config没有define时,is_core_symbol()将返回false:

static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs,
            unsigned int shnum, unsigned int pcpundx)
{
    const Elf_Shdr *sec;

    if (src->st_shndx == SHN_UNDEF
        || src->st_shndx >= shnum
        || !src->st_name)
        return false;

#ifdef CONFIG_KALLSYMS_ALL
    if (src->st_shndx == pcpundx)
        return true;
#endif

    sec = sechdrs + src->st_shndx;
    if (!(sec->sh_flags & SHF_ALLOC)
#ifndef CONFIG_KALLSYMS_ALL
        || !(sec->sh_flags & SHF_EXECINSTR)
#endif
        || (sec->sh_entsize & INIT_OFFSET_MASK))
        return false;

    return true;
}

将属于core_layout的symbol的name string拷贝至core_layout:

static void add_kallsyms(struct module *mod, const struct load_info *info)
{
    unsigned int i, ndst;
    const Elf_Sym *src;
    Elf_Sym *dst;
    char *s;
    Elf_Shdr *symsec = &info->sechdrs[info->index.sym];

    /* Set up to point into init section. */
    mod->kallsyms = mod->init_layout.base + info->mod_kallsyms_init_off;

    mod->kallsyms->symtab = (void *)symsec->sh_addr;
    mod->kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
    /* Make sure we get permanent strtab: don't use info->strtab. */
    mod->kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr;

    /* Set types up while we still have access to sections. */
    for (i = 0; i < mod->kallsyms->num_symtab; i++)
        mod->kallsyms->symtab[i].st_info
            = elf_type(&mod->kallsyms->symtab[i], info);

    /* Now populate the cut down core kallsyms for after init. */
    mod->core_kallsyms.symtab = dst = mod->core_layout.base + info->symoffs;
    mod->core_kallsyms.strtab = s = mod->core_layout.base + info->stroffs;
    src = mod->kallsyms->symtab;
    for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) {
        if (i == 0 || is_livepatch_module(mod) ||
            is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum,
                   info->index.pcpu)) {
            dst[ndst] = src[i];
            dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
            s += strlcpy(s, &mod->kallsyms->strtab[src[i].st_name],
                     KSYM_NAME_LEN) + 1;
        }
    }
    mod->core_kallsyms.num_symtab = ndst;
}
原文地址:https://www.cnblogs.com/aspirs/p/15526339.html