static void _define_builtin_function(Scope *builtin_scope, Type rtype, char *name, builtin_function fn, int nparams, ...) { Symbol *fn_symbol = symbol_new(S_BUILTIN, name); fn_symbol->eval_type = rtype; fn_symbol->fn = fn; scope_define(builtin_scope, fn_symbol); fn_symbol->args = scope_new(NULL); va_list params; va_start(params, nparams); for(int i = 0; i < nparams; i++) { Type t = va_arg(params, Type); /* the n-th parameter is called "n" */ char buf[32]; snprintf(buf, 32, "%d", i); Symbol *sy = symbol_new(S_VARIABLE, buf); sy->eval_type = t; scope_define(fn_symbol->args, sy); } va_end(params); }
struct ast_node* token_id(char *name) { struct ast_node *node; struct symbol *sym; switch (current_token) { case TOKEN_LPARENTH : node = function_call(name); break; case TOKEN_LBRACKET: node = access_node(name); break; default: sym = symbol_table_lookup_all(name); if (sym == NULL) { sym = symbol_new(name, VALUE_TYPE_UNKNOWN); symbol_table_global_put_symbol(sym); } node = (struct ast_node *)ast_node_id(name); break; } return AST_NODE(node); }
/* * make_stab_for_symbol() is called when -g is present for a label that is * being defined. If the label is a text label and in the (__TEXT,__text) * section and not a local label create a stab for it. * * See the detailed comments about stabs in read_a_source_file() for a * description of what is going on here. */ static void make_stab_for_symbol( symbolS *symbolP) { int stabnamelen; char *stabname; if(symbolP->sy_name[0] == 'L') return; if((symbolP->sy_type & N_TYPE) != N_SECT) return; if(symbolP->sy_other != text_nsect) return; stabnamelen = strlen(symbolP->sy_name) + sizeof(":f3"); stabname = xmalloc(stabnamelen); strcpy(stabname, symbolP->sy_name); if(symbolP->sy_type & N_EXT) strcat(stabname, ":F3"); else strcat(stabname, ":f3"); symbol_new( stabname, 36, /* N_FUN */ text_nsect, /* n_sect */ logical_input_line, /* n_desc, line number */ symbolP->sy_value, symbolP->sy_frag); free(stabname); }
void c_dot_file_symbol (const char *filename, int appfile ATTRIBUTE_UNUSED) { symbolS *symbolP; /* BFD converts filename to a .file symbol with an aux entry. It also handles chaining. */ symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag); S_SET_STORAGE_CLASS (symbolP, C_FILE); S_SET_NUMBER_AUXILIARY (symbolP, 1); symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING; #ifndef NO_LISTING { extern int listing; if (listing) listing_source_file (filename); } #endif /* Make sure that the symbol is first on the symbol chain. */ if (symbol_rootP != symbolP) { symbol_remove (symbolP, &symbol_rootP, &symbol_lastP); symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP); } }
void typecheck_visit_program(struct _Visitor *visitor, struct AstNode *node) { node->symbol = symbol_new(NULL); global_symtab = node->symbol; symtab = global_symtab; _inside_procfunc = NULL; ast_node_accept_children(node->children, visitor); }
/* FROM line 136 */ symbolS * symbol_create (const char *name, /* It is copied, the caller can destroy/modify. */ segT segment, /* Segment identifier (SEG_<something>). */ valueT valu, /* Symbol value. */ fragS *frag /* Associated fragment. */) { /* FIXME */ return symbol_new ((char *)name, 0, segment, 0, valu, frag); }
/* Make up a new definition. */ Symbol * workspace_add_def( Workspace *ws, const char *str ) { Column *col = workspace_column_pick( ws ); Symbol *sym; char *name; #ifdef DEBUG printf( "workspace_add_def: %s\n", str ); #endif /*DEBUG*/ if( !str || strspn( str, WHITESPACE ) == strlen( str ) ) return( NULL ); /* Try parsing as a "fred = 12" style def. */ attach_input_string( str ); if( (name = parse_test_define()) ) { sym = symbol_new( ws->sym->expr->compile, name ); IM_FREE( name ); attach_input_string( str + IM_CLIP( 0, input_state.charpos - 1, strlen( str ) ) ); } else { /* That didn't work. Make a sym from the col name. */ sym = workspace_add_symbol( ws ); attach_input_string( str ); } if( !symbol_user_init( sym ) || !parse_rhs( sym->expr, PARSE_RHS ) ) { /* Another parse error. */ expr_error_get( sym->expr ); /* Block changes to error_string ... symbol_destroy() * can set this for compound objects. */ error_block(); IDESTROY( sym ); error_unblock(); return( NULL ); } /* If we're redefining a sym, it might have a row already. */ if( !sym->expr->row ) (void) row_new( col->scol, sym, &sym->expr->root ); symbol_made( sym ); workspace_set_modified( ws, TRUE ); return( sym ); }
static VALUE library_dlsym(VALUE self, VALUE name) { Library* library; void* address = NULL; Check_Type(name, T_STRING); Data_Get_Struct(self, Library, library); address = dl_sym(library->handle, StringValueCStr(name)); return address != NULL ? symbol_new(self, address, name) : Qnil; }
static gboolean row_load( Model *model, ModelLoadState *state, Model *parent, xmlNode *xnode ) { Row *row = ROW( model ); Subcolumn *scol = SUBCOLUMN( parent ); char name[256]; g_assert( IS_SUBCOLUMN( parent ) ); if( !get_sprop( xnode, "name", name, 256 ) ) return( FALSE ); IM_SETSTR( IOBJECT( row )->name, name ); #ifdef DEBUG printf( "row_load: loading row %s (xmlNode %p)\n", name, xnode ); #endif /*DEBUG*/ /* Popup is optional (top level only) */ (void) get_bprop( xnode, "popup", &row->popup ); if( scol->is_top ) { Column *col = scol->top_col; Workspace *ws = col->ws; Symbol *sym; sym = symbol_new( ws->sym->expr->compile, name ); symbol_user_init( sym ); (void) compile_new_local( sym->expr ); row_link_symbol( row, sym, NULL ); /* We can't symbol_made() here, we've not parsed our value * yet. See below ... we just make sure we're on the recomp * lists. */ } if( !MODEL_CLASS( parent_class )->load( model, state, parent, xnode ) ) return( FALSE ); /* If we've loaded a complete row system, mark this row plus any * edited subrows dirty, and make sure this sym is dirty too. */ if( scol->is_top ) { row_dirty_set( row, TRUE ); expr_dirty( row->sym->expr, link_serial_new() ); } return( TRUE ); }
static void add_symbol_to_hash( bfd * abfd, asymbol * s, PTR data, char is_dynamic ) { VALUE sym; VALUE * hash = (VALUE *) data; if (! abfd || ! s ) { return; } sym = symbol_new(abfd, s, is_dynamic); rb_hash_aset( *hash, rb_iv_get(sym, IVAR(SYM_ATTR_NAME)), sym); }
static void process_args(char *name) { struct function *func; struct symbol *arg; /*(*/ consume_token(); func = function_table_lookup(name); /* Delete an old function and make a new one */ if (func != NULL) function_table_delete_function(name); func = function_new(name); while (!match(TOKEN_RPARENTH)) { if (match(TOKEN_EOL)) { error_msg("error: new line in function definition"); return; } if (!match(TOKEN_ID)) { error_msg("error: unexpected symbol in definition"); sync_stream(); ufree(func); return; } arg = symbol_new(lex_prev.id, VALUE_TYPE_UNKNOWN); function_add_arg(func, arg); if (current_token != TOKEN_RPARENTH && !match(TOKEN_COMMA)) { error_msg("error: comma expected"); sync_stream(); return; } } switch(current_token) { case TOKEN_LBRACE: function_table_insert(func); process_function_body(name); break; default: error_msg("error: `{' expected"); sync_stream(); break; } }
/* Make a new symbol, part of the current column. */ static Symbol * workspace_add_symbol( Workspace *ws ) { Column *col = workspace_column_pick( ws ); Symbol *sym; char *name; name = column_name_new( col ); sym = symbol_new( ws->sym->expr->compile, name ); IM_FREE( name ); return( sym ); }
void zpl_add_parameter(const char* def) { const char* warning = "--- Warning 175: Illegal syntax for command line define \"%s\" -- ignored\n"; Set* set; Symbol* sym; Numb* numb; Tuple* tuple; Entry* entry; char* name; char* value; assert(def != NULL); name = strdup(def); value = strchr(name, '='); if (value == NULL) { fprintf(stderr, warning, def); free(name); return; } *value = '\0'; value++; if (strlen(name) == 0 || strlen(value) == 0 || !is_valid_identifier(name)) { if (verbose > VERB_QUIET) fprintf(stderr, warning, def); free(name); return; } set = set_pseudo_new(); sym = symbol_new(str_new(name), SYM_ERR, set, 1, ENTRY_NULL); tuple = tuple_new(0); if (!numb_is_number(value)) entry = entry_new_strg(tuple, str_new(value)); else { numb = numb_new_ascii(value); entry = entry_new_numb(tuple, numb); numb_free(numb); } symbol_add_entry(sym, entry); tuple_free(tuple); set_free(set); free(name); }
/* * symbol_find_or_make() * * If a symbol name does not exist, create it as undefined, and insert * it into the symbol table. Return a pointer to it. */ symbolS * symbol_find_or_make( char *name) { register symbolS * symbolP; symbolP = symbol_table_lookup (name); if (symbolP == NULL) { symbolP = symbol_new (name, N_UNDF, 0, 0, 0, & zero_address_frag); symbol_table_insert (symbolP); } return (symbolP); }
// This is the proper way to create interned symbols // (so that we don't have two symbols that don't eq each other) symbol_t *symbol_intern(vm_t *vm, const char *name, size_t len) { for (symbol_t *s = vm->symbol_table; s != NULL; s = s->next) { if (s->len == len && memcmp(s->name, name, len * sizeof(char)) == 0) { return s; } } symbol_t *sym = symbol_new(vm, name, len); sym->next = vm->symbol_table; vm->symbol_table = sym; return sym; }
int symbol_load_file(char *filename, int level) { FILE *f; char line[MAX_LINE_LEN]; int r,val; int lineno; char *name; if(level==1) { if(includenum>=MAX_INCLUDE_TOP) { msg(0, "Error: Too many include directives\n"); return -1; } include[includenum]=strdup(filename); includenum++; } else if(level>MAX_INCLUDE_LEVEL) { msg(0, "Error: Too many nested include directives\n"); return -1; } f=fopen(filename, "r"); if(f==NULL) { msg(0, "Error: Cannot open '%s': %s\n", filename, strerror(errno)); return -1; } lineno=1; while(fgets(line, MAX_LINE_LEN, f)!=NULL) { r=symbol_load_line(line, &name, &val, level); if(r<0) { msg(0, " at line %d of '%s'\n", lineno, filename); fclose(f); return -1; } if(r==1) { symbol_new(name, val, 50, level!=0); free(name); } lineno++; } fclose(f); return 0; }
symbolS * section_symbol (segT sec) { segment_info_type *seginfo = seg_info (sec); symbolS *s; if (seginfo == 0) abort (); if (seginfo->sym) return seginfo->sym; #ifndef EMIT_SECTION_SYMBOLS #define EMIT_SECTION_SYMBOLS 1 #endif if (! EMIT_SECTION_SYMBOLS || symbol_table_frozen) { /* Here we know it won't be going into the symbol table. */ s = symbol_create (sec->symbol->name, sec, 0, &zero_address_frag); } else { segT seg; s = symbol_find (sec->symbol->name); /* We have to make sure it is the right symbol when we have multiple sections with the same section name. */ if (s == NULL || ((seg = S_GET_SEGMENT (s)) != sec && seg != undefined_section)) s = symbol_new (sec->symbol->name, sec, 0, &zero_address_frag); else if (seg == undefined_section) { S_SET_SEGMENT (s, sec); symbol_set_frag (s, &zero_address_frag); } } S_CLEAR_EXTERNAL (s); /* Use the BFD section symbol, if possible. */ if (obj_sec_sym_ok_for_reloc (sec)) symbol_set_bfdsym (s, sec->symbol); else symbol_get_bfdsym (s)->flags |= BSF_SECTION_SYM; seginfo->sym = s; return s; }
static symbolS * tag_find_or_make (char *name) { symbolS *symbolP; if ((symbolP = tag_find (name)) == NULL) { symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag); tag_insert (S_GET_NAME (symbolP), symbolP); symbol_table_insert (symbolP); } return symbolP; }
struct ast_node* process_local_declaration(void *opaque) { struct scope_ctx helper; struct ast_node_stub *stub_node; struct symbol *var; if (opaque == NULL) { error_msg("error: `local' outside function"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } helper = *(struct scope_ctx *)opaque; if (!helper.is_func) { error_msg("error: `local' outside function"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } while (!match(TOKEN_EOL)) { if (match(TOKEN_ID)) { var = symbol_new(lex_prev.id, VALUE_TYPE_UNKNOWN); symbol_table_put_symbol(var); } if (current_token != TOKEN_EOL && !match(TOKEN_COMMA)) { error_msg("error: `,' expected after variable"); sync_stream(); stub_node = ast_node_stub(); return AST_NODE(stub_node); } } stub_node = ast_node_stub(); return AST_NODE(stub_node); }
void dwarf2_gen_line_info (addressT ofs, struct dwarf2_line_info *loc) { static unsigned int line = -1; static unsigned int filenum = -1; symbolS *sym; /* Early out for as-yet incomplete location information. */ if (loc->filenum == 0 || loc->line == 0) return; /* Don't emit sequences of line symbols for the same line when the symbols apply to assembler code. It is necessary to emit duplicate line symbols when a compiler asks for them, because GDB uses them to determine the end of the prologue. */ if (debug_type == DEBUG_DWARF2 && line == loc->line && filenum == loc->filenum) return; line = loc->line; filenum = loc->filenum; if (linkrelax) { char name[120]; /* Use a non-fake name for the line number location, so that it can be referred to by relocations. */ sprintf (name, ".Loc.%u.%u", line, filenum); sym = symbol_new (name, now_seg, ofs, frag_now); } else sym = symbol_temp_new (now_seg, ofs, frag_now); dwarf2_gen_line_info_1 (sym, loc); }
static int module_add_default_prototype(struct module *m) { struct symbol *param, *fun; param = symbol_new("size", type_long); param->variable.is_parameter = true; fun = function_declare(symbol_new(UUC_WHAT_MALLOC, type_generic), list_new(LI_ELEM, param, NULL), m); module_add_prototype(m, fun); param = symbol_new("map_controller", type_generic); param->variable.is_parameter = true; fun = function_declare(symbol_new("map", type_void), list_new(LI_ELEM, param, NULL), m); // arguments module_add_prototype(m, fun); param = symbol_new("reduce_controller", type_generic); param->variable.is_parameter = true; fun = function_declare(symbol_new("reduce", type_void), list_new(LI_ELEM, param, NULL), m); // arguments module_add_prototype(m, fun); return 0; }
void colon( /* just seen "x:" - rattle symbols & frags */ char *sym_name) /* symbol name, as a cannonical string */ /* We copy this string: OK to alter later. */ { register struct symbol * symbolP; /* symbol we are working with */ if (frchain_now == NULL) { know(flagseen['n']); as_fatal("with -n a section directive must be seen before assembly " "can begin"); } if ((symbolP = symbol_table_lookup( sym_name ))) { /* * Now check for undefined symbols */ if ((symbolP -> sy_type & N_TYPE) == N_UNDF) { temp = symbolP->sy_desc; if( symbolP -> sy_other == 0 /* bug #50416 -O causes this not to work for: && ((symbolP->sy_desc) & (~REFERENCE_TYPE)) == 0 */ && (temp & (~(REFERENCE_TYPE | N_WEAK_REF | N_WEAK_DEF | N_ARM_THUMB_DEF | N_NO_DEAD_STRIP | REFERENCED_DYNAMICALLY))) == 0 && symbolP -> sy_value == 0) { symbolP -> sy_frag = frag_now; symbolP -> sy_value = obstack_next_free(& frags) - frag_now -> fr_literal; know( N_UNDF == 0 ); symbolP -> sy_type |= N_SECT; /* keep N_EXT bit */ symbolP -> sy_other = frchain_now->frch_nsect; symbolP -> sy_desc &= ~REFERENCE_TYPE; symbolP -> sy_desc &= ~N_WEAK_REF; symbol_assign_index(symbolP); if((symbolP->sy_desc & N_WEAK_DEF) == N_WEAK_DEF && (frchain_now->frch_section.flags & S_COALESCED) != S_COALESCED) as_fatal("symbol: %s can't be a weak_definition (currently " "only supported in section of type coalesced)", sym_name); #ifdef NeXT_MOD /* generate stabs for debugging assembly code */ if(flagseen['g']) make_stab_for_symbol(symbolP); #endif } else { as_fatal( "Symbol \"%s\" is already defined as \"%s\"/%d.%d." TA_DFMT ".", sym_name, seg_name [(int) N_TYPE_seg [symbolP -> sy_type & N_TYPE]], symbolP -> sy_other, symbolP -> sy_desc, TA_DFT_CAST(symbolP -> sy_value)); } } else { as_fatal("Symbol %s already defined.",sym_name); } } else { symbolP = symbol_new (sym_name, N_SECT, frchain_now->frch_nsect, 0, (valueT)(obstack_next_free(&frags)-frag_now->fr_literal), frag_now); symbol_table_insert (symbolP); symbol_assign_index (symbolP); #ifdef NeXT_MOD /* generate stabs for debugging assembly code */ if(flagseen['g']) make_stab_for_symbol(symbolP); #endif } #ifdef tc_frob_label tc_frob_label(symbolP); #endif }
Bool zpl_read_with_args(char** argv, int argc, Bool with_management, void* user_data) { const char* options = "D:mP:sv:"; unsigned long seed = 13021967UL; char** param_table; int param_count = 0; int c; int i; Prog* prog = NULL; Set* set; void* lp = NULL; Bool ret = FALSE; char* inppipe = NULL; Bool use_startval = FALSE; stkchk_init(); yydebug = 0; yy_flex_debug = 0; param_table = malloc(sizeof(*param_table)); zpl_print_banner(stdout, FALSE); /* getopt might be called more than once */ optind = 1; while((c = getopt(argc, argv, options)) != -1) { switch(c) { case 'D' : param_table = realloc(param_table, ((unsigned int)param_count + 1) * sizeof(*param_table)); param_table[param_count] = strdup(optarg); if (verbose >= VERB_DEBUG) printf("Parameter %d [%s]\n", param_count, param_table[param_count]); param_count++; break; case 'm' : use_startval = TRUE; break; case 'P' : inppipe = strdup(optarg); break; case 's' : seed = (unsigned long)atol(optarg); break; case 'v' : verbose = atoi(optarg); break; case '?': fprintf(stderr, "Unknown option '%c'\n", c); return FALSE; default : abort(); } } if ((argc - optind) < 1) { fprintf(stderr, "Filename missing\n"); free(param_table); return FALSE; } blk_init(); str_init(); rand_init(seed); numb_init(with_management); elem_init(); set_init(); mio_init(); interns_init(); local_init(); if (0 == setjmp( zpl_read_env)) { is_longjmp_ok = TRUE; /* Make symbol to hold entries of internal variables */ set = set_pseudo_new(); (void)symbol_new(SYMBOL_NAME_INTERNAL, SYM_VAR, set, 100, NULL); set_free(set); /* Now store the param defines */ for(i = 0; i < param_count; i++) zpl_add_parameter(param_table[i]); prog = prog_new(); for(i = optind; i < argc; i++) prog_load(prog, inppipe, argv[i]); if (prog_is_empty(prog)) fprintf(stderr, "*** Error 168: No program statements to execute\n"); else { if (verbose >= VERB_DEBUG) prog_print(stderr, prog); lp = xlp_alloc(argv[optind], use_startval, user_data); prog_execute(prog, lp); ret = TRUE; } } is_longjmp_ok = FALSE; if (lp != NULL) xlp_free(lp); /* Now clean up. */ if (inppipe != NULL) free(inppipe); for(i = 0; i < param_count; i++) free(param_table[i]); free(param_table); if (prog != NULL) prog_free(prog); local_exit(); interns_exit(); mio_exit(); symbol_exit(); define_exit(); set_exit(); elem_exit(); numb_exit(); str_exit(); blk_exit(); return ret; }
Bool zpl_read(const char* filename, Bool with_management, void* user_data) { Prog* prog = NULL; Set* set; void* lp = NULL; Bool ret = FALSE; stkchk_init(); yydebug = 0; yy_flex_debug = 0; zpl_print_banner(stdout, FALSE); blk_init(); str_init(); rand_init(13021967UL); numb_init(with_management); elem_init(); set_init(); mio_init(); interns_init(); local_init(); if (0 == setjmp(zpl_read_env)) { is_longjmp_ok = TRUE; set = set_pseudo_new(); (void)symbol_new(SYMBOL_NAME_INTERNAL, SYM_VAR, set, 100, NULL); set_free(set); prog = prog_new(); prog_load(prog, NULL, filename); if (prog_is_empty(prog)) fprintf(stderr, "*** Error 168: No program statements to execute\n"); else { if (verbose >= VERB_DEBUG) prog_print(stderr, prog); lp = xlp_alloc(filename, FALSE, user_data); prog_execute(prog, lp); ret = TRUE; } } is_longjmp_ok = FALSE; if (lp != NULL) xlp_free(lp); if (prog != NULL) prog_free(prog); local_exit(); interns_exit(); mio_exit(); symbol_exit(); define_exit(); set_exit(); elem_exit(); numb_exit(); str_exit(); blk_exit(); return ret; }
/* * layout_indirect_symbols() setups the indirect symbol tables by looking up or * creating symbol from the indirect symbol names and recording the symbol * pointers. It returns the total count of indirect symbol table entries. */ static uint32_t layout_indirect_symbols(void) { struct frchain *frchainP; uint32_t section_type, total, count, stride; isymbolS *isymbolP; symbolS *symbolP; /* * Mark symbols that only appear in a lazy section with * REFERENCE_FLAG_UNDEFINED_LAZY. To do this we first make sure a * symbol exists for all non-lazy symbols. Then we make a pass looking * up the lazy symbols and if not there we make the symbol and mark it * with REFERENCE_FLAG_UNDEFINED_LAZY. */ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ section_type = frchainP->frch_section.flags & SECTION_TYPE; if(section_type == S_NON_LAZY_SYMBOL_POINTERS){ for(isymbolP = frchainP->frch_isym_root; isymbolP != NULL; isymbolP = isymbolP->isy_next){ /* (void)symbol_find_or_make(isymbolP->isy_name); */ symbolP = symbol_find(isymbolP->isy_name); if(symbolP == NULL){ symbolP = symbol_new(isymbolP->isy_name, N_UNDF, 0, 0, 0, &zero_address_frag); symbol_table_insert(symbolP); } } } } for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ section_type = frchainP->frch_section.flags & SECTION_TYPE; if(section_type == S_LAZY_SYMBOL_POINTERS || section_type == S_SYMBOL_STUBS){ for(isymbolP = frchainP->frch_isym_root; isymbolP != NULL; isymbolP = isymbolP->isy_next){ symbolP = symbol_find(isymbolP->isy_name); if(symbolP == NULL){ symbolP = symbol_find_or_make(isymbolP->isy_name); symbolP->sy_desc |= REFERENCE_FLAG_UNDEFINED_LAZY; } } } } total = 0; for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ section_type = frchainP->frch_section.flags & SECTION_TYPE; if(section_type == S_LAZY_SYMBOL_POINTERS || section_type == S_NON_LAZY_SYMBOL_POINTERS || section_type == S_SYMBOL_STUBS){ count = 0; for(isymbolP = frchainP->frch_isym_root; isymbolP != NULL; isymbolP = isymbolP->isy_next){ /* symbolP = symbol_find_or_make(isymbolP->isy_name); */ symbolP = symbol_find(isymbolP->isy_name); if(symbolP == NULL){ symbolP = symbol_new(isymbolP->isy_name, N_UNDF, 0, 0, 0, &zero_address_frag); symbol_table_insert(symbolP); } isymbolP->isy_symbol = symbolP; count++; } /* * Check for missing indirect symbols. */ if(section_type == S_SYMBOL_STUBS) stride = frchainP->frch_section.reserved2; else stride = sizeof(signed_target_addr_t); if(frchainP->frch_section.size / stride != count) as_bad("missing indirect symbols for section (%s,%s)", frchainP->frch_section.segname, frchainP->frch_section.sectname); /* * Set the index into the indirect symbol table for this * section into the reserved1 field. */ frchainP->frch_section.reserved1 = total; total += count; } } return(total); }
int main(int argc, char* const* argv) { Prog* prog; Set* set; void* lp; const char* extension = ""; char* filter = strdup("%s"); char* outfile; char* tblfile; char* ordfile; char* mstfile; char* basefile = NULL; char* inppipe = NULL; char* outpipe; LpFormat format = LP_FORM_LPF; FILE* fp; Bool write_order = FALSE; Bool write_mst = FALSE; Bool presolve = FALSE; int name_length = 0; char* prog_text; unsigned long seed = 13021967UL; char** param_table; int param_count = 0; int c; int i; FILE* (*openfile)(const char*, const char*) = fopen; int (*closefile)(FILE*) = fclose; stkchk_init(); yydebug = 0; yy_flex_debug = 0; verbose = VERB_NORMAL; param_table = malloc(sizeof(*param_table)); while((c = getopt(argc, argv, options)) != -1) { switch(c) { case 'b' : yydebug = 1; break; case 'D' : param_table = realloc(param_table, ((unsigned int)param_count + 1) * sizeof(*param_table)); param_table[param_count] = strdup(optarg); param_count++; break; case 'h' : zpl_print_banner(stdout, TRUE); printf(usage, argv[0]); puts(help); exit(0); case 'f' : yy_flex_debug = 1; break; case 'F' : free(filter); filter = strdup(optarg); openfile = popen; closefile = pclose; break; case 'l' : name_length = atoi(optarg); break; case 'm' : write_mst = TRUE; break; case 'n' : if (*optarg != 'c') { fprintf(stderr, usage, argv[0]); exit(0); } switch(optarg[1]) { case 'm' : conname_format(CON_FORM_MAKE); break; case 'n' : conname_format(CON_FORM_NAME); break; case 'f' : conname_format(CON_FORM_FULL); break; default : fprintf(stderr, usage, argv[0]); exit(0); } break; case 'o' : basefile = strdup(optarg); break; case 'O' : presolve = TRUE; break; case 'P' : inppipe = strdup(optarg); break; case 's' : seed = (unsigned long)atol(optarg); break; case 'r' : write_order = TRUE; break; case 't' : switch(tolower(*optarg)) { case 'h' : format = LP_FORM_HUM; break; case 'm' : format = LP_FORM_MPS; break; case 'l' : format = LP_FORM_LPF; break; case 'p' : format = LP_FORM_PIP; break; case 'r' : format = LP_FORM_RLP; break; default : if (verbose > VERB_QUIET) fprintf(stderr, "--- Warning 103: Output format \"%s\" not supported, using LP format\n", optarg); format = LP_FORM_LPF; break; } break; case 'v' : verbose = atoi(optarg); break; case 'V' : printf("%s\n", VERSION); exit(0); case '?': fprintf(stderr, usage, argv[0]); exit(0); default : abort(); } } if ((argc - optind) < 1) { fprintf(stderr, usage, argv[0]); exit(0); } zpl_print_banner(stdout, TRUE); if (basefile == NULL) basefile = strip_extension(strdup(strip_path(argv[optind]))); switch(format) { case LP_FORM_LPF : extension = ".lp"; break; case LP_FORM_MPS : extension = ".mps"; break; case LP_FORM_HUM : extension = ".hum"; break; case LP_FORM_RLP : extension = ".rlp"; break; case LP_FORM_PIP : extension = ".pip"; break; default : abort(); } assert(extension != NULL); outfile = add_extention(basefile, extension); tblfile = add_extention(basefile, ".tbl"); ordfile = add_extention(basefile, ".ord"); mstfile = add_extention(basefile, ".mst"); outpipe = malloc(strlen(basefile) + strlen(filter) + 256); assert(outpipe != NULL); blk_init(); str_init(); rand_init(seed); numb_init(TRUE); elem_init(); set_init(); mio_init(); interns_init(); local_init(); /* Make symbol to hold entries of internal variables */ set = set_pseudo_new(); (void)symbol_new(SYMBOL_NAME_INTERNAL, SYM_VAR, set, 100, NULL); set_free(set); /* Now store the param defines */ for(i = 0; i < param_count; i++) zpl_add_parameter(param_table[i]); /* Next we read in the zpl program(s) */ prog = prog_new(); for(i = optind; i < argc; i++) prog_load(prog, inppipe, argv[i]); if (prog_is_empty(prog)) { fprintf(stderr, "*** Error 168: No program statements to execute\n"); exit(EXIT_FAILURE); } if (verbose >= VERB_DEBUG) prog_print(stderr, prog); lp = xlp_alloc(argv[optind], write_mst || write_order, NULL); zlp_setnamelen(lp, name_length); prog_execute(prog, lp); /* Presolve */ if (presolve) fprintf(stderr, "--- Warning: Presolve no longer support. If you need it, send me an email\n"); #if 0 if (!zlp_presolve()) exit(EXIT_SUCCESS); #endif if (verbose >= VERB_NORMAL) zlp_stat(lp); /* Write order file */ if (write_order) { sprintf(outpipe, filter, ordfile, "ord"); if (verbose >= VERB_NORMAL) printf("Writing [%s]\n", outpipe); if (NULL == (fp = (*openfile)(outpipe, "w"))) { fprintf(stderr, "*** Error 104: File open failed "); perror(ordfile); exit(EXIT_FAILURE); } zlp_orderfile(lp, fp, format); check_write_ok(fp, ordfile); (void)(*closefile)(fp); } /* Write MST file */ if (write_mst) { sprintf(outpipe, filter, mstfile, "mst"); if (verbose >= VERB_NORMAL) printf("Writing [%s]\n", outpipe); if (NULL == (fp = (*openfile)(outpipe, "w"))) { fprintf(stderr, "*** Error 104: File open failed "); perror(mstfile); exit(EXIT_FAILURE); } zlp_mstfile(lp, fp, format); check_write_ok(fp, mstfile); (void)(*closefile)(fp); } /* Write Output */ sprintf(outpipe, filter, outfile, "lp"); if (verbose >= VERB_NORMAL) printf("Writing [%s]\n", outpipe); if (NULL == (fp = (*openfile)(outpipe, "w"))) { fprintf(stderr, "*** Error 104: File open failed "); perror(outfile); exit(EXIT_FAILURE); } if (format != LP_FORM_RLP) prog_text = prog_tostr(prog, format == LP_FORM_MPS ? "* " : "\\ ", title, 128); else { prog_text = malloc(strlen(title) + 4); assert(prog_text != NULL); sprintf(prog_text, "\\%s\n", title); } zlp_write(lp, fp, format, prog_text); check_write_ok(fp, outfile); (void)(*closefile)(fp); /* We do not need the translation table for human readable format * Has to be written after the LP file, so the scaling has been done. */ if (format != LP_FORM_HUM) { /* Write translation table */ sprintf(outpipe, filter, tblfile, "tbl"); if (verbose >= VERB_NORMAL) printf("Writing [%s]\n", outpipe); if (NULL == (fp = (*openfile)(outpipe, "w"))) { fprintf(stderr, "*** Error 104: File open failed"); perror(tblfile); exit(EXIT_FAILURE); } zlp_transtable(lp, fp, format); check_write_ok(fp, tblfile); (void)(*closefile)(fp); } free(prog_text); if (verbose >= VERB_DEBUG) symbol_print_all(stderr); #if defined(__INSURE__) || !defined(NDEBUG) || defined(FREEMEM) /* Now clean up. */ if (inppipe != NULL) free(inppipe); for(i = 0; i < param_count; i++) free(param_table[i]); free(param_table); prog_free(prog); local_exit(); interns_exit(); xlp_free(lp); mio_exit(); symbol_exit(); define_exit(); set_exit(); elem_exit(); numb_exit(); str_exit(); blk_exit(); free(mstfile); free(ordfile); free(outfile); free(tblfile); free(basefile); free(filter); free(outpipe); if (verbose >= VERB_NORMAL) { mem_display(stdout); stkchk_maximum(stdout); } #endif /* __INSURE__ || !NDEBUG || FREEMEM */ return 0; }
/* * Summary of operand(). * * in: Input_line_pointer points to 1st char of operand, which may * be a space. * * out: A expressionS. X_seg determines how to understand the rest of the * expressionS. * The operand may have been empty: in this case X_seg == SEG_NONE. * Input_line_pointer -> (next non-blank) char after operand. * */ static segT operand( expressionS *expressionP) { char c, q; char *name; /* points to name of symbol */ struct symbol *symbolP; /* Points to symbol */ SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */ c = *input_line_pointer++;/* Input_line_pointer -> past char in c. */ if(isdigit(c)){ signed_expr_t number; /* offset or (absolute) value */ int digit; /* value of next digit in current radix */ /* invented for humans only, hope */ /* optimising compiler flushes it! */ int radix; /* 8, 10 or 16 */ /* 0 means we saw start of a floating- */ /* point constant. */ int maxdig; /* Highest permitted digit value. */ int too_many_digits;/* If we see >= this number of */ /* digits, assume it is a bignum. */ char *digit_2; /* -> 2nd digit of number. */ int small; /* TRUE if fits in 32 bits. */ int force_bignum; /* TRUE if number is 0xb... */ force_bignum = FALSE; /* * These two initiaizations are to shut up compiler warning as the * may be used with out being set. There used only if radix != 0 * when the number is not a floating-point number. */ maxdig = 0; too_many_digits = 0; if(c == '0'){ /* non-decimal radix */ c = *input_line_pointer++; if(c == 'x' || c=='X'){ c = *input_line_pointer++; /* read past "0x" or "0X" */ maxdig = 16; radix = 16; too_many_digits = 9; } /* * If we have "0b" and some hex digits then treat it as a hex * number and return a bignum. This is for hex immediate * bit-patterns for floating-point immediate constants. */ else if((c == 'b' || c == 'B') && (*input_line_pointer != '\0') && strchr("0123456789abcdefABCDEF", *input_line_pointer) != NULL){ force_bignum = TRUE; c = *input_line_pointer++; /* read past "0b" or "0B" */ maxdig = 16; radix = 16; too_many_digits = 9; } else{ /* * If it says '0f' and the line ends or it DOESN'T look like * a floating point #, its a local label ref. */ if(c == 'f' && (*input_line_pointer == '\0' || (strchr("+-.0123456789", *input_line_pointer) == NULL && strchr(md_EXP_CHARS, *input_line_pointer) == NULL) )){ maxdig = 10; radix = 10; too_many_digits = 11; c = '0'; input_line_pointer -= 2; } else if(c != '\0' && strchr(md_FLT_CHARS, c) != NULL){ radix = 0;/* Start of floating-point constant. */ /* input_line_pointer -> 1st char of number */ expressionP->X_add_number = - (isupper(c) ? tolower(c) : c); } else{ /* By elimination, assume octal radix. */ radix = 8; maxdig = 10; /* Un*x sux. Compatibility. */ too_many_digits = 11; } } /* c == char after "0" or "0x" or "0X" or "0e" etc.*/ } else{ maxdig = 10; radix = 10; too_many_digits = 11; } /* * Expressions are now evaluated as 64-bit values so the number * digits allowed is twice that for 32-bit expressions. */ too_many_digits *= 2; if(radix != 0){ /* Fixed-point integer constant. */ /* May be bignum, or may fit in 32 bits. */ /* * Most numbers fit into 32 bits, and we want this case to be * fast. So we pretend it will fit into 32 bits. If, after * making up a 32 bit number, we realize that we have scanned * more digits than comfortably fit into 32 bits, we re-scan the * digits coding them into a bignum. For decimal and octal * numbers we are conservative: some numbers may be assumed * bignums when in fact they do fit into 32 bits. Numbers of * any radix can have excess leading zeros: we strive to * recognise this and cast them back into 32 bits. We must * check that the bignum really is more than 32 bits, and * change it back to a 32-bit number if it fits. The number we * are looking for is expected to be positive, but if it fits * into 32 bits as an unsigned number, we let it be a 32-bit * number. The cavalier approach is for speed in ordinary cases. */ digit_2 = input_line_pointer; for(number = 0; (digit = hex_value[(int)c]) < maxdig; c = *input_line_pointer++){ number = number * radix + digit; } /* c contains character after number. */ /* Input_line_pointer -> char after c. */ small = input_line_pointer - digit_2 < too_many_digits; if(force_bignum == TRUE) small = FALSE; if(small == FALSE){ /* * Manufacture a bignum. */ /* -> high order littlenum of the bignum. */ LITTLENUM_TYPE *leader; /* -> littlenum we are frobbing now. */ LITTLENUM_TYPE *pointer; long carry; leader = generic_bignum; generic_bignum [0] = 0; /* We could just use digit_2, but lets be mnemonic. */ input_line_pointer = --digit_2; /* -> 1st digit. */ c = *input_line_pointer++; for( ; (carry = hex_value[(int)c]) < maxdig; c = * input_line_pointer++){ for(pointer = generic_bignum; pointer <= leader; pointer++){ long work; work = carry + radix * *pointer; *pointer = work & LITTLENUM_MASK; carry = work >> LITTLENUM_NUMBER_OF_BITS; } if(carry){ if(leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1){ /* Room to grow a longer bignum. */ *++leader = carry; } } } /* Again, C is char after number, */ /* input_line_pointer -> after C. */ /* know(BITS_PER_INT == 32); */ know(LITTLENUM_NUMBER_OF_BITS == 16); /* Hence the constant "2" in the next line. */ if(leader < generic_bignum + 2 && force_bignum == FALSE) { /* Will fit into 32 bits. */ number = ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS) | (generic_bignum[0] & LITTLENUM_MASK); small = TRUE; } else{ /* Number of littlenums in the bignum. */ number = leader - generic_bignum + 1; } } if(small){ /* * Here with number, in correct radix. c is the next char. * Note that unlike Un*x, we allow "011f" "0x9f" to both * mean the same as the (conventional) "9f". This is simply * easier than checking for strict canonical form. */ if(number < 10){ if(c == 'b'){ /* * Backward ref to local label. * Because it is backward, expect it to be DEFINED. */ /* * Construct a local label. */ name = local_label_name((int)number, 0); symbolP = symbol_table_lookup(name); if((symbolP != NULL) && (symbolP->sy_type & N_TYPE) != N_UNDF){ /* Expected path: symbol defined. */ /* Local labels are never absolute. Don't waste time checking absoluteness. */ know((symbolP->sy_type & N_TYPE) == N_SECT); expressionP->X_add_symbol = symbolP; expressionP->X_add_number = 0; expressionP->X_seg = SEG_SECT; } else{ /* Either not seen or not defined. */ as_warn("Backw. ref to unknown label \"%lld\"," "0 assumed.", number); expressionP->X_add_number = 0; expressionP->X_seg = SEG_ABSOLUTE; } } else if(c == 'f'){ /* * Forward reference. Expect symbol to be * undefined or unknown. Undefined: seen it * before. Unknown: never seen it in this pass. * Construct a local label name, then an * undefined symbol. Don't create a XSEG frag * for it: caller may do that. * Just return it as never seen before. */ name = local_label_name((int)number, 1); symbolP = symbol_table_lookup(name); if(symbolP != NULL){ /* We have no need to check symbol properties. */ know((symbolP->sy_type & N_TYPE) == N_UNDF || (symbolP->sy_type & N_TYPE) == N_SECT); } else{ symbolP = symbol_new(name, N_UNDF, 0,0,0, &zero_address_frag); symbol_table_insert(symbolP); } expressionP->X_add_symbol = symbolP; expressionP->X_seg = SEG_UNKNOWN; expressionP->X_subtract_symbol = NULL; expressionP->X_add_number = 0; } else{ /* Really a number, not a local label. */ ignore_c_ll_or_ull(c); expressionP->X_add_number = number; expressionP->X_seg = SEG_ABSOLUTE; input_line_pointer--; /* restore following char */ } } else{ /* a number >= 10 */ ignore_c_ll_or_ull(c); expressionP->X_add_number = number; expressionP->X_seg = SEG_ABSOLUTE; input_line_pointer--; /* restore following char */ } } /* not a small number encode returning a bignum */ else{ ignore_c_ll_or_ull(c); expressionP->X_add_number = number; expressionP->X_seg = SEG_BIG; input_line_pointer--; /* -> char following number. */ } /* if (small) */ } /* (If integer constant) */
/* * fix_new() creates a fixS in obstack 'notes'. */ fixS * fix_new( fragS *frag, /* which frag? */ int where, /* where in that frag? */ int size, /* 1, 2, 4 or 8 bytes */ symbolS *add_symbol, /* X_add_symbol */ symbolS *sub_symbol, /* X_subtract_symbol */ signed_target_addr_t offset, /* X_add_number */ int pcrel, /* TRUE if PC-relative relocation */ int pcrel_reloc, /* TRUE if must have relocation entry */ int r_type) /* relocation type */ { struct fix *fixP; fixP = (struct fix *)obstack_alloc(¬es, sizeof(struct fix)); fixP->fx_frag = frag; fixP->fx_where = where; fixP->fx_size = size; fixP->fx_addsy = add_symbol; fixP->fx_subsy = sub_symbol; fixP->fx_offset = offset; fixP->fx_pcrel = pcrel; fixP->fx_pcrel_reloc = pcrel_reloc; fixP->fx_r_type = r_type; #if defined(I386) && defined(ARCH64) if(fixP->fx_r_type == X86_64_RELOC_SIGNED){ switch(offset){ case -1: fixP->fx_r_type = X86_64_RELOC_SIGNED_1; break; case -2: fixP->fx_r_type = X86_64_RELOC_SIGNED_2; break; case -4: fixP->fx_r_type = X86_64_RELOC_SIGNED_4; break; default: break; } } if(fixP->fx_r_type == X86_64_RELOC_GOT || fixP->fx_r_type == X86_64_RELOC_GOT_LOAD){ /* * GOT and GOT_LOAD relocs are always PC-relative and * should not be converted to non-PC-relative addressing * later. */ fixP->fx_pcrel = TRUE; fixP->fx_pcrel_reloc = TRUE; } /* We don't need this for non-local symbols, but it doesn't hurt. */ fixP->fx_localsy = symbol_new("L0\002", N_SECT, frchain_now->frch_nsect, 0, where, frag); symbol_assign_index(fixP->fx_localsy); #endif as_file_and_line (&fixP->file, &fixP->line); fixP->fx_next = frchain_now->frch_fix_root; frchain_now->frch_fix_root = fixP; return fixP; }