Beispiel #1
0
static void addptr(RList *ret, const char *name, ut64 addr, const ut8 *b, int len) {
	if (b && rjmp (b)) {
		addsym (ret, sdb_fmt ("vector.%s", name), addr);
		ut64 ptr_addr = rjmp_dest (addr, b + addr);
		addsym (ret, sdb_fmt ("syscall.%s", name), ptr_addr);
	}
}
Beispiel #2
0
/*
 * Call to a function
 */
void
calldec(NODE *p, NODE *r)
{
	struct symtab *q = p->n_sp;
	extern void addsym(struct symtab *);
	addsym(q);
}
Beispiel #3
0
static a_sym *make_sym( char *name, token_t value )
{
    a_sym *p;

    p = addsym( name );
    p->token = value;
    return( p );
}
/*
**  OPERATOR -- process a token starting with an operator
**
**	Processes operators, strings, comments, and 
**	floating constants without a leading 0.
**
**	Parameters:
**		chr - first character of token {equel_cmap (chr) == OPATR}
**
**	Returns:
**		NUMBER or STRING token, or operator token.
**		CONTINUE on error.
**
**	Side Effects:
**		Adds a node to the Symbol space, and returns adress
**		in "yylval".
**		Opcode is set to the opcode of the operator.
**		May backup a character.
*/
int
operator(char chr)
{
	register struct optab	*op;
	char			opbuf [3];

	opbuf [0] = chr;
	opbuf [1] = getch();
	opbuf [2] = '\0';

	if (opbuf [0] == '.' && equel_cmap(opbuf[1]) == NUMBR) {
		/* floating mantissa w/o leading 0 */
		backup(opbuf [1]);
		return (number(opbuf [0]));
	}
	if (equel_cmap(opbuf[1]) != OPATR) {
		backup(opbuf [1]);
		opbuf [1] = '\0';
	}
	/* operator has been reduced to its smallest 
	 * possible length, now try to find it in the
	 * operator table [tokens.y]
	 */
	for ( ; ; ) {
		for (op = Optab; op->op_term; op++)
			if (strcmp(op->op_term, opbuf) == 0)
				break;
		if (!op->op_term && opbuf [1]) {
			/* reduce a 2 char operator to 1 char,
			 * and re-search
			 */
			backup(opbuf[1]);
			opbuf [1] = '\0';
			continue;
		}
		break;
	}
	if (op->op_term) {
		/* string quotes ? */
		if (op->op_token == Tokens.sp_quote)
			return (string(op));

		/* comment indicator ? */
		if (op->op_token == Tokens.sp_bgncmnt)
			return (comment());

		/* {strcmp(opbuf, op->op_term) == 0} */
		Opcode = op->op_code;
		yylval.u_dn = addsym(op->op_term);
		return (op->op_token);
	}
	yysemerr("bad operator", opbuf);

	/* operator not found, skip token and try again */
	return (CONTINUE);
}
Beispiel #5
0
void ndinstal(char *name, Char *definition)
	{
	char *copy_string();
	Char *copy_unsigned_string();

	if ( addsym( copy_string( name ),
			(char *) copy_unsigned_string( definition ), 0,
			ndtbl, NAME_TABLE_HASH_SIZE ) )
		synerr( _( "name defined twice" ) );
	}
Beispiel #6
0
FILE *
fincludegets(char *buf, int size, FILE *fp)
{
	char name[MAXPATHLEN];
	FILE *nfp=NULL;
	char *p;
	int ch;

	if (fp == NULL)
		return(NULL);

	if (fgets(buf, size, fp) == NULL) {
		*buf = '\0';
		fclose(fp);
		fp = popfp();
		return (fp);
	}
	if ((p = strchr(buf, '\n')) != NULL)
		*p = '\0';
	else {
		/* Flush this line */
		while ((ch = fgetc(fp)) != '\n' && ch != EOF);
		if (ch == EOF) {
			*buf = '\0';
			fclose(fp);
			fp = popfp();
			return(fp);
		}
	}
	switch (tokenscpp(buf, name)) {
	case T_INCLUDE:
		*buf = '\0';
		if ((nfp = fopen(name, "r")) != NULL) {
			pushfp(fp);
			fp = nfp;
		}
		break;
	case T_DEFINE:
		addsym(name);
		break;
	case T_IFNDEF:
		if (findsym(name)) {
			fclose(fp);
			fp = popfp();
			*buf = '\0';
		}
		break;
	case T_ENDIF:
		*buf = '\0';
		break;
	default:
		break;
	}
	return (fp);
}
Beispiel #7
0
void cclinstal(Char *ccltxt, int cclnum)
	{
	/* We don't bother checking the return status because we are not
	 * called unless the symbol is new.
	 */
	Char *copy_unsigned_string();

	(void) addsym( (char *) copy_unsigned_string( ccltxt ),
			NULL, cclnum,
			ccltab, CCL_HASH_SIZE );
	}
Beispiel #8
0
void scinstal(char *str, int xcluflg)
	{
	char *copy_string();

	/* Generate start condition definition, for use in BEGIN et al. */
	action_define( str, lastsc );

	if ( ++lastsc >= current_max_scs )
		scextend();

	scname[lastsc] = copy_string( str );

	if ( addsym( scname[lastsc], NULL, lastsc,
			sctbl, START_COND_HASH_SIZE ) )
		format_pinpoint_message(
				_( "start condition %s declared twice" ),
					str );

	scset[lastsc] = mkstate( SYM_EPSILON );
	scbol[lastsc] = mkstate( SYM_EPSILON );
	scxclu[lastsc] = xcluflg;
	sceof[lastsc] = false;
	}
