1
/* Copyright William Schelter. All rights reserved. This file does
2
the low level relocation which tends to be very system dependent.
3
It is included by the file sfasl.c
9
static int current_toc;
10
static int ptrgl_offset = 0;
11
static int ptrgl_text;
13
static int akcltoc_used=0;
15
/* This is an alternating list of addresses x1,y1,x2,y2,... where
16
relocation entries for changing value in address x1 shold be read as changing
19
static int toc_addresses_to_relocate [10];
20
static int *next_toc_addresses_to_relocate = toc_addresses_to_relocate ;
21
static int akcltoc_thisload;
22
static int begun_relocate = 0;
24
static int set_rel_bits(address,bits,val)
30
{unsigned short y = *(unsigned short *)address ;
31
y = y & (~0 << bits) ;
32
y |= (val & ~(~0 << bits));
33
*(unsigned short *)address = val;
36
{unsigned int y = *(unsigned int *)address ;
37
y = y & (~0 << bits) ;
38
y |= (val & ~(~0 << bits));
39
*(unsigned int *)address = y;
45
get_symbol(name,scnum,sym_table,length)
48
struct syment *sym_table;
49
{ struct syment *end,*sym;
50
char tem[SYMNMLEN +1];
52
end =sym_table + length;
53
for(sym=sym_table; sym < end; sym += (NUM_AUX(sym) +1))
54
{if ((sym)->n_scnum == scnum)
56
if (strcmp(name,na) == 0)
62
800b0000 l r0,0x0(r11)
63
90410014 st r2,0x14(r1)
65
804b0004 l r2,0x4(r11)
66
816b0008 l r11,0x8(r11)
70
0x800b0000, 0x90410014, 0x7c0903a6, 0x804b0004,
71
0x816b0008, 0x4e800420};
76
static int jmp_r12[2] = { 0x7d8903a6, 0x4e800420};
79
#define SYM_SMC(sym) (((union auxent *)(sym+1))->x_csect.x_smclas)
80
#define SYM_TOC_ADDR(sym) (((union auxent *)(sym+1))->x_csect.x_parmhash)
81
/* #define SYM_USED(sym) (((union auxent *)(&sym[1]))->x_csect.x_snhash) */
82
#define TC_SYMBOL_P(sym) ((sym)->n_scnum == DATA_NSCN && NUM_AUX((sym)) && \
83
(SYM_SMC(sym) == XMC_TC0 || SYM_SMC(sym) == XMC_TC))
88
static int intcmp2(x,y)
93
#define TOP6 (~0 << 26)
94
#define BR_IN_DATA_P(x) (((x) & TOP6) == (DBEGIN & TOP6))
98
{ struct syment *sym = &symbol_table[relocation_info.r_symndx];
100
describe_sym(relocation_info.r_symndx);
101
where = the_start + relocation_info.r_vaddr;
102
dprintf (where has %x , *(int *)where);
103
dprintf( at %x -->, where );
105
if(begun_relocate == 0)
106
{int n = next_toc_addresses_to_relocate - toc_addresses_to_relocate;
108
FIXtemp = 0; /* dummy reference for export problem */
109
qsort((char *)toc_addresses_to_relocate, n/2 , 2*sizeof(int), intcmp2);
110
next_toc_addresses_to_relocate
111
= toc_addresses_to_relocate;}
113
switch(RELOC_RTYPE(relocation_info))
116
case R_TOC: /* TOC_ILodx */
117
set_rel_bits(where,RELOC_RLEN(relocation_info), sym->n_value - toc_start) ;
119
case R_POS: /* Pos_Rel */
121
if (where == *next_toc_addresses_to_relocate)
122
{where = next_toc_addresses_to_relocate [1];
123
next_toc_addresses_to_relocate += 2;}
125
if ( sym->n_scnum == N_UNDEF || TC_SYMBOL_P(sym))
126
set_rel_bits(where,RELOC_RLEN(relocation_info), sym->n_value);
128
set_rel_bits(where,RELOC_RLEN(relocation_info), (*(int *)where)+ sym->n_value);
131
case R_BR: /* Brn_Sel */
132
case R_RBR: /* Brn_Selx */
134
{int link_bit = ((((int *)where)[0]) & 1);
135
if (((((int *)where)[0]) & TOP6 ) == 0x48000000) /* bl or b relative */
137
if (((int *)where)[1] == 0x80410014) /* l r2,0x14(r1) */
138
{int x = SYM_TOC_ADDR(sym);
140
{ ((int *)where)[0] = 0x81820000 ; /* l r12,0x0(r2) */
141
set_rel_bits(where+2,15,x - toc_start);
142
(((int *)where)[1] = 0x48000000); /* b relative */
143
set_rel_bits(where+4, 0x19, ((int) jmp_r12) - ((int) where + 4 ));
144
((int *)where)[1] |= link_bit; /* link bit */
147
else /* must be ptrgl */
148
if (BR_IN_DATA_P(sym->n_value))
149
{set_rel_bits(where, 0x19, sym->n_value - (int) where);
150
((int *)where)[0] |= link_bit; /* link bit */
154
if (BR_IN_DATA_P(sym->n_value))
155
{set_rel_bits(where, 0x19, sym->n_value - (int) where);
156
((int *)where)[0] |= link_bit; /* link bit */
159
FEerror("The type of Br_sel was new ",0,0);
162
fprintf(stdout, "%d: unsupported relocation type.",
163
RELOC_RTYPE(relocation_info) );
164
FEerror("The relocation type was unknown",0,0);
166
dprintf( %x,*(int *)where);
170
fix_undef_toc_address(answ,sym,str)
175
{ if (BR_IN_DATA_P(answ->address)) return;
176
if (answ->tc_offset == 0)
177
{ answ->tc_offset = ( akcltoc + akcltoc_used - toc_start);
178
* ((int *)( akcltoc + akcltoc_used)) = answ->address;
179
akcltoc_used += sizeof(char *);
183
SYM_TOC_ADDR(sym) = (toc_start + answ->tc_offset);
184
else printf("symbol should have aux entry");
196
#define describe_sym(x) do{if(sfasldebug) describe_sym1(x);} while (0)
202
sym= &symbol_table[n];
203
str= sym->n_zeroes == 0 ?
204
&my_string_table[sym->n_offset] :
205
(sym->n_name[SYMNMLEN -1] ?
206
/* MAKE IT NULL TERMINATED */
207
(strncpy(tem,sym->n_name,
210
printf ("sym-index = %d table entry at %x",n,&symbol_table[n]);
211
printf("symbol is (%s):\nsymbol_table[n]._n._n_name %s\nsymbol_table[n]._n._n_n._n_zeroes %d\nsymbol_table[n]._n._n_n._n_offset %d\nsymbol_table[n]._n._n_nptr[0] %d\nsymbol_table[n]._n._n_nptr[n] %d\nsymbol_table[n].n_value %d\nsymbol_table[n].n_scnum %d nsymbol_table[n].n_type %d\nsymbol_table[n].n_sclass %d\nsymbol_table[n].n_numaux %d", str,
212
symbol_table[n]._n._n_name,
213
symbol_table[n]._n._n_n._n_zeroes ,
214
symbol_table[n]._n._n_n._n_offset ,
215
symbol_table[n]._n._n_nptr[0] ,
216
symbol_table[n]._n._n_nptr[1] ,
217
symbol_table[n].n_value ,
218
symbol_table[n].n_scnum ,
219
symbol_table[n].n_type ,
220
symbol_table[n].n_sclass ,
221
symbol_table[n].n_numaux );
229
/* allocate toc space in the preallocated region starting at akcltoc.
230
If a symbol already has a toc entry, use that instead
234
{ bzero(toc_addresses_to_relocate,sizeof(toc_addresses_to_relocate));
235
next_toc_addresses_to_relocate= toc_addresses_to_relocate;
236
akcltoc_thisload = akcltoc + akcltoc_used;
244
{static char tem[SYMNMLEN +1];
247
name = SYM_NAME(sym);
254
/* sym is a symbol in the data section with an aux entry */
255
{ if (SYM_SMC(sym) == XMC_TC0)
256
{ sym->n_value = toc_start; return 1;}
257
if (SYM_SMC(sym) == XMC_TC)
258
{struct node *answ = find_sym(sym,0);
259
if (answ && answ->tc_offset)
260
{ sym->n_value = toc_start + answ->tc_offset;
262
{char *na = sym_name(sym);
264
if (TC_SYMBOL_P(sym) && SYM_USED(sym) == 0)
267
if (answ == 0 && *na && *na != '_')
268
printf("(strange TC synbol %s[%d])",na,sym - symbol_table);}
270
(*next_toc_addresses_to_relocate++) = sym->n_value + start_address;
271
sym->n_value = akcltoc + akcltoc_used;
272
if (answ) answ->tc_offset = sym->n_value - toc_start;
273
(*next_toc_addresses_to_relocate++) = sym->n_value;
274
*((int *)(next_toc_addresses_to_relocate[-1])) =
275
*((int *)(next_toc_addresses_to_relocate[-2]));
276
akcltoc_used += sizeof(long int);
277
if (next_toc_addresses_to_relocate - toc_addresses_to_relocate
278
>= (sizeof(toc_addresses_to_relocate)/sizeof(int)))
279
FEerror("ran out",0,0);
280
if (akcltoc_used > 24000) FEerror("toc exhausted",0,0);