/* Layout of a.out file :
* header of 8 words magic number 405, 407, 410, 411
* data size ) in bytes but even
* flag set if no relocation
* relocation: 16+textsize+datasize
* symbol table: 16+2*(textsize+datasize) or 16+textsize+datasize
#define COMM 05 /* internal use only */
char premeof
[] = "Premature EOF";
char goodnm
[] = "__.SYMDEF";
/* table of contents stuff */
int offt
, offd
, offb
, offs
;
/* one entry for each archive member referenced;
* set in first pass; needs restoring for overlays
struct liblist liblist
[NROUT
];
struct liblist
*libp
= liblist
;
int locindex
; /* index to symbol in file */
struct symbol
*locsymbol
; /* ptr to symbol table */
struct symbol cursym
; /* current symbol */
struct symbol symtab
[NSYM
]; /* actual symbols */
struct symbol
**symhash
[NSYM
]; /* ptr to hash table entry */
struct symbol
*lastsym
; /* last symbol entered */
int symindex
; /* next available symbol table entry */
struct symbol
*hshtab
[NSYM
+2]; /* hash table for symbols */
struct local local
[NSYMPR
];
int xflag
; /* discard local symbols */
int Xflag
; /* discard locals starting with 'L' */
int Sflag
; /* discard all except locals and globals*/
int rflag
; /* preserve relocation bits, don't define common */
int arflag
; /* original copy of rflag */
int sflag
; /* discard all symbols */
int nflag
; /* pure procedure */
int Oflag
; /* set magic # to 0405 (overlay) */
int dflag
; /* define common even with rflag */
int iflag
; /* I/D space separated */
int vflag
; /* overlays used */
char *ofilename
= "l.out";
/* cumulative sizes set in pass 1 */
/* symbol relocation; both passes */
char tfname
[] = "/tmp/ldaXXXXX";
struct symbol
**lookup();
struct symbol
**slookup();
struct symbol
*lookloc();
chmod(ofilename
, 0777 & ~umask(0));
if (signal(SIGINT
, SIG_IGN
) != SIG_IGN
)
if (signal(SIGTERM
, SIG_IGN
) != SIG_IGN
)
signal(SIGTERM
, delexit
);
/* scan files once to find symdefs */
if (trace
) printf("%s:\n", *p
);
error(2, "Bad output file");
error(2, "Bad 'use' or 'entry'");
error(2, "-v: arg missing");
while (--vscan
>=0 && found
==FALSE
)
found
= eq(vnodes
[vscan
].vname
, *p
);
error(2, "-D: arg missing");
error(2, "-D: too small");
if (trace
) printf("%s:\n", ap
);
for (dnum
= atoi(*p
); dorigin
<dnum
; dorigin
+= 2) {
register struct overlay
*v
;
register struct overlay
*v
;
/* scan file to find defined symbols */
nloc
+= (archdr
.asize
+ sizeof(archdr
) + 1) >> 1;
tnum
= archdr
.asize
/ sizeof(struct tab
);
error(2, "fast load buffer too small");
lseek(infil
, (long)(sizeof(filhdr
.fmagic
)+sizeof(archdr
)), 0);
read(infil
, (char *)tab
, tnum
* sizeof(struct tab
));
/* out of date table of contents */
error(0, "out of date (warning)");
for(nloc
= 1+((archdr
.asize
+sizeof(archdr
)+1) >> 1); step(nloc
);
nloc
+= (archdr
.asize
+ sizeof(archdr
) + 1) >> 1);
dseek(&text
, nloc
, sizeof archdr
);
mget((int *)&archdr
, sizeof archdr
);
if (load1(1, nloc
+ (sizeof archdr
) / 2)) {
struct liblist
*oldp
= libp
;
for(i
= 0; i
<tnum
; i
++) {
if ((pp
= slookup(tab
[i
].cname
)) == 0)
if (sp
->stype
!= EXTERN
+UNDEF
)
r
= (long)(unsigned)a
+ (unsigned)b
;
/* single file or archive member */
register struct symbol
*sp
;
int ndef
, nloc
, type
, mtype
;
if ((filhdr
.relflg
&RELFLG
)==1) {
error(1, "No relocation bits");
loc
+= (sizeof filhdr
)/2 + filhdr
.tsize
+ filhdr
.dsize
;
dseek(&text
, loc
, filhdr
.ssize
);
mget((int *)&cursym
, sizeof cursym
);
if (mtype
==1 || mtype
>4) {
if (Xflag
==0 || cursym
.sname
[0]!='L')
if ((sp
= lastsym
)->stype
!= EXTERN
+UNDEF
)
if (cursym
.stype
== EXTERN
+UNDEF
) {
if (cursym
.svalue
> sp
->svalue
)
sp
->svalue
= cursym
.svalue
;
if (sp
->svalue
!= 0 && cursym
.stype
== EXTERN
+TEXT
)
sp
->stype
= cursym
.stype
;
sp
->svalue
= cursym
.svalue
;
tsize
= add(tsize
,filhdr
.tsize
,"text overflow");
dsize
= add(dsize
,filhdr
.dsize
,"data overflow");
bsize
= add(bsize
,filhdr
.bsize
,"bss overflow");
ssize
= add(ssize
,nloc
,"symbol table overflow");
* No symbols defined by this library member.
* Rip out the hash table entries and reset the symbol table.
while (symindex
>savindex
)
register struct symbol
*sp
, *symp
;
p_etext
= *slookup("_etext");
p_edata
= *slookup("_edata");
p_end
= *slookup("_end");
* If there are any undefined symbols, save the relocation bits.
symp
= &symtab
[symindex
];
for (sp
= symtab
; sp
<symp
; sp
++)
if (sp
->stype
==EXTERN
+UNDEF
&& sp
->svalue
==0
&& sp
!=p_end
&& sp
!=p_edata
&& sp
!=p_etext
) {
nflag
= sflag
= iflag
= Oflag
= 0;
* Assign common locations.
ldrsym(p_etext
, tsize
, EXTERN
+TEXT
);
ldrsym(p_edata
, dsize
, EXTERN
+DATA
);
ldrsym(p_end
, bsize
, EXTERN
+BSS
);
for (sp
= symtab
; sp
<symp
; sp
++)
if (sp
->stype
==EXTERN
+UNDEF
&& (t
= sp
->svalue
)!=0) {
csize
= add(csize
, t
, "bss overflow");
* Now set symbols to their final value
tsize
= (tsize
+ 077) & ~077;
dorigin
= (tsize
+017777) & ~017777;
corigin
= dorigin
+ dsize
;
borigin
= corigin
+ csize
;
for (sp
= symtab
; sp
<symp
; sp
++) switch (sp
->stype
) {
if (arflag
==0 && sp
->svalue
==0) {
printf("%.8s\n", sp
->sname
);
bsize
= add(bsize
, csize
, "bss overflow");
nsym
= ssize
/ (sizeof cursym
);
register struct symbol
*sp
;
if (sp
->stype
!= EXTERN
+UNDEF
|| sp
->svalue
) {
printf("%.8s: ", sp
->sname
);
error(1, "Multiply defined");
if (sflag
==0 || xflag
==0)
filhdr
.fmagic
= (Oflag
? OMAGIC
:( iflag
? IMAGIC
: ( nflag
? NMAGIC
: FMAGIC
)));
filhdr
.ssize
= sflag
? 0: (ssize
+ (sizeof cursym
)*symindex
);
if (entrypt
->stype
!=EXTERN
+TEXT
)
error(1, "Entry point not in text");
filhdr
.entry
= entrypt
->svalue
| 01;
filhdr
.relflg
= (rflag
==0);
mput(&toutb
, (int *)&filhdr
, sizeof filhdr
);
nam
= (tempflg
? tfname
: ofilename
);
if ((ufd
= creat(nam
, 0666)) < 0)
error(2, tempflg
?"cannot create temp":"cannot create output");
buf
->fildes
= open(nam
, 2);
buf
->nleft
= sizeof(buf
->iobuf
)/sizeof(int);
register struct liblist
*lp
;
while (cp
>= acp
&& *--cp
!= '/');
} else { /* scan archive members referenced */
for (lp
= libp
; lp
->loc
!= -1; lp
++) {
dseek(&text
, lp
->loc
, sizeof archdr
);
mget((int *)&archdr
, sizeof archdr
);
load2(lp
->loc
+ (sizeof archdr
) / 2);
register struct symbol
*sp
;
register struct local
*lp
;
* Reread the symbol table, recording the numbering
* of symbols for fixing external references.
loc
+= (sizeof filhdr
)/2;
dseek(&text
, loc
+ filhdr
.tsize
+ filhdr
.dsize
, filhdr
.ssize
);
mget((int *)&cursym
, sizeof cursym
);
if (mtype
==1 || mtype
>4) continue;
if ((type
&EXTERN
) == 0) {
if (!sflag
&&!xflag
&&(!Xflag
||cursym
.sname
[0]!='L'))
mput(&soutb
, (int *)&cursym
, sizeof cursym
);
if ((sp
= *lookup()) == 0)
error(2, "internal error: symbol not found");
if (cursym
.stype
== EXTERN
+UNDEF
) {
if (lp
>= &local
[NSYMPR
])
error(2, "Local symbol overflow");
if (cursym
.stype
!=sp
->stype
|| cursym
.svalue
!=sp
->svalue
) {
printf("%.8s: ", cursym
.sname
);
error(1, "Multiply defined");
dseek(&text
, loc
, filhdr
.tsize
);
dseek(&reloc
, loc
+ half(filhdr
.tsize
+ filhdr
.dsize
), filhdr
.tsize
);
load2td(lp
, ctrel
, &toutb
, &troutb
);
dseek(&text
, loc
+half(filhdr
.tsize
), filhdr
.dsize
);
dseek(&reloc
, loc
+filhdr
.tsize
+half(filhdr
.dsize
), filhdr
.dsize
);
load2td(lp
, cdrel
, &doutb
, &droutb
);
load2td(lp
, creloc
, b1
, b2
)
register struct symbol
*sp
;
* The pickup code is copied from "get" for speed.
/* next text or data word */
} else if (--text
.nibuf
< 0) {
/* next relocation word */
error(2, "Relocation error");
} else if (--reloc
.nibuf
< 0) {
if (sp
->stype
==EXTERN
+UNDEF
) {
r
= (r
&01) + ((nsym
+(sp
-symtab
))<<4) + REXT
;
r
= (r
&01) + ((sp
->stype
-(EXTERN
+ABS
))<<1);
for (p
= (int *)symtab
; p
< (int *)&symtab
[symindex
];)
lseek(f
= buf
->fildes
, (long)0, 0);
while ((n
= read(f
, (char *)doutb
.iobuf
, sizeof(doutb
.iobuf
))) > 1) {
mput(&soutb
, (int *)&cursym
, sizeof cursym
);
if ((text
.nibuf
-= n
) >= 0) {
if ((text
.size
-= n
) > 0) {
register struct stream
*sp
;
/* register */ long b
, o
;
if ((p
= &page
[0])->bno
!=b
&& (p
= &page
[1])->bno
!=b
)
if (p
->nuser
==0 || (p
= &page
[0])->nuser
==0) {
if (page
[0].nuser
==0 && page
[1].nuser
==0)
if (page
[0].bno
< page
[1].bno
)
lseek(infil
, (aloc
& ~0377L) << 1, 0);
if ((n
= read(infil
, (char *)p
->buff
, 512)>>1) < 0)
if ((sp
->nibuf
= p
->nibuf
-o
) <= 0)
register struct stream
*sp
;
dseek(sp
, (long)(sp
->bno
+ 1) << 8, -1);
sp
->pno
= (struct page
*)&fpage
;
if (cp
[0]=='-' && cp
[1]=='l') {
filname
= "/usr/lib/libxxxxxxxxxxxxxxx";
if ((infil
= open(filname
+4, 0)) >= 0) {
if (infil
== -1 && (infil
= open(filname
, 0)) < 0)
page
[0].bno
= page
[1].bno
= -1;
page
[0].nuser
= page
[1].nuser
= 0;
text
.pno
= reloc
.pno
= (struct page
*)&fpage
;
if(get(&text
) != ARCMAGIC
)
return(0); /* regualr file */
dseek(&text
, 1L, sizeof archdr
); /* word addressing */
return(1); /* regular archive */
mget((int *)&archdr
, sizeof archdr
);
if(strncmp(archdr
.aname
, goodnm
, 14) != 0)
return(1); /* regular archive */
if(x
.st_mtime
> archdr
.atime
)
register struct symbol
**hp
;
for (cp
= cursym
.sname
; cp
< &cursym
.sname
[8];)
for (hp
= &hshtab
[(i
&077777)%NSYM
+2]; *hp
!=0;) {
for (cp
= cursym
.sname
; cp
< &cursym
.sname
[8];)
if (++hp
>= &hshtab
[NSYM
+2])
struct symbol
**slookup(s
)
cursym
.stype
= EXTERN
+UNDEF
;
register struct symbol
*sp
;
error(2, "Symbol table overflow");
*hp
= lastsym
= sp
= &symtab
[symindex
++];
cp8c(cursym
.sname
, sp
->sname
);
sp
->stype
= cursym
.stype
;
sp
->svalue
= cursym
.svalue
;
cursym
.stype
= EXTERN
+ABS
;
printf("(%.14s)", archdr
.aname
);
register struct local
*clp
, *lp
;
for (clp
= local
; clp
<lp
; clp
++)
error(2, "Local symbol botch");
dseek(&text
, loc
, sizeof filhdr
);
mget((int *)&filhdr
, sizeof filhdr
);
if (filhdr
.fmagic
!= FMAGIC
)
st
= (filhdr
.tsize
+01) & ~01;
sd
= (filhdr
.dsize
+01) & ~01;
filhdr
.bsize
= (filhdr
.bsize
+01) & ~01;
register char *f
, *t
, *te
;
while ((*t
++ = *f
++) && t
<te
);
if ((n
= (char *)b
->xnext
- (char *)b
->iobuf
) > 0)
if (write(b
->fildes
, (char *)b
->iobuf
, n
) != n
)
error(2, "output error");
b
->nleft
= sizeof(b
->iobuf
)/sizeof(int);