Exemple #1
0
int
kobj_boot_mountroot()
{
	int i;

	if (BOP_GETPROPLEN(ops, "ramdisk_start") != 8 ||
	    BOP_GETPROP(ops, "ramdisk_start", (void *)&rd_start) != 0 ||
	    BOP_GETPROPLEN(ops, "ramdisk_end") != 8 ||
	    BOP_GETPROP(ops, "ramdisk_end", (void *)&rd_end) != 0) {
		_kobj_printf(ops,
		    "failed to get ramdisk from boot\n");
		return (-1);
	}
#ifdef KOBJ_DEBUG
	_kobj_printf(ops,
	    "ramdisk range: 0x%llx-%llx\n", rd_start, rd_end);
#endif

	for (i = 0; bfs_tab[i] != NULL; i++) {
		bfs_ops = bfs_tab[i];
		if (BRD_MOUNTROOT(bfs_ops, "dummy") == 0)
			return (0);
	}
	_kobj_printf(ops, "failed to mount ramdisk from boot\n");
	return (-1);
}
Exemple #2
0
/*
 * This one reads the ramdisk. If fi_memp is set, we copy the
 * ramdisk content to the designated buffer. Otherwise, we
 * do a "cached" read (set fi_memp to the actual ramdisk buffer).
 */
int
diskread(fileid_t *filep)
{
	uint_t blocknum;
	caddr_t diskloc;

	/* add in offset of root slice */
	blocknum = filep->fi_blocknum;

	diskloc = (caddr_t)(uintptr_t)rd_start + blocknum * DEV_BSIZE;
	if (diskloc + filep->fi_count > (caddr_t)(uintptr_t)rd_end) {
		_kobj_printf(ops, "diskread: start = 0x%p, size = 0x%x\n",
		    diskloc, filep->fi_count);
		_kobj_printf(ops, "reading beyond end of ramdisk\n");
		return (-1);
	}

	if (filep->fi_memp) {
		bcopy(diskloc, filep->fi_memp, filep->fi_count);
	} else {
		/* "cached" read */
		filep->fi_memp = diskloc;
	}

	return (0);
}
void
kobj_lm_dump(int lmid)
{
	struct modctl_list *lp;

	for (lp = kobj_lm_lookup(lmid); lp; lp = lp->modl_next) {
		struct module *mp = lp->modl_modp->mod_mp;

		_kobj_printf(ops, "module %s: ", mp->filename);
		_kobj_printf(ops, "text at [0x%p, ", mp->text);
		_kobj_printf(ops, "0x%lx] ", (uintptr_t)mp->text +
		    mp->text_size - 1);
		_kobj_printf(ops, "data at 0x%p\n", mp->data);
	}
}
Exemple #4
0
/* ARGSUSED3 */
int
get_progbits_size(struct module *mp, struct proginfo *tp, struct proginfo *dp,
                  struct proginfo *sdp)
{
    struct proginfo *pp;
    uint_t shn;
    Shdr *shp;

