예제 #1
0
static int
relocate_file(linker_file_t lf)
{
    elf_file_t ef = lf->priv;
    const Elf_Rel *rellim;
    const Elf_Rel *rel;
    const Elf_Rela *relalim;
    const Elf_Rela *rela;
    const char *symname;

    /* Perform relocations without addend if there are any: */
    rel = ef->rel;
    if (rel) {
	rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize);
	while (rel < rellim) {
	    if (elf_reloc(lf, (Elf_Addr)ef->address, rel, ELF_RELOC_REL, elf_lookup)) {
		symname = symbol_name(ef, rel->r_info);
		kprintf("link_elf: symbol %s undefined\n", symname);
		return ENOENT;
	    }
	    rel++;
	}
    }

    /* Perform relocations with addend if there are any: */
    rela = ef->rela;
    if (rela) {
	relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize);
	while (rela < relalim) {
	    if (elf_reloc(lf, (Elf_Addr)ef->address, rela, ELF_RELOC_RELA, elf_lookup)) {
		symname = symbol_name(ef, rela->r_info);
		kprintf("link_elf: symbol %s undefined\n", symname);
		return ENOENT;
	    }
	    rela++;
	}
    }

    /* Perform PLT relocations without addend if there are any: */
    rel = ef->pltrel;
    if (rel) {
	rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize);
	while (rel < rellim) {
	    if (elf_reloc(lf, (Elf_Addr)ef->address, rel, ELF_RELOC_REL, elf_lookup)) {
		symname = symbol_name(ef, rel->r_info);
		kprintf("link_elf: symbol %s undefined\n", symname);
		return ENOENT;
	    }
	    rel++;
	}
    }

    /* Perform relocations with addend if there are any: */
    rela = ef->pltrela;
    if (rela) {
	relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize);
	while (rela < relalim) {
	    symname = symbol_name(ef, rela->r_info);
	    if (elf_reloc(lf, (Elf_Addr)ef->address, rela, ELF_RELOC_RELA, elf_lookup)) {
		kprintf("link_elf: symbol %s undefined\n", symname);
		return ENOENT;
	    }
	    rela++;
	}
    }

    return 0;
}
예제 #2
0
static int
relocate_file(elf_file_t ef)
{
	const Elf_Rel *rellim;
	const Elf_Rel *rel;
	const Elf_Rela *relalim;
	const Elf_Rela *rela;
	const char *symname;
	const Elf_Sym *sym;
	int i;
	Elf_Size symidx;
	Elf_Addr base;


	/* Perform relocations without addend if there are any: */
	for (i = 0; i < ef->nreltab; i++) {
		rel = ef->reltab[i].rel;
		if (rel == NULL)
			panic("lost a reltab!");
		rellim = rel + ef->reltab[i].nrel;
		base = findbase(ef, ef->reltab[i].sec);
		if (base == 0)
			panic("lost base for reltab");
		for ( ; rel < rellim; rel++) {
			symidx = ELF_R_SYM(rel->r_info);
			if (symidx >= ef->ddbsymcnt)
				continue;
			sym = ef->ddbsymtab + symidx;
			/* Local relocs are already done */
			if (ELF_ST_BIND(sym->st_info) == STB_LOCAL)
				continue;
			if (elf_reloc(&ef->lf, base, rel, ELF_RELOC_REL,
			    elf_obj_lookup)) {
				symname = symbol_name(ef, rel->r_info);
				printf("link_elf_obj: symbol %s undefined\n",
				    symname);
				return ENOENT;
			}
		}
	}

	/* Perform relocations with addend if there are any: */
	for (i = 0; i < ef->nrelatab; i++) {
		rela = ef->relatab[i].rela;
		if (rela == NULL)
			panic("lost a relatab!");
		relalim = rela + ef->relatab[i].nrela;
		base = findbase(ef, ef->relatab[i].sec);
		if (base == 0)
			panic("lost base for relatab");
		for ( ; rela < relalim; rela++) {
			symidx = ELF_R_SYM(rela->r_info);
			if (symidx >= ef->ddbsymcnt)
				continue;
			sym = ef->ddbsymtab + symidx;
			/* Local relocs are already done */
			if (ELF_ST_BIND(sym->st_info) == STB_LOCAL)
				continue;
			if (elf_reloc(&ef->lf, base, rela, ELF_RELOC_RELA,
			    elf_obj_lookup)) {
				symname = symbol_name(ef, rela->r_info);
				printf("link_elf_obj: symbol %s undefined\n",
				    symname);
				return ENOENT;
			}
		}
	}

	/*
	 * Only clean SHN_FBSD_CACHED for successfull return.  If we
	 * modified symbol table for the object but found an
	 * unresolved symbol, there is no reason to roll back.
	 */
	elf_obj_cleanup_globals_cache(ef);

	return 0;
}
예제 #3
0
static int
relocate_file(linker_file_t lf)
{
	elf_file_t	ef = lf->priv;
	const Elf_Rel *rellim;
	const Elf_Rel *rel;
	const Elf_Rela *relalim;
	const Elf_Rela *rela;
	const char *symname;
	const Elf_Sym *sym;
	int i;
	Elf_Size symidx;
	Elf_Addr base;

	/* Perform relocations without addend if there are any: */
	for (i = 0; i < ef->nreltab; i++) {
		rel = ef->reltab[i].rel;
		if (rel == NULL)
			panic("lost a reltab!");
		rellim = rel + ef->reltab[i].nrel;
		base = findbase(ef, ef->reltab[i].sec);
		if (base == 0)
			panic("lost base for reltab");
		for ( ; rel < rellim; rel++) {
			symidx = ELF_R_SYM(rel->r_info);
			if (symidx >= ef->ddbsymcnt)
				continue;
			sym = ef->ddbsymtab + symidx;
			/* Local relocs are already done */
			if (ELF_ST_BIND(sym->st_info) == STB_LOCAL)
				continue;
			if (elf_reloc(lf, base, rel, ELF_RELOC_REL,
			    elf_obj_lookup)) {
				symname = symbol_name(ef, rel->r_info);
				kprintf("link_elf_obj_obj: symbol %s undefined\n",
				    symname);
				return ENOENT;
			}
		}
	}

	/* Perform relocations with addend if there are any: */
	for (i = 0; i < ef->nrelatab; i++) {
		rela = ef->relatab[i].rela;
		if (rela == NULL)
			panic("lost a relatab!");
		relalim = rela + ef->relatab[i].nrela;
		base = findbase(ef, ef->relatab[i].sec);
		if (base == 0)
			panic("lost base for relatab");
		for ( ; rela < relalim; rela++) {
			symidx = ELF_R_SYM(rela->r_info);
			if (symidx >= ef->ddbsymcnt)
				continue;
			sym = ef->ddbsymtab + symidx;
			/* Local relocs are already done */
			if (ELF_ST_BIND(sym->st_info) == STB_LOCAL)
				continue;
			if (elf_reloc(lf, base, rela, ELF_RELOC_RELA,
			    elf_obj_lookup)) {
				symname = symbol_name(ef, rela->r_info);
				kprintf("link_elf_obj_obj: symbol %s undefined\n",
				    symname);
				return ENOENT;
			}
		}
	}

	return 0;
}