12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- #include <system.h>
- #include <out.h>
- #include "back.h"
- /* Solve the local references.
- */
- #define seg_index( s) ( nname - SEGBSS - 1 + s)
- long get4();
- do_local_relocation()
- /* Check if this reference is solvable. External references contain
- * -1 in 'on_valu'.
- * Also remove useless relocation structures.
- */
- {
- register struct outrelo *rp;
- int diff = 0;
-
- for ( rp = reloc_info; rp < relo; rp++) {
- register struct outname *np = &symbol_table[rp->or_nami];
- int olddiff = diff;
-
- if ( np->on_valu != -1 && ! (np->on_type & S_COM)) {
- register long oldval,newval;
- register char *sect;
- switch( rp->or_sect - S_MIN) {
- case SEGTXT:
- sect = text_area;
- if ((rp->or_type & RELPC) &&
- (np->on_type & S_TYP) - S_MIN == SEGTXT) {
- diff++;
- }
- break;
- case SEGCON:
- sect = data_area;
- break;
- default:
- fprint( STDERR,
- "do_local_relo(): bad section %d\n",
- rp->or_sect - S_MIN);
- break;
- }
- if ( rp->or_type & RELO4) {
- oldval = get4( sect, rp->or_addr);
- newval = oldval + np->on_valu;
- put4( sect, rp->or_addr, newval);
- }
- else if ( rp->or_type & RELO2) {
- oldval = (long) get2( sect, rp->or_addr);
- newval = oldval + np->on_valu;
- put2( sect, rp->or_addr, (int) newval);
- }
- else if ( rp->or_type & RELO1) {
- oldval = (long) get1( sect, rp->or_addr);
- newval = oldval + np->on_valu;
- put1( sect, rp->or_addr, (char) newval);
- }
- else
- fprint( STDERR, "do_relo() : bad relocation size\n");
- rp->or_nami = seg_index((np->on_type & S_TYP) - S_MIN);
- /* print(
- "reloc %s adrr=%ld sect=%ld oldval=%ld newval=%ld def = %ld\n",
- np->on_foff+string_area, rp->or_addr, rp->or_sect-S_MIN, oldval, newval, np->on_valu);
- */
- }
- if (diff && diff == olddiff) {
- rp[-diff] = rp[0];
- }
- }
- relo -= diff;
- }
|