/* Copyright (c) 1979 Regents of the University of California */
struct allocbox
*allochead
;
struct allocbox
*alloctail
;
* Install all known instructions in the symbol table
register struct instab
*ip
;
register struct symtab
**hp
;
for (ip
=instab
; ip
->name
[0]!=0; ip
++) {
hp
= lookup(0); /* 0 => don't install this*/
*hp
= (struct symtab
*)ip
;
continue; /* was pseudo-op */
itab
[ip
->opcode
& 0xFF] = ip
;
* Assign final values to symbols,
* and overwrite the index field with its relative position in
* the symbol table we give to the loader.
register struct symtab
*sp
;
register struct symtab
**cosp
;
register struct symtab
*ubsp
;
register struct allocbox
*allocwalk
;
DECLITERATE(allocwalk
, sp
, ubsp
)
if (sp
->tag
>= IGNOREBOUND
)
continue; /*totally ignore jxxx entries */
* Ignore stabs, but give them a symbol table index
if ((sp
->type
&XTYPE
)==XUNDEF
)
else if ((sp
->type
&XTYPE
)==XDATA
)
sp
->value
+= usedot
[sp
->index
].xvalue
;
else if ((sp
->type
&XTYPE
)==XTEXT
)
sp
->value
+= usedot
[sp
->index
].xvalue
;
else if ((sp
->type
&XTYPE
)==XBSS
) {
sp
->value
= hdr
.bsize
+ datbase
;
if ( (sp
->name
[0] != 'L')
) /*then, we will write it later on*/
* For all of the stabs that had their final value undefined during pass 1
* and during pass 2 assign a final value.
* We have already given stab entrys a initial approximation
* when we constsructed the sorted symbol table.
* Iteration order doesn't matter.
register struct symtab
*sp
, **cosp
;
register struct symtab
*p
;
if(sp
->ptype
&& (sp
->type
& STABFLAG
)) {
printf("STABFIX: %s (old %s) to %d offsets %d %d\n",
sp
->name
, p
->name
, sp
->value
, sp
, p
);
char *Calloc(number
, size
)
newstuff
= (char *)sbrk(number
*size
);
if ((int)newstuff
== -1){
yyerror("Ran out of Memory");
struct symtab
* symalloc()
newbox
= (struct allocbox
*)Calloc(1,ALLOCQTY
);
nextsym
= &newbox
->symslots
[0];
namebuffer
= &newbox
->symnames
[0];
p
= (int *)(&newbox
->symnames
[SYMDALLOP
* NCPS
]);
while ( p
> (int *)newbox
){
allochead
= alloctail
= newbox
;
alloctail
->nextalloc
= newbox
;
nextsym
->name
= namebuffer
;
struct symtab
**pptr
, **qptr
;
register struct symtab
*p
= *pptr
;
register struct symtab
*q
= *qptr
;
* Force jxxx entries to virtually preceed labels defined
* to follow the jxxxx instruction, so that bumping the
* jxxx instruction correctly fixes up the following labels
if (p
->tag
>= IGNOREBOUND
) /*p points to a jxxx*/
if (q
->tag
>= IGNOREBOUND
)
* both are now just plain labels; the relative order doesn't
* matter. Both can't be jxxxes, as they would have different
* We construct the auxiliary table of pointers, symptrs and
* We also assign preliminary values to stab entries that did not yet
* have an absolute value (because they initially referred to
* forward references). We don't worry about .stabds, as they
* already have an estimated final value
register struct symtab
*sp
;
register struct symtab
**cowalk
;
register struct allocbox
*allocwalk
;
int symsin
; /*number put into symptrs*/
symptrs
= (struct symtab
**)Calloc(nsyms
+ 2, sizeof *symptrs
);
* Allocate one word at the beginning of the symptr array
* so that backwards scans through the symptr array will
* work correctly while scanning through the zeroth segment
DECLITERATE(allocwalk
, sp
, ubsp
) {
if (sp
->ptype
&& (sp
->type
&STABFLAG
)){
sp
->value
= sp
->dest
->value
;
sp
->index
= sp
->dest
->index
;
yyerror("INTERNAL ERROR: overfilled symbol table indirection table");
yyerror("INTERNAL ERROR: installed %d syms, should have installed %d",
symptrub
= &symptrs
[nsyms
];
qsort(symptrs
, nsyms
, sizeof *symptrs
, symcmp
);
for (cowalk
= symptrs
, sp
= *cowalk
, segno
= 0, slotno
= 1;
for (; sp
&& sp
->index
== segno
; sp
= *++cowalk
);
symdelim
[slotno
] = cowalk
; /*forms the ub delimeter*/
register struct symtab
*sp
, **cosp
, *ub
;
printf("Symbol Table dump:\n");
for (segno
= 0; segno
< NLOC
+ NLOC
; segno
++){
printf("Segment number: %d\n", segno
);
SEGITERATE(segno
, 0, 0, cosp
, sp
, ub
, ++){
printf("\tSeg: %d \"%8.8s\" value: %d index: %d tag %s\n",
segno
, sp
->name
, sp
->value
, sp
->index
, tagstring(sp
->tag
));
printf("\t\ttype: %d jxbump %d jxfear: %d\n",
sp
->type
, sp
->jxbump
, sp
->jxfear
);
case JXACTIVE
: return("active");
case JXNOTYET
: return("notyet");
case JXALIGN
: return("align");
case JXQUESTIONABLE
: return("jxquestionable");
case JXINACTIVE
: return("inactive");
case JXTUNNEL
: return("tunnel");
case OBSOLETE
: return("obsolete");
case IGNOREBOUND
: return("ignorebound");
case STABFLOATING
: return("stabfloating");
case STABFIXED
: return("stabfixed");
case LABELID
: return("labelid");
case OKTOBUMP
: return("oktobump");
case ISET
: return("iset");
case ILSYM
: return("ilsym");
default: sprintf(tagbuff
,"%d", tag
);
#define HASHCLOGGED (NHASH * 3 ) / 4
struct symtab
**lookup(instflg
)
int instflg
; /* 0: don't install */
register struct symtab
**hp
;
* All strings passed in in yytext had better have
* a trailing null. Strings are placed in yytext for
* hashing by syminstall() and yylex()
for (ihash
= 0, p1
= yytext
; *p1
; ihash
<<= 2, ihash
+= *p1
++);
if (ihash
< 0) ihash
+= NHASH
;
ihash
= 1; /*now, it counts the number of times we rehash*/
for (i
= 0; (i
<NCPS
) && *p1
; i
++)
if (i
>= NCPS
) /*both symbols are maximal length*/
if (*p2
== 0) /*assert *p1 == 0*/
if (hp
>= &hshtab
[NHASH
])
if(++hshused
>= HASHCLOGGED
) {
yyerror("Symbol table overflow");
#define writel(p,n,f) fwrite((long)p, sizeof (long), n, f)
fwrite(&(*p
).loword
,2,1,f
);
fwrite(&(*p
).hiword
,2,1,f
);
int reflen
[] = {0,0,1,1,2,2,4,4,8,8};
* Save the relocation information
outrel(pval
,reftype
,reltype
,xsym
)
register int reftype
,reltype
;
* reftype: PCREL or not, plus length LEN1, LEN2, LEN4, LEN8
* reltype: csect ("segment") number (XTEXT, XDATA, ...) associated with 'val'
* xsym: symbol table pointer
dotp
->xvalue
+= reflen
[reftype
];
yyerror("Padding error");
yyerror("Undefined reference");
if (reltype
!= XABS
|| reftype
& PCREL
) {
/* write the address portion of a relocation datum */
if (dotp
>= &usedot
[NLOC
]) {
hdr
.drsize
+= sizeof(dotp
->xvalue
) + 3 + sizeof tc
;
tl
= dotp
->xvalue
-datbase
;
hdr
.trsize
+= sizeof(dotp
->xvalue
) + 3 + sizeof tc
;
writel(&dotp
->xvalue
,1,relfil
);
/* write the properties portion of a relocation datum */
if (reltype
== XXTRN
+XUNDEF
) {
tc
= (XXTRN
<<3) | (reftype
-LEN1
);
} else if ((reltype
&XTYPE
) == XUNDEFO
) {
tc
= ((XXTRN
+2)<<3) | (reftype
-LEN1
);
fwrite((char *)&ts
, 3, 1, relfil
);
fwrite(&tc
, sizeof(tc
), 1, relfil
);
/* write the raw ("unrelocated") value to the text file */
fwrite(&((*pval
).loword
),1,2,txtfil
);
fwrite(&((*pval
).hiword
),1,t
-2,txtfil
);
} else fwrite(&((*pval
).loword
),1,t
,txtfil
);
* Write out n symbols to file f, beginning at p
* ignoring symbols that are obsolete, jxxx instructions, and
#define NOUTSYMS (nsyms - njxxx - nforgotten - (savelabels ? 0 : nlabels))
int symsout
; /*those actually written*/
int symsdesired
= NOUTSYMS
;
register struct symtab
*sp
, *ub
;
register struct symtab
**copointer
;
register struct allocbox
*allocwalk
;
for (segno
= 0, symsout
= 0; segno
< NLOC
+ NLOC
; segno
++)
SEGITERATE(segno
, 0, 0, copointer
, sp
, ub
, ++)
DECLITERATE(allocwalk
, sp
, ub
)
if (sp
->tag
>= IGNOREBOUND
)
if ((sp
->name
[0] == 'L') && (sp
->tag
== LABELID
) && !savelabels
)
fwrite(sp
->name
, NCPS
, 1, f
);
fwrite((sp
->ptype
) ? (char *)(&(sp
->ptype
)) : (char *)(&(sp
->type
)),
* WATCH OUT. THIS DEPENDS THAT THE ALLOCATION OF
* the four fields ptype, other, desc and value are
* contiguous. This may have to be changed!
* This is safe (as of 2-Nov-79).
+ sizeof (sp
->value
), 1, f
fwrite(&(sp
->name
[0]), sizeof(symtab
[0].name
), 1, f
);
fwrite(sp
->ptype
? &(sp
->ptype
) : &(sp
->type
),
sizeof(symtab
[0].type
), 1, f
);
fwrite(&(sp
->other
), sizeof(symtab
[0].other
), 1, f
);
fwrite(&(sp
->desc
), sizeof(symtab
[0].desc
), 1, f
);
fwrite(&(sp
->value
), sizeof(symtab
[0].value
), 1, f
);
writel(&(p
->value
), 1, f
);
if (symsout
!= symsdesired
)
yyerror("INTERNAL ERROR: Wrote %d symbols, wanted to write %d symbols\n",