home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include "lm.h"
-
- extern long in_file, out_file;
- extern char *get_next_file(), *in_file_name;
- extern BOOL same_output_file;
-
- struct symbol *sym_list_head, *sym_ptr;
-
- extern long mod_buf[MBUF_SIZE];
- int eolib, symbol_offset;
-
- unsigned long buf_count, old_buf_count, current_long, temp;
- void *AllocMem();
-
- long Open(), Write();
-
-
- /* --------------------------------------------------------------------------
- STRIP_LIBRARY ROUTINES
- ---------------------------------------------------------------------------*/
-
- strip_library()
- {
- /*
- Read through the library and discard the symbol and debug
- hunks.
- */
- unsigned module_size;
- unsigned long end_o_hunk = HUNK_END;
-
- printf( ">> Stripping: <%s>\n",in_file_name );
-
- while( (module_size = read_lib_module() ) )
- {
- /*
- Strip symbol/debug hunks if there. All we do is write
- back the module up to the symbol/debug hunk and stick
- a HUNK_END on the end.
- */
- if ( symbol_offset )
- {
- Write( out_file, mod_buf, (long) (symbol_offset << 2) );
- Write( out_file, &end_o_hunk, 4L );
- }
-
- else
- {
- Write( out_file, mod_buf, (long) (module_size << 2) );
- }
- }
- }
-
-
-
-
- /* --------------------------------------------------------------------------
- ADD_MODULE ROUTINES
- ---------------------------------------------------------------------------*/
-
- add_modules( file_list )
- char *file_list;
-
- {
- char *p;
- long fp;
- unsigned long longword;
-
- copy_lib( in_file, out_file );
-
- while( (p = get_next_file( file_list ) ) )
- {
-
- if ( !(fp = Open( p, MODE_OLDFILE ) ) )
- {
- printf( "ERROR: Object file: <%s> not found\n", p );
- }
- else
- {
- printf( ">> Adding: <%s>\n", p );
- copy_lib( fp, out_file );
- Close( fp );
- }
- }
- }
-
-
-
-
- add_symbol( sym_name )
- char *sym_name;
- {
- /*
- Add the symbol in sym_name to the list of symbols.
- */
-
- struct symbol *p;
-
- if(!(p=(struct symbol*)AllocMem((long)sizeof(struct symbol), 0L)))
- {
- my_exit( ENOMEM );
- }
-
- p->next = NULL;
- sym_ptr->next = p;
- sym_ptr = p;
-
- strcpy( sym_ptr->name, sym_name );
- }
-
-
-
- get_and_put()
- {
- /*
- Fetch a longword from the input file, stick it in the module
- buffer, and return it. Return NULL if no more to read.
- */
- long longword;
-
- /*
- First, make sure we are not overwriting innocent ram!
- */
- if ( buf_count > MBUF_SIZE )
- {
- my_exit( ENOBUF );
- }
-
-
- if ( eolib ) /* End of library? */
- {
- my_exit( EOLIB );
- }
-
- if ( !GetLongword( in_file, &longword ) )
- {
- eolib = TRUE;
- return( TRUE );
- }
-
- mod_buf[buf_count++] = longword;
- current_long = longword;
- return( TRUE );
- }
-
-
-
-
- read_lib_module()
- {
- /*
- Read in the next module from the library, if one exists, and
- stick all the XDEF symbols in the symbol list. Return either
- the number of longwords in the module or 0 to indicate the
- end of the library.
- */
-
- clear_sym_list(); /* clean out prev sym list */
- sym_ptr = sym_list_head; /* Reset sym ptr */
- symbol_offset = 0; /* Clear offset of symbol hunk ptr */
- buf_count = 0; /* Nothing in the buffer... */
- eolib = 0; /* Not at end-of-library yet */
-
- while( get_and_put() )
- {
- if ( eolib )
- return( 0 );
-
- switch( current_long )
- {
- case HUNK_UNIT :
- case HUNK_NAME : get_named_hunk();
- break;
-
- case HUNK_CODE :
- case HUNK_DATA : get_code_data_debug_hunk();
- break;
-
- case HUNK_DEBUG : if ( !symbol_offset )
- symbol_offset = buf_count-1;
-
- get_code_data_debug_hunk();
- break;
-
- case HUNK_BSS : get_and_put();
- break;
-
- case HUNK_RELOC32:
- case HUNK_RELOC16:
- case HUNK_RELOC8 : get_reloc_hunk();
- break;
-
- case HUNK_SYMBOL : get_symbol_hunk();
- break;
-
- case HUNK_EXT : get_public_symbols();
- break;
-
- case HUNK_END : return( buf_count );
- break;
- }
- }
- }
-
-
-
- get_public_symbols()
- {
- /*
- Stick the XDEF symbols in the HUNK_EXT hunk in the symbol
- list.
- */
-
- unsigned long size, ref_count, name_buf[10], i;
- unsigned char type;
-
- get_and_put(); /* read first symbol data unit */
-
- while ( current_long ) /* repeat til 0 */
- {
- size = current_long & 0xffffff; /* Strip type field */
- type = current_long >> 24;
-
- for ( i = 0; i < size; i++ )
- {
- get_and_put();
- name_buf[i] = current_long;
- }
- name_buf[size] = '\0'; /* null term the string */
-
- switch( type )
- {
-
- case ext_symb :
- case ext_def :
- case ext_abs :
- /* Eat the Offset longword */
- case ext_res : get_and_put();
- add_symbol( name_buf );
- break;
-
- /*
- The rest of this switch statement just eats the infor-
- mation contained in the hunk because we don't need it.
- */
-
- case ext_ref32 : goto skip;
-
- case ext_common : /* The next field is the size field */
- get_and_put();
-
- skip: case ext_ref16 : /* Eat the ref count and the ref
- offset fields */
-
- case ext_ref8 : get_and_put();
- ref_count = current_long;
-
- for ( i = 0; i < ref_count; i++ )
- get_and_put();
- break;
- }
-
- get_and_put();
- }
- }
-
-
-
- get_named_hunk()
-
- {
- /*
- Read in the named hunk (HUNK_NAME/HUNK_UNIT).
- */
- register int i;
-
- get_and_put();
- temp = current_long;
-
- for( i = 0; i < temp; i++ )
- {
- get_and_put();
- }
- }
-
-
- get_code_data_debug_hunk()
- {
- /*
- Read in the CODE, DATA or DEBUG hunk.
- */
- register int i;
-
- get_and_put();
- temp = current_long;
-
- for ( i = 0; i < temp; i++ )
- get_and_put();
- }
-
-
- get_reloc_hunk()
- {
- /*
- Eat the info in the relocxx hunks.
- */
- register int i;
- unsigned long relocs;
-
- get_and_put();
-
- while( current_long )
- {
- relocs = current_long;
-
- get_and_put();
-
- for( i = 0; i < relocs; i++ )
- get_and_put();
-
- get_and_put();
- }
- }
-
-
- get_symbol_hunk()
- {
- /*
- Chew through the symbol hunk.
- */
-
- unsigned long ext_id;
- unsigned int i;
-
- /*
- Mark the place where the symbol hunk begins.
- */
- symbol_offset = buf_count-1;
-
- get_and_put();
-
- while ( current_long )
- {
- ext_id = current_long;
-
- for ( i = 0; i <= ext_id; i++ )
- get_and_put();
-
- get_and_put();
- }
- }
-
-
- clear_sym_list()
- {
- /*
- Destroy the symbol list if one exists, but leave the head node
- intact for future use and abuse.
- */
-
- struct symbol *p, *q = sym_list_head->next;
-
- while ( q )
- {
- p = q->next;
-
- FreeMem( q, (long) sizeof( struct symbol ) );
- q = p;
- }
-
- sym_list_head->next = NULL;
- }
-
-
- copy_lib( in_file, out_file )
- long in_file, out_file;
- {
- char *p;
- long count, Read();
-
- if ( !( p = AllocMem( READBUFSIZE, 0L ) ) )
- {
- my_exit( ENOMEM );
- }
-
-
- while( ( count = Read( in_file, p, READBUFSIZE ) ) )
- {
- Write( out_file, p, count );
- }
-
- FreeMem( p, READBUFSIZE );
- }
-