Beispiel #9
0
void Pass1::accept_statement(ParseNode *stmt, std::string insn_name, Insn &insn)
{
	assert(stmt->token == RULE_STATEMENT);
	char osz = 0, asz = 0;
	std::list<ParseNode *>::iterator i = stmt->children.begin();
	assert(i != stmt->children.end());
	bool valid = true;
	while((*i)->token == RULE_PREFIX)
	{
		int prefix = (*i)->children.front()->token;
		switch(prefix)
		{
			case KEYWORD_O16:
				if(osz == 0)
					osz = 16;
				else
					valid = false;
				break;
			case KEYWORD_O32:
				if(osz == 0)
					osz = 32;
				else
					valid = false;
				break;
			case KEYWORD_O64:
				if(osz == 0)
					osz = 64;
				else
					valid = false;
				break;
			case KEYWORD_A16:
				if(asz == 0)
					asz = 16;
				else
					valid = false;
				break;
			case KEYWORD_A32:
				if(asz == 0)
					asz = 32;
				else
					valid = false;
				break;
			case KEYWORD_A64:
				if(asz == 0)
					asz = 64;
				else
					valid = false;
				break;
			default:
				assert(0);
				break;
		}
		
		++i;
	}
	assert((*i)->token == RULE_SIMPLE_D_STATEMENT);
	if(!valid)
	{
		throw ParseError("Too many prefix (o16/o32/o64 or a16/a32/a64).",
			stmt->lineNum,
			stmt->fileNum,
			__LINE__
		);
	}
	
	ParseNode *simple = *i;
	assert(!simple->children.empty());
	
	bool is_pure_asgn = false;
	if(simple->children.size() == 3)
	{
		i = simple->children.begin();	// possibly IDENT
		++i;							// skip possible IDENT
		if((*i)->token == '=')
			is_pure_asgn = true;
	}
	
	i = simple->children.begin();
	if(!is_pure_asgn && (*i)->token == CTokenEnums::TOKEN_IDENT)
	{
		if(osz != 0 || asz != 0)
		{
			throw ParseError("Prefix (o16/o32/o64 or a16/a32/a64) used with local variable definition.",
				stmt->lineNum,
				stmt->fileNum,
				__LINE__
			);
		}
	}
	
	std::string asgn_nm;
	ParseNode *asgn_rhs = NULL;
	
	// First allocate a local variable if that is in order.
	if(!is_pure_asgn && (*i)->token == CTokenEnums::TOKEN_IDENT)
	{
		std::string sizeid = (*i)->text;	// get identifier (size)
		++i;								// skip size identifier
		Size sz = get_exact_size(sizeid);
		if(sz.scalar == 0)
		{
			// Look up this size, it's a parameter.
			std::map<std::string, Symbol *>::iterator j = symtab2.find(sizeid);
			if(j == symtab2.end() || j->second->type != ST_ARGSIZE)
			{
				throw ParseError("Local variable size error: can't find size: " + sizeid,
					stmt->lineNum,
					stmt->fileNum,
					__LINE__
				);
			}
			sz.base = j->second->num;
			assert(sz.base < 0);
			sz.scalar = 1;
			if((*i)->token == '*')
			{
				++i;	// skip *
				sz.scalar = get_short((*i)->text);
				if(sz.scalar <= 1)
				{
					throw ParseError("Local variable size error: scalar must be 2..32767, found: " + (*i)->text,
						stmt->lineNum,
						stmt->fileNum,
						__LINE__
					);
				}
				++i;	// skip scalar
			}
		}
		else
		{
			if((*i)->token == '*')
			{
				throw ParseError("Local variable size error: can't use * with built-in type: " + sizeid,
					stmt->lineNum,
					stmt->fileNum,
					__LINE__
				);
			}
		}
		assert((*i)->token == CTokenEnums::TOKEN_IDENT);
		std::string nm = (*i)->text;
		
		// (sz, nm) now set.
		++i;
		if(i != simple->children.end())
		{
			assert((*i)->token == '=');
			++i;		// skip '='
			asgn_rhs = *i;
			asgn_nm = nm;
		}
		
		// Create local variable here.
		if(!is_valid_new_ident(nm))
		{
			throw ParseError("Local variable name already in symbol table: " + nm,
				stmt->lineNum,
				stmt->fileNum,
				__LINE__
			);
		}
		Symbol sym();
		addsym(nm, new Symbol(ST_LOCAL, insn.locals.size(), sz));
		insn.locals.push_back(sz);
		locals.insert(nm);
	}

	i = simple->children.begin();
	if(is_pure_asgn)
	{
		asgn_nm = (*i)->text;	// ident
		++i;					// skip ident
		assert((*i)->token == '=');
		++i;					// skip '='
		asgn_rhs = *i;
	}
	
	// This is used for e.g. both of these cases:
	//    zeta = undefined;
	//    bit tmp = undefined;
	if(asgn_rhs != NULL)
	{
		accept_asgn(asgn_nm, asgn_rhs, simple, insn_name, insn, asz, osz);
	}
	
	// Handle assert, push, pop, discard, outport, inport, reserve, restore here.
	i = simple->children.begin();
	if((*i)->token != CTokenEnums::TOKEN_IDENT)
	{
		int x = 0;
		switch((*i)->token)
		{
			case KEYWORD_ASSERT:
				x = SO_ASSERT;
				break;
			case KEYWORD_PUSH:
				x = SO_PUSH;
				break;
			case KEYWORD_POP:
				x = SO_POP;
				break;
			case KEYWORD_DISCARD:
				x = SO_DISCARD;
				break;
			case KEYWORD_OUTPORT:
				x = SO_OUTPORT;
				break;
			case KEYWORD_INPORT:
				x = SO_INPORT;
				break;
			case KEYWORD_RESERVE:
				x = SO_RESERVE;
				break;
			case KEYWORD_RESTORE:
				x = SO_RESTORE;
				break;
			case KEYWORD_COMMIT:
				x = SO_COMMIT;
				break;
			default:
				assert(0);
				break;
		}
		insn.stmts.push_back(Statement(x));
		Statement &stmt = insn.stmts.back();
		stmt.osz = osz;
		stmt.asz = asz;
		stmt.dest = NULL;
		
		// Now do any arguments.
		if(x == SO_RESERVE || x == SO_RESTORE)
		{
			stmt.src.push_back(Rhs());
			Rhs &outrhs = stmt.src.back();
			++i;	// skip keyword
			++i;	// skip '('
			accept_rhs(outrhs, *i, insn_name, insn, Size(8, 1));
		}
		else
		{
			++i;	// skip keyword
			++i;	// skip '('
			while((*i)->token == RULE_RHS)
			{
				stmt.src.push_back(Rhs());
				Rhs &outrhs = stmt.src.back();
				accept_rhs(outrhs, *i, insn_name, insn, Size(0, 0));
			
				if(outrhs.size.scalar == 0)
				{
					throw ParseError("Unable to resolve size of argument. If NUM, try e.g. tr<B8>(NUM)." + asgn_nm,
					simple->lineNum,
					simple->fileNum,
					__LINE__
					);
				}
			
				++i;	// skip rhs
				if((*i)->token != ',')
					break;
				++i;	// skip comma
			}
			assert((*i)->token == ')');
		}
	}
}
Beispiel #10
0
void Pass1::accept_func_decl(ParseNode *node)
{
	std::list<ParseNode *>::iterator i = node->children.begin();
	ParseNode *tprototype = *i;
	assert(tprototype->token == RULE_PROTOTYPE_D_TYPE);
	++i;
	ParseNode *prototype = *i;
	assert(prototype->token == RULE_PROTOTYPE);
	++i;
	assert((*i)->token == ';');

	//---
	i = prototype->children.begin();
	std::string fn_name = (*i)->text;
	++i;	// skip fn_name
	assert((*i)->token == '(');
	++i;	// skip '('
	
	Symbol *symT = new Symbol(ST_FUNC, numFuncs, Size(0, 0));
	Symbol &sym = *symT;
	
	if((*i)->token == RULE_ARGS)
	{
		Args args(this, *i);
		for(std::vector<Arg>::iterator j = args.args.begin(); j != args.args.end(); ++j)
		{
			short x = j->base_size;
			if(x == -1)
			{
				assert(args.argtypes.find(j->size_name) != args.argtypes.end());
				x = args.argtypes[j->size_name];
				assert(x < 0);
			}
			sym.args.push_back(Size(x, j->scalar));
		}
		
		std::string xs = tprototype->children.front()->text;
		sym.size = get_exact_size(xs);
		if(sym.size.scalar == 0)
		{
			// unknown size.
			if(args.argtypes.find(xs) == args.argtypes.end())
			{
				throw ParseError("Bad return size for function - " + fn_name,
					node->lineNum,
					node->fileNum,
					__LINE__
				);
			}
			short x = args.argtypes[xs];
			assert(x < 0);
			sym.size.base = x;
			sym.size.scalar = 1;
			// Now handle any *.
			if(tprototype->children.size() != 1)
			{
				sym.size.scalar = get_short(tprototype->children.back()->text);
				if(sym.size.scalar <= 1)
				{
					throw ParseError("Bad return size for function - " + fn_name,
						node->lineNum,
						node->fileNum,
						__LINE__
					);
				}
			}
		}
		else
		if(sym.size.scalar != 1 || tprototype->children.size() != 1)
		{
			throw ParseError("Bad return size for function - " + fn_name,
				node->lineNum,
				node->fileNum,
				__LINE__
			);
		}
	}
	else
	{
		sym.size = get_exact_size(tprototype->children.front()->text);
		if(sym.size.scalar != 1 || tprototype->children.size() != 1)
		{
			throw ParseError("Bad return size for function - " + fn_name,
				node->lineNum,
				node->fileNum,
				__LINE__
			);
		}
	}

	if(!is_valid_new_ident(fn_name))
	{
		throw ParseError("Name already exists - " + fn_name,
			node->lineNum,
			node->fileNum,
			__LINE__
		);
	}

///
///sym.dump_function(fn_name, this);
///

	///symtab.insert(std::make_pair(fn_name, sym));
	addsym(fn_name, symT);
	++numFuncs;
	//---
}
Beispiel #11
0
/*
 * read_exec
 *	Read the exec structure; ignore any files that don't look
 *	exactly right. Return MID.
 *	return -1 for files that don't look right.
 *	XXX it's hard to be sure when to ignore files, and when to error
 *	out.
 */
