Exemple #1
0
static void
create_proxy(lua_State *L, const void *data, int index) {
	const struct table * t = gettable(data, index);
	if (t == NULL) {
		luaL_error(L, "Invalid index %d", index);
	}
	lua_getfield(L, LUA_REGISTRYINDEX, NODECACHE);
	if (lua_rawgetp(L, -1, t) == LUA_TTABLE) {
		lua_replace(L, -2);
		return;
	}
	lua_pop(L, 1);
	lua_newtable(L);
	lua_pushvalue(L, lua_upvalueindex(1));
	lua_setmetatable(L, -2);
	lua_pushvalue(L, -1);
	// NODECACHE, table, table
	lua_rawsetp(L, -3, t);
	// NODECACHE, table
	lua_getfield(L, LUA_REGISTRYINDEX, PROXYCACHE);
	// NODECACHE, table, PROXYCACHE
	lua_pushvalue(L, -2);
	// NODECACHE, table, PROXYCACHE, table
	struct proxy * p = lua_newuserdata(L, sizeof(struct proxy));
	// NODECACHE, table, PROXYCACHE, table, proxy
	p->data = data;
	p->index = index;
	lua_rawset(L, -3);
	// NODECACHE, table, PROXYCACHE
	lua_pop(L, 1);
	// NODECACHE, table
	lua_replace(L, -2);
	// table
}
Exemple #2
0
static void
setttymode(const char *tname, int raw)
{
	int off = 0;

	gettable(tname, tabent);
	if (OPset || EPset || APset)
		APset++, OPset++, EPset++;
	setdefaults();
	(void)tcflush(STDIN_FILENO, TCIOFLUSH);	/* clear out the crap */
	ioctl(STDIN_FILENO, FIONBIO, &off);	/* turn off non-blocking mode */
	ioctl(STDIN_FILENO, FIOASYNC, &off);	/* ditto for async mode */

	if (IS)
		cfsetispeed(&tmode, speed(IS));
	else if (SP)
		cfsetispeed(&tmode, speed(SP));
	if (OS)
		cfsetospeed(&tmode, speed(OS));
	else if (SP)
		cfsetospeed(&tmode, speed(SP));
	set_flags(0);
	setchars();
	if (raw)
		cfmakeraw(&tmode);
	if (tcsetattr(STDIN_FILENO, TCSANOW, &tmode) < 0) {
		syslog(LOG_ERR, "tcsetattr %s: %m", ttyn);
		exit(1);
	}
}
Exemple #3
0
static void
update_cache(lua_State *L, const void *data, const void * newdata) {
	lua_getfield(L, LUA_REGISTRYINDEX, NODECACHE);
	int t = lua_gettop(L);
	lua_getfield(L, LUA_REGISTRYINDEX, PROXYCACHE);
	int pt = t + 1;
	lua_newtable(L);	// temp table
	int nt = pt + 1;
	lua_pushnil(L);
	while (lua_next(L, t) != 0) {
		// pointer (-2) -> table (-1)
		lua_pushvalue(L, -1);
		if (lua_rawget(L, pt) == LUA_TUSERDATA) {
			// pointer, table, proxy
			struct proxy * p = lua_touserdata(L, -1);
			if (p->data == data) {
				// update to newdata
				p->data = newdata;
				const struct table * newt = gettable(newdata, p->index);
				lua_pop(L, 1);
				// pointer, table
				clear_table(L);
				lua_pushvalue(L, lua_upvalueindex(1));
				// pointer, table, meta
				lua_setmetatable(L, -2);
				// pointer, table
				if (newt) {
					lua_rawsetp(L, nt, newt);
				} else {
					lua_pop(L, 1);
				}
				// pointer
				lua_pushvalue(L, -1);
				lua_pushnil(L);
				lua_rawset(L, t);
			} else {
				lua_pop(L, 2);
			}
		} else {
			lua_pop(L, 2);
			// pointer
		}
	}
	// copy nt to t
	lua_pushnil(L);
	while (lua_next(L, nt) != 0) {
		lua_pushvalue(L, -2);
		lua_insert(L, -2);
		// key key value
		lua_rawset(L, t);
	}
	// NODECACHE PROXYCACHE TEMP
	lua_pop(L, 3);
}
Exemple #4
0
static int hasRequiredTables(struct ttf_header *hdr) {
    static struct { int name, present; } tables[] = {
	{ CHR('h','e','a','d') },
	{ CHR('h','h','e','a') },
	{ CHR('h','m','t','x') },
	{ CHR('m','a','x','p') },
	/* They can leave out 'gdir' if they want, I don't need it */
	/* (and I'll remove it anyway) */
	{ 0 }};
    int i;

    for ( i=0; tables[i].name!=0; ++i ) {
	if ( gettable(hdr,tables[i].name)==NULL )
return( false );
    }
return( true );
}
Exemple #5
0
/*
 * Read a gettytab database entry and perform necessary quirks.
 */
