/* this function simply checks to see if the user has changed the order, and if so, updates the matrix */ void new_rot_order() { if ((rotorder_var = lookup_global(ROTORDER_NAME)) < 0) { rotorder_var = add_global(ROTORDER_NAME); globals(rotorder_var)->value.real = 4.; globals(rotorder_var)->flags = ORDINARY_PARAM | RECALC_PARAMETER | ALWAYS_RECALC; } rotorder = (int)globals(rotorder_var)->value.real; if ((genpower_var = lookup_global(GENPOWER_NAME)) < 0) { genpower_var = add_global(GENPOWER_NAME); globals(genpower_var)->value.real = 1.; globals(genpower_var)->flags = ORDINARY_PARAM | RECALC_PARAMETER | ALWAYS_RECALC; } genpower = (int)globals(genpower_var)->value.real; rotmat[0][0] = rotmat[1][1] = cos(2*M_PI*genpower/rotorder); rotmat[1][0] = -(rotmat[0][1] = sin(2*M_PI*genpower/rotorder)); }
static void extern_name(char *name1, char *name2, tree *symbol) { char buffer[BUFSIZ]; if (name2) sprintf(buffer, "%s_%s", name1, name2); else sprintf(buffer, "%s", name1); fprintf(state.output.f, " extern %s\n", buffer); add_global(buffer, buffer, symbol); return; }
/** * Process the buffer * Return TRUE to exit program */ int process_buf(char **bufargs) { struct Command *cmd; int argc = 0; /* cd command*/ if (!strcmp(bufargs[0], "cd") && bufargs[0][2] == '\0') { set_cwd(bufargs[1]); return FALSE; } /* exit command */ if (!strcmp(bufargs[0], "exit") && bufargs[0][4] == '\0') { return TRUE; } /* Get argc */ while (bufargs[argc++] != ARR_END); /* Set up command and first process */ cmd = init_command(); cmd->procHead = init_process(argc * sizeof(char *)); cmd->runningProcs++; /* Allocate arguments to their processes within the command */ if (allocate_args(argc, bufargs, cmd) == TRUE) { /* Invalid command */ free_command(NULL, cmd); return FALSE; } /* Add the command to the global commands */ add_global(cmd); /* For each process in the command, fork it and set it up as running */ fork_command(cmd); /* If foreground command, then wait on processes */ if (cmd->type == FG) { wait_running(cmd); /* set the foreground command to null and clean it */ globalCmd[FG] = NULL; free_command(NULL, cmd); } return FALSE; }
int main() { #if 1 int x = 10, y = 20; int z; int *px = &x, *py = &y; z = add_global(); printf("add_global = %d\n",z); z = add_p(px,py); printf("add_p = %d\n",z); z = add(x,y); printf("add = %d\n",z); #endif }
static void write_declarations(void) { entity *entity_list = NULL; tree *current = NULL; int first_time = 1; tree *list; tree *symbol; entity_list = state.list; while (entity_list != NULL) { current = entity_list->node; if ((current->tag == node_decl) && (current->value.decl.storage != EXTERN_STORAGE)) { if ((current->value.decl.type == CONST_TYPE) && (current->value.decl.storage != 0)) { gp_error("constants can't be public or volatile"); } /* FIXME: only bytes are supported so far */ assert(current->value.decl.size == BYTE_SIZE); if (first_time) { fprintf(state.output.f, "; declarations \n"); fprintf(state.output.f, " udata\n"); first_time = 0; } for (list = current->value.decl.expr; list; list = TAIL(list)) { symbol = HEAD(list); assert(symbol->tag == node_symbol); if (current->value.decl.type == VAR_TYPE) { fprintf(state.output.f, "%s res 1\n", symbol->value.symbol); if (current->value.decl.storage == PUBLIC_STORAGE) fprintf(state.output.f, " global %s\n", symbol->value.symbol); } add_global(symbol->value.symbol, symbol->value.symbol, current); } } entity_list = entity_list->next; } if (!first_time) fprintf(state.output.f, "\n"); }
static char *get_tok (char *buf, int doall, FILE *fp_net) { /* Figures out which, if any token is at the start of this line and * * takes the appropriate action. It always returns a pointer to * * the next line (I need to do this so I can do some lookahead). */ char *ptr; ptr = my_strtok(buf,TOKENS,fp_net,buf); if (ptr == NULL) { /* Empty line. Skip. */ ptr = my_fgets(buf, BUFSIZE, fp_net); return (ptr); } if (strcmp(ptr,".clb") == 0) { ptr = add_clb (doall, fp_net, buf); return (ptr); } if (strcmp(ptr,".input") == 0) { add_io (doall, INPAD, fp_net, buf); ptr = my_fgets(buf, BUFSIZE, fp_net); return (ptr); } if (strcmp(ptr,".output") == 0) { add_io (doall, OUTPAD, fp_net, buf); ptr = my_fgets(buf, BUFSIZE, fp_net); return (ptr); } if (strcmp(ptr,".global") == 0) { add_global (doall, fp_net, buf); ptr = my_fgets(buf, BUFSIZE, fp_net); return (ptr); } printf ("Error in get_tok while parsing netlist file.\n"); printf ("Line %d starts with an invalid token (%s).\n", linenum, ptr); exit (1); }
static void write_decl(tree *decl, char *name) { tree *list; tree *symbol; char alias[BUFSIZ]; assert(decl->tag == node_decl); list = decl->value.decl.expr; assert(list->tag == node_list); for (; list; list = TAIL(list)) { symbol = HEAD(list); assert(symbol->tag == node_symbol); sprintf(alias, "%s_%s", name, symbol->value.symbol); add_global(symbol->value.symbol, alias, symbol); if (decl->value.decl.type == VAR_TYPE) { fprintf(state.output.f, "%s res 1\n", alias); } } }
void newfunc_typed(int storage, char *n, int type) { int idx; SYMBOL *symbol; char an[NAMESIZE]; fexitlab = getlabel(); if ((idx = find_global(n)) > -1) { symbol = &symbol_table[idx]; if (symbol->identity != FUNCTION) multidef(n); } else { /* extern implies global scope */ idx = add_global(n, FUNCTION, CINT, 0, storage == EXTERN ? PUBLIC : storage); symbol = &symbol_table[idx]; } local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC; argstk = 0; // ANSI style argument declaration if (doAnsiArguments()) { if (storage == EXTERN) { need_semicolon(); return; } /* No body .. just a definition */ if (match(";")) return; } else { // K&R style argument declaration while (!match(")")) { if (symname(an)) { if (find_locale(an) > -1) multidef(an); else { /* FIXME: struct */ add_local(an, 0, 0, argstk, AUTO); argstk = argstk + INTSIZE; } } else { error("illegal argument name"); junk(); } blanks(); if (!streq(line + lptr, ")")) { if (!match(",")) error("expected comma"); } if (endst()) break; } if (storage == EXTERN) { need_semicolon(); return; } /* No body .. just a definition */ if (match(";")) return; stkp = 0; argtop = argstk; while (argstk) { if ((type = get_type()) != -1) { notvoid(type); getarg(type); need_semicolon(); } else { error("wrong number args"); break; } } } if (symbol->offset == FUNCTION) multidef(n); symbol->offset = FUNCTION; output_string(n); output_label_terminator(); newline(); gen_prologue(); statement(YES); print_label(fexitlab); output_label_terminator(); newline(); gen_epilogue(); gen_modify_stack(0); gen_ret(); stkp = 0; local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC; }
/** * declare a static variable * @param type * @param storage * @param mtag tag of struct whose members are being declared, or zero * @param otag tag of struct object being declared. only matters if mtag is non-zero * @param is_struct struct or union or no meaning * @return 1 if a function was parsed */ int declare_global(int type, int storage, TAG_SYMBOL *mtag, int otag, int is_struct) { int dim, identity; char sname[NAMESIZE]; FOREVER { FOREVER { if (endst ()) return 0; dim = 1; if (match ("*")) { identity = POINTER; } else { identity = VARIABLE; } if (!symname (sname)) illname (); if (match ("(")) { /* FIXME: We need to deal with pointer types properly here */ if (identity == POINTER) type = CINT; newfunc_typed(storage, sname, type); /* Can't int foo(x){blah),a=4; */ return 1; } /* FIXME: we need to deal with extern properly here */ if (find_global (sname) > -1) multidef (sname); if (identity == VARIABLE) notvoid(type); if (match ("[")) { dim = needsub (); //if (dim || storage == EXTERN) { identity = ARRAY; //} else { // identity = POINTER; //} } // add symbol if (mtag == 0) { // real variable, not a struct/union member identity = initials(sname, type, identity, dim, otag); add_global (sname, identity, type, (dim == 0 ? -1 : dim), storage); if (type == STRUCT) { symbol_table[current_symbol_table_idx].tagidx = otag; } break; } else if (is_struct) { // structure member, mtag->size is offset add_member(sname, identity, type, mtag->size, storage); // store (correctly scaled) size of member in tag table entry if (identity == POINTER) type = CINT; scale_const(type, otag, &dim); mtag->size += dim; } else { // union member, offset is always zero add_member(sname, identity, type, 0, storage); // store maximum member size in tag table entry if (identity == POINTER) type = CINT; scale_const(type, otag, &dim); if (mtag->size < dim) mtag->size = dim; } } if (!match (",")) return 0; } }
static void scan_c_stream (FILE *infile) { int commas, minargs, maxargs; int c = '\n'; while (!feof (infile)) { bool doc_keyword = false; bool defunflag = false; bool defvarperbufferflag = false; bool defvarflag = false; enum global_type type = INVALID; static char *name; static ptrdiff_t name_size; if (c != '\n' && c != '\r') { c = getc (infile); continue; } c = getc (infile); if (c == ' ') { while (c == ' ') c = getc (infile); if (c != 'D') continue; c = getc (infile); if (c != 'E') continue; c = getc (infile); if (c != 'F') continue; c = getc (infile); if (c == 'S') { c = getc (infile); if (c != 'Y') continue; c = getc (infile); if (c != 'M') continue; c = getc (infile); if (c != ' ' && c != '\t' && c != '(') continue; type = SYMBOL; } else if (c == 'V') { c = getc (infile); if (c != 'A') continue; c = getc (infile); if (c != 'R') continue; c = getc (infile); if (c != '_') continue; defvarflag = true; c = getc (infile); defvarperbufferflag = (c == 'P'); if (generate_globals) { if (c == 'I') type = EMACS_INTEGER; else if (c == 'L') type = LISP_OBJECT; else if (c == 'B') type = BOOLEAN; } c = getc (infile); /* We need to distinguish between DEFVAR_BOOL and DEFVAR_BUFFER_DEFAULTS. */ if (generate_globals && type == BOOLEAN && c != 'O') type = INVALID; } else continue; } else if (c == 'D') { c = getc (infile); if (c != 'E') continue; c = getc (infile); if (c != 'F') continue; c = getc (infile); defunflag = c == 'U'; } else continue; if (generate_globals && (!defvarflag || defvarperbufferflag || type == INVALID) && !defunflag && type != SYMBOL) continue; while (c != '(') { if (c < 0) goto eof; c = getc (infile); } if (type != SYMBOL) { /* Lisp variable or function name. */ c = getc (infile); if (c != '"') continue; c = read_c_string_or_comment (infile, -1, false, 0); } if (generate_globals) { ptrdiff_t i = 0; char const *svalue = 0; /* Skip "," and whitespace. */ do { c = getc (infile); } while (c == ',' || c == ' ' || c == '\t' || c == '\n' || c == '\r'); /* Read in the identifier. */ do { if (c < 0) goto eof; input_buffer[i++] = c; c = getc (infile); } while (! (c == ',' || c == ' ' || c == '\t' || c == '\n' || c == '\r')); input_buffer[i] = '\0'; if (name_size <= i) { free (name); name_size = i + 1; ptrdiff_t doubled; if (! INT_MULTIPLY_WRAPV (name_size, 2, &doubled) && doubled <= SIZE_MAX) name_size = doubled; name = xmalloc (name_size); } memcpy (name, input_buffer, i + 1); if (type == SYMBOL) { do c = getc (infile); while (c == ' ' || c == '\t' || c == '\n' || c == '\r'); if (c != '"') continue; c = read_c_string_or_comment (infile, -1, false, 0); svalue = input_buffer; } if (!defunflag) { add_global (type, name, 0, svalue); continue; } } if (type == SYMBOL) continue; /* DEFVAR_LISP ("name", addr, "doc") DEFVAR_LISP ("name", addr /\* doc *\/) DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */ if (defunflag) commas = generate_globals ? 4 : 5; else if (defvarperbufferflag) commas = 3; else if (defvarflag) commas = 1; else /* For DEFSIMPLE and DEFPRED. */ commas = 2; while (commas) { if (c == ',') { commas--; if (defunflag && (commas == 1 || commas == 2)) { int scanned = 0; do c = getc (infile); while (c == ' ' || c == '\n' || c == '\r' || c == '\t'); if (c < 0) goto eof; ungetc (c, infile); if (commas == 2) /* Pick up minargs. */ scanned = fscanf (infile, "%d", &minargs); else /* Pick up maxargs. */ if (c == 'M' || c == 'U') /* MANY || UNEVALLED */ { if (generate_globals) maxargs = (c == 'M') ? -1 : -2; else maxargs = -1; } else scanned = fscanf (infile, "%d", &maxargs); if (scanned < 0) goto eof; } } if (c == EOF) goto eof; c = getc (infile); } if (generate_globals) { struct global *g = add_global (FUNCTION, name, maxargs, 0); if (!g) continue; /* The following code tries to recognize function attributes specified after the docstring, e.g.: DEFUN ("foo", Ffoo, Sfoo, X, Y, Z, doc: /\* doc *\/ attributes: attribute1 attribute2 ...) (Lisp_Object arg...) Now only 'noreturn' and 'const' attributes are used. */ /* Advance to the end of docstring. */ c = getc (infile); if (c == EOF) goto eof; int d = getc (infile); if (d == EOF) goto eof; while (1) { if (c == '*' && d == '/') break; c = d, d = getc (infile); if (d == EOF) goto eof; } /* Skip spaces, if any. */ do { c = getc (infile); if (c == EOF) goto eof; } while (c == ' ' || c == '\n' || c == '\r' || c == '\t'); /* Check for 'attributes:' token. */ if (c == 'a' && stream_match (infile, "ttributes:")) { char *p = input_buffer; /* Collect attributes up to ')'. */ while (1) { c = getc (infile); if (c == EOF) goto eof; if (c == ')') break; if (p - input_buffer > sizeof (input_buffer)) abort (); *p++ = c; } *p = 0; if (strstr (input_buffer, "noreturn")) g->flags |= DEFUN_noreturn; if (strstr (input_buffer, "const")) g->flags |= DEFUN_const; } continue; } while (c == ' ' || c == '\n' || c == '\r' || c == '\t') c = getc (infile); if (c == '"') c = read_c_string_or_comment (infile, 0, false, 0); while (c != EOF && c != ',' && c != '/') c = getc (infile); if (c == ',') { c = getc (infile); while (c == ' ' || c == '\n' || c == '\r' || c == '\t') c = getc (infile); while ((c >= 'a' && c <= 'z') || (c >= 'Z' && c <= 'Z')) c = getc (infile); if (c == ':') { doc_keyword = true; c = getc (infile); while (c == ' ' || c == '\n' || c == '\r' || c == '\t') c = getc (infile); } } if (c == '"' || (c == '/' && (c = getc (infile), ungetc (c, infile), c == '*'))) { bool comment = c != '"'; bool saw_usage; printf ("\037%c%s\n", defvarflag ? 'V' : 'F', input_buffer); if (comment) getc (infile); /* Skip past `*'. */ c = read_c_string_or_comment (infile, 1, comment, &saw_usage); /* If this is a defun, find the arguments and print them. If this function takes MANY or UNEVALLED args, then the C source won't give the names of the arguments, so we shouldn't bother trying to find them. Various doc-string styles: 0: DEFUN (..., "DOC") (args) [!comment] 1: DEFUN (..., /\* DOC *\/ (args)) [comment && !doc_keyword] 2: DEFUN (..., doc: /\* DOC *\/) (args) [comment && doc_keyword] */ if (defunflag && maxargs != -1 && !saw_usage) { char argbuf[1024], *p = argbuf; if (!comment || doc_keyword) while (c != ')') { if (c < 0) goto eof; c = getc (infile); } /* Skip into arguments. */ while (c != '(') { if (c < 0) goto eof; c = getc (infile); } /* Copy arguments into ARGBUF. */ *p++ = c; do *p++ = c = getc (infile); while (c != ')'); *p = '\0'; /* Output them. */ fputs ("\n\n", stdout); write_c_args (input_buffer, argbuf, minargs, maxargs); } else if (defunflag && maxargs == -1 && !saw_usage) /* The DOC should provide the usage form. */ fprintf (stderr, "Missing 'usage' for function '%s'.\n", input_buffer); } } eof: if (ferror (infile) || fclose (infile) != 0) fatal ("read error"); }
int primary(LVALUE *lval) { char sname[NAMESIZE]; int num[1], k, symbol_table_idx, offset, reg; SYMBOL *symbol; lval->ptr_type = 0; // clear pointer/array type lval->tagsym = 0; if (match ("(")) { k = hier1 (lval); needbrack (")"); return (k); } if (amatch("sizeof", 6)) { needbrack("("); gen_immediate(); if (amatch("int", 3)) output_number(INTSIZE); else if (amatch("char", 4)) output_number(1); else if (symname(sname)) { if (((symbol_table_idx = find_locale(sname)) > -1) || ((symbol_table_idx = find_global(sname)) > -1)) { symbol = &symbol_table[symbol_table_idx]; if (symbol->storage == LSTATIC) error("sizeof local static"); offset = symbol->offset; if ((symbol->type & CINT) || (symbol->identity == POINTER)) offset *= INTSIZE; else if (symbol->type == STRUCT) offset *= tag_table[symbol->tagidx].size; output_number(offset); } else { error("sizeof undeclared variable"); output_number(0); } } else { error("sizeof only on type or variable"); } needbrack(")"); newline(); lval->symbol = 0; lval->indirect = 0; return(0); } if (symname (sname)) { if ((symbol_table_idx = find_locale(sname)) > -1) { symbol = &symbol_table[symbol_table_idx]; reg = gen_get_locale(symbol); lval->symbol = symbol; lval->indirect = symbol->type; if (symbol->type == STRUCT) { lval->tagsym = &tag_table[symbol->tagidx]; } if (symbol->identity == ARRAY || (symbol->identity == VARIABLE && symbol->type == STRUCT)) { lval->ptr_type = symbol->type; return reg; } if (symbol->identity == POINTER) { lval->indirect = CINT; lval->ptr_type = symbol->type; } return FETCH | reg; } if ((symbol_table_idx = find_global(sname)) > -1) { symbol = &symbol_table[symbol_table_idx]; if (symbol->identity != FUNCTION) { lval->symbol = symbol; lval->indirect = 0; if (symbol->type == STRUCT) { lval->tagsym = &tag_table[symbol->tagidx]; } if (symbol->identity != ARRAY && (symbol->identity != VARIABLE || symbol->type != STRUCT)) { if (symbol->identity == POINTER) { lval->ptr_type = symbol->type; } return FETCH | HL_REG; } gen_immediate(); output_string(symbol->name); newline(); lval->indirect = symbol->type; lval->ptr_type = symbol->type; return 0; } } blanks(); if (ch() != '(') error("undeclared variable"); symbol_table_idx = add_global(sname, FUNCTION, CINT, 0, PUBLIC); symbol = &symbol_table[symbol_table_idx]; lval->symbol = symbol; lval->indirect = 0; return 0; } lval->symbol = 0; lval->indirect = 0; if (constant(num)) return 0; else { error("invalid expression"); gen_immediate(); output_number(0); newline(); junk(); return 0; } }
glxlink::glxlink(char *filename) { bool ok = true; globals = NULL; imports = NULL; exports = NULL; objects = NULL; handle = NULL; settag = NULL; init = NULL; sync = NULL; term = NULL; glxflags = 0; valid_to = 0; last_t = 0; FILE *fp = fopen(filename,"rt"); if ( fp==NULL ) throw "file open failed"; output_debug("opened link '%s'", filename); char line[1024]; int linenum=0; while ( fgets(line,sizeof(line),fp)!=NULL ) { linenum++; if ( line[0]=='#' ) continue; char tag[64], data[1024]=""; if ( sscanf(line,"%s %[^\r\n]",tag,data)>0 ) { output_debug("%s(%d): %s %s", filename, linenum, tag,data); if ( settag!=NULL ) { if ( strcmp(tag,"global")==0 ) { add_global(data); } else if ( strcmp(tag,"object")==0 ) { add_object(data); } else if ( strcmp(tag,"export")==0 ) { add_export(data); } else if ( strcmp(tag,"import")==0 ) { add_import(data); } else if ( !(*settag)(this,tag,data) ) output_error("%s(%d): tag '%s' not accepted", filename, linenum, tag); } else if ( strcmp(tag,"target")==0) { if ( !set_target(data) ) { output_error("%s(%d): target '%s' is not valid", filename, linenum, data); ok = false; } } else output_warning("%s(%d): tag '%s' cannot be processed until target module is loaded", filename, linenum, tag); } } fclose(fp); // append to link list next = first; first = this; if ( ok ) output_verbose("link '%s' ok", filename); else throw "cannot establish link"; }
primary (lvalue_t *lval) { char sname[NAMESIZE]; int num[1], k, symbol_table_idx, offset, reg; symbol_t *symbol; lval->ptr_type = 0; /* clear pointer/array type */ if (match ("(")) { k = hier1 (lval); needbrack (")"); return (k); } if (amatch("sizeof", 6)) { needbrack("("); gen_immediate_c(); if (amatch("int", 3)) output_number(INTSIZE); else if (amatch("char", 4)) output_number(1); else if (symname(sname)) { if ((symbol_table_idx = findloc(sname)) || (symbol_table_idx = findglb(sname))) { symbol = &symbol_table[symbol_table_idx]; if (symbol->storage == LSTATIC) error("sizeof local static"); offset = symbol->count; if ((symbol->type & CINT) || (symbol->identity == POINTER)) offset *= INTSIZE; output_number(offset); } else { error("sizeof undeclared variable"); output_number(0); } } else { error("sizeof only on simple type or variable"); } needbrack(")"); newline(); lval->symbol = 0; lval->indirect = 0; return(0); } if (symname (sname)) { if (symbol_table_idx = findloc (sname)) { symbol = &symbol_table[symbol_table_idx]; reg = gen_get_location (symbol); lval->symbol = symbol; lval->indirect = symbol->type; if (symbol->identity == ARRAY) { //lval->ptr_type = symbol->type; lval->ptr_type = 0; return 0; } if (symbol->identity == POINTER) { lval->indirect = UINT; lval->ptr_type = symbol->type; } return reg; } if (symbol_table_idx = findglb (sname)) { symbol = &symbol_table[symbol_table_idx]; lval->symbol = symbol; switch (symbol->identity) { case ARRAY: gen_immediate_a (); output_string (symbol->name); newline (); /* Fall through */ case FUNCTION: lval->indirect = lval->ptr_type = symbol_table[symbol_table_idx].type; lval->ptr_type = 0; return 0; default: lval->indirect = 0; if (symbol->identity == POINTER) { lval->ptr_type = symbol->type; } return 1; } } blanks (); if (ch() != '(') error("undeclared variable"); symbol_table_idx = add_global (sname, FUNCTION, CINT, 0, PUBLIC, 1); symbol = &symbol_table[symbol_table_idx]; lval->symbol = symbol; lval->indirect = 0; return 0; } if (constant (num)) { lval->symbol = 0; lval->indirect = 0; return 0; } error ("invalid expression"); gen_immediate_c (); output_number(0); newline (); junk (); return 0; }
static void write_procedure(tree *procedure, int is_func) { tree *head; tree *body; char *name; tree *args; tree *decl; tree *statements; tree *argument; int i; int storage; if (is_func) { head = procedure->value.func.head; storage = procedure->value.func.storage; body = procedure->value.func.body; } else { head = procedure->value.proc.head; storage = procedure->value.proc.storage; body = procedure->value.proc.body; } if (storage == EXTERN_STORAGE) return; assert(head->tag == node_head); assert(body->tag == node_body); name = head->value.head.name; args = head->value.head.args; decl = body->value.body.decl; statements = body->value.body.statements; if (is_func) { fprintf(state.output.f, "; function %s\n", name); } else { fprintf(state.output.f, "; procedure %s\n", name); } /* data memory section */ if ((args != NULL) || (decl != NULL)) { fprintf(state.output.f, ".udata_%s udata\n", name); /* the procedure or function has arguments */ if (args != NULL) { assert(args->tag == node_list); for (; args; args = TAIL(args)) { argument = HEAD(args); assert(argument->tag == node_decl); assert(argument->value.decl.type == 0); assert(argument->value.decl.storage == 0); /* FIXME: only bytes are supported so far */ assert(argument->value.decl.size == BYTE_SIZE); write_decl(argument, name); } } /* the procedure or function has local variables */ if (decl != NULL) { assert(decl->tag == node_list); for (; decl; decl = TAIL(decl)) { argument = HEAD(decl); assert(argument->tag == node_decl); assert(argument->value.decl.storage == 0); /* FIXME: only bytes are supported so far */ assert(argument->value.decl.size == BYTE_SIZE); if (argument->value.decl.type == VAR_TYPE) write_decl(argument, name); } } fprintf(state.output.f, "\n"); } /* program memory section */ fprintf(state.output.f, ".code_%s code\n", name); add_global(name, name, procedure); write_label(name); if (storage == PUBLIC_STORAGE) fprintf(state.output.f, " global %s\n", name); max_temp_number = 0; write_statements(statements); fprintf(state.output.f, " return\n"); fprintf(state.output.f, "\n"); /* temp data section */ if (max_temp_number) { /* FIXME: overlay this if possible */ fprintf(state.output.f, ".udata_%s_temp udata\n", name); for(i = 0; i < max_temp_number; i++) fprintf(state.output.f, "_temp_%d res 1\n", i); fprintf(state.output.f, "\n"); } }
// Register global and local symbols for resolving int register_symbols() { DEBUG(( stderr, "register_symbols started\n" )); object *o = root_obj; // process all objects while( o ) { // get object's symtab section *s = o->get_section_by_type( SHT_SYMTAB ); if( !s ) warning( "object '%s' got no symbol table!!! (skipped)", o->filename ); else { // get object's strtab section *strtab = o->sections; while( strtab ) { if( (strtab->header->sh_type == SHT_STRTAB) && (strtab->header->sh_name == s->header->sh_link) ) break; strtab = strtab->next; } if( !strtab ) warning( "object '%s' got no symbol string table!!! (skipped)", o->filename ); else { int nsyms = s->header->sh_size / s->header->sh_entsize; while( nsyms-- ) { Elf32_Sym *sym = (Elf32_Sym *)(s->contents + nsyms * s->header->sh_entsize); if( sym->st_shndx == 0 ) continue; // undefined symbol, will resolve later if( sym->st_name == 0 ) continue; // unnamed symbol, can do nothing about it // find symbol name char *name = strtab->contents + sym->st_name; switch( ELF32_ST_BIND(sym->st_info) ) { case STB_LOCAL: o->add_local( name, sym ); break; case STB_GLOBAL: case STB_WEAK: add_global( name, sym, o ); break; default: warning( "unknown symbol binding %d in object '%s'", ELF32_ST_BIND(sym->st_info), o->filename ); } } } } o = o->next; } DEBUG(( stderr, "register_symbols finished\n" )); return errors; }
int arrange_sections() { object *p; section *s, *last; DEBUG(( stderr, "arrange_sections: arranging text sections\n" )); comp.text.start = text_offset = 0; // arrange text sections for( unsigned int i = 0; i < countof(text_sections_names); i++ ) { if( strcmp( text_sections_names[i], "..text.end" ) == 0 ) { text_offset = text_end_sym.st_value = (text_offset + text_alignment - 1) & -text_alignment; add_global( "text_end", &text_end_sym, NULL ); DEBUG(( stderr, "text ends at %d\n", text_offset )); continue; } // traverse all sections in all objects p = root_obj; while( p ) { s = p->sections; while( s ) { if( strcmp( s->name, text_sections_names[i] ) == 0 ) { // append section to text_sections list DEBUG(( stderr, "adding text_section %s at section offset %d, size %d\n", s->name, text_offset, s->header->sh_size )); s->ord_next = NULL; s->offset = text_offset; text_offset += s->header->sh_size; text_offset = (text_offset + text_alignment - 1) & -text_alignment; if( !text_sections ) { text_sections = s; } else { last = text_sections; while(last->ord_next) last = last->ord_next; last->ord_next = s; } break; } s = s->next; } p = p->next; } } DEBUG(( stderr, "arrange_sections: arranging data sections\n" )); comp.text.size = comp.data.start = data_file_offset = text_offset; // arrange data sections for( unsigned int i = 0; i < countof(data_sections_names); i++ ) { if( strcmp( data_sections_names[i], "..data.end" ) == 0 ) { data_offset = data_end_sym.st_value = (data_offset + data_alignment - 1) & -data_alignment; add_global( "data_end", &data_end_sym, NULL ); comp.data.size = data_offset; comp.bss.start = comp.mt.start = comp.data.start + comp.data.size; DEBUG(( stderr, "data ends at %d\n", data_offset )); continue; } if( strcmp( data_sections_names[i], "..bss.end" ) == 0 ) { data_offset = bss_end_sym.st_value = (data_offset + data_alignment - 1) & -data_alignment; add_global( "bss_end", &bss_end_sym, NULL ); comp.bss.size = data_offset - comp.data.size; comp.mt.size = 0; DEBUG(( stderr, "bss ends at %d\n", data_offset )); continue; } // traverse all sections in all objects p = root_obj; while( p ) { s = p->sections; while( s ) { if( strcmp( s->name, data_sections_names[i] ) == 0 ) { // append section to data_sections list DEBUG(( stderr, "adding data_section %s at section offset %d, size %d\n", s->name, data_offset, s->header->sh_size )); s->ord_next = NULL; s->offset = data_offset; data_offset += s->header->sh_size; data_offset = (data_offset + data_alignment - 1) & -data_alignment; if( !data_sections ) { data_sections = s; } else { last = data_sections; while(last->ord_next)last = last->ord_next; last->ord_next = s; } break; } s = s->next; } p = p->next; } } img_end_sym.st_value = text_offset + data_offset; add_global( "img_end", &img_end_sym, NULL ); DEBUG(( stderr, "the whole image ends at %d\n", img_end_sym.st_value )); DEBUG(( stderr, "arrange_sections: finished\n" )); return 0; }
/** * begin a function * called from "parse", this routine tries to make a function out * of what follows * modified version. p.l. woods */ newfunc() { char n[NAMESIZE]; int idx, type; fexitlab = getlabel(); if (!symname(n)) { error("illegal function or declaration"); kill(); return; } if (idx = findglb(n)) { if (symbol_table[idx].identity != FUNCTION) multidef(n); else if (symbol_table[idx].offset == FUNCTION) multidef(n); else symbol_table[idx].offset = FUNCTION; } else add_global(n, FUNCTION, CINT, FUNCTION, PUBLIC); if (!match("(")) error("missing open paren"); output_string(n); output_label_terminator(); newline(); local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC; argstk = 0; // ANSI style argument declaration if (doAnsiArguments() == 0) { // K&R style argument declaration while (!match(")")) { if (symname(n)) { if (findloc(n)) multidef(n); else { add_local(n, 0, 0, argstk, AUTO); argstk = argstk + INTSIZE; } } else { error("illegal argument name"); junk(); } blanks(); if (!streq(line + lptr, ")")) { if (!match(",")) error("expected comma"); } if (endst()) break; } stkp = 0; argtop = argstk; while (argstk) { if (type = get_type()) { getarg(type); need_semicolon(); } else { error("wrong number args"); break; } } } statement(YES); print_label(fexitlab); output_label_terminator(); newline(); gen_modify_stack(0); gen_ret(); stkp = 0; local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC; }