int
read_exec(FILE *rfp, FILE *wfp, long *symcnt, long *tsymlen)
{
	union {
		struct exec exec;
		Elf32_Ehdr elf32;
		Elf64_Ehdr elf64;
	} eh;
	struct nlist nl;
	off_t r_off, w_off;
	char *strtab = NULL;
	long strsize, nsyms;
	int i;

	/* Get current offsets for original and tmp files. */
	r_off = ftello(rfp);
	w_off = ftello(wfp);

	/* Read in exec structure. */
	if (fread(&eh, sizeof(eh), 1, rfp) != 1)
		err(1, "fread: %s", archive);

	if (!elf32_chk_header(&eh.elf32)) {
		Elf32_Sym sbuf;
		char *shstr;
		Elf32_Shdr *shdr;
		size_t stabsize;

		elf32_fix_header(&eh.elf32);
		if (eh.elf32.e_ehsize < sizeof eh.elf32) {
			warnx("%s: ELF header is too short", archive);
			goto bad;
		}

		if (!(shdr = elf32_load_shdrs(archive, rfp, r_off, &eh.elf32)))
			goto bad;
		elf32_fix_shdrs(&eh.elf32, shdr);

		if (!(shstr = elf32_shstrload(archive, rfp, r_off, &eh.elf32,
		    shdr))) {
			free(shdr);
			goto bad;
		}

		if (!(strtab = elf32_strload(archive, rfp, r_off, &eh.elf32,
		    shdr, shstr, ELF_STRTAB, &stabsize))) {
			free(shstr);
			free(shdr);
			goto bad;
		}

		/* find the symtab section */
		for (i = 0; i < eh.elf32.e_shnum; i++)
			if (!strcmp(shstr + shdr[i].sh_name, ELF_SYMTAB)) {
				nsyms = shdr[i].sh_size / sizeof(Elf32_Sym);
				break;
			}

		if (i == eh.elf32.e_shnum) {
			free(shstr);
			free(shdr);
			goto bad;
		}

		if (fseeko(rfp, r_off + shdr[i].sh_offset, SEEK_SET))
			err(1, "fseeko: %s", archive);

		for (i = 0; i < nsyms; i++) {
			if (fread(&sbuf, sizeof(sbuf), 1, rfp) != 1)
				err(1, "fread: %s", archive);

			elf32_fix_sym(&eh.elf32, &sbuf);
			if (!sbuf.st_name || sbuf.st_name > stabsize)
				continue;

			if (elf32_2nlist(&sbuf, &eh.elf32, shdr, shstr, &nl))
				continue;

			addsym(&nl, strtab, r_off - r_fuzz -
			    sizeof(struct ar_hdr), symcnt, tsymlen, archive);
		}

		free(strtab);
		free(shstr);
		free(shdr);
		(void)fseeko(rfp, r_off, SEEK_SET);
		return MID_ELFFL | eh.elf32.e_machine;

	} else if (!elf64_chk_header(&eh.elf64)) {
		Elf64_Sym sbuf;
		char *shstr;
		Elf64_Shdr *shdr;
		size_t stabsize;

		elf64_fix_header(&eh.elf64);
		if (eh.elf64.e_ehsize < sizeof eh.elf64) {
			warnx("%s: ELF header is too short", archive);
			goto bad;
		}

		if (!(shdr = elf64_load_shdrs(archive, rfp, r_off, &eh.elf64)))
			goto bad;
		elf64_fix_shdrs(&eh.elf64, shdr);

		if (!(shstr = elf64_shstrload(archive, rfp, r_off, &eh.elf64,
		    shdr))) {
			free(shdr);
			goto bad;
		}

		if (!(strtab = elf64_strload(archive, rfp, r_off, &eh.elf64,
		    shdr, shstr, ELF_STRTAB, &stabsize))) {
			free(shstr);
			free(shdr);
			goto bad;
		}

		/* find the symtab section */
		for (i = 0; i < eh.elf64.e_shnum; i++)
			if (!strcmp(shstr + shdr[i].sh_name, ELF_SYMTAB)) {
				nsyms = shdr[i].sh_size / sizeof(Elf64_Sym);
				break;
			}

		if (i == eh.elf64.e_shnum) {
			free(shstr);
			free(shdr);
			goto bad;
		}

		if (fseeko(rfp, r_off + shdr[i].sh_offset, SEEK_SET))
			err(1, "fseeko: %s", archive);

		for (i = 0; i < nsyms; i++) {
			if (fread(&sbuf, sizeof(sbuf), 1, rfp) != 1)
				err(1, "fread: %s", archive);

			elf64_fix_sym(&eh.elf64, &sbuf);
			if (!sbuf.st_name || sbuf.st_name > stabsize)
				continue;

			if (elf64_2nlist(&sbuf, &eh.elf64, shdr, shstr, &nl))
				continue;

			addsym(&nl, strtab, r_off - r_fuzz -
			    sizeof(struct ar_hdr), symcnt, tsymlen, archive);
		}

		free(strtab);
		free(shstr);
		free(shdr);
		(void)fseeko(rfp, r_off, SEEK_SET);
		return MID_ELFFL | eh.elf64.e_machine;

	} else if (BAD_OBJECT(eh.exec) || eh.exec.a_syms == 0)
		goto bad;

	fix_header_order(&eh.exec);

	/* Seek to string table. */
	if (fseeko(rfp, N_STROFF(eh.exec) + r_off, SEEK_SET) == -1) {
		if (errno == EINVAL)
			goto bad;
		else
			err(1, "lseek: %s", archive);
	}

	/* Read in size of the string table. */
	if (fread((char *)&strsize, sizeof(strsize), 1, rfp) != 1)
		err(1, "fread: %s", archive);

	strsize = fix_32_order(strsize, N_GETMID(eh.exec));

	/* Read in the string table. */
	strsize -= sizeof(strsize);
	strtab = malloc(strsize);
	if (!strtab)
		err(1, "malloc: %s", archive);
	if (fread(strtab, strsize, 1, rfp) != 1)
		err(1, "fread: %s", archive);

	/* Seek to symbol table. */
	if (fseek(rfp, N_SYMOFF(eh.exec) + r_off, SEEK_SET) == (off_t)-1)
		err(1, "fseeko: %s", archive);

	/* For each symbol read the nlist entry and save it as necessary. */
	nsyms = eh.exec.a_syms / sizeof(struct nlist);
	while (nsyms--) {
		if (!fread((char *)&nl, sizeof(struct nlist), 1, rfp)) {
			if (feof(rfp))
				badfmt();
			err(1, "fread: %s", archive);
		}
		fix_nlist_order(&nl, N_GETMID(eh.exec));

		addsym(&nl, strtab - sizeof(long), r_off - r_fuzz -
		    sizeof(struct ar_hdr), symcnt, tsymlen, archive);
	}

bad:
	free(strtab);
	(void)fseeko(rfp, r_off, SEEK_SET);
	return N_GETMID(eh.exec);
}
Beispiel #12
0
int
main(int argc, char *argv[])
{
	int opt;

	while ((opt = getopt(argc, argv, "i:D:U:I:o:bBcdeKklnsStV")) != -1)
		switch (opt) {
		case 'i': 
			opt = *optarg++;
			if (opt == 'D')
				addsym(true, true, optarg);
			else if (opt == 'U')
				addsym(true, false, optarg);
			else
				usage();
			break;
		case 'D': 
			addsym(false, true, optarg);
			break;
		case 'U': 
			addsym(false, false, optarg);
			break;
		case 'I': 
			break;
		case 'b': 
		case 'l': 
			lnblank = true;
			break;
		case 'B': 
			compblank = true;
			break;
		case 'c': 
			complement = true;
			break;
		case 'd':
			debugging = true;
			break;
		case 'e': 
			iocccok = true;
			break;
		case 'K': 
			strictlogic = true;
			break;
		case 'k': 
			killconsts = true;
			break;
		case 'n': 
			lnnum = true;
			break;
		case 'o': 
			ofilename = optarg;
			break;
		case 's': 
			symlist = true;
			break;
		case 'S': 
			symlist = symdepth = true;
			break;
		case 't': 
			text = true;
			break;
		case 'V': 
			version();
		default:
			usage();
		}
	argc -= optind;
	argv += optind;
	if (compblank && lnblank)
		errx(2, "-B and -b are mutually exclusive");
	if (argc > 1) {
		errx(2, "can only do one file");
	} else if (argc == 1 && strcmp(*argv, "-") != 0) {
		filename = *argv;
		input = fopen(filename, "rb");
		if (input == NULL)
			err(2, "can't open %s", filename);
	} else {
		filename = "[stdin]";
		input = stdin;
	}
	if (ofilename == NULL) {
		ofilename = "[stdout]";
		output = stdout;
	} else {
		struct stat ist, ost;
		if (stat(ofilename, &ost) == 0 &&
		    fstat(fileno(input), &ist) == 0)
			overwriting = (ist.st_dev == ost.st_dev
				    && ist.st_ino == ost.st_ino);
		if (overwriting) {
			const char *dirsep;
			int ofd;

			dirsep = strrchr(ofilename, '/');
			if (dirsep != NULL)
				snprintf(tempname, sizeof(tempname),
				    "%.*s/" TEMPLATE,
				    (int)(dirsep - ofilename), ofilename);
			else
				snprintf(tempname, sizeof(tempname),
				    TEMPLATE);
			ofd = mkstemp(tempname);
			if (ofd != -1)
				output = fdopen(ofd, "wb+");
			if (output == NULL)
				err(2, "can't create temporary file");
			fchmod(ofd, ist.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO));
		} else {
			output = fopen(ofilename, "wb");
			if (output == NULL)
				err(2, "can't open %s", ofilename);
		}
	}
	process();
	abort(); 
}
/*
 * Add the symbol defined in the kernel, simulating a pseudo module.
 * Create a dummy module entry in the list of modules.
 * This module is used to handle the exported kernel symbols.
 *
 * Load from the currently running kernel
 * OR
 * from a file containing kernel symbols from a different kernel.
 * The file can be either a "System.map" file or a copy of "/proc/ksyms".
 *
 * Return -1 if any error.
 */
