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
4
Thanks to Blewett@research.att.com, for an initial effort on this.
8
Unfortunately the original documentation of the relocation types
9
was rather sketchy, so I was not able to determine the correct
10
behaviour of types which were not currently being output.
12
These will have to be added later, for the moment an abort will occur.
13
One way to check your work is to compile sfasl.c defining STAND, and then
14
compare (using comp.c) the output from it with the output from ld.
21
unsigned int new_value;
23
where = the_start + relocation_info.r_address;
24
dprintf (where has %x , *where);
25
dprintf( at %x -->, where );
29
if(relocation_info.r_extern)
31
switch (relocation_info.r_type)
33
case RELOC_DISP8: /* Disp's (pc-rel) */
35
case RELOC_DISP32: abort();
37
dprintf ( symbol_table[relocation_info.r_index].n_value %d,
38
symbol_table[relocation_info.r_index].n_value);
40
symbol_table[relocation_info.r_index].n_value
41
+ relocation_info.r_addend
44
case RELOC_8: /* simplest relocs */
47
case RELOC_HI22: /* SR 22-bit relocs */
49
dprintf( symbol_table[relocation_info.r_index].n_value = %d ,
50
symbol_table[relocation_info.r_index].n_value);
52
symbol_table[relocation_info.r_index].n_value;
56
printf ("extern non-supported relocation_info.r_type=%d\n",
57
relocation_info.r_type);
61
dprintf( new value %x , new_value);
62
dprintf( rtype %x , relocation_info.r_type);
66
switch(relocation_info.r_index) /* was symbolnum */
68
case N_DATA: case N_BSS: case N_TEXT:
69
new_value= (int)start_address;
77
switch (relocation_info.r_type)
79
#define WHERE relocation_info.r_addend
80
case RELOC_8: /* simplest relocs */
81
*(char *)where = x = new_value + WHERE;
84
*(short *)where = x = new_value + WHERE;
87
*(int *)where = x = new_value + WHERE;
90
case RELOC_DISP8: /* Disp's (pc-rel) */
92
*(char *)where = x = new_value + *(char *) where;
96
*(short *)where = x = new_value + *(short *) where;
100
*(int *)where = new_value + *(int *) where;
101
x = new_value + *( int *) where;
104
case RELOC_WDISP30: /* SR word disp's */
105
#define MASK30BITS 0x3FFFFFFF
106
*(int *)where = ((((int) new_value) >> 2) & MASK30BITS)
107
| (~MASK30BITS & ( *(int *) where));
113
case RELOC_HI22: /* SR 22-bit relocs */
114
x = ((unsigned long) (new_value + relocation_info.r_addend)) >> 10;
115
#define MASK22 0x3fffff
116
*(long *) where= (~MASK22 & *(long *)where) | x;
120
case RELOC_13: /* SR 13&10-bit relocs*/
123
x = ((unsigned long) (new_value + relocation_info.r_addend)) & 0x3ff;
124
*(unsigned short *)(where + 2) |= x;
127
case RELOC_SFA_BASE: /* SR S.F.A. relocs */
128
case RELOC_SFA_OFF13:
129
case RELOC_BASE10: /* base_relative pic */
132
case RELOC_PC10: /* special pc-rel pic*/
134
case RELOC_JMP_TBL: /* jmp_tbl_rel in pic */
135
case RELOC_SEGOFF16: /* ShLib offset-in-seg*/
136
case RELOC_GLOB_DAT: /* rtld relocs */
142
printf ("non-supported relocation_info.r_type=%d\n",
143
relocation_info.r_type);
157
printf("\nrelocation_info:{r_address %d,r_index %d,r_extern %d \n r_type %d, r_addend %d"
158
, relocation_info.r_address
159
, relocation_info.r_index
160
, relocation_info.r_extern
161
, relocation_info.r_type
162
, relocation_info.r_addend);