Exemplo n.º 1
0
/*
 * Finish a fork operation, with process p2 nearly set up.
 */
void
cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize,
    void (*func)(void *), void *arg)
{
	struct trapframe *tf;
	struct callframe *cf;
	struct switchframe *sf;
	caddr_t stktop1, stktop2;
	extern void fork_trampoline(void);
	struct pcb *pcb = &p2->p_addr->u_pcb;
	struct cpu_info *ci = curcpu();

	if (p1 == ci->ci_fpuproc)
		save_fpu();
	*pcb = p1->p_addr->u_pcb;
	
#ifdef ALTIVEC
	if (p1->p_addr->u_pcb.pcb_vr != NULL) {
		if (p1 == ci->ci_vecproc)
			save_vec(p1);
		pcb->pcb_vr = pool_get(&ppc_vecpl, PR_WAITOK);
		*pcb->pcb_vr = *p1->p_addr->u_pcb.pcb_vr;
	} else
		pcb->pcb_vr = NULL;

#endif /* ALTIVEC */

	pcb->pcb_pm = p2->p_vmspace->vm_map.pmap;

	pmap_extract(pmap_kernel(),
	    (vaddr_t)pcb->pcb_pm, (paddr_t *)&pcb->pcb_pmreal);
	
	/*
	 * Setup the trap frame for the new process
	 */
	stktop1 = (caddr_t)trapframe(p1);
	stktop2 = (caddr_t)trapframe(p2);
	bcopy(stktop1, stktop2, sizeof(struct trapframe));

	/*
	 * If specified, give the child a different stack.
	 */
	if (stack != NULL) {
		tf = trapframe(p2);
		tf->fixreg[1] = (register_t)stack + stacksize;
	}

	stktop2 = (caddr_t)((u_long)stktop2 & ~15);  /* Align stack pointer */
	
	/*
	 * There happens to be a callframe, too.
	 */
	cf = (struct callframe *)stktop2;
	cf->lr = (int)fork_trampoline;
	
	/*
	 * Below the trap frame, there is another call frame:
	 */
	stktop2 -= 16;
	cf = (struct callframe *)stktop2;
	cf->r31 = (register_t)func;
	cf->r30 = (register_t)arg;
	
	/*
	 * Below that, we allocate the switch frame:
	 */
	/* must match SFRAMELEN in genassym */
	stktop2 -= roundup(sizeof *sf, 16);

	sf = (struct switchframe *)stktop2;
	bzero((void *)sf, sizeof *sf);		/* just in case */
	sf->sp = (int)cf;
	sf->user_sr = pmap_kernel()->pm_sr[PPC_USER_SR]; /* just in case */
	pcb->pcb_sp = (int)stktop2;
}
Exemplo n.º 2
0
/*
 * generate_shlib()
 *	Take relocatable input image of library, generate mappable one
 *
 * Updates library base after generation so successive libraries
 * are allocated upwards in address.
 * We place data immediately following text.
 */