static int addksyms(const char *file_syms)
{
	FILE *fp;
	MODULE *mod = modules + n_modules++;
	SYMBOL *symtab[MAX_MAP_SYM];
	struct module_symbol *ksym;
	unsigned int so_far = 0;
	int is_mapfile = 0;
	int n_syms = 0;
	int size;
	char line[PATH_MAX];
	char *p;

	mod->name = "-";
	mod->defsym.n_syms = 0;
	mod->defsym.symtab = NULL;
	mod->undefs.n_syms = 0;
	mod->undefs.symtab = NULL;

	/* Fake the _mod_use_count_ symbol provided by insmod */
	/* Dummy */
	symtab[n_syms++] = addsym("mod_use_count_", mod, SYM_DEFINED, 0);
	symtab[n_syms++] = addsym("__this_module", mod, SYM_DEFINED, 0);

	/*
	 * Specification: depmod / kernel syms only
	 * When initialising its symbol table from the kernel
	 * depmod silently discards all symbol from loaded modules.
	 *
	 * This means that depmod may be used at any time to compute
	 * the dependancy table, even if there are modules already
	 * loaded.
	 *
	 * depmod use the kernel system call to obtain the
	 * symbol table, not /proc/ksyms.
	 */

	if (file_syms) {
		if ((fp = fopen(file_syms, "r")) == NULL) {
			bb_error_msg("Can't read %s", file_syms);
			return -1;
		}
		if (!fgets(line, sizeof(line), fp)) {
			fclose(fp);
			bb_error_msg("premature EOF on %s", file_syms);
			return -1;
		}

		p = strtok(line, " \t\n");
		if (!p) {
			fclose(fp);
			bb_error_msg("Illegal format of %s", file_syms);
			return -1;
		}
		if (!isspace(*line))	/* Adressless symbol? */
			p = strtok(NULL, " \t\n");
		/* The second word is either the symbol name or a type */
		if (p && p[0] && !p[1]) { /* System.map */
			is_mapfile = 1;
			p = strtok(NULL, " \t\n");
		} else { /* /proc/ksyms copy */
			if (p && strtok(NULL, " \t\n"))
				p = NULL;
		}

		if (p && strncmp(p, "GPLONLY_", 8) == 0)
			p += 8;
		if (p)
			symtab[n_syms++] = addsym(p, mod, SYM_DEFINED, 0);

		while (fgets(line, sizeof(line), fp)) {
			if (!is_mapfile && strchr(line, '['))
				continue;
			p = strtok(line, " \t\n"); /* Skip first word */
			if (!isspace(*line))	/* Adressless symbol? */
				p = strtok(NULL, " \t\n");
			if (is_mapfile) {
				if (!p || !p[0] || p[1])
					continue;
				p = strtok(NULL, " \t\n");
				/* Sparc has symbols like '.div' that need to be
				 * exported.  They strip the '.' and prefix the
				 * symbol with '__sparc_dot_'.  There is no need
				 * for 'sparc' in the name, other systems with
				 * the same problem should use just '__dot_'.
				 * Support both prefixes, ready for other
				 * systems.
				 * */
				if (!strncmp(p, "__kstrtab___dot_", 15)) {
					p += 15;
					*p = '.';
				}
				else if (!strncmp(p, "__kstrtab___sparc_dot_", 21)) {
					p += 21;
					*p = '.';
				}
				else if (!strncmp(p, "__kstrtab_", 10))
					p += 10;
				else if (!strncmp(p, "__export_priv_", 14)) {
					/* Sparc has some weird exported symbols marked
					 * __export_priv_ instead of the normal __kstrtab_.
					 * Replace the 'v' with '_' and point at the start of
					 * the '__' before the name.  I see no good reason
					 * to use __export_priv_, but for compatibility with
					 * old sparc kernels, it is supported.  Try to remove
					 * __export_priv_ from sparc and remove this code
					 * four releases after the last kernel that uses
					 * __export_priv_.
					 */
					p += 12;
					*p = '_';
				} else
					continue;
			}
			if (strncmp(p, "GPLONLY_", 8) == 0)
				p += 8;
			assert(n_syms < MAX_MAP_SYM);
			symtab[n_syms++] = addsym(p, mod, SYM_DEFINED, 0);
		}
		fclose(fp);
	} else { /* Use the exported symbols from currently running kernel */
		if (!new_get_kernel_info(K_SYMBOLS))
			return -1;

		for (ksym = ksyms; so_far < nksyms; ++so_far, ksym++) {
			if (strncmp((char *)ksym->name, "GPLONLY_", 8) == 0)
				ksym->name = ((char *)ksym->name) + 8;
			assert(n_syms < MAX_MAP_SYM);
			symtab[n_syms++] = addsym((char *)ksym->name, mod, SYM_DEFINED, 0);
		}
	}

	size = n_syms * sizeof(SYMBOL *);
	mod->defsym.symtab = (SYMBOL **)xmalloc(size);
	mod->defsym.n_syms = n_syms;
	memcpy(mod->defsym.symtab, symtab, size);

	return 0;
}
Beispiel #14
0
/*
 * The main program.
 */
