46 |
#include "ext_sym.h" |
#include "ext_sym.h" |
47 |
struct node * find_sym(); |
struct node * find_sym(); |
48 |
int node_compare(); |
int node_compare(); |
|
#ifndef _WIN32 |
|
|
void *malloc(); |
|
|
void *bsearch(); |
|
|
#endif |
|
49 |
|
|
50 |
struct reloc relocation_info; |
struct reloc relocation_info; |
51 |
/* next 5 static after debug */ |
/* next 5 static after debug */ |
67 |
#endif |
#endif |
68 |
#define PTABLE_EXTRA 20 |
#define PTABLE_EXTRA 20 |
69 |
|
|
70 |
#ifdef COFF |
#define COFF_SECTIONS 10 /* Numbner of section headers in section header buffer */ |
|
# define COFF_SECTIONS 10 /* Numbner of section headers in section header buffer */ |
|
|
#endif |
|
71 |
|
|
72 |
#define INVALID_NSCN 64000 /* A number greater than the number of sections ever likely to be read in. */ |
#define INVALID_NSCN 64000 /* A number greater than the number of sections ever likely to be read in. */ |
73 |
|
|
|
#ifdef _WIN32 |
|
74 |
unsigned int TEXT_NSCN = INVALID_NSCN, DATA_NSCN = INVALID_NSCN, |
unsigned int TEXT_NSCN = INVALID_NSCN, DATA_NSCN = INVALID_NSCN, |
75 |
BSS_NSCN = INVALID_NSCN, STAB_NSCN = INVALID_NSCN, |
BSS_NSCN = INVALID_NSCN, STAB_NSCN = INVALID_NSCN, |
76 |
STABSTR_NSCN = INVALID_NSCN, RDATA_NSCN = INVALID_NSCN, |
STABSTR_NSCN = INVALID_NSCN, RDATA_NSCN = INVALID_NSCN, |
77 |
BIGGEST_NSCN_FOUND = 0; |
BIGGEST_NSCN_FOUND = 0; |
|
#endif |
|
|
|
|
78 |
|
|
79 |
struct sfasl_info { |
struct sfasl_info { |
80 |
struct syment *s_symbol_table; |
struct syment *s_symbol_table; |
175 |
*/ |
*/ |
176 |
static void work_out_section_indices ( struct scnhdr *section ) |
static void work_out_section_indices ( struct scnhdr *section ) |
177 |
{ |
{ |
|
#ifdef _WIN32 |
|
178 |
unsigned int i; |
unsigned int i; |
179 |
|
|
180 |
/* Initialise the global *_NSCN variables to INVALID_NSCN */ |
/* Initialise the global *_NSCN variables to INVALID_NSCN */ |
206 |
if ( i > BIGGEST_NSCN_FOUND ) BIGGEST_NSCN_FOUND = i; |
if ( i > BIGGEST_NSCN_FOUND ) BIGGEST_NSCN_FOUND = i; |
207 |
} |
} |
208 |
} |
} |
|
#endif |
|
209 |
} |
} |
210 |
|
|
211 |
int fasload ( object faslfile ) |
int fasload ( object faslfile ) |
213 |
long fasl_vector_start; |
long fasl_vector_start; |
214 |
struct filehdr fileheader; |
struct filehdr fileheader; |
215 |
struct sfasl_info sfasl_info_buf; |
struct sfasl_info sfasl_info_buf; |
|
#ifdef COFF |
|
216 |
struct scnhdr section[COFF_SECTIONS]; |
struct scnhdr section[COFF_SECTIONS]; |
217 |
struct aouthdr header; |
struct aouthdr header; |
|
#endif |
|
218 |
int textsize = 0, datasize = 0, bsssize = 0, stabsize = 0, |
int textsize = 0, datasize = 0, bsssize = 0, stabsize = 0, |
219 |
stabstrsize = 0, rdatasize = 0, nsyms = 0; |
stabstrsize = 0, rdatasize = 0, nsyms = 0; |
|
#if defined ( READ_IN_STRING_TABLE ) || defined ( HPUX ) |
|
|
int string_size=0; |
|
|
#endif |
|
|
|
|
220 |
object memory, data; |
object memory, data; |
221 |
FILE *fp; |
FILE *fp; |
222 |
char filename[MAXPATHLEN]; |
char filename[MAXPATHLEN]; |
253 |
} |
} |
254 |
nsyms = NSYMS(fileheader); |
nsyms = NSYMS(fileheader); |
255 |
|
|
|
#ifdef COFF |
|
|
# ifdef AIX3 |
|
|
setup_for_aix_load(); |
|
|
# endif |
|
|
|
|
256 |
/* Read the optional object file header */ |
/* Read the optional object file header */ |
257 |
fread ( &header, 1, fileheader.f_opthdr, fp ); |
fread ( &header, 1, fileheader.f_opthdr, fp ); |
258 |
|
|
302 |
rdatasize = section[RDATA_NSCN].s_size; |
rdatasize = section[RDATA_NSCN].s_size; |
303 |
} |
} |
304 |
|
|
|
#endif |
|
|
|
|
|
#ifdef BSD |
|
|
textsize=fileheader.a_text; |
|
|
datasize=fileheader.a_data; |
|
|
bsssize=fileheader.a_bss; |
|
|
#endif |
|
305 |
dprintf ( "fasload: %s, ", filename ); |
dprintf ( "fasload: %s, ", filename ); |
306 |
dprintf ( "number of symbols: %d\n", nsyms ); |
dprintf ( "number of symbols: %d\n", nsyms ); |
307 |
|
|
316 |
/* Read the symbol table */ |
/* Read the symbol table */ |
317 |
for (i = 0; i < nsyms; i++) { |
for (i = 0; i < nsyms; i++) { |
318 |
fread((char *)&symbol_table[i], SYMESZ, 1, fp); |
fread((char *)&symbol_table[i], SYMESZ, 1, fp); |
|
#ifdef HPUX |
|
|
symbol_table[i].n_un.n_strx = string_size; |
|
|
dprintf("string_size %d\n", string_size); |
|
|
string_size += symbol_table[i].n_length + 1; |
|
|
fseek(fp,(int)symbol_table[i].n_length,1); |
|
|
#endif |
|
319 |
} |
} |
320 |
/* |
/* |
321 |
on MP386 |
on MP386 |
324 |
fread((char *)symbol_table, SYMESZ*fileheader.f_nsyms,1,fp); |
fread((char *)symbol_table, SYMESZ*fileheader.f_nsyms,1,fp); |
325 |
*/ |
*/ |
326 |
|
|
|
#ifdef READ_IN_STRING_TABLE |
|
|
my_string_table=READ_IN_STRING_TABLE(fp,string_size); |
|
|
#else |
|
|
# ifdef MUST_SEEK_TO_STROFF |
|
|
fseek(fp,N_STROFF(fileheader),0); |
|
|
# endif |
|
327 |
{ |
{ |
328 |
int ii=0; |
int ii=0; |
329 |
if ( !fread ( (char *) &ii, sizeof(int), 1, fp ) ) { |
if ( !fread ( (char *) &ii, sizeof(int), 1, fp ) ) { |
338 |
if ( ii != fread ( my_string_table, 1, ii, fp ) ) { |
if ( ii != fread ( my_string_table, 1, ii, fp ) ) { |
339 |
FEerror ( "Could not read whole string table", 0 ); |
FEerror ( "Could not read whole string table", 0 ); |
340 |
} |
} |
|
#endif |
|
|
|
|
341 |
#ifdef SEEK_TO_END_OFILE |
#ifdef SEEK_TO_END_OFILE |
342 |
SEEK_TO_END_OFILE(fp); |
SEEK_TO_END_OFILE(fp); |
343 |
#else |
#else |
432 |
that c.table */ |
that c.table */ |
433 |
relocate_symbols(NSYMS(fileheader)); |
relocate_symbols(NSYMS(fileheader)); |
434 |
|
|
|
#ifdef COFF |
|
435 |
{ |
{ |
436 |
int j = 0; |
int j = 0; |
437 |
|
|
463 |
} |
} |
464 |
} |
} |
465 |
} |
} |
|
#endif |
|
|
|
|
|
#ifdef BSD |
|
|
fseek(fp,N_RELOFF(fileheader),0); |
|
|
{ |
|
|
int nrel = fileheader.a_trsize/sizeof(struct reloc); |
|
|
for ( i=0; i < nrel; i++ ) { |
|
|
fread ( (char *)&relocation_info, sizeof(struct reloc), |
|
|
1, fp); |
|
|
dprintf("relocating %d\n",i); |
|
|
relocate(); |
|
|
} |
|
|
} |
|
|
# ifdef N_DRELOFF |
|
|
fseek (fp, N_DRELOFF(fileheader), 0); |
|
|
# endif |
|
|
{ |
|
|
int nrel = fileheader.a_drsize/sizeof(struct reloc); |
|
|
the_start += fileheader.a_text; |
|
|
for (i=0; i < nrel; i++) { |
|
|
fread ( (char *) &relocation_info, sizeof(struct reloc), |
|
|
1, fp); |
|
|
dprintf("relocating %d\n",i); |
|
|
relocate(); |
|
|
} |
|
|
} |
|
|
#endif |
|
466 |
|
|
467 |
/* end of relocation */ |
/* end of relocation */ |
468 |
dprintf(" END OF RELOCATION \n",0); |
dprintf(" END OF RELOCATION \n",0); |
500 |
} else { |
} else { |
501 |
data = read_fasl_vector(faslfile); |
data = read_fasl_vector(faslfile); |
502 |
vs_push(data); |
vs_push(data); |
|
#ifdef COFF |
|
503 |
dprintf(" read fasl now symbols %d \n", fileheader.f_nsyms); |
dprintf(" read fasl now symbols %d \n", fileheader.f_nsyms); |
|
#endif |
|
504 |
} |
} |
505 |
close_stream(faslfile); |
close_stream(faslfile); |
506 |
|
|
507 |
#ifndef STAND |
#ifndef STAND |
508 |
ALLOCA_FREE(my_string_table); |
ALLOCA_FREE(my_string_table); |
509 |
ALLOCA_FREE(symbol_table); |
ALLOCA_FREE(symbol_table); |
|
# ifdef CLEAR_CACHE |
|
|
CLEAR_CACHE; |
|
|
# endif |
|
510 |
dprintf ( "About to call_init %x \n", init_address ); |
dprintf ( "About to call_init %x \n", init_address ); |
511 |
call_init ( init_address, memory, data, 0); |
call_init ( init_address, memory, data, 0); |
512 |
dprintf ( "Finished call_init %x \n", memory ); |
dprintf ( "Finished call_init %x \n", memory ); |
520 |
} |
} |
521 |
return ( memory->cfd.cfd_size ); |
return ( memory->cfd.cfd_size ); |
522 |
#endif |
#endif |
|
#if 0 |
|
|
{ |
|
|
FILE *out; |
|
|
out=fopen("/tmp/sfasltest","w"); |
|
|
fwrite((char *)&fileheader, sizeof(struct filehdr), 1, out); |
|
|
fwrite(start_address,sizeof(char),datasize+textsize+stabsize+stabstrsize+rdatasize,out); |
|
|
fclose(out); |
|
|
} |
|
|
#endif |
|
523 |
printf("\n(start %x)\n",start_address); |
printf("\n(start %x)\n",start_address); |
524 |
} |
} |
525 |
} |
} |
530 |
int *ptr; /* store init address offset here */ |
int *ptr; /* store init address offset here */ |
531 |
{ |
{ |
532 |
int result = start; |
int result = start; |
|
|
|
|
#ifdef AIX3 |
|
|
int next_bss = start - bsssize; |
|
|
#endif |
|
|
|
|
533 |
struct syment *end,*sym; |
struct syment *end,*sym; |
534 |
|
|
|
#ifdef BSD |
|
|
char tem[SYMNMLEN +1]; |
|
|
#endif |
|
|
|
|
535 |
end =sym_table + length; |
end =sym_table + length; |
536 |
|
|
537 |
for(sym=sym_table; sym < end; sym++) |
for(sym=sym_table; sym < end; sym++) |
538 |
{ |
{ |
539 |
|
|
540 |
#ifdef FIND_INIT |
#ifdef FIND_INIT |
541 |
FIND_INIT |
FIND_INIT |
542 |
#endif |
#endif |
|
|
|
|
#ifdef AIX3 |
|
|
/* we later go through the relocation entries making this 1 |
|
|
for symbols used */ |
|
|
#ifdef SYM_USED |
|
|
if(TC_SYMBOL_P(sym)) |
|
|
{SYM_USED(sym) = 0;} |
|
|
#endif |
|
543 |
|
|
|
/* fix up the external refer to _ptrgl to be local ref */ |
|
|
if (sym->n_scnum == 0 && |
|
|
strcmp(sym->n_name,"_ptrgl")==0) |
|
|
{struct syment* s = |
|
|
get_symbol("._ptrgl",TEXT_NSCN,sym_table,length); |
|
|
if (s ==0) FEerror("bad glue",0); |
|
|
sym->n_value = next_bss ; |
|
|
ptrgl_offset = next_bss; |
|
|
ptrgl_text = s->n_value; |
|
|
next_bss += 0xc; |
|
|
sym->n_scnum = DATA_NSCN; |
|
|
((union auxent *)(sym+1))->x_csect.x_scnlen = 0xc; |
|
|
|
|
|
} |
|
|
|
|
|
if(sym->n_scnum != BSS_NSCN) goto NEXT; |
|
|
if(SYM_EXTERNAL_P(sym)) |
|
|
{int val=sym->n_value; |
|
|
struct node joe; |
|
|
if (val && c_table.ptable) |
|
|
{struct node *answ; |
|
|
answ= find_sym(sym,0); |
|
|
if(answ) |
|
|
{sym->n_value = answ->address ; |
|
|
sym->n_scnum = N_UNDEF; |
|
|
val= ((union auxent *)(sym+1))->x_csect.x_scnlen; |
|
|
result -= val; |
|
|
goto NEXT; |
|
|
}} |
|
|
} |
|
|
/* reallocate the bss space */ |
|
|
if (sym->n_value == 0) |
|
|
{result += ((union auxent *)(sym+1))->x_csect.x_scnlen;} |
|
|
sym->n_value = next_bss; |
|
|
next_bss += ((union auxent *)(sym+1))->x_csect.x_scnlen; |
|
|
NEXT: |
|
|
; |
|
|
/* end aix3 */ |
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#ifdef BSD |
|
|
tem; /* ignored */ |
|
|
if(SYM_EXTERNAL_P(sym) && SYM_UNDEF_P(sym)) |
|
|
#endif |
|
|
#ifdef COFF |
|
544 |
if(0) |
if(0) |
545 |
/* what we really want is |
/* what we really want is |
546 |
if (sym->n_scnum==0 && sym->n_sclass == C_EXT |
if (sym->n_scnum==0 && sym->n_sclass == C_EXT |
556 |
you could make the pass setting the relative addresses. |
you could make the pass setting the relative addresses. |
557 |
for the ones you flagged last time. |
for the ones you flagged last time. |
558 |
*/ |
*/ |
|
#endif |
|
559 |
/* external bss so not included in size of bss for file */ |
/* external bss so not included in size of bss for file */ |
560 |
{int val=sym->n_value; |
{int val=sym->n_value; |
561 |
if (val && c_table.ptable |
if (val && c_table.ptable |
588 |
for ( sym = symbol_table; sym < end; sym++ ) { |
for ( sym = symbol_table; sym < end; sym++ ) { |
589 |
typ = NTYPE ( sym ); |
typ = NTYPE ( sym ); |
590 |
|
|
|
#ifdef BSD |
|
|
# ifdef N_STAB |
|
|
if (N_STAB & sym->n_type) continue; /* skip: It is for dbx only */ |
|
|
# endif |
|
|
typ=N_SECTION(sym); |
|
|
/* if(sym->n_type & N_EXT) should add the symbol name, |
|
|
so it would be accessible by future loads */ |
|
|
if ( typ == N_ABS || typ == N_TEXT || typ == N_DATA || typ == N_BSS ) { |
|
|
#endif |
|
|
|
|
|
#ifdef COFF |
|
591 |
if ( typ == TEXT_NSCN || typ == DATA_NSCN || typ == RDATA_NSCN || typ == BSS_NSCN ) { |
if ( typ == TEXT_NSCN || typ == DATA_NSCN || typ == RDATA_NSCN || typ == BSS_NSCN ) { |
|
#ifdef _WIN32 |
|
592 |
if ( typ == TEXT_NSCN ) n_value = (int)start_address; |
if ( typ == TEXT_NSCN ) n_value = (int)start_address; |
593 |
if ( typ == DATA_NSCN ) n_value = (int)sfaslp->s_start_data; |
if ( typ == DATA_NSCN ) n_value = (int)sfaslp->s_start_data; |
594 |
if ( typ == RDATA_NSCN ) n_value = (int)sfaslp->s_start_rdata; |
if ( typ == RDATA_NSCN ) n_value = (int)sfaslp->s_start_rdata; |
595 |
if ( typ == BSS_NSCN ) n_value = (int)sfaslp->s_start_bss; |
if ( typ == BSS_NSCN ) n_value = (int)sfaslp->s_start_bss; |
|
#endif /* _WIN32 */ |
|
|
#endif /* COFF */ |
|
596 |
str=SYM_NAME(sym); |
str=SYM_NAME(sym); |
|
#ifdef AIX3 |
|
|
if ( N_SECTION(sym) == DATA_NSCN |
|
|
&& NUM_AUX(sym) |
|
|
&& allocate_toc(sym) ) |
|
|
break; |
|
|
#endif |
|
597 |
sym->n_value = n_value; |
sym->n_value = n_value; |
598 |
} else { |
} else { |
599 |
if ( typ == N_UNDEF ) { |
if ( typ == N_UNDEF ) { |
604 |
set_symbol_address(sym,str); |
set_symbol_address(sym,str); |
605 |
describe_sym ( sym-symbol_table, 0 ); |
describe_sym ( sym-symbol_table, 0 ); |
606 |
} else { |
} else { |
|
#ifdef COFF |
|
607 |
dprintf("relocate_symbols: am ignoring a scnum %d\n",(sym->n_scnum)); |
dprintf("relocate_symbols: am ignoring a scnum %d\n",(sym->n_scnum)); |
|
#endif |
|
608 |
} |
} |
609 |
} |
} |
610 |
sym += NUM_AUX(sym); |
sym += NUM_AUX(sym); |
636 |
answ = find_sym(sym,string); |
answ = find_sym(sym,string); |
637 |
dprintf("answ %d \n", (answ ? answ->address : -1) ); |
dprintf("answ %d \n", (answ ? answ->address : -1) ); |
638 |
if ( answ ) { |
if ( answ ) { |
|
#ifdef COFF |
|
|
#ifdef _AIX370 |
|
|
if ( NTYPE(sym) == N_UNDEF ) |
|
|
sym->n_value = answ->address; |
|
|
else |
|
|
#endif |
|
639 |
sym->n_value = answ->address -sym->n_value; |
sym->n_value = answ->address -sym->n_value; |
640 |
/* for symbols in the local data,text and bss this gets added |
/* for symbols in the local data,text and bss this gets added |
641 |
on when we add the current value */ |
on when we add the current value */ |
|
#endif |
|
|
#ifdef BSD |
|
|
/* the old value of sym->n_value is the length of the common area |
|
|
starting at this address */ |
|
|
sym->n_value = answ->address; |
|
|
#endif |
|
|
#ifdef AIX3 |
|
|
fix_undef_toc_address(answ,sym,string); |
|
|
#endif |
|
|
|
|
642 |
} else { |
} else { |
643 |
fprintf ( stdout,"undefined %s symbol", string ); |
fprintf ( stdout,"undefined %s symbol", string ); |
644 |
fflush(stdout); |
fflush(stdout); |