static void
generate_shlib(void)
{
	char buf[128], tmpf[32], tabf[32];
	FILE *fp;
	int x, cmdlen;
	ulong txtsize, datasize, bsssize;

	/*
	 * Build a jump table to prepend to the .shl output
	 */
	sprintf(tabf, "/tmp/sht%d.s", getpid());
	fp = fopen(tabf, "w");
	if (fp == NULL) {
		perror(tabf);
		exit(1);
	}
	fprintf(fp, "\t.text\n");
	fprintf(fp, "tbl_%s:\n", curlib);
	for (x = 0; db_syms[x]; ++x) {
		fprintf(fp, "\t.long\t%s\n", db_syms[x]);
	}
	fclose(fp);
	sprintf(buf, "cd /tmp; gcc -c %s", tabf);
	do_system(buf);
	unlink(tabf);

	/*
	 * Convert jump table filename to a .o
	 */
	tabf[strlen(tabf)-1] = 'o';

	/*
	 * Get shared library text size using size(1)
	 */
	sprintf(tmpf, "/tmp/shll%d", getpid());
	sprintf(buf, "size %s > %s", curinput, tmpf);
	do_system(buf);
	fp = fopen(tmpf, "r");
	(void)fgets(buf, sizeof(buf), fp);
	if (fscanf(fp, "%ld", &txtsize) != 1) {
		fprintf(stderr, "Error: corrupt size(1) output in %s\n",
			tmpf);
		exit(1);
	}
	fclose(fp);
	unlink(tmpf);

	/*
	 * Generate the library at its assigned address
	 */
	txtsize += (sizeof(struct aout) + (sizeof(ulong) * (ndb_syms-1)));
	txtsize = roundup(txtsize, page_size);
	sprintf(buf, "ld -o %s -Ttext %lx -Tdata %lx %s %s",
		curoutput,
		lib_base + sizeof(struct aout),
		lib_base + txtsize,
		tabf, curinput);

	/*
	 * Run the command to get our object
	 */
	unlink(curoutput);
	do_system(buf);

	/*
	 * Dig up data size so we can bump lib_base forward
	 * the right amount.  We couldn't calculate this until
	 * now, because BSS/common has an undecided size until
	 * finally linked.
	 */
	sprintf(tmpf, "/tmp/xsh%d", getpid());
	sprintf(buf, "size %s > %s", curoutput, tmpf);
	do_system(buf);
	fp = fopen(tmpf, "r");
	if (fp == NULL) {
		perror(tmpf);
		exit(1);
	}

	/*
	 * Skip header line, get data and BSS size
	 */
	(void)fgets(buf, sizeof(buf), fp);
	if (fscanf(fp, "%ld\t%ld\t%ld", &txtsize, &datasize, &bsssize) != 3) {
		fprintf(stderr, "Error: corrupt size(1) output in %s\n",
			tmpf);
		exit(1);
	}
	fclose(fp);

	/*
	 * Advance library base.  Make sure everything still flies
	 * as a shared library--can't map partial pages!
	 */
	txtsize += sizeof(struct aout);
	lib_base += (txtsize + datasize + roundup(bsssize, page_size));
	if (lib_base & (page_size - 1)) {
		fprintf(stderr, "Error: lib_base no longer page aligned\n");
		fprintf(stderr, " txt 0x%lx data 0x%lx BSS 0x%lx base 0x%x\n",
			txtsize, datasize, bsssize, lib_base);
		exit(1);
	}
	unlink(tmpf);
	unlink(tabf);
}
Exemplo n.º 3
0
void
pass2(void)
{
	union dinode *dp;
	struct inoinfo **inpp, *inp;
	struct inoinfo **inpend;
	struct inodesc curino;
	union dinode dino;
	int i;
	char pathbuf[MAXPATHLEN + 1];

	switch (inoinfo(ROOTINO)->ino_state) {

	case USTATE:
		pfatal("ROOT INODE UNALLOCATED");
		if (reply("ALLOCATE") == 0) {
			ckfini(0);
			exit(EEXIT);
		}
		if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
			errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
		break;

	case DCLEAR:
		pfatal("DUPS/BAD IN ROOT INODE");
		if (reply("REALLOCATE")) {
			freeino(ROOTINO);
			if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
				errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
			break;
		}
		if (reply("CONTINUE") == 0) {
			ckfini(0);
			exit(EEXIT);
		}
		break;

	case FSTATE:
	case FCLEAR:
	case FZLINK:
		pfatal("ROOT INODE NOT DIRECTORY");
		if (reply("REALLOCATE")) {
			freeino(ROOTINO);
			if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
				errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
			break;
		}
		if (reply("FIX") == 0) {
			ckfini(0);
			exit(EEXIT);
		}
		dp = ginode(ROOTINO);
		DIP_SET(dp, di_mode, DIP(dp, di_mode) & ~IFMT);
		DIP_SET(dp, di_mode, DIP(dp, di_mode) | IFDIR);
		inodirty();
		break;

	case DSTATE:
	case DZLINK:
		break;

	default:
		errx(EEXIT, "BAD STATE %d FOR ROOT INODE",
		    inoinfo(ROOTINO)->ino_state);
	}
	inoinfo(ROOTINO)->ino_state = DFOUND;
	inoinfo(WINO)->ino_state = FSTATE;
	inoinfo(WINO)->ino_type = DT_WHT;
	/*
	 * Sort the directory list into disk block order.
	 */
	qsort((char *)inpsort, (size_t)inplast, sizeof *inpsort, blksort);
	/*
	 * Check the integrity of each directory.
	 */
	memset(&curino, 0, sizeof(struct inodesc));
	curino.id_type = DATA;
	curino.id_func = pass2check;
	inpend = &inpsort[inplast];
	for (inpp = inpsort; inpp < inpend; inpp++) {
		if (got_siginfo) {
			printf("%s: phase 2: dir %td of %d (%d%%)\n", cdevname,
			    inpp - inpsort, (int)inplast,
			    (int)((inpp - inpsort) * 100 / inplast));
			got_siginfo = 0;
		}
		if (got_sigalarm) {
			setproctitle("%s p2 %d%%", cdevname,
			    (int)((inpp - inpsort) * 100 / inplast));
			got_sigalarm = 0;
		}
		inp = *inpp;
		if (inp->i_isize == 0)
			continue;
		if (inp->i_isize < MINDIRSIZE) {
			direrror(inp->i_number, "DIRECTORY TOO SHORT");
			inp->i_isize = roundup(MINDIRSIZE, DIRBLKSIZ);
			if (reply("FIX") == 1) {
				dp = ginode(inp->i_number);
				DIP_SET(dp, di_size, inp->i_isize);
				inodirty();
			}
		} else if ((inp->i_isize & (DIRBLKSIZ - 1)) != 0) {
			getpathname(pathbuf, inp->i_number, inp->i_number);
			if (usedsoftdep)
				pfatal("%s %s: LENGTH %jd NOT MULTIPLE OF %d",
					"DIRECTORY", pathbuf,
					(intmax_t)inp->i_isize, DIRBLKSIZ);
			else
				pwarn("%s %s: LENGTH %jd NOT MULTIPLE OF %d",
					"DIRECTORY", pathbuf,
					(intmax_t)inp->i_isize, DIRBLKSIZ);
			if (preen)
				printf(" (ADJUSTED)\n");
			inp->i_isize = roundup(inp->i_isize, DIRBLKSIZ);
			if (preen || reply("ADJUST") == 1) {
				dp = ginode(inp->i_number);
				DIP_SET(dp, di_size,
				    roundup(inp->i_isize, DIRBLKSIZ));
				inodirty();
			}
		}
		dp = &dino;
		memset(dp, 0, sizeof(struct ufs2_dinode));
		DIP_SET(dp, di_mode, IFDIR);
		DIP_SET(dp, di_size, inp->i_isize);
		for (i = 0;
		     i < (inp->i_numblks<NDADDR ? inp->i_numblks : NDADDR);
		     i++)
			DIP_SET(dp, di_db[i], inp->i_blks[i]);
		if (inp->i_numblks > NDADDR)
			for (i = 0; i < NIADDR; i++)
				DIP_SET(dp, di_ib[i], inp->i_blks[NDADDR + i]);
		curino.id_number = inp->i_number;
		curino.id_parent = inp->i_parent;
		(void)ckinode(dp, &curino);
	}
	/*
	 * Now that the parents of all directories have been found,
	 * make another pass to verify the value of `..'
	 */
	for (inpp = inpsort; inpp < inpend; inpp++) {
		inp = *inpp;
		if (inp->i_parent == 0 || inp->i_isize == 0)
			continue;
		if (inoinfo(inp->i_parent)->ino_state == DFOUND &&
		    INO_IS_DUNFOUND(inp->i_number))
			inoinfo(inp->i_number)->ino_state = DFOUND;
		if (inp->i_dotdot == inp->i_parent ||
		    inp->i_dotdot == (ino_t)-1)
			continue;
		if (inp->i_dotdot == 0) {
			inp->i_dotdot = inp->i_parent;
			fileerror(inp->i_parent, inp->i_number, "MISSING '..'");
			if (reply("FIX") == 0)
				continue;
			(void)makeentry(inp->i_number, inp->i_parent, "..");
			inoinfo(inp->i_parent)->ino_linkcnt--;
			continue;
		}
		/*
		 * Here we have:
		 *    inp->i_number is directory with bad ".." in it.
		 *    inp->i_dotdot is current value of "..".
		 *    inp->i_parent is directory to which ".." should point.
		 */
		getpathname(pathbuf, inp->i_parent, inp->i_number);
		printf("BAD INODE NUMBER FOR '..' in DIR I=%ju (%s)\n",
		    (uintmax_t)inp->i_number, pathbuf);
		getpathname(pathbuf, inp->i_dotdot, inp->i_dotdot);
		printf("CURRENTLY POINTS TO I=%ju (%s), ",
		    (uintmax_t)inp->i_dotdot, pathbuf);
		getpathname(pathbuf, inp->i_parent, inp->i_parent);
		printf("SHOULD POINT TO I=%ju (%s)",
		    (uintmax_t)inp->i_parent, pathbuf);
		if (cursnapshot != 0) {
			/*
			 * We need to:
			 *    setcwd(inp->i_number);
			 *    setdotdot(inp->i_dotdot, inp->i_parent);
			 */
			cmd.value = inp->i_number;
			if (sysctlbyname("vfs.ffs.setcwd", 0, 0,
			    &cmd, sizeof cmd) == -1) {
				/* kernel lacks support for these functions */
				printf(" (IGNORED)\n");
				continue;
			}
			cmd.value = inp->i_dotdot; /* verify same value */
			cmd.size = inp->i_parent;  /* new parent */
			if (sysctlbyname("vfs.ffs.setdotdot", 0, 0,
			    &cmd, sizeof cmd) == -1) {
				printf(" (FIX FAILED: %s)\n", strerror(errno));
				continue;
			}
			printf(" (FIXED)\n");
			inoinfo(inp->i_parent)->ino_linkcnt--;
			inp->i_dotdot = inp->i_parent;
			continue;
		}
		if (preen)
			printf(" (FIXED)\n");
		else if (reply("FIX") == 0)
			continue;
		inoinfo(inp->i_dotdot)->ino_linkcnt++;
		inoinfo(inp->i_parent)->ino_linkcnt--;
		inp->i_dotdot = inp->i_parent;
		(void)changeino(inp->i_number, "..", inp->i_parent);
	}
	/*
	 * Mark all the directories that can be found from the root.
	 */
	propagate();
}
Exemplo n.º 4
0
NBLog::Writer::Writer(size_t size, void *shared)
    : mSize(roundup(size)), mShared((Shared *) shared), mRear(0), mEnabled(mShared != NULL)
{
}
Exemplo n.º 5
0
size_t
dt_buf_offset(const dt_buf_t *bp, size_t align)
{
    size_t off = (size_t)(bp->dbu_ptr - bp->dbu_buf);
    return (roundup(off, align));
}
Exemplo n.º 6
0
NBLog::Reader::Reader(size_t size, const void *shared)
    : mSize(roundup(size)), mShared((const Shared *) shared), mFront(0)
{
}
Exemplo n.º 7
0
NBLog::Timeline::Timeline(size_t size, void *shared)
    : mSize(roundup(size)), mOwn(shared == NULL),
      mShared((Shared *) (mOwn ? new char[sharedSize(size)] : shared))
{
    new (mShared) Shared;
}
Exemplo n.º 8
0
void
pass2()
{
	register struct dinode *dp;
	register struct inoinfo **inpp, *inp;
	struct inoinfo **inpend;
	struct inodesc curino;
	struct dinode dino;
	char pathbuf[MAXPATHLEN + 1];

	switch (statemap[ROOTINO]) {

	case USTATE:
		pfatal("ROOT INODE UNALLOCATED");
		if (reply("ALLOCATE") == 0)
			exit(EEXIT);
		if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
			errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
		break;

	case DCLEAR:
		pfatal("DUPS/BAD IN ROOT INODE");
		if (reply("REALLOCATE")) {
			freeino(ROOTINO);
			if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
				errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
			break;
		}
		if (reply("CONTINUE") == 0)
			exit(EEXIT);
		break;

	case FSTATE:
	case FCLEAR:
		pfatal("ROOT INODE NOT DIRECTORY");
		if (reply("REALLOCATE")) {
			freeino(ROOTINO);
			if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
				errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
			break;
		}
		if (reply("FIX") == 0)
			exit(EEXIT);
		dp = ginode(ROOTINO);
		dp->di_mode &= ~IFMT;
		dp->di_mode |= IFDIR;
		inodirty();
		break;

	case DSTATE:
		break;

	default:
		errx(EEXIT, "BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]);
	}
	statemap[ROOTINO] = DFOUND;
	if (newinofmt) {
		statemap[WINO] = FSTATE;
		typemap[WINO] = DT_WHT;
	}
	/*
	 * Sort the directory list into disk block order.
	 */
	qsort((char *)inpsort, (size_t)inplast, sizeof *inpsort, blksort);
	/*
	 * Check the integrity of each directory.
	 */
	memset(&curino, 0, sizeof(struct inodesc));
	curino.id_type = DATA;
	curino.id_func = pass2check;
	dp = &dino;
	inpend = &inpsort[inplast];
	for (inpp = inpsort; inpp < inpend; inpp++) {
		inp = *inpp;
		if (inp->i_isize == 0)
			continue;
		if (inp->i_isize < MINDIRSIZE) {
			direrror(inp->i_number, "DIRECTORY TOO SHORT");
			inp->i_isize = roundup(MINDIRSIZE, DIRBLKSIZ);
			if (reply("FIX") == 1) {
				dp = ginode(inp->i_number);
				dp->di_size = inp->i_isize;
				inodirty();
				dp = &dino;
			}
		} else if ((inp->i_isize & (DIRBLKSIZ - 1)) != 0) {
			getpathname(pathbuf, inp->i_number, inp->i_number);
			pwarn("DIRECTORY %s: LENGTH %d NOT MULTIPLE OF %d",
				pathbuf, inp->i_isize, DIRBLKSIZ);
			if (preen)
				printf(" (ADJUSTED)\n");
			inp->i_isize = roundup(inp->i_isize, DIRBLKSIZ);
			if (preen || reply("ADJUST") == 1) {
				dp = ginode(inp->i_number);
				dp->di_size = roundup(inp->i_isize, DIRBLKSIZ);
				inodirty();
				dp = &dino;
			}
		}
		memset(&dino, 0, sizeof(struct dinode));
		dino.di_mode = IFDIR;
		dp->di_size = inp->i_isize;
		memmove(&dp->di_db[0], &inp->i_blks[0], (size_t)inp->i_numblks);
		curino.id_number = inp->i_number;
		curino.id_parent = inp->i_parent;
		(void)ckinode(dp, &curino);
	}
	/*
	 * Now that the parents of all directories have been found,
	 * make another pass to verify the value of `..'
	 */
	for (inpp = inpsort; inpp < inpend; inpp++) {
		inp = *inpp;
		if (inp->i_parent == 0 || inp->i_isize == 0)
			continue;
		if (statemap[inp->i_parent] == DFOUND &&
		    statemap[inp->i_number] == DSTATE)
			statemap[inp->i_number] = DFOUND;
		if (inp->i_dotdot == inp->i_parent ||
		    inp->i_dotdot == (ino_t)-1)
			continue;
		if (inp->i_dotdot == 0) {
			inp->i_dotdot = inp->i_parent;
			fileerror(inp->i_parent, inp->i_number, "MISSING '..'");
			if (reply("FIX") == 0)
				continue;
			(void)makeentry(inp->i_number, inp->i_parent, "..");
			lncntp[inp->i_parent]--;
			continue;
		}
		fileerror(inp->i_parent, inp->i_number,
		    "BAD INODE NUMBER FOR '..'");
		if (reply("FIX") == 0)
			continue;
		lncntp[inp->i_dotdot]++;
		lncntp[inp->i_parent]--;
		inp->i_dotdot = inp->i_parent;
		(void)changeino(inp->i_number, "..", inp->i_parent);
	}
	/*
	 * Mark all the directories that can be found from the root.
	 */
	propagate();
}
Exemplo n.º 9
0
static int
#ifdef HAVE_ENCODE_FH_WITH_INODE
zpl_encode_fh(struct inode *ip, __u32 *fh, int *max_len, struct inode *parent)
{
#else
zpl_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, int connectable)
{
	struct inode *ip = dentry->d_inode;
#endif /* HAVE_ENCODE_FH_WITH_INODE */
	fstrans_cookie_t cookie;
	fid_t *fid = (fid_t *)fh;
	int len_bytes, rc;

	len_bytes = *max_len * sizeof (__u32);

	if (len_bytes < offsetof(fid_t, fid_data))
		return (255);

	fid->fid_len = len_bytes - offsetof(fid_t, fid_data);
	cookie = spl_fstrans_mark();

	if (zfsctl_is_node(ip))
		rc = zfsctl_fid(ip, fid);
	else
		rc = zfs_fid(ip, fid);

	spl_fstrans_unmark(cookie);
	len_bytes = offsetof(fid_t, fid_data) + fid->fid_len;
	*max_len = roundup(len_bytes, sizeof (__u32)) / sizeof (__u32);

	return (rc == 0 ? FILEID_INO32_GEN : 255);
}

static struct dentry *
zpl_dentry_obtain_alias(struct inode *ip)
{
	struct dentry *result;

#ifdef HAVE_D_OBTAIN_ALIAS
	result = d_obtain_alias(ip);
#else
	result = d_alloc_anon(ip);

	if (result == NULL) {
		iput(ip);
		result = ERR_PTR(-ENOMEM);
	}
#endif /* HAVE_D_OBTAIN_ALIAS */

	return (result);
}

static struct dentry *
zpl_fh_to_dentry(struct super_block *sb, struct fid *fh,
    int fh_len, int fh_type)
{
	fid_t *fid = (fid_t *)fh;
	fstrans_cookie_t cookie;
	struct inode *ip;
	int len_bytes, rc;

	len_bytes = fh_len * sizeof (__u32);

	if (fh_type != FILEID_INO32_GEN ||
	    len_bytes < offsetof(fid_t, fid_data) ||
	    len_bytes < offsetof(fid_t, fid_data) + fid->fid_len)
		return (ERR_PTR(-EINVAL));

	cookie = spl_fstrans_mark();
	rc = zfs_vget(sb, &ip, fid);
	spl_fstrans_unmark(cookie);

	if (rc) {
		/*
		 * If we see ENOENT it might mean that an NFSv4 * client
		 * is using a cached inode value in a file handle and
		 * that the sought after file has had its inode changed
		 * by a third party.  So change the error to ESTALE
		 * which will trigger a full lookup by the client and
		 * will find the new filename/inode pair if it still
		 * exists.
		 */
		if (rc == ENOENT)
			rc = ESTALE;

		return (ERR_PTR(-rc));
	}

	ASSERT((ip != NULL) && !IS_ERR(ip));

	return (zpl_dentry_obtain_alias(ip));
}
Exemplo n.º 10
0
/**
 * pch_gbe_check_options - Range Checking for Command Line Parameters
 * @adapter:  Board private structure
 */
void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
{
	struct pch_gbe_hw *hw = &adapter->hw;
	struct net_device *dev = adapter->netdev;
	int val;

	{ /* Transmit Descriptor Count */
		static const struct pch_gbe_option opt = {
			.type = range_option,
			.name = "Transmit Descriptors",
			.err  = "using default of "
				__MODULE_STRING(PCH_GBE_DEFAULT_TXD),
			.def  = PCH_GBE_DEFAULT_TXD,
			.arg  = { .r = { .min = PCH_GBE_MIN_TXD,
					 .max = PCH_GBE_MAX_TXD } }
		};
		struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
		tx_ring->count = TxDescriptors;
		pch_gbe_validate_option(&tx_ring->count, &opt, adapter);
		tx_ring->count = roundup(tx_ring->count,
					PCH_GBE_TX_DESC_MULTIPLE);
	}
	{ /* Receive Descriptor Count */
		static const struct pch_gbe_option opt = {
			.type = range_option,
			.name = "Receive Descriptors",
			.err  = "using default of "
				__MODULE_STRING(PCH_GBE_DEFAULT_RXD),
			.def  = PCH_GBE_DEFAULT_RXD,
			.arg  = { .r = { .min = PCH_GBE_MIN_RXD,
					 .max = PCH_GBE_MAX_RXD } }
		};
		struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;
		rx_ring->count = RxDescriptors;
		pch_gbe_validate_option(&rx_ring->count, &opt, adapter);
		rx_ring->count = roundup(rx_ring->count,
				PCH_GBE_RX_DESC_MULTIPLE);
	}
	{ /* Checksum Offload Enable/Disable */
		static const struct pch_gbe_option opt = {
			.type = enable_option,
			.name = "Checksum Offload",
			.err  = "defaulting to Enabled",
			.def  = PCH_GBE_DEFAULT_RX_CSUM
		};
		val = XsumRX;
		pch_gbe_validate_option(&val, &opt, adapter);
		if (!val)
			dev->features &= ~NETIF_F_RXCSUM;
	}
	{ /* Checksum Offload Enable/Disable */
		static const struct pch_gbe_option opt = {
			.type = enable_option,
			.name = "Checksum Offload",
			.err  = "defaulting to Enabled",
			.def  = PCH_GBE_DEFAULT_TX_CSUM
		};
		val = XsumTX;
		pch_gbe_validate_option(&val, &opt, adapter);
		if (!val)
			dev->features &= ~NETIF_F_ALL_CSUM;
	}
	{ /* Flow Control */
		static const struct pch_gbe_option opt = {
			.type = list_option,
			.name = "Flow Control",
			.err  = "reading default settings from EEPROM",
			.def  = PCH_GBE_FC_DEFAULT,
			.arg  = { .l = { .nr = (int)ARRAY_SIZE(fc_list),
					 .p = fc_list } }
		};
		hw->mac.fc = FlowControl;
		pch_gbe_validate_option((int *)(&hw->mac.fc),
						&opt, adapter);
	}

	pch_gbe_check_copper_options(adapter);
}
Exemplo n.º 11
0
int
main(int argc, char *argv[])
{
	struct stat sb;
	ino_t ino;
	int dirty;
	union dinode *dp;
	struct fstab *dt;
	char *map, *mntpt;
	int ch, mode, mntflags;
	int i, anydirskipped, bflag = 0, Tflag = 0, honorlevel = 1;
	int just_estimate = 0;
	ino_t maxino;
	char *tmsg;

	spcl.c_date = _time_to_time64(time(NULL));

	tsize = 0;	/* Default later, based on 'c' option for cart tapes */
	dumpdates = _PATH_DUMPDATES;
	popenout = NULL;
	tape = NULL;
	temp = _PATH_DTMP;
	if (TP_BSIZE / DEV_BSIZE == 0 || TP_BSIZE % DEV_BSIZE != 0)
		quit("TP_BSIZE must be a multiple of DEV_BSIZE\n");
	level = 0;
	rsync_friendly = 0;

	if (argc < 2)
		usage();

	obsolete(&argc, &argv);
	while ((ch = getopt(argc, argv,
	    "0123456789aB:b:C:cD:d:f:h:LnP:RrSs:T:uWw")) != -1)
		switch (ch) {
		/* dump level */
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			level = 10 * level + ch - '0';
			break;

		case 'a':		/* `auto-size', Write to EOM. */
			unlimited = 1;
			break;

		case 'B':		/* blocks per output file */
			blocksperfile = numarg("number of blocks per file",
			    1L, 0L);
			break;

		case 'b':		/* blocks per tape write */
			ntrec = numarg("number of blocks per write",
			    1L, 1000L);
			break;

		case 'C':
			cachesize = numarg("cachesize", 0, 0) * 1024 * 1024;
			break;

		case 'c':		/* Tape is cart. not 9-track */
			cartridge = 1;
			break;

		case 'D':
			dumpdates = optarg;
			break;

		case 'd':		/* density, in bits per inch */
			density = numarg("density", 10L, 327670L) / 10;
			if (density >= 625 && !bflag)
				ntrec = HIGHDENSITYTREC;
			break;

		case 'f':		/* output file */
			if (popenout != NULL)
				errx(X_STARTUP, "You cannot use the P and f "
				    "flags together.\n");
			tape = optarg;
			break;

		case 'h':
			honorlevel = numarg("honor level", 0L, 10L);
			break;

		case 'L':
			snapdump = 1;
			break;

		case 'n':		/* notify operators */
			notify = 1;
			break;

		case 'P':
			if (tape != NULL)
				errx(X_STARTUP, "You cannot use the P and f "
				    "flags together.\n");
			popenout = optarg;
			break;

		case 'r': /* store slightly less data to be friendly to rsync */
			if (rsync_friendly < 1)
				rsync_friendly = 1;
			break;

		case 'R': /* store even less data to be friendlier to rsync */
			if (rsync_friendly < 2)
				rsync_friendly = 2;
			break;

		case 'S':               /* exit after estimating # of tapes */
			just_estimate = 1;
			break;

		case 's':		/* tape size, feet */
			tsize = numarg("tape size", 1L, 0L) * 12 * 10;
			break;

		case 'T':		/* time of last dump */
			spcl.c_ddate = unctime(optarg);
			if (spcl.c_ddate < 0) {
				(void)fprintf(stderr, "bad time \"%s\"\n",
				    optarg);
				exit(X_STARTUP);
			}
			Tflag = 1;
			lastlevel = -1;
			break;

		case 'u':		/* update /etc/dumpdates */
			uflag = 1;
			break;

		case 'W':		/* what to do */
		case 'w':
			lastdump(ch);
			exit(X_FINOK);	/* do nothing else */

		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc < 1) {
		(void)fprintf(stderr, "Must specify disk or file system\n");
		exit(X_STARTUP);
	}
	disk = *argv++;
	argc--;
	if (argc >= 1) {
		(void)fprintf(stderr, "Unknown arguments to dump:");
		while (argc--)
			(void)fprintf(stderr, " %s", *argv++);
		(void)fprintf(stderr, "\n");
		exit(X_STARTUP);
	}
	if (rsync_friendly && (level > 0)) {
		(void)fprintf(stderr, "%s %s\n", "rsync friendly options",
		    "can be used only with level 0 dumps.");
		exit(X_STARTUP);
	}
	if (Tflag && uflag) {
	        (void)fprintf(stderr,
		    "You cannot use the T and u flags together.\n");
		exit(X_STARTUP);
	}
	if (popenout) {
		tape = "child pipeline process";
	} else if (tape == NULL && (tape = getenv("TAPE")) == NULL)
		tape = _PATH_DEFTAPE;
	if (strcmp(tape, "-") == 0) {
		pipeout++;
		tape = "standard output";
	}

	if (blocksperfile)
		blocksperfile = blocksperfile / ntrec * ntrec; /* round down */
	else if (!unlimited) {
		/*
		 * Determine how to default tape size and density
		 *
		 *         	density				tape size
		 * 9-track	1600 bpi (160 bytes/.1")	2300 ft.
		 * 9-track	6250 bpi (625 bytes/.1")	2300 ft.
		 * cartridge	8000 bpi (100 bytes/.1")	1700 ft.
		 *						(450*4 - slop)
		 * hilit19 hits again: "
		 */
		if (density == 0)
			density = cartridge ? 100 : 160;
		if (tsize == 0)
			tsize = cartridge ? 1700L*120L : 2300L*120L;
	}

	if (strchr(tape, ':')) {
		host = tape;
		tape = strchr(host, ':');
		*tape++ = '\0';
#ifdef RDUMP
		if (index(tape, '\n')) {
		    (void)fprintf(stderr, "invalid characters in tape\n");
		    exit(X_STARTUP);
		}
		if (rmthost(host) == 0)
			exit(X_STARTUP);
#else
		(void)fprintf(stderr, "remote dump not enabled\n");
		exit(X_STARTUP);
#endif
	}
	(void)setuid(getuid()); /* rmthost() is the only reason to be setuid */

	if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
		signal(SIGHUP, sig);
	if (signal(SIGTRAP, SIG_IGN) != SIG_IGN)
		signal(SIGTRAP, sig);
	if (signal(SIGFPE, SIG_IGN) != SIG_IGN)
		signal(SIGFPE, sig);
	if (signal(SIGBUS, SIG_IGN) != SIG_IGN)
		signal(SIGBUS, sig);
	if (signal(SIGSEGV, SIG_IGN) != SIG_IGN)
		signal(SIGSEGV, sig);
	if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
		signal(SIGTERM, sig);
	if (signal(SIGINT, interrupt) == SIG_IGN)
		signal(SIGINT, SIG_IGN);

	dump_getfstab();	/* /etc/fstab snarfed */
	/*
	 *	disk can be either the full special file name,
	 *	the suffix of the special file name,
	 *	the special name missing the leading '/',
	 *	the file system name with or without the leading '/'.
	 */
	dt = fstabsearch(disk);
	if (dt != NULL) {
		disk = rawname(dt->fs_spec);
 		if (disk == NULL)
 			errx(X_STARTUP, "%s: unknown file system", dt->fs_spec);
		(void)strncpy(spcl.c_dev, dt->fs_spec, NAMELEN);
		(void)strncpy(spcl.c_filesys, dt->fs_file, NAMELEN);
	} else {
		(void)strncpy(spcl.c_dev, disk, NAMELEN);
		(void)strncpy(spcl.c_filesys, "an unlisted file system",
		    NAMELEN);
	}
	spcl.c_dev[NAMELEN-1]='\0';
	spcl.c_filesys[NAMELEN-1]='\0';

	if ((mntpt = getmntpt(disk, &mntflags)) != 0) {
		if (mntflags & MNT_RDONLY) {
			if (snapdump != 0) {
				msg("WARNING: %s\n",
				    "-L ignored for read-only filesystem.");
				snapdump = 0;
			}
		} else if (snapdump == 0) {
			msg("WARNING: %s\n",
			    "should use -L when dumping live read-write "
			    "filesystems!");
		} else {
			char snapname[BUFSIZ], snapcmd[BUFSIZ];

			snprintf(snapname, sizeof snapname, "%s/.snap", mntpt);
			if ((stat(snapname, &sb) < 0) || !S_ISDIR(sb.st_mode)) {
				msg("WARNING: %s %s\n",
				    "-L requested but snapshot location",
				    snapname);
				msg("         %s: %s\n",
				    "is not a directory",
				    "dump downgraded, -L ignored");
				snapdump = 0;
			} else {
				snprintf(snapname, sizeof snapname,
				    "%s/.snap/dump_snapshot", mntpt);
				snprintf(snapcmd, sizeof snapcmd, "%s %s %s",
				    _PATH_MKSNAP_FFS, mntpt, snapname);
				unlink(snapname);
				if (system(snapcmd) != 0)
					errx(X_STARTUP, "Cannot create %s: %s\n",
					    snapname, strerror(errno));
				if ((diskfd = open(snapname, O_RDONLY)) < 0) {
					unlink(snapname);
					errx(X_STARTUP, "Cannot open %s: %s\n",
					    snapname, strerror(errno));
				}
				unlink(snapname);
				if (fstat(diskfd, &sb) != 0)
					err(X_STARTUP, "%s: stat", snapname);
				spcl.c_date = _time_to_time64(sb.st_mtime);
			}
		}
	} else if (snapdump != 0) {
		msg("WARNING: Cannot use -L on an unmounted filesystem.\n");
		snapdump = 0;
	}
	if (snapdump == 0) {
		if ((diskfd = open(disk, O_RDONLY)) < 0)
			err(X_STARTUP, "Cannot open %s", disk);
		if (fstat(diskfd, &sb) != 0)
			err(X_STARTUP, "%s: stat", disk);
		if (S_ISDIR(sb.st_mode))
			errx(X_STARTUP, "%s: unknown file system", disk);
	}

	(void)strcpy(spcl.c_label, "none");
	(void)gethostname(spcl.c_host, NAMELEN);
	spcl.c_level = level;
	spcl.c_type = TS_TAPE;
	if (rsync_friendly) {
		/* don't store real dump times */
		spcl.c_date = 0;
		spcl.c_ddate = 0;
	}
	if (spcl.c_date == 0) {
		tmsg = "the epoch\n";
	} else {
		time_t t = _time64_to_time(spcl.c_date);
		tmsg = ctime(&t);
	}
	msg("Date of this level %d dump: %s", level, tmsg);

	if (!Tflag && (!rsync_friendly))
	        getdumptime();		/* /etc/dumpdates snarfed */
	if (spcl.c_ddate == 0) {
		tmsg = "the epoch\n";
	} else {
		time_t t = _time64_to_time(spcl.c_ddate);
		tmsg = ctime(&t);
	}
	if (lastlevel < 0)
		msg("Date of last (level unknown) dump: %s", tmsg);
	else
		msg("Date of last level %d dump: %s", lastlevel, tmsg);

	msg("Dumping %s%s ", snapdump ? "snapshot of ": "", disk);
	if (dt != NULL)
		msgtail("(%s) ", dt->fs_file);
	if (host)
		msgtail("to %s on host %s\n", tape, host);
	else
		msgtail("to %s\n", tape);

	sync();
	sblock = (struct fs *)sblock_buf;
	for (i = 0; sblock_try[i] != -1; i++) {
		sblock->fs_fsize = SBLOCKSIZE; /* needed in bread */
		bread(sblock_try[i] >> dev_bshift, (char *) sblock, SBLOCKSIZE);
		if ((sblock->fs_magic == FS_UFS1_MAGIC ||
		     (sblock->fs_magic == FS_UFS2_MAGIC &&
		      sblock->fs_sblockloc == sblock_try[i])) &&
		    sblock->fs_bsize <= MAXBSIZE &&
		    sblock->fs_bsize >= sizeof(struct fs))
			break;
	}
	if (sblock_try[i] == -1)
		quit("Cannot find file system superblock\n");
	dev_bsize = sblock->fs_fsize / fsbtodb(sblock, 1);
	dev_bshift = ffs(dev_bsize) - 1;
	if (dev_bsize != (1 << dev_bshift))
		quit("dev_bsize (%ld) is not a power of 2", dev_bsize);
	tp_bshift = ffs(TP_BSIZE) - 1;
	if (TP_BSIZE != (1 << tp_bshift))
		quit("TP_BSIZE (%d) is not a power of 2", TP_BSIZE);
	maxino = sblock->fs_ipg * sblock->fs_ncg;
	mapsize = roundup(howmany(maxino, CHAR_BIT), TP_BSIZE);
	usedinomap = (char *)calloc((unsigned) mapsize, sizeof(char));
	dumpdirmap = (char *)calloc((unsigned) mapsize, sizeof(char));
	dumpinomap = (char *)calloc((unsigned) mapsize, sizeof(char));
	tapesize = 3 * (howmany(mapsize * sizeof(char), TP_BSIZE) + 1);

	nonodump = spcl.c_level < honorlevel;

	passno = 1;
	setproctitle("%s: pass 1: regular files", disk);
	msg("mapping (Pass I) [regular files]\n");
	anydirskipped = mapfiles(maxino, &tapesize);

	passno = 2;
	setproctitle("%s: pass 2: directories", disk);
	msg("mapping (Pass II) [directories]\n");
	while (anydirskipped) {
		anydirskipped = mapdirs(maxino, &tapesize);
	}

	if (pipeout || unlimited) {
		tapesize += 10;	/* 10 trailer blocks */
		msg("estimated %ld tape blocks.\n", tapesize);
	} else {
		double fetapes;

		if (blocksperfile)
			fetapes = (double) tapesize / blocksperfile;
		else if (cartridge) {
			/* Estimate number of tapes, assuming streaming stops at
			   the end of each block written, and not in mid-block.
			   Assume no erroneous blocks; this can be compensated
			   for with an artificially low tape size. */
			fetapes =
			(	  (double) tapesize	/* blocks */
				* TP_BSIZE	/* bytes/block */
				* (1.0/density)	/* 0.1" / byte " */
			  +
				  (double) tapesize	/* blocks */
				* (1.0/ntrec)	/* streaming-stops per block */
				* 15.48		/* 0.1" / streaming-stop " */
			) * (1.0 / tsize );	/* tape / 0.1" " */
		} else {
			/* Estimate number of tapes, for old fashioned 9-track
			   tape */
			int tenthsperirg = (density == 625) ? 3 : 7;
			fetapes =
			(	  (double) tapesize	/* blocks */
				* TP_BSIZE	/* bytes / block */
				* (1.0/density)	/* 0.1" / byte " */
			  +
				  (double) tapesize	/* blocks */
				* (1.0/ntrec)	/* IRG's / block */
				* tenthsperirg	/* 0.1" / IRG " */
			) * (1.0 / tsize );	/* tape / 0.1" " */
		}
		etapes = fetapes;		/* truncating assignment */
		etapes++;
		/* count the dumped inodes map on each additional tape */
		tapesize += (etapes - 1) *
			(howmany(mapsize * sizeof(char), TP_BSIZE) + 1);
		tapesize += etapes + 10;	/* headers + 10 trailer blks */
		msg("estimated %ld tape blocks on %3.2f tape(s).\n",
		    tapesize, fetapes);
	}

        /*
         * If the user only wants an estimate of the number of
         * tapes, exit now.
         */
        if (just_estimate)
                exit(0);

	/*
	 * Allocate tape buffer.
	 */
	if (!alloctape())
		quit(
	"can't allocate tape buffers - try a smaller blocking factor.\n");

	startnewtape(1);
	(void)time((time_t *)&(tstart_writing));
	dumpmap(usedinomap, TS_CLRI, maxino - 1);

	passno = 3;
	setproctitle("%s: pass 3: directories", disk);
	msg("dumping (Pass III) [directories]\n");
	dirty = 0;		/* XXX just to get gcc to shut up */
	for (map = dumpdirmap, ino = 1; ino < maxino; ino++) {
		if (((ino - 1) % CHAR_BIT) == 0)	/* map is offset by 1 */
			dirty = *map++;
		else
			dirty >>= 1;
		if ((dirty & 1) == 0)
			continue;
		/*
		 * Skip directory inodes deleted and maybe reallocated
		 */
		dp = getino(ino, &mode);
		if (mode != IFDIR)
			continue;
		(void)dumpino(dp, ino);
	}

	passno = 4;
	setproctitle("%s: pass 4: regular files", disk);
	msg("dumping (Pass IV) [regular files]\n");
	for (map = dumpinomap, ino = 1; ino < maxino; ino++) {
		if (((ino - 1) % CHAR_BIT) == 0)	/* map is offset by 1 */
			dirty = *map++;
		else
			dirty >>= 1;
		if ((dirty & 1) == 0)
			continue;
		/*
		 * Skip inodes deleted and reallocated as directories.
		 */
		dp = getino(ino, &mode);
		if (mode == IFDIR)
			continue;
		(void)dumpino(dp, ino);
	}

	(void)time((time_t *)&(tend_writing));
	spcl.c_type = TS_END;
	for (i = 0; i < ntrec; i++)
		writeheader(maxino - 1);
	if (pipeout)
		msg("DUMP: %jd tape blocks\n", (intmax_t)spcl.c_tapea);
	else
		msg("DUMP: %jd tape blocks on %d volume%s\n",
		    (intmax_t)spcl.c_tapea, spcl.c_volume,
		    (spcl.c_volume == 1) ? "" : "s");

	/* report dump performance, avoid division through zero */
	if (tend_writing - tstart_writing == 0)
		msg("finished in less than a second\n");
	else
		msg("finished in %jd seconds, throughput %jd KBytes/sec\n",
		    (intmax_t)tend_writing - tstart_writing, 
		    (intmax_t)(spcl.c_tapea / 
		    (tend_writing - tstart_writing)));

	putdumptime();
	trewind();
	broadcast("DUMP IS DONE!\a\a\n");
	msg("DUMP IS DONE\n");
	Exit(X_FINOK);
	/* NOTREACHED */
}
Exemplo n.º 12
0
/* We are trying to perform a static TLS relocation in MAP, but it was
   dynamically loaded.  This can only work if there is enough surplus in
   the static TLS area already allocated for each running thread.  If this
   object's TLS segment is too big to fit, we fail.  If it fits,
   we set MAP->l_tls_offset and return.
   This function intentionally does not return any value but signals error
   directly, as static TLS should be rare and code handling it should
   not be inlined as much as possible.  */
int
internal_function
_dl_try_allocate_static_tls (struct link_map *map)
{
  /* If we've already used the variable with dynamic access, or if the
     alignment requirements are too high, fail.  */
  if (map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET
      || map->l_tls_align > GL(dl_tls_static_align))
    {
    fail:
      return -1;
    }

#if TLS_TCB_AT_TP
  size_t freebytes;
  size_t n;
  size_t blsize;

  freebytes = GL(dl_tls_static_size) - GL(dl_tls_static_used);
  if (freebytes < TLS_TCB_SIZE)
    goto fail;
  freebytes -= TLS_TCB_SIZE;

  blsize = map->l_tls_blocksize + map->l_tls_firstbyte_offset;
  if (freebytes < blsize)
    goto fail;

  n = (freebytes - blsize) / map->l_tls_align;

  size_t offset = GL(dl_tls_static_used) + (freebytes - n * map->l_tls_align
					    - map->l_tls_firstbyte_offset);

  map->l_tls_offset = GL(dl_tls_static_used) = offset;
#elif TLS_DTV_AT_TP
  size_t used;
  size_t check;

  size_t offset = roundup (GL(dl_tls_static_used), map->l_tls_align);
  used = offset + map->l_tls_blocksize;
  check = used;
  /* dl_tls_static_used includes the TCB at the beginning.  */

  if (check > GL(dl_tls_static_size))
    goto fail;

  map->l_tls_offset = offset;
  GL(dl_tls_static_used) = used;
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif

  /* If the object is not yet relocated we cannot initialize the
     static TLS region.  Delay it.  */
  if (map->l_real->l_relocated)
    {
#ifdef SHARED
      if (__builtin_expect (THREAD_DTV()[0].counter != GL(dl_tls_generation),
			    0))
	/* Update the slot information data for at least the generation of
	   the DSO we are allocating data for.  */
	(void) _dl_update_slotinfo (map->l_tls_modid);
#endif

      GL(dl_init_static_tls) (map);
    }
  else
    map->l_need_tls_init = 1;

  return 0;
}
Exemplo n.º 13
0
/*
 * Load the information expected by a sparc64 kernel.
 *
 * - The 'boothowto' argument is constructed
 * - The 'bootdev' argument is constructed
 * - The kernel environment is copied into kernel space.
 * - Module metadata are formatted and placed in kernel space.
 */
int
md_load(char *args, vm_offset_t *modulep)
{
    struct preloaded_file	*kfp;
    struct preloaded_file	*xp;
    struct file_metadata	*md;
    vm_offset_t			kernend;
    vm_offset_t			addr;
    vm_offset_t			envp;
    vm_offset_t			size;
    char			*rootdevname;
    int				howto;

    howto = md_getboothowto(args);

    /* 
     * Allow the environment variable 'rootdev' to override the supplied device 
     * This should perhaps go to MI code and/or have $rootdev tested/set by
     * MI code before launching the kernel.
     */
    if ((rootdevname = getenv("rootdev")) == NULL)
	    rootdevname = getenv("currdev");
    getrootmount(rootdevname);

    /* find the last module in the chain */
    addr = 0;
    for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
	if (addr < (xp->f_addr + xp->f_size))
	    addr = xp->f_addr + xp->f_size;
    }
    /* pad to a page boundary */
    addr = roundup(addr, PAGE_SIZE);

    /* copy our environment */
    envp = addr;
    addr = md_copyenv(addr);

    /* pad to a page boundary */
    addr = roundup(addr, PAGE_SIZE);

    kernend = 0;
    kfp = file_findfile(NULL, "elf64 kernel");
    if (kfp == NULL)
	kfp = file_findfile(NULL, "elf kernel");
    if (kfp == NULL)
	panic("can't find kernel file");
    file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
    file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
    file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
    file_addmetadata(kfp, MODINFOMD_DTLB_SLOTS, sizeof dtlb_slot, &dtlb_slot);
    file_addmetadata(kfp, MODINFOMD_ITLB_SLOTS, sizeof itlb_slot, &itlb_slot);
    file_addmetadata(kfp, MODINFOMD_DTLB,
	dtlb_slot * sizeof(*dtlb_store), dtlb_store);
    file_addmetadata(kfp, MODINFOMD_ITLB,
	itlb_slot * sizeof(*itlb_store), itlb_store);

    *modulep = addr;
    size = md_copymodules(0);
    kernend = roundup(addr + size, PAGE_SIZE);

    md = file_findmetadata(kfp, MODINFOMD_KERNEND);
    bcopy(&kernend, md->md_data, sizeof kernend);

    (void)md_copymodules(addr);

    return(0);
}
Exemplo n.º 14
0
Arquivo: dns.c Projeto: 0mp/freebsd
static int
add_host(int pref, const char *host, int port, struct mx_hostentry **he, size_t *ps)
{
	struct addrinfo hints, *res, *res0 = NULL;
	char servname[10];
	struct mx_hostentry *p;
	const int count_inc = 10;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	snprintf(servname, sizeof(servname), "%d", port);
	switch (getaddrinfo(host, servname, &hints, &res0)) {
	case 0:
		break;
	case EAI_AGAIN:
	case EAI_NONAME:
		/*
		 * EAI_NONAME gets returned for:
		 * SMARTHOST set but DNS server not reachable -> defer
		 * SMARTHOST set but DNS server returns "host does not exist"
		 *           -> buggy configuration
		 *           -> either defer or bounce would be ok -> defer
		 * MX entry was returned by DNS server but name doesn't resolve
		 *           -> hopefully transient situation -> defer
		 * all other DNS problems should have been caught earlier
		 * in dns_get_mx_list().
		 */
		goto out;
	default:
		return(-1);
	}

	for (res = res0; res != NULL; res = res->ai_next) {
		if (*ps + 1 >= roundup(*ps, count_inc)) {
			size_t newsz = roundup(*ps + 2, count_inc);
			*he = reallocf(*he, newsz * sizeof(**he));
			if (*he == NULL)
				goto out;
		}

		p = &(*he)[*ps];
		strlcpy(p->host, host, sizeof(p->host));
		p->pref = pref;
		p->ai = *res;
		p->ai.ai_addr = NULL;
		bcopy(res->ai_addr, &p->sa, p->ai.ai_addrlen);

		getnameinfo((struct sockaddr *)&p->sa, p->ai.ai_addrlen,
			    p->addr, sizeof(p->addr),
			    NULL, 0, NI_NUMERICHOST);

		(*ps)++;
	}
	freeaddrinfo(res0);

	return (0);

out:
	if (res0 != NULL)
		freeaddrinfo(res0);
	return (1);
}
Exemplo n.º 15
0
static int
   elfreadsyms (int fd, Elf32_Ehdr *eh, Elf32_Shdr *shtab, int flags)
{
	Elf32_Shdr *sh, *strh, *shstrh, *ksh;
	Elf32_Sym *symtab;
	Elf32_Ehdr *keh;
	char *shstrtab, *strtab, *symend;
	int nsym, offs, size, i;
	int *symptr;

	/* Fix up twirl */
	if (bootseg++ > 0) {
		fprintf (stderr, "\b + ");
	}

	/*
	 *  If we are loading symbols to support kernel DDB symbol handling
	 *  make room for an ELF header at _end and after that a section
	 *  header. DDB then finds the symbols using the data put here.
	 */
	if(flags & KFLAG) {
		tablebase = roundup(tablebase, sizeof(long));
		symptr = (int *)tablebase;
		tablebase += sizeof(int *) * 2;
		keh = (Elf32_Ehdr *)tablebase;
		tablebase += sizeof(Elf32_Ehdr); 
		tablebase = roundup(tablebase, sizeof(long));
		ksh = (Elf32_Shdr *)tablebase;
		tablebase += roundup((sizeof(Elf32_Shdr) * eh->e_shnum), sizeof(long)); 
		memcpy(ksh, shtab, roundup((sizeof(Elf32_Shdr) * eh->e_shnum), sizeof(long)));
		sh = ksh;
	}
	else {
		sh = shtab;
	}
	shstrh = &sh[eh->e_shstrndx];

	for (i = 0; i < eh->e_shnum; sh++, i++) {
		if (sh->sh_type == SHT_SYMTAB) {
			break;
		}
	}
	if (i >= eh->e_shnum) {
		return (0);
	}

	if(flags & KFLAG) {
		strh = &ksh[sh->sh_link];
		nsym = sh->sh_size / sh->sh_entsize;
		offs = sh->sh_offset;
		size = sh->sh_size;
		fprintf (stderr, "%d syms ", nsym);
	} else {
		strh = &shtab[sh->sh_link];
		nsym = (sh->sh_size / sh->sh_entsize) - sh->sh_info;
		offs = sh->sh_offset + (sh->sh_info * sh->sh_entsize);
		size = nsym * sh->sh_entsize;
		fprintf (stderr, "%d syms ", nsym);
	}



	/*
	 *  Allocate tables in correct order so the kernel grooks it.
	 *  Then we read them in the order they are in the ELF file.
	 */
	shstrtab = gettable(shstrh->sh_size, "shstrtab", flags);
	strtab = gettable(strh->sh_size, "strtab", flags);
	symtab = gettable(size, "symtab", flags);
	symend = (char *)symtab + size;


	do {
		if(shstrh->sh_offset < offs && shstrh->sh_offset < strh->sh_offset) {
#if 0
			/*
			 *  We would like to read the shstrtab from the file but since this
			 *  table is located in front of the shtab it is already gone. We can't
			 *  position backwards outside the current segment when using tftp.
			 *  Instead we create the names we need in the string table because
			 *  it can be reconstructed from the info we now have access to.
			 */
			if (!readtable (shstrh->sh_offset, (void *)shstrtab,
					shstrh->sh_size, "shstring", flags)) {
				return(0);
			}
#else
			memset(shstrtab, 0, shstrh->sh_size);
			strcpy(shstrtab + shstrh->sh_name, ".shstrtab");
			strcpy(shstrtab + strh->sh_name, ".strtab");
			strcpy(shstrtab + sh->sh_name, ".symtab");
#endif
			shstrh->sh_offset = 0x7fffffff;
		}

		if (offs < strh->sh_offset && offs < shstrh->sh_offset) {
			if (!(readtable(fd, offs, (void *)symtab, size, "sym", flags))) {
				return (0);
			}
			offs = 0x7fffffff;
		}

		if (strh->sh_offset < offs && strh->sh_offset < shstrh->sh_offset) {
			if (!(readtable (fd, strh->sh_offset, (void *)strtab,
					 strh->sh_size, "string", flags))) {
				return (0);
			}
			strh->sh_offset = 0x7fffffff;
		}
		if (offs == 0x7fffffff && strh->sh_offset == 0x7fffffff &&
		    shstrh->sh_offset == 0x7fffffff) {
			break;
		}
	} while(1);


	if(flags & KFLAG) {
		/*
		 *  Update the kernel headers with the current info.
		 */
		shstrh->sh_offset = (Elf32_Off)shstrtab - (Elf32_Off)keh;
		strh->sh_offset = (Elf32_Off)strtab - (Elf32_Off)keh;
		sh->sh_offset = (Elf32_Off)symtab - (Elf32_Off)keh;
		memcpy(keh, eh, sizeof(Elf32_Ehdr));
		keh->e_phoff = 0;
		keh->e_shoff = sizeof(Elf32_Ehdr);
		keh->e_phentsize = 0;
		keh->e_phnum = 0;

		printf("\nKernel debugger symbols ELF hdr @ %p", keh);

		symptr[0] = (int)keh;
		symptr[1] = roundup((int)symend, sizeof(int));

	} else {

		/*
		 *  Add all global sybols to PMONs internal symbol table.
		 */
		for (i = 0; i < nsym; i++, symtab++) {
			int type;

			dotik (4000, 0);
			if (symtab->st_shndx == SHN_UNDEF ||
			    symtab->st_shndx == SHN_COMMON) {
				continue;
			}

			type = ELF_ST_TYPE (symtab->st_info);
			if (type == STT_SECTION || type == STT_FILE) {
				continue;
			}

			/* only use globals and functions */
			if (ELF_ST_BIND(symtab->st_info) == STB_GLOBAL ||
			    type == STT_FUNC){
				if (symtab->st_name >= strh->sh_size) {
					fprintf (stderr, "\ncorrupt string pointer");
					return (0);
				}
			}
			if (!newsym (strtab + symtab->st_name, symtab->st_value)) {
				fprintf (stderr, "\nonly room for %d symbols", i);
				return (0);
			}
		}
	}
	return (1);
}
Exemplo n.º 16
0
void *
dtrace_dof_create(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t flags)
{
	dt_dof_t *ddo = &dtp->dt_dof;

	const dtrace_ecbdesc_t *edp, *last;
	const dtrace_probedesc_t *pdp;
	const dtrace_actdesc_t *ap;
	const dt_stmt_t *stp;

	uint_t maxacts = 0;
	uint_t maxfmt = 0;

	dt_provider_t *pvp;
	dt_xlator_t *dxp;
	dof_actdesc_t *dofa;
	dof_sec_t *sp;
	size_t ssize, lsize;
	dof_hdr_t h;

	dt_buf_t dof;
	char *fmt;
	uint_t i;

	if (flags & ~DTRACE_D_MASK) {
		(void) dt_set_errno(dtp, EINVAL);
		return (NULL);
	}

	flags |= dtp->dt_dflags;

	if (dof_hdr(dtp, pgp->dp_dofversion, &h) != 0)
		return (NULL);

	if (dt_dof_reset(dtp, pgp) != 0)
		return (NULL);

	/*
	 * Iterate through the statement list computing the maximum number of
	 * actions and the maximum format string for allocating local buffers.
	 */
	for (last = NULL, stp = dt_list_next(&pgp->dp_stmts);
	    stp != NULL; stp = dt_list_next(stp), last = edp) {

		dtrace_stmtdesc_t *sdp = stp->ds_desc;
		dtrace_actdesc_t *ap = sdp->dtsd_action;

		if (sdp->dtsd_fmtdata != NULL) {
			i = dtrace_printf_format(dtp,
			    sdp->dtsd_fmtdata, NULL, 0);
			maxfmt = MAX(maxfmt, i);
		}

		if ((edp = sdp->dtsd_ecbdesc) == last)
			continue; /* same ecb as previous statement */

		for (i = 0, ap = edp->dted_action; ap; ap = ap->dtad_next)
			i++;

		maxacts = MAX(maxacts, i);
	}

	dofa = alloca(sizeof (dof_actdesc_t) * maxacts);
	fmt = alloca(maxfmt + 1);

	ddo->ddo_strsec = dof_add_lsect(ddo, NULL, DOF_SECT_STRTAB, 1, 0, 0, 0);
	(void) dof_add_string(ddo, "");

	/*
	 * If there are references to dynamic translators in the program, add
	 * an imported translator table entry for each referenced translator.
	 */
	if (pgp->dp_xrefslen != 0) {
		for (dxp = dt_list_next(&dtp->dt_xlators);
		    dxp != NULL; dxp = dt_list_next(dxp)) {
			if (dxp->dx_id < pgp->dp_xrefslen &&
			    pgp->dp_xrefs[dxp->dx_id] != NULL)
				dof_add_translator(ddo, dxp, DOF_SECT_XLIMPORT);
		}
	}

	/*
	 * Now iterate through the statement list, creating the DOF section
	 * headers and data for each one and adding them to our buffers.
	 */
	for (last = NULL, stp = dt_list_next(&pgp->dp_stmts);
	    stp != NULL; stp = dt_list_next(stp), last = edp) {

		dof_secidx_t probesec = DOF_SECIDX_NONE;
		dof_secidx_t prdsec = DOF_SECIDX_NONE;
		dof_secidx_t actsec = DOF_SECIDX_NONE;

		const dt_stmt_t *next = stp;
		dtrace_stmtdesc_t *sdp = stp->ds_desc;
		dof_stridx_t strndx = 0;
		dof_probedesc_t dofp;
		dof_ecbdesc_t dofe;
		uint_t i;

		if ((edp = stp->ds_desc->dtsd_ecbdesc) == last)
			continue; /* same ecb as previous statement */

		pdp = &edp->dted_probe;

		/*
		 * Add a DOF_SECT_PROBEDESC for the ECB's probe description,
		 * and copy the probe description strings into the string table.
		 */
		dofp.dofp_strtab = ddo->ddo_strsec;
		dofp.dofp_provider = dof_add_string(ddo, pdp->dtpd_provider);
		dofp.dofp_mod = dof_add_string(ddo, pdp->dtpd_mod);
		dofp.dofp_func = dof_add_string(ddo, pdp->dtpd_func);
		dofp.dofp_name = dof_add_string(ddo, pdp->dtpd_name);
		dofp.dofp_id = pdp->dtpd_id;

		probesec = dof_add_lsect(ddo, &dofp, DOF_SECT_PROBEDESC,
		    sizeof (dof_secidx_t), 0,
		    sizeof (dof_probedesc_t), sizeof (dof_probedesc_t));

		/*
		 * If there is a predicate DIFO associated with the ecbdesc,
		 * write out the DIFO sections and save the DIFO section index.
		 */
		if (edp->dted_pred.dtpdd_difo != NULL)
			prdsec = dof_add_difo(ddo, edp->dted_pred.dtpdd_difo);

		/*
		 * Now iterate through the action list generating DIFOs as
		 * referenced therein and adding action descriptions to 'dofa'.
		 */
		for (i = 0, ap = edp->dted_action;
		    ap != NULL; ap = ap->dtad_next, i++) {

			if (ap->dtad_difo != NULL) {
				dofa[i].dofa_difo =
				    dof_add_difo(ddo, ap->dtad_difo);
			} else
				dofa[i].dofa_difo = DOF_SECIDX_NONE;

			/*
			 * If the first action in a statement has format data,
			 * add the format string to the global string table.
			 */
			if (sdp != NULL && ap == sdp->dtsd_action) {
				if (sdp->dtsd_fmtdata != NULL) {
					(void) dtrace_printf_format(dtp,
					    sdp->dtsd_fmtdata, fmt, maxfmt + 1);
					strndx = dof_add_string(ddo, fmt);
				} else
					strndx = 0; /* use dtad_arg instead */

				if ((next = dt_list_next(next)) != NULL)
					sdp = next->ds_desc;
				else
					sdp = NULL;
			}

			if (strndx != 0) {
				dofa[i].dofa_arg = strndx;
				dofa[i].dofa_strtab = ddo->ddo_strsec;
			} else {
				dofa[i].dofa_arg = ap->dtad_arg;
				dofa[i].dofa_strtab = DOF_SECIDX_NONE;
			}

			dofa[i].dofa_kind = ap->dtad_kind;
			dofa[i].dofa_ntuple = ap->dtad_ntuple;
			dofa[i].dofa_uarg = ap->dtad_uarg;
		}

		if (i > 0) {
			actsec = dof_add_lsect(ddo, dofa, DOF_SECT_ACTDESC,
			    sizeof (uint64_t), 0, sizeof (dof_actdesc_t),
			    sizeof (dof_actdesc_t) * i);
		}

		/*
		 * Now finally, add the DOF_SECT_ECBDESC referencing all the
		 * previously created sub-sections.
		 */
		dofe.dofe_probes = probesec;
		dofe.dofe_pred = prdsec;
		dofe.dofe_actions = actsec;
		dofe.dofe_pad = 0;
		dofe.dofe_uarg = edp->dted_uarg;

		(void) dof_add_lsect(ddo, &dofe, DOF_SECT_ECBDESC,
		    sizeof (uint64_t), 0, 0, sizeof (dof_ecbdesc_t));
	}

	/*
	 * If any providers are user-defined, output DOF sections corresponding
	 * to the providers and the probes and arguments that they define.
	 */
	if (flags & DTRACE_D_PROBES) {
		for (pvp = dt_list_next(&dtp->dt_provlist);
		    pvp != NULL; pvp = dt_list_next(pvp))
			dof_add_provider(ddo, pvp);
	}

	/*
	 * If we're not stripping unloadable sections, generate compiler
	 * comments and any other unloadable miscellany.
	 */
	if (!(flags & DTRACE_D_STRIP)) {
		(void) dof_add_usect(ddo, _dtrace_version, DOF_SECT_COMMENTS,
		    sizeof (char), 0, 0, strlen(_dtrace_version) + 1);
		(void) dof_add_usect(ddo, &dtp->dt_uts, DOF_SECT_UTSNAME,
		    sizeof (char), 0, 0, sizeof (struct utsname));
	}

	/*
	 * Compute and fill in the appropriate values for the dof_hdr_t's
	 * dofh_secnum, dofh_loadsz, and dofh_filez values.
	 */
	h.dofh_secnum = ddo->ddo_nsecs;
	ssize = sizeof (h) + dt_buf_len(&ddo->ddo_secs);

	h.dofh_loadsz = ssize +
	    dt_buf_len(&ddo->ddo_ldata) +
	    dt_buf_len(&ddo->ddo_strs);

	if (dt_buf_len(&ddo->ddo_udata) != 0) {
		lsize = roundup(h.dofh_loadsz, sizeof (uint64_t));
		h.dofh_filesz = lsize + dt_buf_len(&ddo->ddo_udata);
	} else {
		lsize = h.dofh_loadsz;
		h.dofh_filesz = lsize;
	}

	/*
	 * Set the global DOF_SECT_STRTAB's offset to be after the header,
	 * section headers, and other loadable data.  Since we're going to
	 * iterate over the buffer data directly, we must check for errors.
	 */
	if ((i = dt_buf_error(&ddo->ddo_secs)) != 0) {
		(void) dt_set_errno(dtp, i);
		return (NULL);
	}

	sp = dt_buf_ptr(&ddo->ddo_secs);
	assert(sp[ddo->ddo_strsec].dofs_type == DOF_SECT_STRTAB);
	assert(ssize == sizeof (h) + sizeof (dof_sec_t) * ddo->ddo_nsecs);

	sp[ddo->ddo_strsec].dofs_offset = ssize + dt_buf_len(&ddo->ddo_ldata);
	sp[ddo->ddo_strsec].dofs_size = dt_buf_len(&ddo->ddo_strs);

	/*
	 * Now relocate all the other section headers by adding the appropriate
	 * delta to their respective dofs_offset values.
	 */
	for (i = 0; i < ddo->ddo_nsecs; i++, sp++) {
		if (i == ddo->ddo_strsec)
			continue; /* already relocated above */

		if (sp->dofs_flags & DOF_SECF_LOAD)
			sp->dofs_offset += ssize;
		else
			sp->dofs_offset += lsize;
	}

	/*
	 * Finally, assemble the complete in-memory DOF buffer by writing the
	 * header and then concatenating all our buffers.  dt_buf_concat() will
	 * propagate any errors and cause dt_buf_claim() to return NULL.
	 */
	dt_buf_create(dtp, &dof, "dof", h.dofh_filesz);

	dt_buf_write(dtp, &dof, &h, sizeof (h), sizeof (uint64_t));
	dt_buf_concat(dtp, &dof, &ddo->ddo_secs, sizeof (uint64_t));
	dt_buf_concat(dtp, &dof, &ddo->ddo_ldata, sizeof (uint64_t));
	dt_buf_concat(dtp, &dof, &ddo->ddo_strs, sizeof (char));
	dt_buf_concat(dtp, &dof, &ddo->ddo_udata, sizeof (uint64_t));

	return (dt_buf_claim(dtp, &dof));
}
Exemplo n.º 17
0
long
   load_elf (int fd, char *buf, int *n, int flags)
{
	Elf32_Ehdr *ep;
	Elf32_Phdr *phtab = 0;
	Elf32_Shdr *shtab = 0;
	unsigned int nbytes;
	int i;
	Elf32_Off highest_load = 0;

	bootseg = 0;
	myflags=flags;

#ifdef __mips__
	tablebase = PHYS_TO_CACHED(memorysize);
#else
	tablebase = memorysize;
#endif

#if NGZIP > 0
	lseek(fd,*n,0);	
	read(fd,buf,2);
	if(((unsigned char)buf[0]==0x1f) && ((unsigned char)buf[1]==0x8b))flags |=ZFLAG;
	else flags &=~ZFLAG;
	myflags=flags;
	lseek(fd,*n,0);	
if(myflags&ZFLAG){
	gz_open(fd);
	*n = 0;
	gz_lseek (fd, 0, SEEK_SET);
	}
#endif /* NGZIP */

	ep = (Elf32_Ehdr *)buf;
	if (sizeof(*ep) > *n) {
#if NGZIP > 0
if(myflags&ZFLAG)
		*n += gz_read (fd, buf+*n, sizeof(*ep)-*n);
else 
#endif /* NGZIP */
{
	lseek(fd,*n,0);	
	*n += read (fd, buf+*n, sizeof(*ep)-*n);
}
		if (*n < sizeof(*ep)) {
#if NGZIP > 0
if(myflags&ZFLAG)			gz_close(fd);
#endif /* NGZIP */
			return -1;
		}
	}

	/* check header validity */
	if (ep->e_ident[EI_MAG0] != ELFMAG0 ||
	    ep->e_ident[EI_MAG1] != ELFMAG1 ||
	    ep->e_ident[EI_MAG2] != ELFMAG2 ||
	    ep->e_ident[EI_MAG3] != ELFMAG3) {

#if NGZIP > 0
if(myflags&ZFLAG)		gz_close(fd);
#endif /* NGZIP */

		return (-1);
	}

	fprintf (stderr, "(elf)\n");

	{
		char *nogood = (char *)0;
		if (ep->e_ident[EI_CLASS] == ELFCLASS64)
			return load_elf64(fd, buf, n, flags);

		if (ep->e_ident[EI_CLASS] != ELFCLASS32)
			nogood = "not 32-bit";
		else if (
#if BYTE_ORDER == BIG_ENDIAN
			 ep->e_ident[EI_DATA] != ELFDATA2MSB
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
			 ep->e_ident[EI_DATA] != ELFDATA2LSB
#endif
			  )
			nogood = "incorrect endianess";
		else if (ep->e_ident[EI_VERSION] != EV_CURRENT)
			nogood = "version not current";
		else if (
#ifdef powerpc
			 ep->e_machine != EM_PPC
#else /* default is MIPS */
#define GREENHILLS_HACK
#ifdef GREENHILLS_HACK
			 ep->e_machine != 10 && 
#endif
			 ep->e_machine != EM_MIPS
#endif
			  )
			nogood = "incorrect machine type";

		if (nogood) {
			fprintf (stderr, "Invalid ELF: %s\n", nogood);
#if NGZIP > 0
if(myflags&ZFLAG)			gz_close(fd);
#endif /* NGZIP */
			return -2;
		}
	}

	/* Is there a program header? */
	if (ep->e_phoff == 0 || ep->e_phnum == 0 ||
	    ep->e_phentsize != sizeof(Elf32_Phdr)) {
		fprintf (stderr, "missing program header (not executable)\n");
#if NGZIP > 0
if(myflags&ZFLAG)		gz_close(fd);
#endif /* NGZIP */
		return (-2);
	}

	/* Load program header */
#if _ORIG_CODE_
	nbytes = ep->e_phnum * sizeof(Elf32_Phdr);
#else
	/* XXX: We need to figure out why it works by adding 32!!!! */
	nbytes = ep->e_phnum * sizeof(Elf32_Phdr)+32;
#endif
	phtab = (Elf32_Phdr *) malloc (nbytes);
	if (!phtab) {
		fprintf (stderr,"\nnot enough memory to read program headers");
#if NGZIP > 0
if(myflags&ZFLAG)		gz_close(fd);
#endif /* NGZIP */
		return (-2);
	}

#if NGZIP > 0
if(myflags&ZFLAG){
	if (gz_lseek (fd, ep->e_phoff, SEEK_SET) != ep->e_phoff || 
	    gz_read (fd, (void *)phtab, nbytes) != nbytes) {
		perror ("program header");
		free (phtab);
		gz_close(fd);
		return (-2);
	}
	}else
#endif /* NGZIP */
	if (lseek (fd, ep->e_phoff, SEEK_SET) != ep->e_phoff || 
	    read (fd, (void *)phtab, nbytes) != nbytes) {
		perror ("program header");
		free (phtab);
		return (-2);
	}

	/*
	 * From now on we've got no guarantee about the file order, 
	 * even where the section header is.  Hopefully most linkers
	 * will put the section header after the program header, when
	 * they know that the executable is not demand paged.  We assume
	 * that the symbol and string tables always follow the program 
	 * segments.
	 */

	/* read section table (if before first program segment) */
	if (!(flags & NFLAG) && ep->e_shoff < phtab[0].p_offset)
		shtab = elfgetshdr (fd, ep);

	/* load program segments */
	if (!(flags & YFLAG)) {
		/* We cope with a badly sorted program header, as produced by 
		 * older versions of the GNU linker, by loading the segments
		 * in file offset order, not in program header order. */
		while (1) {
			Elf32_Off lowest_offset = ~0;
			Elf32_Phdr *ph = 0;

			/* find nearest loadable segment */
			for (i = 0; i < ep->e_phnum; i++)
				if (phtab[i].p_type == PT_LOAD && phtab[i].p_offset < lowest_offset) {
					ph = &phtab[i];
					lowest_offset = ph->p_offset;
				}
			if (!ph)
				break;		/* none found, finished */

			/* load the segment */
			if (ph->p_filesz) {
#if NGZIP > 0
if(myflags&ZFLAG){
				if (gz_lseek (fd, ph->p_offset, SEEK_SET) != ph->p_offset) {
					fprintf (stderr, "seek failed (corrupt object file?)\n");
					if (shtab)
						free (shtab);
					free (phtab);
					gz_close(fd);
					return (-2);
				}
				}else
#endif /* NGZIP */
				if (lseek (fd, ph->p_offset, SEEK_SET) != ph->p_offset) {
					fprintf (stderr, "seek failed (corrupt object file?)\n");
					if (shtab)
						free (shtab);
					free (phtab);
					return (-2);
				}
				if (bootread (fd, (void *)ph->p_vaddr, ph->p_filesz) != ph->p_filesz) {
					if (shtab) free (shtab);
					free (phtab);
#if NGZIP > 0
if(myflags&ZFLAG)					gz_close(fd);
#endif /* NGZIP */
					return (-2);
				}
			}
			if((ph->p_vaddr + ph->p_memsz) > highest_load) {
				highest_load = ph->p_vaddr + ph->p_memsz;
			}
			if (ph->p_filesz < ph->p_memsz)
				bootclear (fd, (void *)ph->p_vaddr + ph->p_filesz, ph->p_memsz - ph->p_filesz);
			ph->p_type = PT_NULL; /* remove from consideration */
		}
	}

	if (flags & KFLAG) {
		highest_load = roundup(highest_load, sizeof(long));
		tablebase = highest_load;
	}
	if (!(flags & NFLAG)) {
		/* read section table (if after last program segment) */
		if (!shtab)
			shtab = elfgetshdr (fd, ep);
		if (shtab) {
			elfreadsyms (fd, ep, shtab, flags);
			free (shtab);
		}
	}

	free (phtab);
#if NGZIP > 0
if(myflags&ZFLAG)	gz_close(fd);
#endif /* NGZIP */
	return (ep->e_entry + dl_offset);
}
Exemplo n.º 18
0
main()
{
	// file related
	int		fd;
	char		*fname = "dummy_core";
	int		page_size = sysconf(_SC_PAGE_SIZE);
	struct stat	statbuf;
	size_t		file_size = 0;

	struct rlimit	rlimit;

	// time
	struct timeval	start_time, end_time;
	long		mtime, seconds, useconds;

	char		*buf, *mem_buf;
	size_t		read_size = 0;
	size_t		total_size = 0;
	int		index = 0;

	// set rlimit for memory
	rlimit.rlim_max = RLIM_INFINITY;
	rlimit.rlim_cur = RLIM_INFINITY;
	if (setrlimit(RLIMIT_AS, &rlimit) < 0) {
		fprintf(stderr,"setrlimit RLIMIT_AS failed!\n");
		_exit(2);
	}

	if (setrlimit(RLIMIT_DATA, &rlimit) < 0) {
		fprintf(stderr,"setrlimit RLIMIT_DATA failed!\n");
		_exit(2);
	}

	if (setrlimit(RLIMIT_MEMLOCK, &rlimit) < 0) {
		fprintf(stderr,"setrlimit RLIMIT_MEMLOCK failed!\n");
		_exit(2);
	}

	if (setrlimit(RLIMIT_RSS, &rlimit) < 0) {
		fprintf(stderr,"setrlimit RLIMIT_RSS failed!\n");
		_exit(2);
	}

	if ((fd = open(fname, O_RDONLY)) < 0) {
		fprintf(stderr,"dcore: open(%s) failed!\n", fname);
		_exit(2);
	}
	if (fstat(fd, &statbuf) < 0) {
		fprintf(stderr,"dcore: stat(%s) failed!\n", fname);
		_exit(2);
	}
	file_size = roundup(statbuf.st_size, page_size);

	printf("file_size is %ld\n", file_size);

	if (file_size > (size_t)(35 * (size_t)GB) ) {
		file_size = (size_t) (35 * (size_t)GB);
	}

	if ((buf = malloc(file_size)) == NULL) {
		fprintf(stderr, "buf malloc failed\n");
		_exit(2);
	}

	if ((mem_buf = malloc(file_size)) == NULL) {
		fprintf(stderr, "mem_buf malloc failed\n");
		_exit(2);
	}

	if (mlock(buf, file_size)) {
		fprintf(stderr, "buf mlock failed\n");
		_exit(2);
	}

	if (mlock(mem_buf, file_size)) {
		fprintf(stderr, "mem_buf mlock failed\n");
		_exit(2);
	}

	// start testing
	printf("start loading...\n");

	while (total_size < file_size) {
		read_size = read(fd, buf+total_size , GB);

		if ( read_size != GB ) {
			fprintf(stderr, "read_size %ld doesn't match file_size %ld\n",
			read_size, file_size);
		}

		total_size += read_size;
		index++;

		printf("%d %ld\n", index, total_size);
	}

	if (total_size != file_size) {
			fprintf(stderr, "total_size %ld doesn't match file_size %ld\n",
			total_size, file_size);
	}

	printf("read %ld bytes to memory\n", total_size);
	printf("start memcpy\n");

	gettimeofday(&start_time, NULL);
	memcpy(mem_buf, buf, total_size);
	gettimeofday(&end_time, NULL);

	seconds = end_time.tv_sec - start_time.tv_sec;
	useconds = end_time.tv_usec - start_time.tv_usec;

	mtime = seconds * 1000 + (useconds/1000);

	printf("total time in msec is %ld\n", mtime);
#if 0
	read_size = read(fd, buf, file_size);

	if ( read_size != file_size ) {
		fprintf(stderr, "read_size %ld doesn't match file_size %ld\n",
			read_size, file_size);
	}

	printf("read %ld bytes to memory\n", read_size);
#endif

}
Exemplo n.º 19
0
NBLog::Reader::Reader(size_t size, const sp<IMemory>& iMemory)
    : mSize(roundup(size)), mShared(iMemory != 0 ? (const Shared *) iMemory->pointer() : NULL),
      mIMemory(iMemory), mFront(0)
{
}
Exemplo n.º 20
0
static int clamp_thread(void *arg)
{
	int cpunr = (unsigned long)arg;
	DEFINE_TIMER(wakeup_timer, noop_timer, 0, 0);
	static const struct sched_param param = {
		.sched_priority = MAX_USER_RT_PRIO/2,
	};
	unsigned int count = 0;
	unsigned int target_ratio;

	set_bit(cpunr, cpu_clamping_mask);
	set_freezable();
	init_timer_on_stack(&wakeup_timer);
	sched_setscheduler(current, SCHED_FIFO, &param);

	while (true == clamping && !kthread_should_stop() &&
		cpu_online(cpunr)) {
		int sleeptime;
		unsigned long target_jiffies;
		unsigned int guard;
		unsigned int compensation = 0;
		int interval; /* jiffies to sleep for each attempt */
		unsigned int duration_jiffies = msecs_to_jiffies(duration);
		unsigned int window_size_now;

		try_to_freeze();
		/*
		 * make sure user selected ratio does not take effect until
		 * the next round. adjust target_ratio if user has changed
		 * target such that we can converge quickly.
		 */
		target_ratio = set_target_ratio;
		guard = 1 + target_ratio/20;
		window_size_now = window_size;
		count++;

		/*
		 * systems may have different ability to enter package level
		 * c-states, thus we need to compensate the injected idle ratio
		 * to achieve the actual target reported by the HW.
		 */
		compensation = get_compensation(target_ratio);
		interval = duration_jiffies*100/(target_ratio+compensation);

		/* align idle time */
		target_jiffies = roundup(jiffies, interval);
		sleeptime = target_jiffies - jiffies;
		if (sleeptime <= 0)
			sleeptime = 1;
		schedule_timeout_interruptible(sleeptime);
		/*
		 * only elected controlling cpu can collect stats and update
		 * control parameters.
		 */
		if (cpunr == control_cpu && !(count%window_size_now)) {
			should_skip =
				powerclamp_adjust_controls(target_ratio,
							guard, window_size_now);
			smp_mb();
		}

		if (should_skip)
			continue;

		target_jiffies = jiffies + duration_jiffies;
		mod_timer(&wakeup_timer, target_jiffies);
		if (unlikely(local_softirq_pending()))
			continue;
		/*
		 * stop tick sched during idle time, interrupts are still
		 * allowed. thus jiffies are updated properly.
		 */
		preempt_disable();
		/* mwait until target jiffies is reached */
		while (time_before(jiffies, target_jiffies)) {
			unsigned long ecx = 1;
			unsigned long eax = target_mwait;

			/*
			 * REVISIT: may call enter_idle() to notify drivers who
			 * can save power during cpu idle. same for exit_idle()
			 */
			local_touch_nmi();
			stop_critical_timings();
			mwait_idle_with_hints(eax, ecx);
			start_critical_timings();
			atomic_inc(&idle_wakeup_counter);
		}
		preempt_enable();
	}
	del_timer_sync(&wakeup_timer);
	clear_bit(cpunr, cpu_clamping_mask);

	return 0;
}