int
main(int argc, char *argv[])
{
	int opt;

	while ((opt = getopt(argc, argv, "i:D:U:I:cdeklnst")) != -1)
		switch (opt) {
		case 'i': /* treat stuff controlled by these symbols as text */
			/*
			 * For strict backwards-compatibility the U or D
			 * should be immediately after the -i but it doesn't
			 * matter much if we relax that requirement.
			 */
			opt = *optarg++;
			if (opt == 'D')
				addsym(true, true, optarg);
			else if (opt == 'U')
				addsym(true, false, optarg);
			else
				usage();
			break;
		case 'D': /* define a symbol */
			addsym(false, true, optarg);
			break;
		case 'U': /* undef a symbol */
			addsym(false, false, optarg);
			break;
		case 'I':
			/* no-op for compatibility with cpp */
			break;
		case 'c': /* treat -D as -U and vice versa */
			complement = true;
			break;
		case 'd':
			debugging = true;
			break;
		case 'e': /* fewer errors from dodgy lines */
			iocccok = true;
			break;
		case 'k': /* process constant #ifs */
			killconsts = true;
			break;
		case 'l': /* blank deleted lines instead of omitting them */
			lnblank = true;
			break;
		case 'n': /* add #line directive after deleted lines */
			lnnum = true;
			break;
		case 's': /* only output list of symbols that control #ifs */
			symlist = true;
			break;
		case 't': /* don't parse C comments */
			text = true;
			break;
		default:
			usage();
		}
	argc -= optind;
	argv += optind;
	if (argc > 1) {
		errx(2, "can only do one file");
	} else if (argc == 1 && strcmp(*argv, "-") != 0) {
		filename = *argv;
		input = fopen(filename, "r");
		if (input == NULL)
			err(2, "can't open %s", filename);
	} else {
		filename = "[stdin]";
		input = stdin;
	}
	process();
	abort(); /* bug */
}
Beispiel #15
0
/*
 * The main program.
 */