    /*
     * loop through sections to find out how much space we need
     * for text, data, (also bss that is already assigned)
     */
    for (shn = 1; shn < mp->hdr.e_shnum; shn++) {
        shp = (Shdr *)(mp->shdrs + shn * mp->hdr.e_shentsize);
        if (!(shp->sh_flags & SHF_ALLOC))
            continue;
        if (shp->sh_addr != 0) {
            _kobj_printf(ops,
                         "%s non-zero sect addr in input file\n",
                         mp->filename);
            return (-1);
        }
        pp = (shp->sh_flags & SHF_WRITE)? dp : tp;

        if (shp->sh_addralign > pp->align)
            pp->align = shp->sh_addralign;
        pp->size = ALIGN(pp->size, shp->sh_addralign);
        pp->size += ALIGN(shp->sh_size, 8);
    }
    tp->size = ALIGN(tp->size, 8);
    dp->size = ALIGN(dp->size, 8);
    return (0);
}
Exemple #5
0
/*PRINTFLIKE1*/
void
kobj_printf(char *fmt, ...)
{
	va_list adx;

	va_start(adx, fmt);
	_kobj_printf(ops, fmt, adx);
	va_end(adx);
}
Exemple #6
0
void
kobj_boot_unmountroot()
{
#ifdef	DEBUG
	if (boothowto & RB_VERBOSE)
		_kobj_printf(ops, "boot scratch memory used: 0x%llx\n",
		    scratch_max);
#endif
	(void) BRD_UNMOUNTROOT(bfs_ops);
}
Exemple #7
0
int
do_relocations(struct module *mp)
{
	uint_t shn;
	Shdr *shp, *rshp;
	uint_t nreloc;

	/* do the relocations */
	for (shn = 1; shn < mp->hdr.e_shnum; shn++) {
		rshp = (Shdr *)
			(mp->shdrs + shn * mp->hdr.e_shentsize);
		if (rshp->sh_type == SHT_RELA) {
			_kobj_printf(ops, "%s can't process type SHT_RELA\n",
			    mp->filename);
			return (-1);
		}
		if (rshp->sh_type != SHT_REL)
			continue;
		if (rshp->sh_link != mp->symtbl_section) {
			_kobj_printf(ops, "%s reloc for non-default symtab\n",
			    mp->filename);
			return (-1);
		}
		if (rshp->sh_info >= mp->hdr.e_shnum) {
			_kobj_printf(ops, "do_relocations: %s sh_info ",
			    mp->filename);
			_kobj_printf(ops, "out of range %d\n", shn);
			goto bad;
		}
		nreloc = rshp->sh_size / rshp->sh_entsize;

		/* get the section header that this reloc table refers to */
		shp = (Shdr *)
		    (mp->shdrs + rshp->sh_info * mp->hdr.e_shentsize);

		/*
		 * Do not relocate any section that isn't loaded into memory.
		 * Most commonly this will skip over the .rela.stab* sections
		 */
		if (!(shp->sh_flags & SHF_ALLOC))
			continue;
#ifdef	KOBJ_DEBUG
		if (kobj_debug & D_RELOCATIONS) {
			_kobj_printf(ops, "krtld: relocating: file=%s ",
			    mp->filename);
			_kobj_printf(ops, "section=%d\n", shn);
		}
#endif

		if (do_relocate(mp, (char *)rshp->sh_addr, rshp->sh_type,
		    nreloc, rshp->sh_entsize, shp->sh_addr) < 0) {
			_kobj_printf(ops,
			    "do_relocations: %s do_relocate failed\n",
			    mp->filename);
			goto bad;
		}
		kobj_free((void *)rshp->sh_addr, rshp->sh_size);
		rshp->sh_addr = 0;
	}
	mp->flags |= KOBJ_RELOCATED;
	return (0);
bad:
	kobj_free((void *)rshp->sh_addr, rshp->sh_size);
	rshp->sh_addr = 0;
	return (-1);
}
Exemple #8
0
int
/* ARGSUSED2 */
do_relocate(struct module *mp, char *reltbl, Word relshtype, int nreloc,
	int relocsize, Addr baseaddr)
{
	unsigned long stndx;
	unsigned long off;	/* can't be register for tnf_reloc_resolve() */
	register unsigned long reladdr, rend;
	register unsigned int rtype;
	long value;
	Sym *symref;
	int err = 0;
	tnf_probe_control_t *probelist = NULL;
	tnf_tag_data_t *taglist = NULL;
	int symnum;

	reladdr = (unsigned long)reltbl;
	rend = reladdr + nreloc * relocsize;

#ifdef	KOBJ_DEBUG
	if (kobj_debug & D_RELOCATIONS) {
		_kobj_printf(ops, "krtld:\ttype\t\t\toffset      symbol\n");
		_kobj_printf(ops, "krtld:\t\t\t\t\t   value\n");
	}
#endif

	symnum = -1;
	/* loop through relocations */
	while (reladdr < rend) {
		symnum++;
		rtype = ELF32_R_TYPE(((Rel *)reladdr)->r_info);
		off = ((Rel *)reladdr)->r_offset;
		stndx = ELF32_R_SYM(((Rel *)reladdr)->r_info);
		if (stndx >= mp->nsyms) {
			_kobj_printf(ops, "do_relocate: bad strndx %d\n",
			    symnum);
			return (-1);
		}
		if ((rtype > R_386_NUM) || IS_TLS_INS(rtype)) {
			_kobj_printf(ops, "krtld: invalid relocation type %d",
			    rtype);
			_kobj_printf(ops, " at 0x%llx:", off);
			_kobj_printf(ops, " file=%s\n", mp->filename);
			err = 1;
			continue;
		}


		reladdr += relocsize;


		if (rtype == R_386_NONE)
			continue;

#ifdef	KOBJ_DEBUG
		if (kobj_debug & D_RELOCATIONS) {
			Sym *	symp;
			symp = (Sym *)
				(mp->symtbl+(stndx * mp->symhdr->sh_entsize));
			_kobj_printf(ops, "krtld:\t%s",
				conv_reloc_386_type(rtype));
			_kobj_printf(ops, "\t0x%8x", off);
			_kobj_printf(ops, "  %s\n",
			    (const char *)mp->strings + symp->st_name);
		}
#endif

		if (!(mp->flags & KOBJ_EXEC))
			off += baseaddr;

		/*
		 * if R_386_RELATIVE, simply add base addr
		 * to reloc location
		 */

		if (rtype == R_386_RELATIVE) {
			value = baseaddr;
		} else {
			/*
			 * get symbol table entry - if symbol is local
			 * value is base address of this object
			 */
			symref = (Sym *)
				(mp->symtbl+(stndx * mp->symhdr->sh_entsize));

			if (ELF32_ST_BIND(symref->st_info) == STB_LOCAL) {
				/* *** this is different for .o and .so */
				value = symref->st_value;
			} else {
				/*
				 * It's global. Allow weak references.  If
				 * the symbol is undefined, give TNF (the
				 * kernel probes facility) a chance to see
				 * if it's a probe site, and fix it up if so.
				 */
				if (symref->st_shndx == SHN_UNDEF &&
				    sdt_reloc_resolve(mp, mp->strings +
				    symref->st_name, (uint8_t *)off) == 0)
					continue;

				if (symref->st_shndx == SHN_UNDEF &&
				    tnf_reloc_resolve(mp->strings +
					symref->st_name, &symref->st_value,
					off,
					&probelist,
					&taglist) != 0) {
					if (ELF32_ST_BIND(symref->st_info)
					    != STB_WEAK) {
						_kobj_printf(ops,
						    "not found: %s\n",
						    mp->strings +
						    symref->st_name);
						err = 1;
					}
					continue;
				} else { /* symbol found  - relocate */
					/*
					 * calculate location of definition
					 * - symbol value plus base address of
					 * containing shared object
					 */
					value = symref->st_value;

				} /* end else symbol found */
			} /* end global or weak */
		} /* end not R_386_RELATIVE */

		/*
		 * calculate final value -
		 * if PC-relative, subtract ref addr
		 */
		if (IS_PC_RELATIVE(rtype))
			value -= off;

#ifdef	KOBJ_DEBUG
		if (kobj_debug & D_RELOCATIONS) {
			_kobj_printf(ops, "krtld:\t\t\t\t0x%8x", off);
			_kobj_printf(ops, " 0x%8x\n", value);
		}
#endif

		if (do_reloc(rtype, (unsigned char *)off, (Word *)&value,
		    (const char *)mp->strings + symref->st_name,
		    mp->filename, 0) == 0)
			err = 1;

	} /* end of while loop */
	if (err)
		return (-1);

	if (tnf_splice_probes(mp->flags & KOBJ_PRIM, probelist, taglist))
		mp->flags |= KOBJ_TNF_PROBE;

	return (0);
}