/*
 * 1 HZ polling while clamping is active, useful for userspace
 * to monitor actual idle ratio.
 */
static void poll_pkg_cstate(struct work_struct *dummy);
static DECLARE_DELAYED_WORK(poll_pkg_cstate_work, poll_pkg_cstate);
static void poll_pkg_cstate(struct work_struct *dummy)
{
	static u64 msr_last;
	static u64 tsc_last;
	static unsigned long jiffies_last;

	u64 msr_now;
	unsigned long jiffies_now;
	u64 tsc_now;
	u64 val64;

	msr_now = pkg_state_counter();
	rdtscll(tsc_now);
	jiffies_now = jiffies;

	/* calculate pkg cstate vs tsc ratio */
	if (!msr_last || !tsc_last)
		pkg_cstate_ratio_cur = 1;
	else {
		if (tsc_now - tsc_last) {
			val64 = 100 * (msr_now - msr_last);
			do_div(val64, (tsc_now - tsc_last));
			pkg_cstate_ratio_cur = val64;
		}
	}

	/* update record */
	msr_last = msr_now;
	jiffies_last = jiffies_now;
	tsc_last = tsc_now;

	if (true == clamping)
		schedule_delayed_work(&poll_pkg_cstate_work, HZ);
}

static int start_power_clamp(void)
{
	unsigned long cpu;
	struct task_struct *thread;

	/* check if pkg cstate counter is completely 0, abort in this case */
	if (!has_pkg_state_counter()) {
		pr_err("pkg cstate counter not functional, abort\n");
		return -EINVAL;
	}

	set_target_ratio = clamp(set_target_ratio, 0U, MAX_TARGET_RATIO - 1);
	/* prevent cpu hotplug */
	get_online_cpus();

	/* prefer BSP */
	control_cpu = 0;
	if (!cpu_online(control_cpu))
		control_cpu = smp_processor_id();

	clamping = true;
	schedule_delayed_work(&poll_pkg_cstate_work, 0);

	/* start one thread per online cpu */
	for_each_online_cpu(cpu) {
		struct task_struct **p =
			per_cpu_ptr(powerclamp_thread, cpu);

		thread = kthread_create_on_node(clamp_thread,
						(void *) cpu,
						cpu_to_node(cpu),
						"kidle_inject/%ld", cpu);
		/* bind to cpu here */
		if (likely(!IS_ERR(thread))) {
			kthread_bind(thread, cpu);
			wake_up_process(thread);
			*p = thread;
		}

	}
	put_online_cpus();

	return 0;
}
Exemplo n.º 21
0
/*static*/
size_t NBLog::Timeline::sharedSize(size_t size)
{
    return sizeof(Shared) + roundup(size);
}
Exemplo n.º 22
0
/*
 * Attach a display.  We need to notice if it is the console, too.
 */
