// Resolve references between symbols int resolve_references() { DEBUG(( stderr, "resolve_references():\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 { 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; // defined symbol, no need to resolve if( sym->st_name == 0 ) continue; // unnamed symbol, can do nothing about it char *name = strtab->contents + sym->st_name; DEBUG(( stderr, "undefined symbol '%s', ", name )); if( !get_global_value( name, &sym->st_value ) ) DEBUG(( stderr, "value fixed to %x\n", sym->st_value )); } } } o = o->next; } DEBUG(( stderr, "resolve_references finished\n" )); return errors; }
// recursive helper function to generate method table int fill_methods( char *filename ) { DEBUG(( stderr, "fill_methods(%s):\n", filename )); FILE *fp = fopen( filename, "rb" ); if( !fp ) { error( "couldn't open inf file '%s'", filename ); return 1; } fseek( fp, 0, SEEK_END ); Elf32_Word size = ftell(fp); fseek( fp, 0, SEEK_SET ); char *table = new char [size]; if( fread( table, size, 1, fp ) != 1 ) { error( "couldn't read from inf file '%s'", filename ); return 1; } DEBUG(( stderr, "fill_methods: file size %d (table = %p)\n", size, table )); int check_dirs = nsearch_dirs; if( table[1] != '-' ) // lets look for base files { DEBUG(( stderr, "fill_methods: looking up base file(s)\n" )); char *look_dir; char cwd[1000]; getcwd( cwd, 999 ); strtok( table, "]" ); char fn[ 1000 ]; strcat( strcpy( fn, table + 1 ), ".inf" ); look_dir = "./"; while( access(fn,0) && check_dirs > 0 ) { look_dir = search_dirs[ --check_dirs ]; DEBUG(( stderr, "fill_methods: looking up '%s' in '%s'\n", fn, look_dir )); chdir( look_dir ); } if( access(fn,0) ) { error( "couldn't open base interface file '%s'", fn ); return 1; } chdir( cwd ); char base[1000]; strcat( strcpy( base, look_dir ), fn ); DEBUG(( stderr, "fill_methods: base interface file '%s'\n", base )); fill_methods( base ); } char *c = table; while( *(++c) ) ; *c = ']'; char *mname; char *p = table; if( linker_options & OPT_VERBOSE ) fprintf( stdout, "\n** Name ******************************************** Offs ***** Param **\n" ); while( 1 ) { Elf32_Word offs; unsigned short psize = count( strtok( p, ":" ), ';' ); // WHAT FOR? psize = psize*4; p = 0; // reset p to NULL so that next time strtok above will return next token strtok( 0, " " ); mname = strtok( 0, "\n" ); DEBUG(( stderr, "fill_methods: found %s (table = %p)\n", mname, table )); if( mname == 0 ) break; char namecp[ 100 ]; strcpy( namecp, "method_" ); strncat( namecp, mname, 90 ); if( linker_options & OPT_VERBOSE ) fprintf(stdout, "* %-40s", mname); if( get_global_value(namecp, &offs) ) { error( "cannot find entry for function %s()", mname ); return 1; } if( strcmp( mname, "ctor" ) == 0 ) { if( linker_options & OPT_VERBOSE ) fprintf(stdout, "[ CTOR ]"); mtbl.ctor_entry = (void *)offs; } else if( strcmp( mname, "dtor" ) == 0 ) { if( linker_options & OPT_VERBOSE ) fprintf(stdout, "[ DTOR ]"); mtbl.dtor_entry = (void *)offs; } else { if( linker_options & OPT_VERBOSE ) fprintf(stdout, " "); mtbl[ mtbl.mcount ].start = (void *)offs; mtbl[ mtbl.mcount ].psize = psize; mtbl.mcount++; } if( linker_options & OPT_VERBOSE ) fprintf(stdout, " 0x%08x 0x%08x\n", offs, psize); } delete table; DEBUG(( stderr, "fill_methods: finished\n" )); return 0; }
bool COctaveInterface::run_octave_helper(CSGInterface* from_if) { from_if->SG_DEBUG("Entering Octave\n"); octave_save_signal_mask (); if (octave_set_current_context) { #if defined (USE_EXCEPTIONS_FOR_INTERRUPTS) panic_impossible (); #else unwind_protect::run_all (); raw_mode (0); octave_restore_signal_mask (); #endif } can_interrupt = true; octave_catch_interrupts (); octave_initialized = true; try { int parse_status; char* octave_code=NULL; clear_octave_globals(); for (int i=0; i<from_if->get_nrhs(); i++) { int len=0; char* var_name = from_if->get_string(len); from_if->SG_DEBUG("var_name = '%s'\n", var_name); if (strmatch(var_name, "octavecode")) { len=0; octave_code=from_if->get_string(len); from_if->SG_DEBUG("octave_code = '%s'\n", octave_code); break; } else { octave_value_list args; COctaveInterface* in = new COctaveInterface(args, 1, false); in->create_return_values(1); from_if->translate_arg(from_if, in); #if OCTAVE_APIVERSION >= 37 symbol_table::varref (var_name) = in->get_return_values()(0); #else set_global_value(var_name, in->get_return_values()(0)); #endif delete[] var_name; SG_UNREF(in); } } #if OCTAVE_APIVERSION >= 37 #else symbol_table* old=curr_sym_tab; curr_sym_tab = global_sym_tab; #endif reset_error_handler (); eval_string(octave_code, false, parse_status); delete[] octave_code; int32_t sz=0; octave_value_list results; #if OCTAVE_APIVERSION >= 37 if (symbol_table::is_variable("results")) { results = symbol_table::varval("results"); //results = get_global_value("results", false); sz=results.length(); } #else if (curr_sym_tab->lookup("results")) { results = get_global_value("results", false); sz=results.length(); } #endif if (sz>0) { if (results(0).is_list()) { from_if->SG_DEBUG("Found return list of length %d\n", results(0).length()); results=results(0).list_value(); sz=results.length(); } } if (sz>0 && from_if->create_return_values(sz)) { from_if->SG_DEBUG("Found %d args\n", sz); COctaveInterface* out = new COctaveInterface(results, sz, false); //process d for (int32_t i=0; i<sz; i++) from_if->translate_arg(out, from_if); SG_UNREF(out); } else { if (sz!=from_if->get_nlhs()) { from_if->SG_ERROR("Number of return values (%d) does not match number of expected" " return values (%d).\n", sz, from_if->get_nlhs()); } } #if OCTAVE_APIVERSION >= 37 #else curr_sym_tab=old; #endif } catch (octave_interrupt_exception) { recover_from_exception (); SG_SPRINT("%\n"); } catch (std::bad_alloc) { recover_from_exception (); SG_SPRINT("%\n"); } octave_restore_signal_mask(); octave_initialized = false; from_if->SG_DEBUG("Leaving Octave.\n"); return true; }