relocation.c 1.8 KB

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