static void
dogettytab(void)
{
	
	/* Read the database entry. */
	gettable(tname, tabent);

	/*
	 * Avoid inheriting the parity values from the default entry
	 * if any of them is set in the current entry.
	 * Mixing different parity settings is unreasonable.
	 */
	if (OPset || EPset || APset || NPset)
		OPset = EPset = APset = NPset = 1;

	/* Fill in default values for unset capabilities. */
	setdefaults();
}
Exemple #6
0
static void
copytable(lua_State *L, int tbl, struct proxy *p) {
	const struct document * doc = (const struct document *)p->data; 
	if (p->index < 0 || p->index >= doc->n) {
		luaL_error(L, "Invalid proxy (index = %d, total = %d)", p->index, (int)doc->n);
	}
	const struct table * t = gettable(doc, p->index);
	if (t == NULL) {
		luaL_error(L, "Invalid proxy (index = %d)", p->index);
	}
	const uint32_t * v = (const uint32_t *)((const char *)t + sizeof(uint32_t) + ((t->dict*2+ 3) & ~3));
	int i;
	for (i=0;i<t->dict;i++) {
		pushvalue(L, v++, t->type[2*i], doc);
		pushvalue(L, v++, t->type[2*i+1], doc);
		lua_rawset(L, tbl);
	}
}
Exemple #7
0
void exitmethod(struct heap_state *heap, struct hashtable *ht, long long uid) {
  //Lets show the roles!!!!
  int i=0;
  struct genhashtable * dommap;
  struct rolereturnstate *rrs=(struct rolereturnstate *)calloc(1, sizeof(struct rolereturnstate));
#ifdef DEBUG
  printf("Returning Context for method %s.%s%s:\n", heap->methodlist->methodname->classname->classname, heap->methodlist->methodname->methodname, heap->methodlist->methodname->signature);
#endif

  doincrementalreachability(heap,ht,1);
  updateroleeffects(heap); /*Merge in this invocation's effects*/
  dommap=builddominatormappings(heap,1);

  if (heap->methodlist->numobjectargs!=0)
    rrs->paramroles=(char **)calloc(heap->methodlist->numobjectargs, sizeof(char *));
  for(;i<heap->methodlist->numobjectargs;i++) {
    if (heap->methodlist->params[i]!=NULL) {
      rrs->paramroles[i]=findrolestring(heap, dommap, heap->methodlist->params[i],1);
    }
  }
  if (uid!=-1) {
    rrs->returnrole=findrolestring(heap, dommap, gettable(ht,uid),1);
  }
  addrolereturn(heap->methodlist->rm,rrs);
  /* Finished building return instantiation of method*/

  /* Assign roles to all objects that might have changed*/
  {
    struct ositerator *it=getIterator(heap->changedset);
    while(hasNext(it)) {
      struct heap_object *ho=nextobject(it);
      free(findrolestring(heap, dommap, ho,1));
    }
    freeIterator(it);

    while(!setisempty(heap->changedset)) {
      struct heap_object *ho=removeobject(heap->changedset, NULL);
      struct fieldlist *fl=ho->fl;
      struct fieldlist *rfl=ho->reversefield;
      struct arraylist *al=ho->al;
      struct arraylist *ral=ho->reversearray;

      while(fl!=NULL) {
	addrolerelation(heap, fl->src, fl->fieldname, fl->object);
	fl=fl->next;
      }

      while(rfl!=NULL) {
	addrolerelation(heap, rfl->src, rfl->fieldname, rfl->object);
	rfl=rfl->dstnext;
      }

      while(al!=NULL) {
	addrolerelation(heap, al->src, getfieldc(heap->namer,al->src->class,"[]", NULL),al->object);
	al=al->next;
      }

      while(ral!=NULL) {
	addrolerelation(heap, ral->src, getfieldc(heap->namer,ral->src->class,"[]", NULL),ral->object);
	ral=ral->dstnext;
      }
    }
  }
  genfreekeyhashtable(dommap);
  /* Merge in any rolechanges we've observed*/
  mergerolechanges(heap);
}
Exemple #8
0
int
main(int argc, char *argv[])
{
	extern	char **environ;
	int first_sleep = 1, first_time = 1;
	struct rlimit limit;
	int rval;

	signal(SIGINT, SIG_IGN);
	signal(SIGQUIT, SIG_IGN);

	openlog("getty", LOG_ODELAY|LOG_CONS|LOG_PID, LOG_AUTH);
	gethostname(hostname, sizeof(hostname) - 1);
	hostname[sizeof(hostname) - 1] = '\0';
	if (hostname[0] == '\0')
		strcpy(hostname, "Amnesiac");

	/*
	 * Limit running time to deal with broken or dead lines.
	 */
	(void)signal(SIGXCPU, timeoverrun);
	limit.rlim_max = RLIM_INFINITY;
	limit.rlim_cur = GETTY_TIMEOUT;
	(void)setrlimit(RLIMIT_CPU, &limit);

	gettable("default", defent);
	gendefaults();
	tname = "default";
	if (argc > 1)
		tname = argv[1];

	/*
	 * The following is a work around for vhangup interactions
	 * which cause great problems getting window systems started.
	 * If the tty line is "-", we do the old style getty presuming
	 * that the file descriptors are already set up for us.
	 * J. Gettys - MIT Project Athena.
	 */
	if (argc <= 2 || strcmp(argv[2], "-") == 0)
	    strcpy(ttyn, ttyname(STDIN_FILENO));
	else {
	    strcpy(ttyn, dev);
	    strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev));
	    if (strcmp(argv[0], "+") != 0) {
		chown(ttyn, 0, 0);
		chmod(ttyn, 0600);
		revoke(ttyn);

		/*
		 * Do the first scan through gettytab.
		 * Terminal mode parameters will be wrong until
		 * defttymode() called, but they're irrelevant for
		 * the initial setup of the terminal device.
		 */
		dogettytab();

		/*
		 * Init or answer modem sequence has been specified.
		 */
		if (IC || AC) {
			if (!opentty(ttyn, O_RDWR|O_NONBLOCK))
				exit(1);
			defttymode();
			setttymode(1);
		}

		if (IC) {
			if (getty_chat(IC, CT, DC) > 0) {
				syslog(LOG_ERR, "modem init problem on %s", ttyn);
				(void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
				exit(1);
			}
		}

		if (AC) {
			int i, rfds;
			struct timeval to;

        		rfds = 1 << 0;	/* FD_SET */
        		to.tv_sec = RT;
        		to.tv_usec = 0;
        		i = select(32, (fd_set*)&rfds, (fd_set*)NULL,
        			       (fd_set*)NULL, RT ? &to : NULL);
        		if (i < 0) {
				syslog(LOG_ERR, "select %s: %m", ttyn);
			} else if (i == 0) {
				syslog(LOG_NOTICE, "recycle tty %s", ttyn);
				(void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
				exit(0);  /* recycle for init */
			}
			i = getty_chat(AC, CT, DC);
			if (i > 0) {
				syslog(LOG_ERR, "modem answer problem on %s", ttyn);
				(void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
				exit(1);
			}
		} else { /* maybe blocking open */
			if (!opentty(ttyn, O_RDWR | (NC ? O_NONBLOCK : 0 )))
				exit(1);
		}
	    }
	}

	defttymode();
	for (;;) {

		/*
		 * if a delay was specified then sleep for that 
		 * number of seconds before writing the initial prompt
		 */
		if (first_sleep && DE) {
		    sleep(DE);
		    /* remove any noise */
		    (void)tcflush(STDIN_FILENO, TCIOFLUSH);
		}
		first_sleep = 0;

		setttymode(0);
		if (AB) {
			tname = autobaud();
			dogettytab();
			continue;
		}
		if (PS) {
			tname = portselector();
			dogettytab();
			continue;
		}
		if (CL && *CL)
			putpad(CL);
		edithost(HE);

		/* if this is the first time through this, and an
		   issue file has been given, then send it */
		if (first_time && IF) {
			int fd;

			if ((fd = open(IF, O_RDONLY)) != -1) {
				char * cp;

				while ((cp = getline(fd)) != NULL) {
					  putf(cp);
				}
				close(fd);
			}
		}
		first_time = 0;

		if (IM && *IM && !(PL && PP))
			putf(IM);
		if (setjmp(timeout)) {
			cfsetispeed(&tmode, B0);
			cfsetospeed(&tmode, B0);
			(void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
			exit(1);
		}
		if (TO) {
			signal(SIGALRM, dingdong);
			alarm(TO);
		}

		rval = 0;
		if (AL) {
			const char *p = AL;
			char *q = name;

			while (*p && q < &name[sizeof name - 1]) {
				if (isupper(*p))
					upper = 1;
				else if (islower(*p))
					lower = 1;
				else if (isdigit(*p))
					digit = 1;
				*q++ = *p++;
			}
		} else if (!(PL && PP))
			rval = getname();
		if (rval == 2 || (PL && PP)) {
			oflush();
			alarm(0);
			limit.rlim_max = RLIM_INFINITY;
			limit.rlim_cur = RLIM_INFINITY;
			(void)setrlimit(RLIMIT_CPU, &limit);
			execle(PP, "ppplogin", ttyn, (char *) 0, env);
			syslog(LOG_ERR, "%s: %m", PP);
			exit(1);
		} else if (rval || AL) {
			int i;

			oflush();
			alarm(0);
			signal(SIGALRM, SIG_DFL);
			if (name[0] == '\0')
				continue;
			if (name[0] == '-') {
				puts("user names may not start with '-'.");
				continue;
			}
			if (!(upper || lower || digit)) {
				if (AL) {
					syslog(LOG_ERR,
					    "invalid auto-login name: %s", AL);
					exit(1);
				} else
					continue;
			}
			set_flags(2);
			if (crmod) {
				tmode.c_iflag |= ICRNL;
				tmode.c_oflag |= ONLCR;
			}
#if REALLY_OLD_TTYS
			if (upper || UC)
				tmode.sg_flags |= LCASE;
			if (lower || LC)
				tmode.sg_flags &= ~LCASE;
#endif
			if (tcsetattr(STDIN_FILENO, TCSANOW, &tmode) < 0) {
				syslog(LOG_ERR, "tcsetattr %s: %m", ttyn);
				exit(1);
			}
			signal(SIGINT, SIG_DFL);
			for (i = 0; environ[i] != (char *)0; i++)
				env[i] = environ[i];
			makeenv(&env[i]);

			limit.rlim_max = RLIM_INFINITY;
			limit.rlim_cur = RLIM_INFINITY;
			(void)setrlimit(RLIMIT_CPU, &limit);
			execle(LO, "login", AL ? "-fp" : "-p", name,
			    (char *) 0, env);
			syslog(LOG_ERR, "%s: %m", LO);
			exit(1);
		}
		alarm(0);
		signal(SIGALRM, SIG_DFL);
		signal(SIGINT, SIG_IGN);
		if (NX && *NX) {
			tname = NX;
			dogettytab();
		}
	}
}
Exemple #9
0
int
main(int argc, char *argv[])
{
	extern char **environ;
	char *tname;
	int repcnt = 0, failopenlogged = 0;
	struct rlimit limit;
	int rval;

	signal(SIGINT, SIG_IGN);
/*
	signal(SIGQUIT, SIG_DFL);
*/
	openlog("getty", LOG_ODELAY|LOG_CONS|LOG_PID, LOG_AUTH);
	gethostname(hostname, sizeof(hostname));
	if (hostname[0] == '\0')
		strlcpy(hostname, "Amnesiac", sizeof hostname);
	uname(&kerninfo);

	/*
	 * Limit running time to deal with broken or dead lines.
	 */
	(void)signal(SIGXCPU, timeoverrun);
	limit.rlim_max = RLIM_INFINITY;
	limit.rlim_cur = GETTY_TIMEOUT;
	(void)setrlimit(RLIMIT_CPU, &limit);

	/*
	 * The following is a work around for vhangup interactions
	 * which cause great problems getting window systems started.
	 * If the tty line is "-", we do the old style getty presuming
	 * that the file descriptors are already set up for us.
	 * J. Gettys - MIT Project Athena.
	 */
	if (argc <= 2 || strcmp(argv[2], "-") == 0) {
		snprintf(ttyn, sizeof ttyn, "%s", ttyname(0));
	} else {
		int i;

		snprintf(ttyn, sizeof ttyn, "%s%s", dev, argv[2]);
		if (strcmp(argv[0], "+") != 0) {
			chown(ttyn, 0, 0);
			chmod(ttyn, 0600);
			revoke(ttyn);
			/*
			 * Delay the open so DTR stays down long enough to be detected.
			 */
			sleep(2);
			while ((i = open(ttyn, O_RDWR)) == -1) {
				if ((repcnt % 10 == 0) &&
				    (errno != ENXIO || !failopenlogged)) {
					syslog(LOG_ERR, "%s: %m", ttyn);
					closelog();
					failopenlogged = 1;
				}
				repcnt++;
				sleep(60);
			}
			login_tty(i);
		}
	}

	/* Start with default tty settings */
	if (tcgetattr(0, &tmode) < 0) {
		syslog(LOG_ERR, "%s: %m", ttyn);
		exit(1);
	}
	omode = tmode;

	gettable("default", defent);
	gendefaults();
	tname = "default";
	if (argc > 1)
		tname = argv[1];
	for (;;) {
		int off;

		gettable(tname, tabent);
		if (OPset || EPset || APset)
			APset++, OPset++, EPset++;
		setdefaults();
		off = 0;
		(void)tcflush(0, TCIOFLUSH);	/* clear out the crap */
		ioctl(0, FIONBIO, &off);	/* turn off non-blocking mode */
		ioctl(0, FIOASYNC, &off);	/* ditto for async mode */

		if (IS)
			cfsetispeed(&tmode, IS);
		else if (SP)
			cfsetispeed(&tmode, SP);
		if (OS)
			cfsetospeed(&tmode, OS);
		else if (SP)
			cfsetospeed(&tmode, SP);
		setflags(0);
		setchars();
		if (tcsetattr(0, TCSANOW, &tmode) < 0) {
			syslog(LOG_ERR, "%s: %m", ttyn);
			exit(1);
		}
		if (AB) {
			tname = autobaud();
			continue;
		}
		if (PS) {
			tname = portselector();
			continue;
		}
		if (CL && *CL)
			putpad(CL);
		edithost(HE);
		if (IM && *IM)
			putf(IM);
		if (TO) {
			signal(SIGALRM, dingdong);
			alarm(TO);
		}
		if ((rval = getname()) == 2) {
			oflush();
			alarm(0);
			signal(SIGALRM, SIG_DFL);
			execle(PP, "ppplogin", ttyn, (char *) 0, env);
			syslog(LOG_ERR, "%s: %m", PP);
			exit(1);
		} else if (rval) {
			int i;

			oflush();
			alarm(0);
			signal(SIGALRM, SIG_DFL);
			if (name[0] == '-') {
				xputs("user names may not start with '-'.");
				continue;
			}
			if (!(upper || lower || digit))
				continue;
			setflags(2);
			if (crmod) {
				tmode.c_iflag |= ICRNL;
				tmode.c_oflag |= ONLCR;
			}
			if (upper || UC) {
				tmode.c_iflag |= IUCLC;
				tmode.c_oflag |= OLCUC;
				tmode.c_lflag |= XCASE;
			}
			if (lower || LC) {
				tmode.c_iflag &= ~IUCLC;
				tmode.c_oflag &= ~OLCUC;
				tmode.c_lflag &= ~XCASE;
			}
			if (tcsetattr(0, TCSANOW, &tmode) < 0) {
				syslog(LOG_ERR, "%s: %m", ttyn);
				exit(1);
			}
			signal(SIGINT, SIG_DFL);
			for (i = 0; environ[i] != (char *)0; i++)
				env[i] = environ[i];
			makeenv(&env[i]);

			limit.rlim_max = RLIM_INFINITY;
			limit.rlim_cur = RLIM_INFINITY;
			(void)setrlimit(RLIMIT_CPU, &limit);
			execle(LO, "login", "-p", "--", name, (char *)0, env);
			syslog(LOG_ERR, "%s: %m", LO);
			exit(1);
		}
		alarm(0);
		signal(SIGALRM, SIG_DFL);
		signal(SIGINT, SIG_IGN);
		if (NX && *NX)
			tname = NX;
	}
}
Exemple #10
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);
}
Exemple #11
0
static void ktap_execute(ktap_state *ks)
{
	int exec_count = 0;
	ktap_callinfo *ci;
	ktap_lclosure *cl;
	ktap_value *k;
	unsigned int instr, opcode;
	StkId base; /* stack pointer */
	StkId ra; /* register pointer */
	int res, nresults; /* temp varible */

	ci = ks->ci;

 newframe:
	cl = CLVALUE(ci->func);
	k = cl->p->k;
	base = ci->u.l.base;

 mainloop:
	/* main loop of interpreter */

	/* dead loop detaction */
	if (exec_count++ == 10000) {
		if (G(ks)->mainthread != ks) {
			kp_error(ks, "non-mainthread executing too much, "
				     "please try to enlarge execution limit\n");
			return;
		}

		cond_resched();
		if (signal_pending(current)) {
			flush_signals(current);
			return;
		}
		exec_count = 0;
	}

	instr = *(ci->u.l.savedpc++);
	opcode = GET_OPCODE(instr);

	/* ra is target register */
	ra = RA(instr);

	switch (opcode) {
	case OP_MOVE:
		setobj(ra, base + GETARG_B(instr));
		break;
	case OP_LOADK:
		setobj(ra, k + GETARG_Bx(instr));
		break;
	case OP_LOADKX:
		setobj(ra, k + GETARG_Ax(*ci->u.l.savedpc++));
		break;
	case OP_LOADBOOL:
		setbvalue(ra, GETARG_B(instr));
		if (GETARG_C(instr))
			ci->u.l.savedpc++;
		break;
	case OP_LOADNIL: {
		int b = GETARG_B(instr);
		do {
			setnilvalue(ra++);
		} while (b--);
		break;
		}
	case OP_GETUPVAL: {
		int b = GETARG_B(instr);
		setobj(ra, cl->upvals[b]->v);
		break;
		}
	case OP_GETTABUP: {
		int b = GETARG_B(instr);
		gettable(ks, cl->upvals[b]->v, RKC(instr), ra);
		base = ci->u.l.base;
		break;
		}
	case OP_GETTABLE:
		gettable(ks, RB(instr), RKC(instr), ra);
		base = ci->u.l.base;
		break;
	case OP_SETTABUP: {
		int a = GETARG_A(instr);
		settable(ks, cl->upvals[a]->v, RKB(instr), RKC(instr));
		base = ci->u.l.base;
		break;
		}
	case OP_SETUPVAL: {
		ktap_upval *uv = cl->upvals[GETARG_B(instr)];
		setobj(uv->v, ra);
		break;
		}
	case OP_SETTABLE:
		settable(ks, ra, RKB(instr), RKC(instr));
		base = ci->u.l.base;
		break;
	case OP_NEWTABLE: {
		int b = GETARG_B(instr);
		int c = GETARG_C(instr);
		ktap_table *t = kp_table_new(ks);
		sethvalue(ra, t);
		if (b != 0 || c != 0)
			kp_table_resize(ks, t, fb2int(b), fb2int(c));
		break;
		}
	case OP_SELF: {
		StkId rb = RB(instr);
		setobj(ra+1, rb);
		gettable(ks, rb, RKC(instr), ra);
		base = ci->u.l.base;
		break;
		}
	case OP_ADD:
		arith_op(ks, NUMADD);
		break;
	case OP_SUB:
		arith_op(ks, NUMSUB);
		break;
	case OP_MUL:
		arith_op(ks, NUMMUL);
		break;
	case OP_DIV:
		/* divide 0 checking */
		if (!nvalue(RKC(instr))) {
			kp_error(ks, "divide 0 arith operation\n");
			return;
		}
		arith_op(ks, NUMDIV);
		break;
	case OP_MOD:
		/* divide 0 checking */
		if (!nvalue(RKC(instr))) {
			kp_error(ks, "mod 0 arith operation\n");
			return;
		}
		arith_op(ks, NUMMOD);
		break;
	case OP_POW:
		kp_error(ks, "ktap don't support pow arith in kernel\n");
		return;
	case OP_UNM: {
		ktap_value *rb = RB(instr);
		if (ttisnumber(rb)) {
			ktap_number nb = nvalue(rb);
			setnvalue(ra, NUMUNM(nb));
		}
		break;
		}
	case OP_NOT:
		res = isfalse(RB(instr));
		setbvalue(ra, res);
		break;
	case OP_LEN: {
		int len = kp_objlen(ks, RB(instr));
		if (len < 0)
			return;
		setnvalue(ra, len);
		break;
		}
	case OP_CONCAT: {
		int b = GETARG_B(instr);
		int c = GETARG_C(instr);
		ktap_concat(ks, b, c);
		break;
		}
	case OP_JMP:
		dojump(ci, instr, 0);
		break;
	case OP_EQ: {
		ktap_value *rb = RKB(instr);
		ktap_value *rc = RKC(instr);
		if ((int)equalobj(ks, rb, rc) != GETARG_A(instr))
			ci->u.l.savedpc++;
		else
			donextjump(ci);

		base = ci->u.l.base;
		break;
		}
	case OP_LT:
		if (lessthan(ks, RKB(instr), RKC(instr)) != GETARG_A(instr))
			ci->u.l.savedpc++;
		else
			donextjump(ci);
		base = ci->u.l.base;
		break;
	case OP_LE:
		if (lessequal(ks, RKB(instr), RKC(instr)) != GETARG_A(instr))
			ci->u.l.savedpc++;
		else
			donextjump(ci);
		base = ci->u.l.base;
		break;
	case OP_TEST:
		if (GETARG_C(instr) ? isfalse(ra) : !isfalse(ra))
			ci->u.l.savedpc++;
		else
			donextjump(ci);
		break;
	case OP_TESTSET: {
		ktap_value *rb = RB(instr);
		if (GETARG_C(instr) ? isfalse(rb) : !isfalse(rb))
			ci->u.l.savedpc++;
		else {
			setobj(ra, rb);
			donextjump(ci);
		}
		break;
		}
	case OP_CALL: {
		int b = GETARG_B(instr);
		int ret;

		nresults = GETARG_C(instr) - 1;

		if (b != 0)
			ks->top = ra + b;

		ret = precall(ks, ra, nresults);
		if (ret) { /* C function */
			if (nresults >= 0)
				ks->top = ci->top;
			base = ci->u.l.base;
			break;
		} else { /* ktap function */
			ci = ks->ci;
			/* this flag is used for return time, see OP_RETURN */
			ci->callstatus |= CIST_REENTRY;
			goto newframe;
		}
		break;
		}
	case OP_TAILCALL: {
		int b = GETARG_B(instr);

		if (b != 0)
			ks->top = ra+b;
		if (precall(ks, ra, -1))  /* C function? */
			base = ci->u.l.base;
		else {
			int aux;

			/* 
			 * tail call: put called frame (n) in place of
			 * caller one (o)
			 */
			ktap_callinfo *nci = ks->ci;  /* called frame */
			ktap_callinfo *oci = nci->prev;  /* caller frame */
			StkId nfunc = nci->func;  /* called function */
			StkId ofunc = oci->func;  /* caller function */
			/* last stack slot filled by 'precall' */
			StkId lim = nci->u.l.base +
				    CLVALUE(nfunc)->p->numparams;

			/* close all upvalues from previous call */
			if (cl->p->sizep > 0)
				function_close(ks, oci->u.l.base);

			/* move new frame into old one */
			for (aux = 0; nfunc + aux < lim; aux++)
				setobj(ofunc + aux, nfunc + aux);
			/* correct base */
			oci->u.l.base = ofunc + (nci->u.l.base - nfunc);
			/* correct top */
			oci->top = ks->top = ofunc + (ks->top - nfunc);
			oci->u.l.savedpc = nci->u.l.savedpc;
			/* remove new frame */
			ci = ks->ci = oci;
			/* restart ktap_execute over new ktap function */
			goto newframe;
		}
		break;
		}
	case OP_RETURN: {
		int b = GETARG_B(instr);
		if (b != 0)
			ks->top = ra+b-1;
		if (cl->p->sizep > 0)
			function_close(ks, base);
		b = poscall(ks, ra);

		/* if it's called from external invocation, just return */
		if (!(ci->callstatus & CIST_REENTRY))
			return;

		ci = ks->ci;
		if (b)
			ks->top = ci->top;
		goto newframe;
		}
	case OP_FORLOOP: {
		ktap_number step = nvalue(ra+2);
		/* increment index */
		ktap_number idx = NUMADD(nvalue(ra), step);
		ktap_number limit = nvalue(ra+1);
		if (NUMLT(0, step) ? NUMLE(idx, limit) : NUMLE(limit, idx)) {
			ci->u.l.savedpc += GETARG_sBx(instr);  /* jump back */
			setnvalue(ra, idx);  /* update internal index... */
			setnvalue(ra+3, idx);  /* ...and external index */
		}
		break;
		}
	case OP_FORPREP: {
		const ktap_value *init = ra;
		const ktap_value *plimit = ra + 1;
		const ktap_value *pstep = ra + 2;

		if (!ktap_tonumber(init, ra)) {
			kp_error(ks, KTAP_QL("for")
				 " initial value must be a number\n");
			return;
		} else if (!ktap_tonumber(plimit, ra + 1)) {
			kp_error(ks, KTAP_QL("for")
				 " limit must be a number\n");
			return;
		} else if (!ktap_tonumber(pstep, ra + 2)) {
			kp_error(ks, KTAP_QL("for") " step must be a number\n");
			return;
		}

		setnvalue(ra, NUMSUB(nvalue(ra), nvalue(pstep)));
		ci->u.l.savedpc += GETARG_sBx(instr);
		break;
		}
	case OP_TFORCALL: {
		StkId cb = ra + 3;  /* call base */
		setobj(cb + 2, ra + 2);
		setobj(cb + 1, ra + 1);
		setobj(cb, ra);
		ks->top = cb + 3;  /* func. + 2 args (state and index) */
		kp_call(ks, cb, GETARG_C(instr));
		base = ci->u.l.base;
		ks->top = ci->top;
		instr = *(ci->u.l.savedpc++);  /* go to next instruction */
		ra = RA(instr);
		}
		/*go through */
	case OP_TFORLOOP:
		if (!ttisnil(ra + 1)) {  /* continue loop? */
			setobj(ra, ra + 1);  /* save control variable */
			ci->u.l.savedpc += GETARG_sBx(instr);  /* jump back */
		}
		break;
	case OP_SETLIST: {
		int n = GETARG_B(instr);
		int c = GETARG_C(instr);
		int last;
		ktap_table *h;

		if (n == 0)
			n = (int)(ks->top - ra) - 1;
		if (c == 0)
			c = GETARG_Ax(*ci->u.l.savedpc++);

		h = hvalue(ra);
		last = ((c - 1) * LFIELDS_PER_FLUSH) + n;
		if (last > h->sizearray)  /* needs more space? */
			kp_table_resizearray(ks, h, last);

		for (; n > 0; n--) {
			ktap_value *val = ra+n;
			kp_table_setint(ks, h, last--, val);
		}
		/* correct top (in case of previous open call) */
		ks->top = ci->top;
		break;
		}
	case OP_CLOSURE: {
		/* need to use closure cache? (multithread contention issue)*/
		ktap_proto *p = cl->p->p[GETARG_Bx(instr)];
		pushclosure(ks, p, cl->upvals, base, ra);
		break;
		}
	case OP_VARARG: {
		int b = GETARG_B(instr) - 1;
		int j;
		int n = (int)(base - ci->func) - cl->p->numparams - 1;
		if (b < 0) {  /* B == 0? */
			b = n;  /* get all var. arguments */
			checkstack(ks, n);
			/* previous call may change the stack */
			ra = RA(instr);
			ks->top = ra + n;
		}
		for (j = 0; j < b; j++) {
			if (j < n) {
				setobj(ra + j, base - n + j);
			} else
				setnilvalue(ra + j);
		}
		break;
		}
	case OP_EXTRAARG:
		return;

	case OP_EVENT: {
		struct ktap_event *e = ks->current_event;

		if (unlikely(!e)) {
			kp_error(ks, "invalid event context\n");
			return;
		}
		setevalue(ra, e);
		break;
		}

	case OP_EVENTNAME: {
		struct ktap_event *e = ks->current_event;

		if (unlikely(!e)) {
			kp_error(ks, "invalid event context\n");
			return;
		}
		setsvalue(ra, kp_tstring_new(ks, e->call->name));
		break;
		}
	case OP_EVENTARG:
		if (unlikely(!ks->current_event)) {
			kp_error(ks, "invalid event context\n");
			return;
		}

		kp_event_getarg(ks, ra, GETARG_B(instr));		
		break;
	case OP_LOAD_GLOBAL: {
		ktap_value *cfunc = cfunction_cache_get(ks, GETARG_C(instr));
		setobj(ra, cfunc);
		}
		break;

	case OP_EXIT:
		return;
	}

	goto mainloop;
}