finish.c 6.0 KB

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