void
cgfourteenattach(device_t parent, device_t self, void *aux)
{
	union obio_attach_args *uoba = aux;
	struct sbus_attach_args *sa = &uoba->uoba_sbus;
	struct cgfourteen_softc *sc = device_private(self);
	struct fbdevice *fb = &sc->sc_fb;
	bus_space_handle_t bh;
	int node, ramsize;
	volatile uint32_t *lut;
	int i, isconsole;

	sc->sc_dev = self;
	node = sa->sa_node;

	/* Remember cookies for cgfourteenmmap() */
	sc->sc_bustag = sa->sa_bustag;

	fb->fb_driver = &cgfourteenfbdriver;
	fb->fb_device = sc->sc_dev;
	/* Mask out invalid flags from the user. */
	fb->fb_flags = device_cfdata(sc->sc_dev)->cf_flags & FB_USERMASK;

	/*
	 * We're emulating a cg3/8, so represent ourselves as one
	 */
#ifdef CG14_CG8
	fb->fb_type.fb_type = FBTYPE_MEMCOLOR;
	fb->fb_type.fb_depth = 32;
#else
	fb->fb_type.fb_type = FBTYPE_SUN3COLOR;
	fb->fb_type.fb_depth = 8;
#endif
	fb_setsize_obp(fb, sc->sc_fb.fb_type.fb_depth, 1152, 900, node);
	ramsize = roundup(fb->fb_type.fb_height * fb->fb_linebytes, NBPG);

	fb->fb_type.fb_cmsize = CG14_CLUT_SIZE;
	fb->fb_type.fb_size = ramsize + COLOUR_OFFSET;

	if (sa->sa_nreg < 2) {
		printf("%s: only %d register sets\n",
			self->dv_xname, sa->sa_nreg);
		return;
	}
	bcopy(sa->sa_reg, sc->sc_physadr,
	      sa->sa_nreg * sizeof(struct sbus_reg));

	sc->sc_vramsize = sc->sc_physadr[CG14_PXL_IDX].sbr_size;

	printf(": %d MB VRAM", (uint32_t)(sc->sc_vramsize >> 20));
	/*
	 * Now map in the 8 useful pages of registers
	 */
	if (sa->sa_size < 0x10000) {
#ifdef DIAGNOSTIC
		printf("warning: can't find all cgfourteen registers...\n");
#endif
		sa->sa_size = 0x10000;
	}
	if (sbus_bus_map(sa->sa_bustag, sa->sa_slot,
			 sa->sa_offset,
			 sa->sa_size,
			 BUS_SPACE_MAP_LINEAR,
			 &bh) != 0) {
		printf("%s: cannot map control registers\n", self->dv_xname);
		return;
	}
	sc->sc_regh = bh;

	sc->sc_ctl   = (struct cg14ctl  *) (bh);
	sc->sc_hwc   = (struct cg14curs *) (bh + CG14_OFFSET_CURS);
	sc->sc_dac   = (struct cg14dac  *) (bh + CG14_OFFSET_DAC);
	sc->sc_xlut  = (struct cg14xlut *) (bh + CG14_OFFSET_XLUT);
	sc->sc_clut1 = (struct cg14clut *) (bh + CG14_OFFSET_CLUT1);
	sc->sc_clut2 = (struct cg14clut *) (bh + CG14_OFFSET_CLUT2);
	sc->sc_clut3 = (struct cg14clut *) (bh + CG14_OFFSET_CLUT3);
	sc->sc_clutincr =        (u_int *) (bh + CG14_OFFSET_CLUTINCR);

	/*
	 * Let the user know that we're here
	 */
#ifdef CG14_CG8
	printf(": cgeight emulated at %dx%dx24bpp",
		fb->fb_type.fb_width, fb->fb_type.fb_height);
#else
	printf(": cgthree emulated at %dx%dx8bpp",
		fb->fb_type.fb_width, fb->fb_type.fb_height);
#endif
	/*
	 * Enable the video.
	 */
	cg14_set_video(sc, 1);

	/*
	 * Grab the initial colormap
	 */
	lut = sc->sc_clut1->clut_lut;
	for (i = 0; i < CG14_CLUT_SIZE; i++)
		sc->sc_cmap.cm_chip[i] = lut[i];

	/* See if we're the console */
        isconsole = fb_is_console(node);

#if defined(RASTERCONSOLE)
	if (isconsole) {
		printf(" (console)\n");
		/* *sbus*_bus_map?  but that's how we map the regs... */
		if (sbus_bus_map( sc->sc_bustag,
				  sc->sc_physadr[CG14_PXL_IDX].sbr_slot,
				  sc->sc_physadr[CG14_PXL_IDX].sbr_offset +
				    0x03800000,
				  1152 * 900, BUS_SPACE_MAP_LINEAR,
				  &bh) != 0) {
			printf("%s: cannot map pixels\n",
			    device_xname(sc->sc_dev));
			return;
		}
		sc->sc_rcfb = sc->sc_fb;
		sc->sc_rcfb.fb_type.fb_type = FBTYPE_SUN3COLOR;
		sc->sc_rcfb.fb_type.fb_depth = 8;
		sc->sc_rcfb.fb_linebytes = 1152;
		sc->sc_rcfb.fb_type.fb_size = roundup(1152*900,NBPG);
		sc->sc_rcfb.fb_pixels = (void *)bh;

		printf("vram at %p\n",(void *)bh);
		/* XXX should use actual screen size */

		for (i = 0; i < 1152 * 900; i++)
		    ((unsigned char *)bh)[i] = 0;
		fbrcons_init(&sc->sc_rcfb);
		cg14_set_rcons_luts(sc);
		sc->sc_ctl->ctl_mctl = CG14_MCTL_ENABLEVID | 
		    CG14_MCTL_PIXMODE_32 | CG14_MCTL_POWERCTL;
	} else
		printf("\n");
#endif

#if NWSDISPLAY > 0
	if (sbus_bus_map( sc->sc_bustag,
	    sc->sc_physadr[CG14_PXL_IDX].sbr_slot,
	    sc->sc_physadr[CG14_PXL_IDX].sbr_offset,
	    ramsize, BUS_SPACE_MAP_LINEAR, &bh) != 0) {
		printf("%s: cannot map pixels\n", device_xname(sc->sc_dev));
		return;
	}

	sc->sc_fb.fb_pixels = bus_space_vaddr(sc->sc_bustag, bh);
	if (isconsole)
		printf(" (console)\n");
	else
		printf("\n");

	sc->sc_depth = 8;
	cg14_setup_wsdisplay(sc, isconsole);
#endif

	/* Attach to /dev/fb */
	fb_attach(&sc->sc_fb, isconsole);
}
Exemplo n.º 23
0
NBLog::Writer::Writer(size_t size, const sp<IMemory>& iMemory)
    : mSize(roundup(size)), mShared(iMemory != 0 ? (Shared *) iMemory->pointer() : NULL),
      mIMemory(iMemory), mRear(0), mEnabled(mShared != NULL)
{
}
Exemplo n.º 24
0
Elf *
fake_elf32(struct ps_prochandle *P, file_info_t *fptr, uintptr_t addr,
    Ehdr *ehdr, uint_t phnum, Phdr *phdr)