int
main(int argc, char *argv[])
{
	int opt;

	while ((opt = getopt(argc, argv, "i:D:U:I:M:o:x:bBcdehKklmnsStV")) != -1)
		switch (opt) {
		case 'i': /* treat stuff controlled by these symbols as text */
			/*
			 * For strict backwards-compatibility the U or D
			 * should be immediately after the -i but it doesn't
			 * matter much if we relax that requirement.
			 */
			opt = *optarg++;
			if (opt == 'D')
				addsym(true, true, optarg);
			else if (opt == 'U')
				addsym(true, false, optarg);
			else
				usage();
			break;
		case 'D': /* define a symbol */
			addsym(false, true, optarg);
			break;
		case 'U': /* undef a symbol */
			addsym(false, false, optarg);
			break;
		case 'I': /* no-op for compatibility with cpp */
			break;
		case 'b': /* blank deleted lines instead of omitting them */
		case 'l': /* backwards compatibility */
			lnblank = true;
			break;
		case 'B': /* compress blank lines around removed section */
			compblank = true;
			break;
		case 'c': /* treat -D as -U and vice versa */
			complement = true;
			break;
		case 'd':
			debugging = true;
			break;
		case 'e': /* fewer errors from dodgy lines */
			iocccok = true;
			break;
		case 'h':
			help();
			break;
		case 'K': /* keep ambiguous #ifs */
			strictlogic = true;
			break;
		case 'k': /* process constant #ifs */
			killconsts = true;
			break;
		case 'm': /* modify in place */
			inplace = true;
			break;
		case 'M': /* modify in place and keep backup */
			inplace = true;
			backext = optarg;
			break;
		case 'n': /* add #line directive after deleted lines */
			lnnum = true;
			break;
		case 'o': /* output to a file */
			ofilename = optarg;
			break;
		case 's': /* only output list of symbols that control #ifs */
			symlist = true;
			break;
		case 'S': /* list symbols with their nesting depth */
			symlist = symdepth = true;
			break;
		case 't': /* don't parse C comments */
			text = true;
			break;
		case 'V':
			version();
			break;
		case 'x':
			exitmode = atoi(optarg);
			if(exitmode < 0 || exitmode > 2)
				usage();
			break;
		default:
			usage();
		}
	argc -= optind;
	argv += optind;
	if (compblank && lnblank)
		errx(2, "-B and -b are mutually exclusive");
	if (symlist && (ofilename != NULL || inplace || argc > 1))
		errx(2, "-s only works with one input file");
	if (argc > 1 && ofilename != NULL)
		errx(2, "-o cannot be used with multiple input files");
	if (argc > 1 && !inplace)
		errx(2, "multiple input files require -m or -M");
	if (argc == 0)
		argc = 1;
	if (argc == 1 && !inplace && ofilename == NULL)
		ofilename = "-";

	atexit(cleantemp);
	if (ofilename != NULL)
		processinout(*argv, ofilename);
	else while (argc-- > 0) {
		processinout(*argv, *argv);
		argv++;
	}
	switch(exitmode) {
	case(0): exit(exitstat);
	case(1): exit(!exitstat);
	case(2): exit(0);
	default: abort(); /* bug */
	}
}
Beispiel #16
0
void rules( void )
{
    a_sym               *lhs, *sym, *precsym;
    a_sym               **rhs;
    unsigned            nrhs;
    unsigned            maxrhs = { 16 };
    a_pro               *pro;
    char                buffer[ 20 ];
    unsigned            i;
    int                 numacts;
    bool                action_defined;
    bool                unit_production;
    bool                not_token;
    a_SR_conflict_list  *list_of_ambiguities;
    a_SR_conflict_list  *am;

    rhs = CALLOC( maxrhs, a_sym * );
    while( token == C_IDENTIFIER ) {
        int sym_lineno = lineno;
        lhs = addsym( buf );
        if( lhs->token )
            msg( "%s used on lhs.\n", lhs->name );
        if( !startsym )
            startsym = lhs;
        numacts = 0;
        do {
            action_defined = FALSE;
            precsym = NULL;
            list_of_ambiguities = NULL;
            nrhs = 0;
            scanextra( 0, &precsym, &list_of_ambiguities );
            for(;;) {
                if( token != '{' && token != IDENTIFIER )
                    break;
                if( nrhs + 2 > maxrhs )
                    rhs = REALLOC( rhs, maxrhs *= 2, a_sym * );
                if( token == '{' ) {
                    i = bufused;
                    scanextra( bufused, &precsym, &list_of_ambiguities );
                    numacts++;
                    if( token == '{' || token == IDENTIFIER ) {
                        sprintf( buffer, "$pro%d", npro );
                        sym = addsym( buffer );
                        copyact( npro, sym, rhs, nrhs, nrhs );
                        addpro( sym, rhs, 0 );
                    } else {
                        copyact( npro, lhs, rhs, 0, nrhs );
                        action_defined = TRUE;
                        break;
                    }
                    memcpy( buf, &buf[ i ], bufused -= i );
                } else {
                    sym = addsym( buf );
                    if( value )
                        sym->token = value;
                    if( sym->token )
                        precsym = sym;
                    scanextra( 0, &precsym, &list_of_ambiguities );
                }
                rhs[ nrhs++ ] = sym;
            }
            unit_production = FALSE;
            if( ! action_defined ) {
                if( nrhs > 0 ) {
                    /* { $$ = $1; } is default action */
                    if( defaultwarnflag ) {
                        char *type_lhs = type_name( lhs->type );
                        char *type_rhs = type_name( rhs[ 0 ]->type );
                        if( strcmp( type_rhs, type_lhs ) != 0 ) {
                            warn("default action would copy '%s <%s>' to '%s <%s>'\n",
                                rhs[ 0 ]->name, type_rhs, lhs->name, type_lhs );
                        }
                    }
                    if( nrhs == 1 ) {
                        unit_production = TRUE;
                    }
                } else {
                    if( sym_lineno == lineno && token == '|' ) {
                        warn( "unexpected epsilon reduction for '%s'?\n", lhs->name );
                    }
                }
            }
            pro = addpro( lhs, rhs, nrhs );
            if( unit_production ) {
                pro->unit = TRUE;
            }
            if( precsym ) {
                pro->prec = precsym->prec;
            }
            if( list_of_ambiguities ) {
                for( am = list_of_ambiguities; am != NULL; am = am->next ) {
                    am->pro = pro;
                }
                pro->SR_conflicts = list_of_ambiguities;
            }
            if( token == ';' ) {
                do {
                    scan( 0 );
                } while( token == ';' );
            } else if( token != '|' ) {
                if( token == C_IDENTIFIER ) {
                    msg( "Missing ';'\n" );
                } else {
                    msg( "Incorrect syntax.\n" );
                }
            }
        } while( token == '|' );
    }
    free( rhs );

    not_token = FALSE;
    for( sym = symlist; sym; sym = sym->next ) {
        /* check for special symbols */
        if( sym == eofsym )
            continue;
        if( denseflag ) {
            if( sym->token != 0 && sym->token < TOKEN_DENSE_BASE ) {
                continue;
            }
        } else {
            if( sym->token != 0 && sym->token < TOKEN_SPARSE_BASE ) {
                continue;
            }
        }
        if( !sym->pro && !sym->token ) {
            not_token = TRUE;
            warn( "%s not defined as '%%token'.\n", sym->name );
        }
    }
    if( not_token ) {
        msg( "cannot continue (because of %%token problems)\n" );
    }
    copyUniqueActions();
}
Beispiel #17
0
void defs( void )
{
    token_t     gentoken;
    a_sym       *sym;
    int         ctype;
    char        *dupbuf( void );
    char        *type;
    a_prec      prec;

    eofsym = make_sym( "$eof", TOKEN_EOF );
    nosym = make_sym( "$impossible", TOKEN_IMPOSSIBLE );
    errsym = make_sym( "error", TOKEN_ERROR );
    if( denseflag ) {
        gentoken = TOKEN_DENSE_BASE;
    } else {
        gentoken = TOKEN_SPARSE_BASE;
    }
    scan( 0 );
    prec.prec = 0;
    prec.assoc = NON_ASSOC;
    for( ;; ) {
        switch( token ) {
        case MARK:
            scan( 0 );
            return;
        case START:
            if( scan( 0 ) != IDENTIFIER )
                msg( "Identifier needed after %%start.\n" );
            startsym = addsym( buf );
            scan( 0 );
            break;
        case UNION:
            if( scan( 0 ) != '{' ) {
                msg( "Need '{' after %%union.\n" );
            }
            fprintf( actout, "#ifndef __YYSTYPE_DEFINED\n" );
            fprintf( actout, "#define __YYSTYPE_DEFINED\n" );
            fprintf( actout, "typedef union " );
            lineinfo();
            fprintf( actout, "%s YYSTYPE;\n", buf );
            fprintf( actout, "#endif\n" );
            fprintf( tokout, "#ifndef __YYSTYPE_DEFINED\n" );
            fprintf( tokout, "#define __YYSTYPE_DEFINED\n" );
            fprintf( tokout, "typedef union %s YYSTYPE;\n", buf );
            fprintf( tokout, "#endif\n" );
            scan( 0 );
            break;
        case LCURL:
            lineinfo();
            copycurl();
            scan( 0 );
            break;
        case KEYWORD_ID:
            switch( scan( 0 ) ) {
            case IDENTIFIER:
                sym = addsym( buf );
                if( ! sym->token ) {
                    msg( "Token must be assigned number before %keyword_id\n" );
                }
                value = sym->token;
                break;
            case NUMBER:
                break;
            default:
                msg( "Expecting identifier or number.\n" );
            }
            keyword_id_low = value;
            switch( scan( 0 ) ) {
            case IDENTIFIER:
                sym = addsym( buf );
                if( ! sym->token ) {
                    msg( "Token must be assigned number before %keyword_id\n" );
                }
                value = sym->token;
                break;
            case NUMBER:
                break;
            default:
                msg( "Expecting identifier or number.\n" );
            }
            keyword_id_high = value;
            scan( 0 );
            break;
        case LEFT:
        case RIGHT:
        case NONASSOC:
            ++prec.prec;
            prec.assoc = value;
            // pass through
        case TOKEN:
        case TYPE:
            ctype = token;
            if( scan( 0 ) == '<' ) {
                if( scan_typename( 0 ) != TYPENAME ) {
                    msg( "Expecting type specifier.\n" );
                }
                type = dupbuf();
                if( scan( 0 ) != '>' ) {
                    msg( "Expecting '>'.\n" );
                }
                scan( 0 );
            } else {
                type = NULL;
            }
            while( token == IDENTIFIER ) {
                sym = addsym( buf );
                if( type != NULL && sym->type != NULL ) {
                    if( strcmp( sym->type, type ) != 0 ) {
                        msg( "'%s' type redeclared from '%s' to '%s'\n",
                            buf, sym->type, type );
                    }
                }
                sym->type = type;
                if( ctype == TYPE ) {
                    scan( 0 );
                } else {
                    if( !sym->token ) {
                        sym->token = value;
                    }
                    if( ctype != TOKEN ) {
                        sym->prec = prec;
                    }
                    if( scan( 0 ) == NUMBER ) {
                        if( sym->token ) {
                            if( sym->name[ 0 ] != '\'' ) {
                                fprintf( tokout, "#undef\t%-20s\n", sym->name );
                            }
                        }
                        sym->token = value;
                        scan( 0 );
                    }
                    if( !sym->token ) {
                        sym->token = gentoken++;
                    }
                    if( sym->name[ 0 ] != '\'' ) {
                        fprintf( tokout, "#define\t%-20s\t0x%02x\n",
                            sym->name, sym->token );
                    }
                }
                if( token == ',' ) {
                    scan( 0 );
                }
            }
            break;
        default:
            msg( "Incorrect syntax.\n" );
        }
    }
}
Beispiel #18
0
/*
 * Extern variable not necessary common.
 */
