2
/* Copyright William Schelter. All rights reserved. This file does
3
the low level relocation which tends to be very system dependent.
4
It is included by the file sfasl.c
5
Thanks to Blewett@research.att.com, for an initial effort on this.
9
Unfortunately the original documentation of the relocation types
10
was rather sketchy, so I was not able to determine the correct
11
behaviour of types which were not currently being output.
13
These will have to be added later, for the moment an abort will occur.
14
One way to check your work is to compile sfasl.c defining STAND, and then
15
compare (using comp.c) the output from it with the output from ld.
22
unsigned int new_value;
24
where = the_start + relocation_info.r_address;
25
dprintf (where has %x , *where);
26
dprintf( at %x -->, where );
30
if(relocation_info.r_extern)
32
switch (relocation_info.r_type)
34
case RELOC_DISP8: /* Disp's (pc-rel) */
36
case RELOC_DISP32: abort();
38
dprintf ( symbol_table[relocation_info.r_index].n_value %d,
39
symbol_table[relocation_info.r_index].n_value);
41
symbol_table[relocation_info.r_index].n_value
42
+ relocation_info.r_addend
45
case RELOC_8: /* simplest relocs */
48
case RELOC_HI22: /* SR 22-bit relocs */
50
dprintf( symbol_table[relocation_info.r_index].n_value = %d ,
51
symbol_table[relocation_info.r_index].n_value);
53
symbol_table[relocation_info.r_index].n_value;
57
printf ("extern non-supported relocation_info.r_type=%d\n",
58
relocation_info.r_type);
62
dprintf( new value %x , new_value);
63
dprintf( rtype %x , relocation_info.r_type);
67
switch(relocation_info.r_index) /* was symbolnum */
69
case N_DATA: case N_BSS: case N_TEXT:
70
new_value= (int)start_address;
78
switch (relocation_info.r_type)
80
#define WHERE relocation_info.r_addend
81
case RELOC_8: /* simplest relocs */
82
*(char *)where = x = new_value + WHERE;
85
*(short *)where = x = new_value + WHERE;
88
*(int *)where = x = new_value + WHERE;
91
case RELOC_DISP8: /* Disp's (pc-rel) */
93
*(char *)where = x = new_value + *(char *) where;
97
*(short *)where = x = new_value + *(short *) where;
101
*(int *)where = new_value + *(int *) where;
102
x = new_value + *( int *) where;
105
case RELOC_WDISP30: /* SR word disp's */
106
#define MASK30BITS 0x3FFFFFFF
107
*(int *)where = ((((int) new_value) >> 2) & MASK30BITS)
108
| (~MASK30BITS & ( *(int *) where));
114
case RELOC_HI22: /* SR 22-bit relocs */
115
x = ((unsigned long) (new_value + relocation_info.r_addend)) >> 10;
116
#define MASK22 0x3fffff
117
*(long *) where= (~MASK22 & *(long *)where) | x;
121
case RELOC_13: /* SR 13&10-bit relocs*/
124
x = ((unsigned long) (new_value + relocation_info.r_addend)) & 0x3ff;
125
*(unsigned short *)(where + 2) |= x;
128
case RELOC_SFA_BASE: /* SR S.F.A. relocs */
129
case RELOC_SFA_OFF13:
130
case RELOC_BASE10: /* base_relative pic */
133
case RELOC_PC10: /* special pc-rel pic*/
135
case RELOC_JMP_TBL: /* jmp_tbl_rel in pic */
136
case RELOC_SEGOFF16: /* ShLib offset-in-seg*/
137
case RELOC_GLOB_DAT: /* rtld relocs */
143
printf ("non-supported relocation_info.r_type=%d\n",
144
relocation_info.r_type);
158
printf("\nrelocation_info:{r_address %d,r_index %d,r_extern %d \n r_type %d, r_addend %d"
159
, relocation_info.r_address
160
, relocation_info.r_index
161
, relocation_info.r_extern
162
, relocation_info.r_type
163
, relocation_info.r_addend);