#endif
{
	enum {
		DI_PLTGOT,
		DI_JMPREL,
		DI_PLTRELSZ,
		DI_PLTREL,
		DI_SYMTAB,
		DI_HASH,
		DI_SYMENT,
		DI_STRTAB,
		DI_STRSZ,
		DI_SUNW_SYMTAB,
		DI_SUNW_SYMSZ,
		DI_NENT
	};
	/*
	 * Mask of dynamic options that must be present in a well
	 * formed dynamic section. We need all of these in order to
	 * put together a complete set of elf sections. They are
	 * mandatory in both executables and shared objects so if one
	 * of them is missing, we're in some trouble and should abort.
	 * The PLT items are expected, but we will let them slide if
	 * need be. The DI_SUNW_SYM* items are completely optional, so
	 * we use them if they are present and ignore them otherwise.
	 */
	const int di_req_mask = (1 << DI_SYMTAB) | (1 << DI_HASH) |
		(1 << DI_SYMENT) | (1 << DI_STRTAB) | (1 << DI_STRSZ);
	int di_mask = 0;
	size_t size = 0;
	caddr_t elfdata = NULL;
	Elf *elf;
	size_t dynsym_size = 0, ldynsym_size;
	int dynstr_shndx;
	Ehdr *ep;
	Shdr *sp;
	Dyn *dp = NULL;
	Dyn *d[DI_NENT] = { 0 };
	uint_t i;
	Off off;
	size_t pltsz = 0, pltentries = 0;
	uintptr_t hptr = NULL;
	Word hnchains, hnbuckets;

	if (ehdr->e_type == ET_DYN)
		phdr->p_vaddr += addr;

	if (P->rap != NULL) {
		if (rd_get_dyns(P->rap, addr, (void **)&dp, NULL) != RD_OK)
			goto bad;
	} else {
		if ((dp = malloc(phdr->p_filesz)) == NULL)
			goto bad;
		if (Pread(P, dp, phdr->p_filesz, phdr->p_vaddr) !=
		    phdr->p_filesz)
			goto bad;
	}

	/*
	 * Iterate over the items in the dynamic section, grabbing
	 * the address of items we want and saving them in dp[].
	 */
	for (i = 0; i < phdr->p_filesz / sizeof (Dyn); i++) {
		switch (dp[i].d_tag) {
		/* For the .plt section */
		case DT_PLTGOT:
			d[DI_PLTGOT] = &dp[i];
			break;
		case DT_JMPREL:
			d[DI_JMPREL] = &dp[i];
			break;
		case DT_PLTRELSZ:
			d[DI_PLTRELSZ] = &dp[i];
			break;
		case DT_PLTREL:
			d[DI_PLTREL] = &dp[i];
			break;

		/* For the .dynsym section */
		case DT_SYMTAB:
			d[DI_SYMTAB] = &dp[i];
			di_mask |= (1 << DI_SYMTAB);
			break;
		case DT_HASH:
			d[DI_HASH] = &dp[i];
			di_mask |= (1 << DI_HASH);
			break;
		case DT_SYMENT:
			d[DI_SYMENT] = &dp[i];
			di_mask |= (1 << DI_SYMENT);
			break;
		case DT_SUNW_SYMTAB:
			d[DI_SUNW_SYMTAB] = &dp[i];
			break;
		case DT_SUNW_SYMSZ:
			d[DI_SUNW_SYMSZ] = &dp[i];
			break;

		/* For the .dynstr section */
		case DT_STRTAB:
			d[DI_STRTAB] = &dp[i];
			di_mask |= (1 << DI_STRTAB);
			break;
		case DT_STRSZ:
			d[DI_STRSZ] = &dp[i];
			di_mask |= (1 << DI_STRSZ);
			break;
		}
	}

	/* Ensure all required entries were collected */
	if ((di_mask & di_req_mask) != di_req_mask) {
		dprintf("text section missing required dynamic entries\n");
		goto bad;
	}

	/* SUNW_ldynsym must be adjacent to dynsym. Ignore if not */
	if ((d[DI_SUNW_SYMTAB] != NULL) && (d[DI_SUNW_SYMSZ] != NULL) &&
	    ((d[DI_SYMTAB]->d_un.d_ptr <= d[DI_SUNW_SYMTAB]->d_un.d_ptr) ||
	    (d[DI_SYMTAB]->d_un.d_ptr >= (d[DI_SUNW_SYMTAB]->d_un.d_ptr +
	    d[DI_SUNW_SYMSZ]->d_un.d_val)))) {
		d[DI_SUNW_SYMTAB] = NULL;
		d[DI_SUNW_SYMSZ] = NULL;
	}

	/* elf header */
	size = sizeof (Ehdr);

	/* program headers from in-core elf fragment */
	size += phnum * ehdr->e_phentsize;

	/* unused shdr, and .shstrtab section */
	size += sizeof (Shdr);
	size += sizeof (Shdr);
	size += roundup(sizeof (shstr), SH_ADDRALIGN);

	if (d[DI_HASH] != NULL) {
		Word hash[2];

		hptr = d[DI_HASH]->d_un.d_ptr;
		if (ehdr->e_type == ET_DYN)
			hptr += addr;

		if (Pread(P, hash, sizeof (hash), hptr) != sizeof (hash)) {
			dprintf("Pread of .hash at %lx failed\n",
			    (long)(hptr));
			goto bad;
		}

		hnbuckets = hash[0];
		hnchains = hash[1];
	}

	if ((d[DI_HASH] == NULL) || (hnbuckets == 0) || (hnchains == 0)) {
		dprintf("empty or missing .hash\n");
		goto bad;
	}

	/*
	 * .dynsym and .SUNW_ldynsym sections.
	 *
	 * The string table section used for the symbol table and
	 * dynamic sections lies immediately after the dynsym, so the
	 * presence of SUNW_ldynsym changes the dynstr section index.
	 */
	if (d[DI_SUNW_SYMTAB] != NULL) {
		size += sizeof (Shdr);	/* SUNW_ldynsym shdr */
		ldynsym_size = (size_t)d[DI_SUNW_SYMSZ]->d_un.d_val;
		dynsym_size = ldynsym_size - (d[DI_SYMTAB]->d_un.d_ptr
		    - d[DI_SUNW_SYMTAB]->d_un.d_ptr);
		ldynsym_size -= dynsym_size;
		dynstr_shndx = 4;
	} else {
		dynsym_size = sizeof (Sym) * hnchains;
		ldynsym_size = 0;
		dynstr_shndx = 3;
	}
	size += sizeof (Shdr) + ldynsym_size + dynsym_size;

	/* .dynstr section */
	size += sizeof (Shdr);
	size += roundup(d[DI_STRSZ]->d_un.d_val, SH_ADDRALIGN);

	/* .dynamic section */
	size += sizeof (Shdr);
	size += roundup(phdr->p_filesz, SH_ADDRALIGN);

	/* .plt section */
	if (d[DI_PLTGOT] != NULL && d[DI_JMPREL] != NULL &&
	    d[DI_PLTRELSZ] != NULL && d[DI_PLTREL] != NULL) {
		size_t pltrelsz = d[DI_PLTRELSZ]->d_un.d_val;

		if (d[DI_PLTREL]->d_un.d_val == DT_RELA) {
			pltentries = pltrelsz / sizeof (Rela);
		} else if (d[DI_PLTREL]->d_un.d_val == DT_REL) {
			pltentries = pltrelsz / sizeof (Rel);
		} else {
			/* fall back to the platform default */
#if ((defined(__i386) || defined(__amd64)) && !defined(_ELF64))
			pltentries = pltrelsz / sizeof (Rel);
			dprintf("DI_PLTREL not found, defaulting to Rel");
#else /* (!(__i386 || __amd64)) || _ELF64 */
			pltentries = pltrelsz / sizeof (Rela);
			dprintf("DI_PLTREL not found, defaulting to Rela");
#endif /* (!(__i386 || __amd64) || _ELF64 */
		}

		if (pltentries < PLTREL_MIN_ENTRIES) {
			dprintf("too few PLT relocation entries "
			    "(found %lu, expected at least %d)\n",
			    (long)pltentries, PLTREL_MIN_ENTRIES);
			goto bad;
		}
		if (pltentries < PLTREL_MIN_ENTRIES + 2)
			goto done_with_plt;

		/*
		 * Now that we know the number of plt relocation entries
		 * we can calculate the size of the plt.
		 */
		pltsz = (pltentries + M_PLT_XNumber) * M_PLT_ENTSIZE;
#if defined(__sparc)
		/* The sparc PLT always has a (delay slot) nop at the end */
		pltsz += 4;
#endif /* __sparc */

		size += sizeof (Shdr);
		size += roundup(pltsz, SH_ADDRALIGN);
	}
done_with_plt:

	if ((elfdata = calloc(1, size)) == NULL)
		goto bad;

	/* LINTED - alignment */
	ep = (Ehdr *)elfdata;
	(void) memcpy(ep, ehdr, offsetof(Ehdr, e_phoff));

	ep->e_ehsize = sizeof (Ehdr);
	ep->e_phoff = sizeof (Ehdr);
	ep->e_phentsize = ehdr->e_phentsize;
	ep->e_phnum = phnum;
	ep->e_shoff = ep->e_phoff + phnum * ep->e_phentsize;
	ep->e_shentsize = sizeof (Shdr);
	/*
	 * Plt and SUNW_ldynsym sections are optional. C logical
	 * binary operators return a 0 or 1 value, so the following
	 * adds 1 for each optional section present.
	 */
	ep->e_shnum = 5 + (pltsz != 0) + (d[DI_SUNW_SYMTAB] != NULL);
	ep->e_shstrndx = 1;

	/* LINTED - alignment */
	sp = (Shdr *)(elfdata + ep->e_shoff);
	off = ep->e_shoff + ep->e_shentsize * ep->e_shnum;

	/*
	 * Copying the program headers directly from the process's
	 * address space is a little suspect, but since we only
	 * use them for their address and size values, this is fine.
	 */
	if (Pread(P, &elfdata[ep->e_phoff], phnum * ep->e_phentsize,
	    addr + ehdr->e_phoff) != phnum * ep->e_phentsize) {
		dprintf("failed to read program headers\n");
		goto bad;
	}

	/*
	 * The first elf section is always skipped.
	 */
	sp++;

	/*
	 * Section Header: .shstrtab
	 */
	sp->sh_name = SHSTR_NDX_shstrtab;
	sp->sh_type = SHT_STRTAB;
	sp->sh_flags = SHF_STRINGS;
	sp->sh_addr = 0;
	sp->sh_offset = off;
	sp->sh_size = sizeof (shstr);
	sp->sh_link = 0;
	sp->sh_info = 0;
	sp->sh_addralign = 1;
	sp->sh_entsize = 0;

	(void) memcpy(&elfdata[off], shstr, sizeof (shstr));
	off += roundup(sp->sh_size, SH_ADDRALIGN);
	sp++;

	/*
	 * Section Header: .SUNW_ldynsym
	 */
	if (d[DI_SUNW_SYMTAB] != NULL) {
		sp->sh_name = SHSTR_NDX_SUNW_ldynsym;
		sp->sh_type = SHT_SUNW_LDYNSYM;
		sp->sh_flags = SHF_ALLOC;
		sp->sh_addr = d[DI_SUNW_SYMTAB]->d_un.d_ptr;
		if (ehdr->e_type == ET_DYN)
			sp->sh_addr += addr;
		sp->sh_offset = off;
		sp->sh_size = ldynsym_size;
		sp->sh_link = dynstr_shndx;
		/* Index of 1st global in table that has none == # items */
		sp->sh_info = sp->sh_size / sizeof (Sym);
		sp->sh_addralign = SH_ADDRALIGN;
		sp->sh_entsize = sizeof (Sym);

		if (Pread(P, &elfdata[off], sp->sh_size,
		    sp->sh_addr) != sp->sh_size) {
			dprintf("failed to read .SUNW_ldynsym at %lx\n",
			    (long)sp->sh_addr);
			goto bad;
		}
		off += sp->sh_size;
		/* No need to round up ldynsym data. Dynsym data is same type */
		sp++;
	}

	/*
	 * Section Header: .dynsym
	 */
	sp->sh_name = SHSTR_NDX_dynsym;
	sp->sh_type = SHT_DYNSYM;
	sp->sh_flags = SHF_ALLOC;
	sp->sh_addr = d[DI_SYMTAB]->d_un.d_ptr;
	if (ehdr->e_type == ET_DYN)
		sp->sh_addr += addr;
	sp->sh_offset = off;
	sp->sh_size = dynsym_size;
	sp->sh_link = dynstr_shndx;
	sp->sh_info = 1;	/* Index of 1st global in table */
	sp->sh_addralign = SH_ADDRALIGN;
	sp->sh_entsize = sizeof (Sym);

	if (Pread(P, &elfdata[off], sp->sh_size,
	    sp->sh_addr) != sp->sh_size) {
		dprintf("failed to read .dynsym at %lx\n",
		    (long)sp->sh_addr);
		goto bad;
	}

	off += roundup(sp->sh_size, SH_ADDRALIGN);
	sp++;

	/*
	 * Section Header: .dynstr
	 */
	sp->sh_name = SHSTR_NDX_dynstr;
	sp->sh_type = SHT_STRTAB;
	sp->sh_flags = SHF_ALLOC | SHF_STRINGS;
	sp->sh_addr = d[DI_STRTAB]->d_un.d_ptr;
	if (ehdr->e_type == ET_DYN)
		sp->sh_addr += addr;
	sp->sh_offset = off;
	sp->sh_size = d[DI_STRSZ]->d_un.d_val;
	sp->sh_link = 0;
	sp->sh_info = 0;
	sp->sh_addralign = 1;
	sp->sh_entsize = 0;

	if (Pread(P, &elfdata[off], sp->sh_size,
	    sp->sh_addr) != sp->sh_size) {
		dprintf("failed to read .dynstr\n");
		goto bad;
	}
	off += roundup(sp->sh_size, SH_ADDRALIGN);
	sp++;

	/*
	 * Section Header: .dynamic
	 */
	sp->sh_name = SHSTR_NDX_dynamic;
	sp->sh_type = SHT_DYNAMIC;
	sp->sh_flags = SHF_WRITE | SHF_ALLOC;
	sp->sh_addr = phdr->p_vaddr;
	if (ehdr->e_type == ET_DYN)
		sp->sh_addr -= addr;
	sp->sh_offset = off;
	sp->sh_size = phdr->p_filesz;
	sp->sh_link = dynstr_shndx;
	sp->sh_info = 0;
	sp->sh_addralign = SH_ADDRALIGN;
	sp->sh_entsize = sizeof (Dyn);

	(void) memcpy(&elfdata[off], dp, sp->sh_size);
	off += roundup(sp->sh_size, SH_ADDRALIGN);
	sp++;

	/*
	 * Section Header: .plt
	 */
	if (pltsz != 0) {
		ulong_t		plt_symhash;
		uint_t		htmp, ndx;
		uintptr_t	strtabptr, strtabname;
		Sym		sym, *symtabptr;
		uint_t		*hash;
		char		strbuf[sizeof ("_PROCEDURE_LINKAGE_TABLE_")];

		/*
		 * Now we need to find the address of the plt by looking
		 * up the "_PROCEDURE_LINKAGE_TABLE_" symbol.
		 */

		/* get the address of the symtab and strtab sections */
		strtabptr = d[DI_STRTAB]->d_un.d_ptr;
		symtabptr = (Sym *)(uintptr_t)d[DI_SYMTAB]->d_un.d_ptr;
		if (ehdr->e_type == ET_DYN) {
			strtabptr += addr;
			symtabptr = (Sym*)((uintptr_t)symtabptr + addr);
		}

		/* find the .hash bucket address for this symbol */
		plt_symhash = elf_hash("_PROCEDURE_LINKAGE_TABLE_");
		htmp = plt_symhash % hnbuckets;
		hash = &((uint_t *)hptr)[2 + htmp];

		/* read the elf hash bucket index */
		if (Pread(P, &ndx, sizeof (ndx), (uintptr_t)hash) !=
		    sizeof (ndx)) {
			dprintf("Pread of .hash at %lx failed\n", (long)hash);
			goto bad;
		}

		while (ndx) {
			if (Pread(P, &sym, sizeof (sym),
			    (uintptr_t)&symtabptr[ndx]) != sizeof (sym)) {
				dprintf("Pread of .symtab at %lx failed\n",
				    (long)&symtabptr[ndx]);
				goto bad;
			}

			strtabname = strtabptr + sym.st_name;
			if (Pread_string(P, strbuf, sizeof (strbuf),
			    strtabname) < 0) {
				dprintf("Pread of .strtab at %lx failed\n",
				    (long)strtabname);
				goto bad;
			}

			if (strcmp("_PROCEDURE_LINKAGE_TABLE_", strbuf) == 0)
				break;

			hash = &((uint_t *)hptr)[2 + hnbuckets + ndx];
			if (Pread(P, &ndx, sizeof (ndx), (uintptr_t)hash) !=
			    sizeof (ndx)) {
				dprintf("Pread of .hash at %lx failed\n",
				    (long)hash);
				goto bad;
			}
		}

#if defined(__sparc)
		if (sym.st_value != d[DI_PLTGOT]->d_un.d_ptr) {
			dprintf("warning: DI_PLTGOT (%lx) doesn't match "
			    ".plt symbol pointer (%lx)",
			    (long)d[DI_PLTGOT]->d_un.d_ptr,
			    (long)sym.st_value);
		}
#endif /* __sparc */

		if (ndx == 0) {
			dprintf(
			    "Failed to find \"_PROCEDURE_LINKAGE_TABLE_\"\n");
			goto bad;
		}

		sp->sh_name = SHSTR_NDX_plt;
		sp->sh_type = SHT_PROGBITS;
		sp->sh_flags = SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR;
		sp->sh_addr = sym.st_value;
		if (ehdr->e_type == ET_DYN)
			sp->sh_addr += addr;
		sp->sh_offset = off;
		sp->sh_size = pltsz;
		sp->sh_link = 0;
		sp->sh_info = 0;
		sp->sh_addralign = SH_ADDRALIGN;
		sp->sh_entsize = M_PLT_ENTSIZE;

		if (Pread(P, &elfdata[off], sp->sh_size, sp->sh_addr) !=
		    sp->sh_size) {
			dprintf("failed to read .plt at %lx\n",
			    (long)sp->sh_addr);
			goto bad;
		}
		off += roundup(sp->sh_size, SH_ADDRALIGN);
		sp++;
	}

	/* make sure we didn't write past the end of allocated memory */
	sp++;
	assert(((uintptr_t)(sp) - 1) < ((uintptr_t)elfdata + size));

	free(dp);
	if ((elf = elf_memory(elfdata, size)) == NULL) {
		free(elfdata);
		return (NULL);
	}

	fptr->file_elfmem = elfdata;

	return (elf);

bad:
	if (dp != NULL)
		free(dp);
	if (elfdata != NULL)
		free(elfdata);
	return (NULL);
}
Exemplo n.º 25
0
/*
 * Load the information expected by an amd64 kernel.
 *
 * - The 'boothowto' argument is constructed
 * - The 'bootdev' argument is constructed
 * - The 'bootinfo' struct is constructed, and copied into the kernel space.
 * - The kernel environment is copied into kernel space.
 * - Module metadata are formatted and placed in kernel space.
 */
