finish.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. #include <out.h>
  6. #include "const.h"
  7. #include "arch.h"
  8. #include "memory.h"
  9. #include "defs.h"
  10. #include "orig.h"
  11. #include "scan.h"
  12. #include "object.h"
  13. extern bool incore;
  14. extern unsigned short NLocals;
  15. extern int flagword;
  16. static void adjust_names(struct outname *name, struct outhead *head, char *chars);
  17. static void handle_relos(struct outhead *head, struct outsect *sects, struct outname *names);
  18. static void put_locals(struct outname *name, unsigned int nnames);
  19. static void compute_origins(struct outsect *sect, unsigned int nsect);
  20. #ifdef SYMDBUG
  21. static void put_dbug(long offdbug);
  22. #endif
  23. /*
  24. * We know all there is to know about the current module.
  25. * Now we relocate the values in the emitted bytes and write
  26. * those to the final output file. Then we compute the relative origins
  27. * for the next module.
  28. */
  29. void finish()
  30. {
  31. struct outhead *head;
  32. struct outsect *sects;
  33. struct outname *names;
  34. char *chars;
  35. get_modul();
  36. head = (struct outhead *)modulptr(IND_HEAD);
  37. sects = (struct outsect *)modulptr(IND_SECT(*head));
  38. names = (struct outname *)modulptr(IND_NAME(*head));
  39. chars = (char *)modulptr(IND_CHAR(*head));
  40. adjust_names(names, head, chars);
  41. handle_relos(head, sects, names);
  42. if (!incore && !(flagword & SFLAG)) {
  43. put_locals(names, head->oh_nname);
  44. #ifdef SYMDBUG
  45. put_dbug(OFF_DBUG(*head));
  46. #endif /* SYMDBUG */
  47. }
  48. compute_origins(sects, head->oh_nsect);
  49. skip_modul(head);
  50. }
  51. /*
  52. * Adjust all local names for the move into core.
  53. */
  54. static void adjust_names(struct outname *name, struct outhead *head, char *chars)
  55. {
  56. int cnt;
  57. long charoff;
  58. struct outname *base = name;
  59. cnt = head->oh_nname;
  60. charoff = OFF_CHAR(*head);
  61. while (cnt--) {
  62. if (name->on_foff != (long)0)
  63. name->on_mptr = chars + (ind_t)(name->on_foff - charoff);
  64. name++;
  65. }
  66. if (! incore) {
  67. do_crs(base, head->oh_nname);
  68. }
  69. }
  70. void do_crs(struct outname *base, unsigned int count)
  71. {
  72. struct outname *name = base;
  73. while (count--) {
  74. if ((name->on_type & S_TYP) == S_CRS) {
  75. char *s;
  76. struct outname *p;
  77. s = address(ALLOGCHR, (ind_t) name->on_valu);
  78. p = searchname(s, hash(s));
  79. if (flagword & RFLAG) {
  80. name->on_valu = NLocals + (p -
  81. (struct outname *)
  82. address(ALLOGLOB, (ind_t) 0));
  83. }
  84. else {
  85. name->on_valu = p->on_valu;
  86. name->on_type &= ~S_TYP;
  87. name->on_type |= (p->on_type & S_TYP);
  88. }
  89. }
  90. name++;
  91. }
  92. }
  93. /*
  94. * If all sections are in core, we can access them randomly, so we need only
  95. * scan the relocation table once. Otherwise we must for each section scan
  96. * the relocation table again, because the relocation entries of one section
  97. * need not be consecutive.
  98. */
  99. static void handle_relos(struct outhead *head, struct outsect *sects, struct outname *names)
  100. {
  101. struct outrelo *relo;
  102. int sectindex;
  103. int nrelo;
  104. char *emit;
  105. extern char *getemit();
  106. extern struct outrelo *nextrelo();
  107. static long zeros[MAXSECT];
  108. if (incore) {
  109. nrelo = head->oh_nrelo; sectindex = -1;
  110. startrelo(head); relo = nextrelo();
  111. while (nrelo--) {
  112. if (sectindex != relo->or_sect - S_MIN) {
  113. sectindex = relo->or_sect - S_MIN;
  114. emit = getemit(head, sects, sectindex);
  115. }
  116. relocate(head, emit, names, relo, 0L);
  117. relo++;
  118. }
  119. } else {
  120. for (sectindex = 0; sectindex < head->oh_nsect; sectindex++) {
  121. if (sects[sectindex].os_flen) {
  122. wrt_nulls(sectindex, zeros[sectindex]);
  123. zeros[sectindex] = 0;
  124. emit = getemit(head, sects, sectindex);
  125. if (emit) {
  126. nrelo = head->oh_nrelo; startrelo(head);
  127. while (nrelo--) {
  128. relo = nextrelo();
  129. if (relo->or_sect - S_MIN == sectindex) {
  130. relocate(head,emit,names,relo,0L);
  131. /*
  132. * Write out the (probably changed)
  133. * relocation information.
  134. */
  135. if (flagword & (RFLAG|CFLAG))
  136. wr_relo(relo, 1);
  137. }
  138. }
  139. wrt_emit(emit, sectindex,
  140. sects[sectindex].os_flen);
  141. }
  142. else {
  143. long sz = sects[sectindex].os_flen;
  144. long sf = 0;
  145. long blksz;
  146. char *getblk();
  147. emit = getblk(sz, &blksz, sectindex);
  148. while (sz) {
  149. long sz2 = sz > blksz ? blksz : sz;
  150. rd_emit(emit, sz2);
  151. nrelo = head->oh_nrelo; startrelo(head);
  152. while (nrelo--) {
  153. relo = nextrelo();
  154. if (relo->or_sect-S_MIN==sectindex
  155. &&
  156. relo->or_addr >= sf
  157. &&
  158. relo->or_addr < sf + sz2){
  159. relocate(head,emit,names,relo,
  160. sf);
  161. /*
  162. * Write out the (probably changed)
  163. * relocation information.
  164. */
  165. if (flagword & (RFLAG|CFLAG))
  166. wr_relo(relo, 1);
  167. }
  168. }
  169. wrt_emit(emit, sectindex, sz2);
  170. sz -= sz2;
  171. sf += sz2;
  172. }
  173. }
  174. endemit(emit);
  175. }
  176. zeros[sectindex] += sects[sectindex].os_size -
  177. sects[sectindex].os_flen;
  178. }
  179. }
  180. }
  181. /*
  182. * Write out the local names that must be saved.
  183. */
  184. static void put_locals(struct outname *name, unsigned int nnames)
  185. {
  186. register struct outname *oname = name;
  187. register struct outname *iname = oname;
  188. while (nnames--) {
  189. if ((iname->on_type & S_EXT) == 0 && mustsavelocal(iname)) {
  190. namerelocate(iname);
  191. addbase(iname);
  192. wrt_name(iname, 0);
  193. *oname++ = *iname;
  194. }
  195. iname++;
  196. }
  197. wr_name(name, (unsigned int) (oname - name));
  198. }
  199. /*
  200. * Add all flen's and all (size - flen == zero)'s of preceding sections
  201. * with the same number.
  202. */
  203. static void compute_origins(struct outsect *sect, unsigned int nsect)
  204. {
  205. extern struct orig relorig[];
  206. register struct orig *orig = relorig;
  207. while (nsect--) {
  208. orig->org_size += sect->os_size;
  209. orig++; sect++;
  210. }
  211. }
  212. #ifdef SYMDBUG
  213. /*
  214. * Write out what is after the string area. This is likely to be
  215. * debugging information.
  216. */
  217. static void put_dbug(long offdbug)
  218. {
  219. char buf[512];
  220. int nbytes;
  221. long dbugsize;
  222. extern long objectsize;
  223. dbugsize = objectsize - offdbug;
  224. while (dbugsize) {
  225. nbytes = dbugsize > 512 ? 512 : dbugsize;
  226. rd_dbug(buf, (long)nbytes);
  227. wr_dbug(buf, (long) nbytes);
  228. dbugsize -= nbytes;
  229. }
  230. }
  231. #endif /* SYMDBUG */