zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    深入理解Java容器——HashMap
    深入理解Java并发容器——ConcurrentHashMap
    String、StringBuilder和StringBuffer的比较
    接口类、抽象类和普通类的区别
    跟我一起学算法——二项堆
    跟我一起学算法——分治法
    跟我一起学算法——动态规划
    跟我一起学算法——斐波那契堆
    Redis操作三部曲:SpringBoot2.0.X集成Redis + Redis分布式锁 + RedisCacheManager配置
    SpringBoot使用Redis做集中式缓存
  • 原文地址:https://www.cnblogs.com/aspirs/p/15526339.html
Copyright © 2011-2022 走看看