int
bi_load64(char *args, vm_offset_t addr, vm_offset_t *modulep,
    vm_offset_t *kernendp, int add_smap)
{
    struct preloaded_file	*xp, *kfp;
    struct i386_devdesc		*rootdev;
    struct file_metadata	*md;
    uint64_t			kernend;
    uint64_t			envp;
    uint64_t			module;
    vm_offset_t			size;
    char			*rootdevname;
    int				howto;

    if (!bi_checkcpu()) {
	printf("CPU doesn't support long mode\n");
	return (EINVAL);
    }

    howto = bi_getboothowto(args);

    /*
     * Allow the environment variable 'rootdev' to override the supplied device
     * This should perhaps go to MI code and/or have $rootdev tested/set by
     * MI code before launching the kernel.
     */
    rootdevname = getenv("rootdev");
    i386_getdev((void **)(&rootdev), rootdevname, NULL);
    if (rootdev == NULL) {		/* bad $rootdev/$currdev */
	printf("can't determine root device\n");
	return(EINVAL);
    }

    /* Try reading the /etc/fstab file to select the root device */
    getrootmount(i386_fmtdev((void *)rootdev));

    if (addr == 0) {
        /* find the last module in the chain */
        for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
            if (addr < (xp->f_addr + xp->f_size))
                addr = xp->f_addr + xp->f_size;
        }
    }
    /* pad to a page boundary */
    addr = roundup(addr, PAGE_SIZE);

    /* place the metadata before anything */
    module = *modulep = addr;

    kfp = file_findfile(NULL, "elf kernel");
    if (kfp == NULL)
      kfp = file_findfile(NULL, "elf64 kernel");
    if (kfp == NULL)
	panic("can't find kernel file");
    kernend = 0;	/* fill it in later */
    file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
    file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
    file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
    file_addmetadata(kfp, MODINFOMD_MODULEP, sizeof module, &module);
    if (add_smap != 0)
        bios_addsmapdata(kfp);
