示例#1
0
文件: module.c 项目: 274914765/C
int
module_frob_arch_sections(Elf64_Ehdr *hdr, Elf64_Shdr *sechdrs,
              char *secstrings, struct module *me)
{
    struct got_entry *chains;
    Elf64_Rela *rela;
    Elf64_Shdr *esechdrs, *symtab, *s, *got;
    unsigned long nsyms, nrela, i;

    esechdrs = sechdrs + hdr->e_shnum;
    symtab = got = NULL;

    /* Find out how large the symbol table is.  Allocate one got_entry
       head per symbol.  Normally this will be enough, but not always.
       We'll chain different offsets for the symbol down each head.  */
    for (s = sechdrs; s < esechdrs; ++s)
        if (s->sh_type == SHT_SYMTAB)
            symtab = s;
        else if (!strcmp(".got", secstrings + s->sh_name)) {
            got = s;
            me->arch.gotsecindex = s - sechdrs;
        }

    if (!symtab) {
        printk(KERN_ERR "module %s: no symbol table\n", me->name);
        return -ENOEXEC;
    }
    if (!got) {
        printk(KERN_ERR "module %s: no got section\n", me->name);
        return -ENOEXEC;
    }

    nsyms = symtab->sh_size / sizeof(Elf64_Sym);
    chains = kcalloc(nsyms, sizeof(struct got_entry), GFP_KERNEL);
    if (!chains) {
        printk(KERN_ERR
               "module %s: no memory for symbol chain buffer\n",
               me->name);
        return -ENOMEM;
    }

    got->sh_size = 0;
    got->sh_addralign = 8;
    got->sh_type = SHT_NOBITS;

    /* Examine all LITERAL relocations to find out what GOT entries
       are required.  This sizes the GOT section as well.  */
    for (s = sechdrs; s < esechdrs; ++s)
        if (s->sh_type == SHT_RELA) {
            nrela = s->sh_size / sizeof(Elf64_Rela);
            rela = (void *)hdr + s->sh_offset;
            for (i = 0; i < nrela; ++i)
                process_reloc_for_got(rela+i, chains,
                              &got->sh_size);
        }

    /* Free the memory we allocated.  */
    for (i = 0; i < nsyms; ++i) {
        struct got_entry *g, *n;
        for (g = chains[i].next; g ; g = n) {
            n = g->next;
            kfree(g);
        }
    }
    kfree(chains);

    return 0;
}
示例#2
0
int
module_frob_arch_sections(Elf64_Ehdr *hdr, Elf64_Shdr *sechdrs,
			  char *secstrings, struct module *me)
{
	struct got_entry *chains;
	Elf64_Rela *rela;
	Elf64_Shdr *esechdrs, *symtab, *s, *got;
	unsigned long nsyms, nrela, i;

	esechdrs = sechdrs + hdr->e_shnum;
	symtab = got = NULL;

	for (s = sechdrs; s < esechdrs; ++s)
		if (s->sh_type == SHT_SYMTAB)
			symtab = s;
		else if (!strcmp(".got", secstrings + s->sh_name)) {
			got = s;
			me->arch.gotsecindex = s - sechdrs;
		}

	if (!symtab) {
		printk(KERN_ERR "module %s: no symbol table\n", me->name);
		return -ENOEXEC;
	}
	if (!got) {
		printk(KERN_ERR "module %s: no got section\n", me->name);
		return -ENOEXEC;
	}

	nsyms = symtab->sh_size / sizeof(Elf64_Sym);
	chains = kcalloc(nsyms, sizeof(struct got_entry), GFP_KERNEL);
	if (!chains) {
		printk(KERN_ERR
		       "module %s: no memory for symbol chain buffer\n",
		       me->name);
		return -ENOMEM;
	}

	got->sh_size = 0;
	got->sh_addralign = 8;
	got->sh_type = SHT_NOBITS;

	for (s = sechdrs; s < esechdrs; ++s)
		if (s->sh_type == SHT_RELA) {
			nrela = s->sh_size / sizeof(Elf64_Rela);
			rela = (void *)hdr + s->sh_offset;
			for (i = 0; i < nrela; ++i)
				process_reloc_for_got(rela+i, chains,
						      &got->sh_size);
		}

	
	for (i = 0; i < nsyms; ++i) {
		struct got_entry *g, *n;
		for (g = chains[i].next; g ; g = n) {
			n = g->next;
			kfree(g);
		}
	}
	kfree(chains);

	return 0;
}