|
|
researchv9-SUN3(old)
/* UNIX HEADER */
#include <stdio.h>
/* COMMON SGS HEADERS */
#include "filehdr.h"
#include "scnhdr.h"
#include "reloc.h"
#include "syms.h"
#include "ldfcn.h"
#include "linenum.h"
/* STRIP HEADER */
#include "defs.h"
/* SGS SPECIFIC HEADER */
#include "sgs.h"
#if !UNIX
long rel_skipped;
long reloc_ptrs[MAXSECTIONS];
#endif
#if !AR16WR
static TEMPENT *basep = NULL;
static TEMPENT *oldptr = NULL;
static TEMPENT *entptr = NULL;
#endif
long start_reloc;
int havelnums = 0;
#if FLEXNAMES
long string_size = 0L;
#endif
/* buildfcns.c is a collection of functions that copy parts of an object
* file to strip's temporary file
*
* copyopthdr( )
*
* copies the optional header to the temporary file
*
* calls:
* - docopy((long) HEADER(ldptr).f_opthdr) to do the copying
* after positioning ldptr at the start of the optional header
*
* returns SUCCESS or FAILURE depending on the success of the copying
*/
int
cpyopthdr( )
{
/* OBJECT FILE ACCESS ROUTINE CALLED */
extern int ldohseek( );
/* STRIP FUNCTION CALLED */
extern int docopy( );
/* EXTERNAL VARIABLE USED */
extern LDFILE *ldptr;
if (ldohseek(ldptr) == SUCCESS) {
if (docopy((long) HEADER(ldptr).f_opthdr) == SUCCESS) {
return(SUCCESS);
}
}
return(FAILURE);
}
/* cpyscnhdrs( )
*
* copies each section header to the temporary file
* sets number of line numbers and line number pointer to zero
*
* returns SUCCESS or FAILURE depending on the success of the copy
*/
int
cpyscnhdrs( )
{
/* UNIX FUNCTIONS CALLED */
extern int fwrite( );
/* COMMON ACCESS ROUTINE CALLED */
extern int ldshread( );
/* EXTERNAL VARIABLES USED */
extern LDFILE *ldptr;
extern FILE *strp1;
extern int sflag;
extern int havelnums;
extern long start_reloc;
extern int fflag;
extern int rflag;
extern int lflag;
extern int xflag;
#if !UNIX
extern long rel_skipped;
extern long reloc_ptrs[];
#endif
/* LOCAL VARIABLES */
SCNHDR secthead;
unsigned short section;
#if !UNIX
if (fflag) {
rel_skipped = 0L;
for (section = 1; section <= HEADER(ldptr).f_nscns; ++section) {
if (ldshread( ldptr, section, §head ) != SUCCESS)
return( FAILURE );
if (secthead.s_flags & STYP_COPY)
reloc_ptrs[section - 1] = secthead.s_relptr - rel_skipped;
else {
reloc_ptrs[section - 1] = 0L;
rel_skipped += (long) secthead.s_nreloc * RELSZ;
}
}
}
#endif
if (fflag || sflag || rflag || xflag || lflag)
start_reloc = HEADER(ldptr).f_symptr;
else
start_reloc = 0L;
for (section = 1; section <= HEADER(ldptr).f_nscns; ++section) {
if (ldshread(ldptr, section, §head) != SUCCESS) {
return(FAILURE);
}
/*
* Pick up the earliest section's relocation or line numbers,
* so that a gap between the last section and the next
* information will be handled correctly, since the next strip
* routine will assume a properly seeked pointer to the
* temp file "strp1"
*/
if ((secthead.s_relptr != 0L) && (secthead.s_relptr < start_reloc))
start_reloc = secthead.s_relptr;
if ((secthead.s_lnnoptr != 0L) && (secthead.s_lnnoptr < start_reloc))
start_reloc = secthead.s_lnnoptr;
#if !UNIX
if (fflag) {
secthead.s_relptr = reloc_ptrs[section - 1];
if (secthead.s_relptr == 0L)
secthead.s_nreloc = 0;
}
#endif
if (!sflag) {
secthead.s_lnnoptr = 0L;
secthead.s_nlnno = 0;
} else {
if ( secthead.s_nlnno != 0 ) {
havelnums = 1;
#if !UNIX
if (fflag)
secthead.s_lnnoptr -= rel_skipped;
#endif
}
}
if (fwrite(§head, SCNHSZ, 1, strp1) != 1) {
return(FAILURE);
}
} /* for loop */
return(SUCCESS);
}
/* copyscns( )
*
* copies the section contents to the temporary file
* keeps track of the file address that might be the start of the symbol
* table in a partially stripped file
*
* calls:
* - docopy(secthead.s_size) to do the copying after positioning
* ldptr at the start of a section's contents and after seeking
* to the section content file address in strp1 (to account for
* section content alignment in the object file)
*
* returns the address to be used for the start of the symbol table
* in a partially stripped file -- if everything goes okay
* returns ERROR if anything went wrong
*/
long
copyscns( )
{
/* UNIX FUNCTION CALLED */
extern int fseek( );
extern int fwrite( );
/* OBJECT FILE ACCESS ROUTINES CALLED */
extern int ldshread( ),
ldsseek( );
/* STRIP FUNCTION CALLED */
extern int docopy( );
/* EXTERNAL VARIABLES USED */
extern LDFILE *ldptr;
extern FILE *strp1;
extern int sflag;
extern long start_reloc;
/* LOCAL VARIABLES */
SCNHDR secthead;
unsigned short section;
long fileaddr;
long gap;
char buf[BUFSIZ];
register char *p;
p = buf;
while (p < (buf + BUFSIZ))
*p++ = '\0';
fileaddr = (long) FILHSZ + HEADER(ldptr).f_opthdr +
SCNHSZ * HEADER(ldptr).f_nscns;
for (section = 1; section <= HEADER(ldptr).f_nscns; ++section) {
if (ldshread(ldptr, section, §head) != SUCCESS) {
return(ERROR);
}
if (secthead.s_scnptr != 0L) {
if (ldsseek(ldptr, section) != SUCCESS) {
return(ERROR);
}
/* If loader directive BLOCK is used, have to seek to section
* address in strp1 to ensure that the section contents appear
* in the right place. Note that the fileheader is not written
* to the temporary file so its size must be subtracted from the
* seek address. Under UNIX/RT, zeros must be written in the gap.
*/
#if RT
while (fileaddr < secthead.s_scnptr) {
gap = secthead.s_scnptr - fileaddr;
if (gap > BUFSIZ)
gap = BUFSIZ;
if (fwrite( buf, (int) gap, 1, strp1) != 1)
return( ERROR );
fileaddr += gap;
}
#else
if (fseek(strp1,secthead.s_scnptr - FILHSZ, BEGINNING) !=
OKFSEEK) {
return (ERROR);
}
#endif
if (docopy(secthead.s_size) != SUCCESS) {
return(ERROR);
}
fileaddr = secthead.s_scnptr + secthead.s_size;
}
}
/*
* If there is a hole in the object file between the last byte of
* sections contents and whatever comes next, adjust "fileaddr"
* and the strp1 pointer so that the next strip routine called
* after this one will start at the right place in the
* temporary file
* This is also needed for .m files
*/
if ((start_reloc != 0L) && (fileaddr < start_reloc))
while (fileaddr < start_reloc) {
gap = start_reloc - fileaddr;
if (gap > BUFSIZ)
gap = BUFSIZ;
if (fwrite( buf, (int) gap, 1, strp1 ) != 1)
return( ERROR );
fileaddr += gap;
}
return(fileaddr);
}
/* cpyreloc(fileaddr)
*
* cpyreloc is called only if lflag is ON
* or if the rflag is ON and local symbols have already been stripped
* It copies the relocation information to the temporary file
* and increments fileaddr, the address of the symbol table in a partially
* stripped file.
*
* calls:
* - docopy((long) secthead.s_nreloc * RELSZ) to do the copying
* after ldptr has been positioned at the start of the reloc info
*
* returns the address to be used for the symbol table in a partially
* stripped if copy is successful
* returns ERROR otherwise.
*/
long
cpyreloc(fileaddr)
long fileaddr;
{
/* COMMON OBJECT FILE ACCESS ROUTINES CALLED */
extern int ldshread( ),
ldrseek( );
/* STRIP FUNCTION CALLED */
extern int docopy( );
/* EXTERNAL VARIABLES USED */
extern LDFILE *ldptr;
#if !UNIX
extern int fflag;
#endif
/* LOCAL VARIABLES */
SCNHDR secthead;
unsigned short section;
for (section = 1; section <= HEADER(ldptr).f_nscns; ++section) {
if (ldshread(ldptr, section, §head) != SUCCESS) {
return(ERROR);
}
if (secthead.s_nreloc != 0) {
#if !UNIX
if (fflag && !(secthead.s_flags & STYP_COPY))
continue;
#endif
if (ldrseek(ldptr, section) != SUCCESS) {
return(ERROR);
}
if (docopy((long) secthead.s_nreloc * RELSZ) != SUCCESS) {
return(ERROR);
}
fileaddr += (long) secthead.s_nreloc * RELSZ;
}
}
return(fileaddr);
}
/* cpylnums( )
*
* cpylnums is called only if sflag is ON
* it copies the line number information to the temporary file
* and resets the symbol table index to the correct index of the
* partially stripped symbol table.
*
* fileaddr will be incremented to point to the spot where the
* new symbol table will be. cpylnums returns this value or ERROR
*/
long
cpylnums(fileaddr)
long fileaddr;
{
/* UNIX FUNCTIONS CALLED */
extern int fread( );
extern int fwrite( );
/* COMMON OBJECT FILE ACCESS ROUTINES CALLED */
extern int ldlseek();
extern int ldshread();
/* EXTERNAL VARIABLES USED */
extern LDFILE *ldptr;
extern FILE *strp1;
/* STRIP FUNCTIONS CALLED */
extern long newndx( );
/* LOCAL VARIABLES */
long lindex;
unsigned short section;
SCNHDR secthead;
LINENO lnum;
long numlnums;
for (section = 1; section <= HEADER(ldptr).f_nscns; ++section) {
if (ldshread( ldptr, section, §head) != SUCCESS) {
fprintf( stderr, "cannot read section header for section %s\n", section );
return(ERROR);
}
if (secthead.s_nlnno != 0) {
if (ldlseek(ldptr, section) != SUCCESS) {
fprintf( stderr, "could not seek to line numbers\n" );
return(ERROR);
}
for (numlnums = 0L; numlnums < secthead.s_nlnno; ++numlnums) {
if (FREAD( &lnum, LINESZ, 1, ldptr ) != 1) {
fprintf( stderr, "could not read line numbers\n" );
return( ERROR );
}
if (lnum.l_lnno == 0) {
lindex = lnum.l_addr.l_symndx;
if ((lindex = newndx(lindex)) == ERROR){
fprintf( stderr, "could not locate new symbol table index\n" );
return( ERROR );
}
lnum.l_addr.l_symndx = lindex;
}
if (fwrite( &lnum, LINESZ, 1, strp1) != 1) {
fprintf( stderr, "could not write line numbers\n" );
return( ERROR );
}
}
fileaddr += (long) secthead.s_nlnno * LINESZ;
}
}
return(fileaddr);
}
/* copysyms( )
*
* copies the entire symbol table to the temporary file (if lflag is ON
* or if the rflag is on and local symbols have already been stripped)
* sets the line number pointer in function auxiliary entries to zero
*
* returns SUCCESS or FAILURE
*/
int
copysyms( )
{
/* UNIX FUNCTIONS CALLED */
extern int fread( ),
fwrite( );
/* COMMON OBJECT FILE ACCESS ROUTINES CALLED */
extern int ldtbseek( );
#if FLEXNAMES
extern int ldahread( );
#endif
/* EXTERNAL VARIABLES USED */
extern LDFILE *ldptr;
extern FILE *strp1;
#if !UNIX
extern int fflag;
extern long reloc_ptrs[];
#endif
/* LOCAL VARIABLES */
SYMENT symbol;
long symindx;
AUXENT aux;
#if FLEXNAMES
ARCHDR arhead;
long str_size;
long size;
long str_table;
#endif
if (ldtbseek(ldptr) != SUCCESS)
return(FAILURE);
for (symindx = 0L; symindx < HEADER(ldptr).f_nsyms; ++symindx)
{
if (FREAD(&symbol, SYMESZ, 1, ldptr) != 1)
return(FAILURE);
if (fwrite(&symbol, SYMESZ, 1, strp1) != 1)
return(FAILURE);
if (symbol.n_numaux == 1)
{
if (FREAD(&aux, AUXESZ, 1, ldptr) != 1)
return(FAILURE);
++symindx;
if (ISFCN(symbol.n_type))
{
aux.x_sym.x_fcnary.x_fcn.x_lnnoptr = 0L;
}
if ((symbol.n_sclass == C_STAT)
&& (symbol.n_zeroes != 0L)
&& (strncmp( _TEXT, symbol.n_name, 8 ) == 0))
{
aux.x_scn.x_nlinno = 0;
#if !UNIX
if (fflag && (reloc_ptrs[symbol.n_scnum - 1] == 0L))
aux.x_scn.x_nreloc = 0L;
#endif
}
if ((symbol.n_sclass == C_FCN) ||
(symbol.n_sclass == C_BLOCK) ||
(ISARY(symbol.n_type)))
aux.x_sym.x_misc.x_lnsz.x_lnno = 0;
if (fwrite(&aux, AUXESZ, 1, strp1) != 1)
{
return(FAILURE);
}
}
}
#if FLEXNAMES
/* copy the string table, if there is one */
str_table = STROFFSET(ldptr);
if (TYPE(ldptr) == USH_ARTYPE)
{
if (ldahread( ldptr, &arhead ) != SUCCESS)
{
fprintf( stderr, "could not read archive header" );
return( FAILURE );
}
if (arhead.ar_size <= (str_table + 1))
return( SUCCESS );
if ((FSEEK( ldptr, str_table, BEGINNING ) != OKFSEEK)
|| (FREAD( &str_size, sizeof( long ), 1, ldptr ) != 1 ))
{
fprintf( stderr, "could not read string table\n" );
return( FAILURE );
}
}
else if ((FSEEK( ldptr, str_table, BEGINNING ) != OKFSEEK)
|| (FREAD( &str_size, sizeof( long ), 1, ldptr ) != 1 ))
return( SUCCESS );
/* make it even so the archive won't get screwed up */
size = str_size + (str_size & 01);
if ((fwrite( &size, sizeof( long ), 1, strp1 ) != 1)
|| (docopy( str_size - 4 ) != SUCCESS ))
return( FAILURE );
if (size != str_size)
putc( '\0', strp1 );
#endif
return(SUCCESS);
}
/* EXTERNAL VARIABLE DEFINED */
LDFILE *fwdptr;
/* copyexts(filename)
*
* copies external, static and extdef symbols to the temporary file (xflag)
* sets the line number pointer in function aux entries to zero
* sets the forward file index in function aux entries appropriatly for
* the stripped symbol table
* sets the index of a structure, union or enumeration tag entry to zero
* for any structure, union or enumeration types left in the table
*
* defines:
* - fwdptr = ldaopen(filename, ldptr) to read entries between a
* function and a .ef entry to determine the value of the
* forward file index in the function aux entry
*
* calls:
* - findndx(aux.x_sym.x_fcnary.x_fcn.x_endndx, oldndx, count) to determine the
* new value of aux.x_sym.x_fcnary.x_fcn.x_endndx
*
* returns the number of symbols left in the symbol table after partial
* stripping if successful
* returns ERROR otherwise
*
* Note that TUS people would like strip to keep .bf and .ef entries around
* when locals are stripped from the symbol table but this is not
* currently done.
*/
long
copyexts(filename)
char *filename;
{
/* UNIX FUNCTIONS CALLED */
extern int fread( ),
fwrite( );
/* COMMON OBJECT FILE ACCESS ROUTINES CALLED */
extern LDFILE *ldaopen( );
extern int ldaclose( ),
ldtbseek( );
#if FLEXNAMES
extern char *ldgetname( );
#endif
/* STRIP FUNCTION CALLED */
extern long findndx( );
#if !AR16WR
extern TEMPENT *getempent( );
#endif
/* EXTERNAL VARIABLES USED */
extern LDFILE *ldptr,
*fwdptr;
extern FILE *strp2;
#if AR16WR
extern FILE *readtmp,
*tempfil;
#else
extern TEMPENT *basep;
#endif
extern int rflag,
havelnums,
bflag,
sflag;
#if !UNIX
extern int fflag;
extern long rel_skipped;
extern long reloc_ptrs[];
#endif
#if FLEXNAMES
extern long string_file;
extern char tmpnam5[];
#endif
/* LOCAL VARIABLES */
SYMENT symbol;
#if AR16WR
TEMPENT temp;
#else
TEMPENT *temp;
TEMPENT *tail;
#endif
long oldndx;
long count;
AUXENT aux;
#if FLEXNAMES
FILE *string_file;
char *sym_name;
int name_length;
#endif
if ((fwdptr = ldaopen(filename, ldptr)) == NULL) {
return(ERROR);
}
if (ldtbseek(ldptr) != SUCCESS) {
return(ERROR);
}
#if FLEXNAMES
string_size = 0L;
if ((string_file = fopen( tmpnam5, "w" )) == NULL )
return( ERROR );
#endif
count = 0L;
#if !AR16WR
tail = NULL;
#endif
for (oldndx = 0L; oldndx < HEADER(ldptr).f_nsyms; ++oldndx)
{
if (FREAD(&symbol, SYMESZ, 1, ldptr) != 1)
{
return(ERROR);
}
if ((symbol.n_sclass == C_EXT) || (symbol.n_sclass == C_STAT) ||
(bflag && ((symbol.n_sclass == C_BLOCK) ||
(symbol.n_sclass == C_FCN))) ||
(symbol.n_sclass == C_HIDDEN) ||
(symbol.n_sclass == C_EXTDEF) ||
(symbol.n_sclass == C_FILE))
{
#if AR16WR
temp.new = count;
temp.old = oldndx;
if (fwrite(&temp, TEMPSZ, 1, tempfil) != 1)
{
fprintf(stderr,"couldn't fwrite to tempfil\n");
return(ERROR);
}
fflush(tempfil);
#else
temp = getempent( );
temp->new = count;
temp->old = oldndx;
temp->link = NULL;
if (tail)
tail->link = temp;
else
basep = temp;
tail = temp;
#endif
++count;
#if FLEXNAMES
if (symbol.n_zeroes == 0L)
{
if ((sym_name = ldgetname( ldptr, &symbol )) == NULL)
return( ERROR );
name_length = strlen( sym_name ) + 1;
if (fwrite( sym_name, name_length, 1, string_file ) != 1)
return( ERROR );
symbol.n_offset = string_size + 4;
string_size += name_length;
}
#endif
if(symbol.n_sclass == C_FILE && symbol.n_value != 0L)
{
if((symbol.n_value = findndx(symbol.n_value, oldndx, count+symbol.n_numaux)) == ERROR)
return(ERROR);
}
if (fwrite(&symbol, SYMESZ, 1, strp2) != 1)
{
return(ERROR);
}
if (symbol.n_numaux == 1)
{
if (FREAD(&aux, AUXESZ, 1, ldptr) != 1)
{
return(ERROR);
}
++oldndx;
++count;
if (ISFCN(symbol.n_type))
{
if ( !sflag)
aux.x_sym.x_fcnary.x_fcn.x_lnnoptr = 0L;
#if !UNIX
else if ((havelnums == 1) && fflag && (aux.x_sym.x_fcnary.x_fcn.x_lnnoptr != 0))
aux.x_sym.x_fcnary.x_fcn.x_lnnoptr -= rel_skipped;
#endif
}
if (ISFCN(symbol.n_type) || (bflag &&
(strncmp(symbol.n_name,".bb",3)==0)))
{
if ((aux.x_sym.x_fcnary.x_fcn.x_endndx =
findndx(aux.x_sym.x_fcnary.x_fcn.x_endndx, oldndx, count)) == ERROR)
return(ERROR);
}
if (!sflag && ISARY(symbol.n_type))
aux.x_sym.x_misc.x_lnsz.x_lnno = 0;
if ((symbol.n_sclass == C_STAT)
&& (symbol.n_zeroes != 0)
&& (strncmp(_TEXT, symbol.n_name, 8 ) == 0))
{
if (!sflag)
aux.x_scn.x_nlinno = 0;
#if !UNIX
if (fflag && (reloc_ptrs[symbol.n_scnum - 1] == 0L))
aux.x_scn.x_nreloc = 0L;
#endif
}
if (((symbol.n_type & N_BTMASK) == T_STRUCT) ||
((symbol.n_type & N_BTMASK) == T_UNION) ||
((symbol.n_type & N_BTMASK) == T_ENUM))
aux.x_sym.x_tagndx = 0L;
if (fwrite(&aux, AUXESZ, 1, strp2) != 1)
return(ERROR);
}
}
else /* NOT EXT, STAT, EXTDEF, OR FILE */
{
if (symbol.n_numaux == 1)
{
if (FREAD(&aux, AUXESZ, 1, ldptr) != 1)
return(ERROR);
++oldndx;
}
}
}
#if AR16WR
fflush( tempfil );
#endif
#if FLEXNAMES
if (string_size > 0L)
{
if (string_size & 01)
{
string_size += 1;
putc( '\0', string_file );
}
string_size += 4;
}
fclose( string_file );
#endif
ldaclose(fwdptr);
fflush(strp2);
return(count);
}
/* findndx(fwdndx, oldndx, count)
*
* determines the new index of the symbol that used to be at fwdndx
* (the entry after a .ef entry)
* simply counts the number of external, static or extdef symbols that
* appear between the current entry and the symbol at fwdndx
*
* returns new index of symbol that used to be at fwdndx if successful
* returns ERROR if the symbol table is messed up
*/
long
findndx(fwdndx, oldndx, count)
register long fwdndx,
oldndx,
count;
{
/* COMMON OBJECT FILE ACCESS ROUTINE CALLED */
extern int ldtbread( );
/* EXTERNAL VARIABLES USED */
extern LDFILE *fwdptr;
extern int bflag;
/* LOCAL VARIABLE */
SYMENT symbol;
/* fwdndx is the old symbol table index of the entry following a .ef entry
* oldndx is the old symbol table index of the last symbol read
* count is the new index of the last symbol read
* the idea is to increment count for each symbol (up to fwdndx) that
* will be written to the stripped symbol table: thus returning the
* new symbol table index of the symbol at old fwdndx
*/
while (++oldndx < fwdndx) {
if (ldtbread(fwdptr, oldndx, &symbol) != SUCCESS) {
return(ERROR);
}
if ((symbol.n_sclass == C_EXT) || (symbol.n_sclass == C_STAT) ||
(symbol.n_sclass == C_HIDDEN) || (symbol.n_sclass == C_EXTDEF) ||
(symbol.n_sclass == C_FILE) ||
(bflag && ((symbol.n_sclass == C_BLOCK) ||
(symbol.n_sclass == C_FCN)))) {
++count;
if (symbol.n_numaux == 1) {
++count;
++oldndx;
}
} else {
if (symbol.n_numaux == 1) {
++oldndx;
}
}
}
return(count);
}
/* docopy(size)
*
* copies size bytes from the original object file (positioned by calling
* routine) to the temporary file (positioned by calling routine or by
* default)
*
* docopy simply reads into and out of buffer until copying is done
*
* returns SUCCESS or FAILURE
*/
int
docopy(size)
long size;
{
/* UNIX FUNCTIONS CALLED */
extern int fread( ),
fwrite( );
/* EXTERNAL VARIABLES USED */
extern LDFILE *ldptr;
extern FILE *strp1;
/* LOCAL VARIABLES */
short buffer[BSIZE];
long index;
short remaindr;
for (index = size/BSIZE; index > 0; --index) {
if (FREAD(buffer, BSIZE, 1, ldptr) != 1) {
return(FAILURE);
}
if (fwrite(buffer, BSIZE, 1, strp1) != 1) {
return(FAILURE);
}
}
if ((remaindr = size % BSIZE) != 0) {
if (FREAD(buffer, remaindr, 1, ldptr) != 1) {
return(FAILURE);
}
if (fwrite(buffer, remaindr, 1, strp1) != 1) {
return(FAILURE);
}
}
fflush(strp1);
return(SUCCESS);
}
/* newreloc(fileaddr)
*
*
* newreloc will copy each relocation entry to the temporary
* file and reset the symbol table index to the correct
* index of the partially stripped symbol table.
* fileaddr will be incremented to point to the spot where the
* new symbol table will be. returns this value.
*
*
*/
long
newreloc(fileaddr)
long fileaddr;
{
/* UNIX FUNCTIONS CALLED */
extern int fread( ),
fwrite( );
/* COMMON OBJECT FILE ACCESS ROUTINES CALLED */
extern int ldshread( ),
ldrseek( );
/* STRIP FUNCTIONS CALLED */
extern long newndx( );
/* EXTERNAL VARIABLES USED */
extern LDFILE *ldptr;
extern FILE *strp1;
#if !UNIX
extern int fflag;
#endif
/* LOCAL VARIABLES */
SCNHDR secthead;
unsigned short sect;
long numreloc;
RELOC rloc;
for (sect = 1; sect <= HEADER(ldptr).f_nscns; ++sect) {
if (ldshread(ldptr, sect, §head) != SUCCESS) {
fprintf(stderr,"Could not read reloc info for sect. %d\n",sect);
return(ERROR);
}
if (secthead.s_nreloc != 0) {
#if !UNIX
if (fflag && !(secthead.s_flags & STYP_COPY))
continue;
#endif
if (ldrseek(ldptr,sect) != SUCCESS) {
fprintf(stderr,"Could not seek to reloc entries in sect: %d\n",sect);
return(ERROR);
}
for(numreloc = 0L; numreloc < secthead.s_nreloc; ++numreloc) {
if(FREAD(&rloc, RELSZ, 1,ldptr) != 1) {
fprintf( stderr, "could not read relocation\n" );
return(ERROR);
}
if((rloc.r_symndx = newndx( rloc.r_symndx )) == ERROR)
return(ERROR);
if (fwrite(&rloc, RELSZ, 1, strp1) != 1) {
fprintf(stderr,"couldn't fwrite\n");
return(ERROR);
}
} /* inner for loop */
fileaddr += (long) secthead.s_nreloc * RELSZ;
}
} /* outer for loop */
fflush(strp1);
return(fileaddr);
}
/* newndx(index)
*
*
* newndx accepts as input, a symbol index, gotten from the old
* symbol table in <fileindex>. This symbol name is then compared
* to the symbol indexs from a partially stripped symbol table.
* When a match is found, the index of the symbol is returned, else
* ERROR
*
*/
long
newndx(rind)
register long rind;
{
/* UNIX FUNCTIONS CALLED */
extern int fseek( );
extern int fread( );
/* EXTERNAL VARIABLES USED */
#if AR16WR
extern FILE *readtmp;
extern FILE *tempfil;
#else
extern TEMPENT *basep;
#endif
extern FILHDR filehead;
/* LOCAL VARIABLES */
#if AR16WR
TEMPENT tmp;
register long count;
#else
register TEMPENT *temp;
#endif
if (rind == -1L)
return(-1L);
#if AR16WR
count = 0L;
if(fseek(readtmp,0L,0) != 0) {
fprintf(stderr,"Could not seek to beginning of file.\n");
return(ERROR);
}
for(count=0; count < filehead.f_nsyms; ++count) {
if(fread(&tmp, TEMPSZ, 1, readtmp) != 1) {
fprintf(stderr,"Could not read index extry. Index: %ld\n",rind);
return(ERROR);
}
if( rind == tmp.old ) {
return((long) tmp.new);
}
}
#else
for ( temp = basep; temp; temp = temp->link ) {
if (temp->old == rind)
return( (long) temp->new );
}
#endif
fprintf(stderr,"No index found for relocation entry: %lo\n",rind);
return(ERROR);
}
#if !AR16WR
/*
* getempent will return an item for a TEMPENT linked list. If necessary,
* malloc() will be called to get space for the item. getempent will
* get space for multiple items whenever it calls malloc();
*/
TEMPENT *
getempent()
{
/* UNIX FUNCTIONS CALLED */
extern char *malloc( );
/* EXTERNAL VARIABLES USED */
extern TEMPENT *entptr;
extern TEMPENT *oldptr;
/* VARIABLES DEFINED */
static int nument;
if ((oldptr == NULL) || (nument >= MAXTEMPENTS)) {
if ((entptr = (TEMPENT *) malloc( sizeof(TEMPENT) * MAXTEMPENTS )) == NULL) {
fprintf( stderr, "malloc failed, can't reset relocation\n");
exit(1);
}
entptr->link = oldptr;
oldptr = entptr;
nument = 1;
entptr++;
}
nument++;
return( entptr++ );
}
/*
* freetempent() will free up the space used by the TEMPENT list
*/
freetempent( )
{
/* EXTERNAL VARIABLES USED */
extern TEMPENT *oldptr;
extern TEMPENT *entptr;
for ( ; oldptr; oldptr = oldptr->link ) {
free( oldptr );
}
oldptr = entptr = NULL;
}
#endif
/*
* @(#)buildfcns.c 1.16 11/15/83;
*/
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.