#ifdef LOADER_GELI_SUPPORT
    geli_export_key_metadata(kfp);
#endif

    size = bi_copymodules64(0);

    /* copy our environment */
    envp = roundup(addr + size, PAGE_SIZE);
    addr = bi_copyenv(envp);

    /* set kernend */
    kernend = roundup(addr, PAGE_SIZE);
    *kernendp = kernend;

    /* patch MODINFOMD_KERNEND */
    md = file_findmetadata(kfp, MODINFOMD_KERNEND);
    bcopy(&kernend, md->md_data, sizeof kernend);

    /* patch MODINFOMD_ENVP */
    md = file_findmetadata(kfp, MODINFOMD_ENVP);
    bcopy(&envp, md->md_data, sizeof envp);

    /* copy module list and metadata */
    (void)bi_copymodules64(*modulep);

    return(0);
}
Exemplo n.º 26
0
/*
 * Initialize the 4-word tx control descriptor on 5212
 */
static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
	struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len,
	int padsize,
	enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0,
	unsigned int tx_tries0, unsigned int key_index,
	unsigned int antenna_mode, unsigned int flags,
	unsigned int rtscts_rate,
	unsigned int rtscts_duration)
{
	struct ath5k_hw_4w_tx_ctl *tx_ctl;
	unsigned int frame_len;

	/*
	 * Use local variables for these to reduce load/store access on
	 * uncached memory
	 */
	u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0;

	tx_ctl = &desc->ud.ds_tx5212.tx_ctl;

	/*
	 * Validate input
	 * - Zero retries don't make sense.
	 * - A zero rate will put the HW into a mode where it continuously sends
	 *   noise on the channel, so it is important to avoid this.
	 */
	if (unlikely(tx_tries0 == 0)) {
		ATH5K_ERR(ah->ah_sc, "zero retries\n");
		WARN_ON(1);
		return -EINVAL;
	}
	if (unlikely(tx_rate0 == 0)) {
		ATH5K_ERR(ah->ah_sc, "zero rate\n");
		WARN_ON(1);
		return -EINVAL;
	}

	tx_power += ah->ah_txpower.txp_offset;
	if (tx_power > AR5K_TUNE_MAX_TXPOWER)
		tx_power = AR5K_TUNE_MAX_TXPOWER;

	/* Clear descriptor status area */
	memset(&desc->ud.ds_tx5212.tx_stat, 0,
	       sizeof(desc->ud.ds_tx5212.tx_stat));

	/* Setup control descriptor */

	/* Verify and set frame length */

	/* remove padding we might have added before */
	frame_len = pkt_len - padsize + FCS_LEN;

	if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
		return -EINVAL;

	txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;

	/* Verify and set buffer length */

	/* NB: beacon's BufLen must be a multiple of 4 bytes */
	if (type == AR5K_PKT_TYPE_BEACON)
		pkt_len = roundup(pkt_len, 4);

	if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
		return -EINVAL;

	txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;

	txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
		  AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
	txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
	txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
	txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;

#define _TX_FLAGS(_c, _flag)					\
	if (flags & AR5K_TXDESC_##_flag) {			\
		txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag;	\
	}

	_TX_FLAGS(0, CLRDMASK);
	_TX_FLAGS(0, VEOL);
	_TX_FLAGS(0, INTREQ);
	_TX_FLAGS(0, RTSENA);
	_TX_FLAGS(0, CTSENA);
	_TX_FLAGS(1, NOACK);

#undef _TX_FLAGS

	/*
	 * WEP crap
	 */
	if (key_index != AR5K_TXKEYIX_INVALID) {
		txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
		txctl1 |= AR5K_REG_SM(key_index,
				AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX);
	}

	/*
	 * RTS/CTS
	 */
	if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {
		if ((flags & AR5K_TXDESC_RTSENA) &&
				(flags & AR5K_TXDESC_CTSENA))
			return -EINVAL;
		txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
		txctl3 |= AR5K_REG_SM(rtscts_rate,
				AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
	}

	tx_ctl->tx_control_0 = txctl0;
	tx_ctl->tx_control_1 = txctl1;
	tx_ctl->tx_control_2 = txctl2;
	tx_ctl->tx_control_3 = txctl3;

	return 0;
}
Exemplo n.º 27
0
u32
bfa_msgq_meminfo(void)
{
	return roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ) +
		roundup(BFA_MSGQ_RSPQ_SIZE, BFA_DMA_ALIGN_SZ);
}
Exemplo n.º 28
0
/*
 * Initialize the 2-word tx control descriptor on 5210/5211
 */
