Files
Arquivotheca.SunOS-4.1.4/lang/ld/extra.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

128 lines
3.7 KiB
C

#ident "@(#)extra.c 1.1 94/10/31"
#include <a.out.h>
#include <stdio.h>
/*
* collect_extra_sections is called from load2() when it is
* noticed that there is more stuff after the string table.
* this is assumed to be the extra section stuff, which
* is to be concatenated, each in its respective sections,
* at the end of the output file. Because we don't know
* how long the string table is going to turn out to be,
* we cannot simply copy to the appropriate place in
* that file. Instead, we use temp files, which have
* to be copied at the end. Sad.
*/
#define MAX_EXTRA_SECTIONS 2
FILE * temp_file[MAX_EXTRA_SECTIONS] = { NULL, NULL };
char * temp_file_name[MAX_EXTRA_SECTIONS] = { NULL, NULL };
int n_extra_sections = 0;
int total_size[MAX_EXTRA_SECTIONS];
void
collect_extra_sections( iop, loc, offset, maxoff )
void * iop; /* opaque-to-me pointer to an IO block. */
long loc; /* offset in containing file (for archives) */
int offset; /* where in the input file/element the string table ends */
int maxoff; /* where the input file/element ends */
{
struct extra_sections xtra;
int section_size[ MAX_EXTRA_SECTIONS];
FILE * sect_fd;
int secno, l, seclength;
char buffer[512];
/* establish IO contact with the extra sections */
dseek1( iop, loc+offset, maxoff-offset );
/* read the header */
mget( (char *)&xtra, sizeof(xtra), iop);
if (xtra.extra_magic != EXTRA_MAGIC)
error(1, "bad secondary magic number");
if ( xtra.extra_nsects >= MAX_EXTRA_SECTIONS )
error(1, "too many extra sections");
/* read the section size table */
mget( (char *)section_size, xtra.extra_nsects*sizeof(int), iop );
/* open the temp files, as necessary */
while ( n_extra_sections < xtra.extra_nsects ){
create_section_temp( n_extra_sections++ );
}
/* now shovel the stuff */
for ( secno = 0 ; secno < xtra.extra_nsects ; secno += 1 ){
seclength = 0;
sect_fd = temp_file[secno];
while ( (l = section_size[secno] - seclength) > 0 ){
if ( l > sizeof(buffer) ) l = sizeof(buffer);
mget( buffer, l, iop );
fwrite( buffer, l, 1, sect_fd );
seclength += l;
}
total_size[secno] += seclength;
}
}
void
write_extra_sections( strout )
void * strout; /* opaque-to-me pointer to an IO block. */
{
struct extra_sections xtra;
FILE * sect_fd;
int secno, l, seclength;
char buffer[512];
if ( n_extra_sections == 0 ) return;
/* setup and write the header */
xtra.extra_magic = EXTRA_MAGIC;
xtra.extra_nsects = n_extra_sections;
bwrite( &xtra, sizeof(xtra), strout );
/* write segment size table */
bwrite( &total_size[0], n_extra_sections*sizeof(total_size[0]), strout );
/* now shovel the stuff */
for ( secno = 0 ; secno < xtra.extra_nsects ; secno += 1 ){
seclength = 0;
sect_fd = temp_file[secno];
rewind( sect_fd );
while ( (l = total_size[secno] - seclength) > 0 ){
if ( l > sizeof(buffer) ) l = sizeof(buffer);
if ( fread( buffer, 1, l, sect_fd ) != l )
error(1, "ioerror in write_extra_sections");
bwrite( buffer, l, strout );
seclength += l;
}
}
}
/*
* junk routines for tmp file housekeeping.
*/
create_section_temp( n ) /* called from collect_extra_sections() as needed */
{
char tmpprefix[23] ; /* random number */
sprintf( tmpprefix, "ld.%d.", n );
temp_file_name[n] = tempnam( NULL, tmpprefix );
if ( (temp_file[n] = fopen( temp_file_name[n], "w+")) == NULL){
error(1,"cannot create section temp files");
}
}
void
delete_section_temps() /* called from delexit() */
{
while (n_extra_sections > 0 ){
fclose( temp_file[n_extra_sections-1] );
if ( unlink( temp_file_name[n_extra_sections-1] ) != 0 ){
error(1, "cannot remove section temp files");
}
free( temp_file_name[n_extra_sections-1] );
n_extra_sections -= 1;
}
}