Pristine Ack-5.5
[Ack-5.5.git] / util / ceg / ce_back / obj_back / relocation.c
1 #include <system.h>
2 #include <out.h>
3 #include "back.h"
4
5 /* Solve the local references.
6  */
7
8 #define seg_index( s)   ( nname - SEGBSS - 1 + s)
9
10 long            get4(); 
11
12 do_local_relocation()
13
14 /* Check if this reference is solvable. External references contain
15  * -1 in 'on_valu'.
16  * Also remove useless relocation structures.
17  */
18 {
19         register struct outrelo *rp;
20         int diff = 0;
21         
22         for ( rp = reloc_info; rp < relo; rp++) {
23                 register struct outname *np = &symbol_table[rp->or_nami];
24                 int olddiff = diff;
25                 
26                 if ( np->on_valu  != -1 && ! (np->on_type & S_COM)) {
27                         register long oldval,newval;
28                         register char *sect;
29
30                         switch( rp->or_sect - S_MIN) {
31                                 case SEGTXT:
32                                         sect = text_area;
33                                         if ((rp->or_type & RELPC) &&
34                                             (np->on_type & S_TYP) - S_MIN == SEGTXT) {
35                                                 diff++;
36                                         }
37                                         break;
38                                 case SEGCON:
39                                         sect = data_area;
40                                         break;
41                                 default:
42                                         fprint( STDERR, 
43                                           "do_local_relo(): bad section %d\n",
44                                                 rp->or_sect - S_MIN);
45                                         break;
46                         }
47
48                         if  ( rp->or_type & RELO4) {
49                                 oldval = get4( sect, rp->or_addr);
50                                 newval = oldval + np->on_valu;
51                                 put4( sect, rp->or_addr, newval);
52                         }
53                         else if  ( rp->or_type & RELO2) {
54                                 oldval = (long) get2( sect, rp->or_addr);
55                                 newval = oldval + np->on_valu;
56                                 put2( sect, rp->or_addr, (int) newval);
57                         }
58                         else if  ( rp->or_type & RELO1) {
59                                 oldval = (long) get1( sect, rp->or_addr);
60                                 newval = oldval + np->on_valu;
61                                 put1( sect, rp->or_addr, (char) newval);
62                         }
63                         else
64                                 fprint( STDERR, "do_relo() : bad relocation size\n");
65                         rp->or_nami = seg_index((np->on_type & S_TYP) - S_MIN);
66                         /* print( 
67                                 "reloc %s adrr=%ld sect=%ld oldval=%ld newval=%ld def = %ld\n",
68                                 np->on_foff+string_area, rp->or_addr, rp->or_sect-S_MIN, oldval,                newval, np->on_valu);
69                         */
70                 }
71                 if (diff && diff == olddiff) {
72                         rp[-diff] = rp[0];
73                 }
74         }
75         relo -= diff;
76 }