static int
ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
	unsigned int pkt_len, unsigned int hdr_len, int padsize,
	enum ath5k_pkt_type type,
	unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0,
	unsigned int key_index, unsigned int antenna_mode, unsigned int flags,
	unsigned int rtscts_rate, unsigned int rtscts_duration)
{
	u32 frame_type;
	struct ath5k_hw_2w_tx_ctl *tx_ctl;
	unsigned int frame_len;

	tx_ctl = &desc->ud.ds_tx5210.tx_ctl;

	/*
	 * Validate input
	 * - Zero retries don't make sense.
	 * - A zero rate will put the HW into a mode where it continuously sends
	 *   noise on the channel, so it is important to avoid this.
	 */
	if (unlikely(tx_tries0 == 0)) {
		ATH5K_ERR(ah->ah_sc, "zero retries\n");
		WARN_ON(1);
		return -EINVAL;
	}
	if (unlikely(tx_rate0 == 0)) {
		ATH5K_ERR(ah->ah_sc, "zero rate\n");
		WARN_ON(1);
		return -EINVAL;
	}

	/* Clear descriptor */
	memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));

	/* Setup control descriptor */

	/* Verify and set frame length */

	/* remove padding we might have added before */
	frame_len = pkt_len - padsize + FCS_LEN;

	if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
		return -EINVAL;

	tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;

	/* Verify and set buffer length */

	/* NB: beacon's BufLen must be a multiple of 4 bytes */
	if (type == AR5K_PKT_TYPE_BEACON)
		pkt_len = roundup(pkt_len, 4);

	if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
		return -EINVAL;

	tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;

	/*
	 * Verify and set header length (only 5210)
	 */
	if (ah->ah_version == AR5K_AR5210) {
		if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210)
			return -EINVAL;
		tx_ctl->tx_control_0 |=
			AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210);
	}

	/*Differences between 5210-5211*/
	if (ah->ah_version == AR5K_AR5210) {
		switch (type) {
		case AR5K_PKT_TYPE_BEACON:
		case AR5K_PKT_TYPE_PROBE_RESP:
			frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
			break;
		case AR5K_PKT_TYPE_PIFS:
			frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
			break;
		default:
			frame_type = type;
			break;
		}

		tx_ctl->tx_control_0 |=
		AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210) |
		AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);

	} else {
		tx_ctl->tx_control_0 |=
			AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
			AR5K_REG_SM(antenna_mode,
				AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
		tx_ctl->tx_control_1 |=
			AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211);
	}

#define _TX_FLAGS(_c, _flag)					\
	if (flags & AR5K_TXDESC_##_flag) {			\
		tx_ctl->tx_control_##_c |=			\
			AR5K_2W_TX_DESC_CTL##_c##_##_flag;	\
	}
#define _TX_FLAGS_5211(_c, _flag)					\
	if (flags & AR5K_TXDESC_##_flag) {				\
		tx_ctl->tx_control_##_c |=				\
			AR5K_2W_TX_DESC_CTL##_c##_##_flag##_5211;	\
	}
	_TX_FLAGS(0, CLRDMASK);
	_TX_FLAGS(0, INTREQ);
	_TX_FLAGS(0, RTSENA);

	if (ah->ah_version == AR5K_AR5211) {
		_TX_FLAGS_5211(0, VEOL);
		_TX_FLAGS_5211(1, NOACK);
	}

#undef _TX_FLAGS
#undef _TX_FLAGS_5211

	/*
	 * WEP crap
	 */
	if (key_index != AR5K_TXKEYIX_INVALID) {
		tx_ctl->tx_control_0 |=
			AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
		tx_ctl->tx_control_1 |=
			AR5K_REG_SM(key_index,
			AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX);
	}

	/*
	 * RTS/CTS Duration [5210 ?]
	 */
	if ((ah->ah_version == AR5K_AR5210) &&
			(flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
		tx_ctl->tx_control_1 |= rtscts_duration &
				AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210;

	return 0;
}
Exemplo n.º 29
0
/*===========================================================================*
 *				lmfs_rw_scattered			     *
 *===========================================================================*/
void lmfs_rw_scattered(
  dev_t dev,			/* major-minor device number */
  struct buf **bufq,		/* pointer to array of buffers */
  int bufqsize,			/* number of buffers */
  int rw_flag			/* READING or WRITING */
)
{
/* Read or write scattered data from a device. */

  register struct buf *bp;
  int gap;
  register int i;
  register iovec_t *iop;
  static iovec_t iovec[NR_IOREQS];
  off_t pos;
  int iov_per_block;
  unsigned int start_in_use = bufs_in_use, start_bufqsize = bufqsize;

  assert(bufqsize >= 0);
  if(bufqsize == 0) return;

  /* for READING, check all buffers on the list are obtained and held
   * (count > 0)
   */
  if (rw_flag == READING) {
	for(i = 0; i < bufqsize; i++) {
		assert(bufq[i] != NULL);
		assert(bufq[i]->lmfs_count > 0);
  	}

  	/* therefore they are all 'in use' and must be at least this many */
	  assert(start_in_use >= start_bufqsize);
  }

  assert(dev != NO_DEV);
  assert(fs_block_size > 0);
  iov_per_block = roundup(fs_block_size, PAGE_SIZE) / PAGE_SIZE;
  assert(iov_per_block < NR_IOREQS);
  
  /* (Shell) sort buffers on lmfs_blocknr. */
  gap = 1;
  do
	gap = 3 * gap + 1;
  while (gap <= bufqsize);
  while (gap != 1) {
  	int j;
	gap /= 3;
	for (j = gap; j < bufqsize; j++) {
		for (i = j - gap;
		     i >= 0 && bufq[i]->lmfs_blocknr > bufq[i + gap]->lmfs_blocknr;
		     i -= gap) {
			bp = bufq[i];
			bufq[i] = bufq[i + gap];
			bufq[i + gap] = bp;
		}
	}
  }

  /* Set up I/O vector and do I/O.  The result of bdev I/O is OK if everything
   * went fine, otherwise the error code for the first failed transfer.
   */
  while (bufqsize > 0) {
  	int nblocks = 0, niovecs = 0;
	int r;
	for (iop = iovec; nblocks < bufqsize; nblocks++) {
		int p;
		vir_bytes vdata, blockrem;
		bp = bufq[nblocks];
		if (bp->lmfs_blocknr != (block_t) bufq[0]->lmfs_blocknr + nblocks)
			break;
		if(niovecs >= NR_IOREQS-iov_per_block) break;
		vdata = (vir_bytes) bp->data;
		blockrem = fs_block_size;
		for(p = 0; p < iov_per_block; p++) {
			vir_bytes chunk = blockrem < PAGE_SIZE ? blockrem : PAGE_SIZE;
			iop->iov_addr = vdata;
			iop->iov_size = chunk;
			vdata += PAGE_SIZE;
			blockrem -= chunk;
			iop++;
			niovecs++;
		}
		assert(p == iov_per_block);
		assert(blockrem == 0);
	}

	assert(nblocks > 0);
	assert(niovecs > 0);

	pos = (off_t)bufq[0]->lmfs_blocknr * fs_block_size;
	if (rw_flag == READING)
		r = bdev_gather(dev, pos, iovec, niovecs, BDEV_NOFLAGS);
	else
		r = bdev_scatter(dev, pos, iovec, niovecs, BDEV_NOFLAGS);

	/* Harvest the results.  The driver may have returned an error, or it
	 * may have done less than what we asked for.
	 */
	if (r < 0) {
		printf("fs cache: I/O error %d on device %d/%d, block %u\n",
			r, major(dev), minor(dev), bufq[0]->lmfs_blocknr);
	}
	for (i = 0; i < nblocks; i++) {
		bp = bufq[i];
		if (r < (ssize_t) fs_block_size) {
			/* Transfer failed. */
			if (i == 0) {
				bp->lmfs_dev = NO_DEV;	/* Invalidate block */
			}
			break;
		}
		if (rw_flag == READING) {
			bp->lmfs_dev = dev;	/* validate block */
			lmfs_put_block(bp, PARTIAL_DATA_BLOCK);
		} else {
			MARKCLEAN(bp);
		}
		r -= fs_block_size;
	}

	bufq += i;
	bufqsize -= i;

	if (rw_flag == READING) {
		/* Don't bother reading more than the device is willing to
		 * give at this time.  Don't forget to release those extras.
		 */
		while (bufqsize > 0) {
			lmfs_put_block(*bufq++, PARTIAL_DATA_BLOCK);
			bufqsize--;
		}
	}
	if (rw_flag == WRITING && i == 0) {
		/* We're not making progress, this means we might keep
		 * looping. Buffers remain dirty if un-written. Buffers are
		 * lost if invalidate()d or LRU-removed while dirty. This
		 * is better than keeping unwritable blocks around forever..
		 */
		break;
	}
  }

  if(rw_flag == READING) {
  	assert(start_in_use >= start_bufqsize);

	/* READING callers assume all bufs are released. */
	assert(start_in_use - start_bufqsize == bufs_in_use);
  }
}
Exemplo n.º 30
0
/*
 * Attempt to load the file (file) as an ELF module.  It will be stored at
 * (dest), and a pointer to a module structure describing the loaded object
 * will be saved in (result).
 */
int
__elfN(obj_loadfile)(char *filename, u_int64_t dest,
    struct preloaded_file **result)
{
	struct preloaded_file *fp, *kfp;
	struct elf_file	ef;
	Elf_Ehdr *hdr;
	int err;
	ssize_t bytes_read;

	fp = NULL;
	bzero(&ef, sizeof(struct elf_file));

	/*
	 * Open the image, read and validate the ELF header
	 */
	if (filename == NULL)	/* can't handle nameless */
		return(EFTYPE);
	if ((ef.fd = open(filename, O_RDONLY)) == -1)
		return(errno);

	hdr = &ef.hdr;
	bytes_read = read(ef.fd, hdr, sizeof(*hdr));
	if (bytes_read != sizeof(*hdr)) {
		err = EFTYPE;	/* could be EIO, but may be small file */
		goto oerr;
	}

	/* Is it ELF? */
	if (!IS_ELF(*hdr)) {
		err = EFTYPE;
		goto oerr;
	}
	if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||	/* Layout ? */
	    hdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
	    hdr->e_ident[EI_VERSION] != EV_CURRENT ||	/* Version ? */
	    hdr->e_version != EV_CURRENT ||
	    hdr->e_machine != ELF_TARG_MACH ||		/* Machine ? */
	    hdr->e_type != ET_REL) {
		err = EFTYPE;
		goto oerr;
	}

	if (hdr->e_shnum * hdr->e_shentsize == 0 || hdr->e_shoff == 0 ||
	    hdr->e_shentsize != sizeof(Elf_Shdr)) {
		err = EFTYPE;
		goto oerr;
	}

	kfp = file_findfile(NULL, __elfN(obj_kerneltype));
	if (kfp == NULL) {
		printf("elf" __XSTRING(__ELF_WORD_SIZE)
		    "_obj_loadfile: can't load module before kernel\n");
		err = EPERM;
		goto oerr;
	}

	if (archsw.arch_loadaddr != NULL)
		dest = archsw.arch_loadaddr(LOAD_ELF, hdr, dest);
	else
		dest = roundup(dest, PAGE_SIZE);

	/*
	 * Ok, we think we should handle this.
	 */
	fp = file_alloc();
	if (fp == NULL) {
		printf("elf" __XSTRING(__ELF_WORD_SIZE)
		    "_obj_loadfile: cannot allocate module info\n");
		err = EPERM;
		goto out;
	}
	fp->f_name = strdup(filename);
	fp->f_type = strdup(__elfN(obj_moduletype));

	printf("%s ", filename);

	fp->f_size = __elfN(obj_loadimage)(fp, &ef, dest);
	if (fp->f_size == 0 || fp->f_addr == 0)
		goto ioerr;

	/* save exec header as metadata */
	file_addmetadata(fp, MODINFOMD_ELFHDR, sizeof(*hdr), hdr);

	/* Load OK, return module pointer */
	*result = (struct preloaded_file *)fp;
	err = 0;
	goto out;

ioerr:
	err = EIO;
oerr:
	file_discard(fp);
out:
	close(ef.fd);
	if (ef.e_shdr != NULL)
		free(ef.e_shdr);

	return(err);
}