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); } }
/* * Call to a function */ void calldec(NODE *p, NODE *r) { struct symtab *q = p->n_sp; extern void addsym(struct symtab *); addsym(q); }
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); }
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" ) ); }
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); }
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 ); }
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; }
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 == ')'); } } }
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; //--- }
/* * 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); }
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; }
/* * 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 */ }
/* * 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 */ } }
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(); }
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" ); } } }
/* * 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; }
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; }