void
extdec(struct symtab *q)
{
	extern void addsym(struct symtab *);
	addsym(q);
}
/*
 *	Read the symbols in an object and register them in the symbol table.
 *	Return -1 if there is an error.
 */
static int loadobj(const char *objname, int ignore_suffix)
{
	static char *currdir;
	static int currdir_len;
	int fp;
	MODULE *mod;
	SYMBOL *undefs[5000];
	SYMBOL *defsym[5000];
	struct obj_file *f;
	struct obj_section *sect;
	struct obj_symbol *objsym;
	int i;
	int is_2_2;
	int ksymtab;
	int len;
	int n_undefs = 0;
	int n_defsym = 0;
	char *p;
	void *image;
	unsigned long m_size;

	p = strrchr(objname, '/');
	len = 1 + (int)(p - objname);

	if ((fp = open(objname, O_RDONLY)) < 0)
		return 1;

	if (!(f = obj_load(fp, ET_REL, objname))) {
		close(fp);
		return -1;
	}
	close(fp);

	/*
	 * Allow arch code to define _GLOBAL_OFFSET_TABLE_
	 */
	arch_create_got(f);

	/*
	 * If we have changed base directory
	 * then use the defined symbols from modules
	 * in the _same_ directory to resolve whatever
	 * undefined symbols there are.
	 *
	 * This strategy ensures that we will have
	 * as correct dependencies as possible,
	 * even if the same symbol is defined by
	 * other modules in other directories.
	 */
	if (currdir_len != len || currdir == NULL ||
	    strncmp(currdir, objname, len) != 0) {
		if (currdir)
			resolve();
		currdir = bb_xstrdup(objname);
		currdir_len = len;
	}

	mod = modules + n_modules++;
	mod->name = bb_xstrdup(objname);

	if ((sect = obj_find_section(f, "__ksymtab")) != NULL)
		ksymtab = sect->idx; /* Only in 2.2 (or at least not 2.0) */
	else
		ksymtab = -1;

	if (sect ||
	    obj_find_section(f, ".modinfo") ||
	    obj_find_symbol(f, "__this_module"))
		is_2_2 = 1;
	else
		is_2_2 = 0;

	for (i = 0; i < HASH_BUCKETS; ++i) {
		for (objsym = f->symtab[i]; objsym; objsym = objsym->next) {
			if (objsym->secidx == SHN_UNDEF) {
				if (ELFW(ST_BIND)(objsym->info) != STB_WEAK &&
				    objsym->r_type /* assumes that R_arch_NONE is always 0 on all arch */) {
					undefs[n_undefs++] = addsym(objsym->name,
								    mod,
								    SYM_UNDEF,
								    ignore_suffix);
				}
				continue;
			}
			/* else */

			if (is_2_2 && ksymtab != -1) {
				/* A 2.2 module using EXPORT_SYMBOL */
				if (objsym->secidx == ksymtab &&
				    ELFW(ST_BIND)(objsym->info) == STB_GLOBAL) {
					/* Ignore leading "__ksymtab_" */
					defsym[n_defsym++] = addsym(objsym->name + 10,
								    mod,
								    SYM_DEFINED,
								    ignore_suffix);
				}
				continue;
			}
			/* else */

			if (is_2_2) {
				/*
				 * A 2.2 module _not_ using EXPORT_SYMBOL
				 * It might still want to export symbols,
				 * although strictly speaking it shouldn't...
				 * (Seen in pcmcia)
				 */
				if (ELFW(ST_BIND)(objsym->info) == STB_GLOBAL) {
					defsym[n_defsym++] = addsym(objsym->name,
								    mod,
								    SYM_DEFINED,
								    ignore_suffix);
				}
				continue;
			}
			/* else */

			/* Not undefined or 2.2 ksymtab entry */
			if (objsym->secidx < SHN_LORESERVE
			/*
			 * The test below is removed for 2.0 compatibility
			 * since some 2.0-modules (correctly) hide the
			 * symbols it exports via register_symtab()
			 */
			/* && ELFW(ST_BIND)(objsym->info) == STB_GLOBAL */
			     ) {
				defsym[n_defsym++] = addsym(objsym->name,
							    mod,
							    SYM_DEFINED,
							    ignore_suffix);
			}
		}
	}

	/*
	 *	Finalize the information about a module.
	 */
	mod->defsym.n_syms = n_defsym;
	if (n_defsym > 0) {
		int size = n_defsym * sizeof(SYMBOL *);

		mod->defsym.symtab = (SYMBOL **)xmalloc(size);
		memcpy(mod->defsym.symtab, defsym, size);
	} else
		mod->defsym.symtab = NULL;

	mod->undefs.n_syms = n_undefs;
	if (n_undefs > 0) {
		int size = n_undefs * sizeof(SYMBOL *);

		mod->undefs.symtab = (SYMBOL **) xmalloc(size);
		memcpy(mod->undefs.symtab, undefs, size);
		mod->resolved = 0;
	} else {
		mod->undefs.symtab = NULL;
		mod->resolved = 1;
	}

	/* Do a pseudo relocation to base address 0x1000 (arbitrary).
	 * All undefined symbols are treated as absolute 0.  This builds
	 * enough of a module to allow extraction of internal data such
	 * as device tables.
	 */
	obj_clear_undefineds(f);
	obj_allocate_commons(f);
	m_size = obj_load_size(f);
	if (!obj_relocate(f, 0x1000)) {
		bb_error_msg("depmod obj_relocate failed\n");
		return(-1);
	}
	extract_generic_string(f, mod);
	image = xmalloc(m_size);
	obj_create_image(f, image);
	free(image);

	obj_free(f);
	return 0;
}
Beispiel #20
0
static RList* symbols(RBinFile *arch) {
	ut32 *vtable = (ut32*)arch->buf->buf;
	const char *name;
	SMD_Header *hdr;
	int i;
	RList *ret = NULL;

	if (!(ret = r_list_new ()))
		return NULL;
	ret->free = free;
	// TODO: store all this stuff in SDB
	hdr = (SMD_Header*)(arch->buf->buf + 0x100);
	addsym (ret, "rom_start", hdr->RomStart);
	addsym (ret, "rom_end", hdr->RomEnd);
	addsym (ret, "ram_start", hdr->RamStart);
	addsym (ret, "ram_end", hdr->RamEnd);
	showstr ("Copyright", hdr->CopyRights, 32);
	showstr ("DomesticName", hdr->DomesticName, 48);
	showstr ("OverseasName", hdr->OverseasName, 48);
	showstr ("ProductCode", hdr->ProductCode, 14);
	eprintf ("Checksum: 0x%04x\n", (ut32)hdr->CheckSum);
	showstr ("Peripherials", hdr->Peripherials, 16);
	showstr ("SramCode", hdr->CountryCode, 12);
	showstr ("ModemCode", hdr->CountryCode, 12);
	showstr ("CountryCode", hdr->CountryCode, 16);
	/* parse vtable */
	for (i=0; i<64; i++) {
		switch (i) {
		case 0: name = "SSP"; break;
		case 1: name = "Reset"; break;
		case 2: name = "BusErr"; break;
		case 3: name = "InvOpCode"; break;
		case 4: name = "DivBy0"; break;
		case 5: name = "Check"; break;
		case 6: name = "TrapV"; break;
		case 7: name = "GPF"; break;
		case 8: name = "Trace"; break;
		case 9: name = "Reserv0"; break;
		case 10: name = "Reserv1"; break;
		case 11: name = "Reserv2"; break;
		case 12: name = "Reserv3"; break;
		case 13: name = "Reserv4"; break;
		case 14: name = "BadInt"; break;
		case 15: name = "Reserv10"; break;
		case 16: name = "Reserv11"; break;
		case 17: name = "Reserv12"; break;
		case 18: name = "Reserv13"; break;
		case 19: name = "Reserv14"; break;
		case 20: name = "Reserv15"; break;
		case 21: name = "Reserv16"; break;
		case 22: name = "Reserv17"; break;
		case 23: name = "BadIRQ"; break;
		case 24: name = "IRQ1"; break;
		case 25: name = "EXT"; break;
		case 26: name = "IRQ3"; break;
		case 27: name = "HBLANK"; break;
		case 28: name = "IRQ5"; break;
		case 29: name = "VBLANK"; break;
		case 30: name = "IRQ7"; break;
		case 31: name = "Trap0"; break;
		case 32: name = "Trap1"; break;
		case 33: name = "Trap2"; break;
		case 34: name = "Trap3"; break;
		case 35: name = "Trap4"; break;
		case 36: name = "Trap5"; break;
		case 37: name = "Trap6"; break;
		case 38: name = "Trap7"; break;
		case 39: name = "Trap8"; break;
		case 40: name = "Trap9"; break;
		case 41: name = "Trap10"; break;
		case 42: name = "Trap11"; break;
		case 43: name = "Trap12"; break;
		case 44: name = "Trap13"; break;
		case 45: name = "Trap14"; break;
		case 46: name = "Trap15"; break;
		case 47: name = "Reserv30"; break;
		case 48: name = "Reserv31"; break;
		case 49: name = "Reserv32"; break;
		case 50: name = "Reserv33"; break;
		case 51: name = "Reserv34"; break;
		case 52: name = "Reserv35"; break;
		case 53: name = "Reserv36"; break;
		case 54: name = "Reserv37"; break;
		case 55: name = "Reserv38"; break;
		case 56: name = "Reserv39"; break;
		case 57: name = "Reserv3A"; break;
		case 58: name = "Reserv3B"; break;
		case 59: name = "Reserv3C"; break;
		case 60: name = "Reserv3D"; break;
		case 61: name = "Reserv3E"; break;
		case 62: name = "Reserv3F"; break;
		default: name = NULL;
		}
		if (!name || !vtable[i]) continue;
		addsym (ret, name, vtable[i]);
	}
	return ret;
}