linksyms.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* linksyms.c - write binary file for linker */
  2. /* Copyright (C) 1994 Bruce Evans */
  3. #include "syshead.h"
  4. #include "const.h"
  5. #include "obj.h"
  6. #include "type.h"
  7. #undef EXTERN
  8. #include "globvar.h"
  9. FORWARD void linkrefs P((struct modstruct *modptr));
  10. PUBLIC bool_t reloc_output = 0;
  11. /* link all symbols connected to entry symbols */
  12. PUBLIC void linksyms(argreloc_output)
  13. bool_pt argreloc_output;
  14. {
  15. char needlink;
  16. struct entrylist *elptr;
  17. struct modstruct *modptr;
  18. struct symstruct *symptr;
  19. #ifdef REL_OUTPUT
  20. reloc_output = argreloc_output;
  21. if (argreloc_output)
  22. {
  23. if (modfirst->modnext != NUL_PTR)
  24. fatalerror("relocatable output only works for one input file");
  25. for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext)
  26. modptr->loadflag = TRUE;
  27. return;
  28. }
  29. #endif
  30. if ((symptr = findsym("_start")) != NUL_PTR ||
  31. (symptr = findsym("_main")) != NUL_PTR)
  32. entrysym(symptr);
  33. do
  34. {
  35. if ((elptr = entryfirst) == NUL_PTR)
  36. fatalerror("no start symbol");
  37. for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext)
  38. modptr->loadflag = FALSE;
  39. for (; elptr != NUL_PTR; elptr = elptr->elnext)
  40. linkrefs(elptr->elsymptr->modptr);
  41. if ((symptr = findsym("start")) != NUL_PTR)
  42. linkrefs(symptr->modptr);
  43. needlink = FALSE;
  44. {
  45. struct redlist *prlptr = 0;
  46. struct redlist *rlptr;
  47. for (rlptr = redfirst; rlptr != NUL_PTR;
  48. rlptr = (prlptr = rlptr)->rlnext)
  49. if (rlptr->rlmodptr->loadflag &&
  50. rlptr->rlmodptr->class > rlptr->rlsymptr->modptr->class)
  51. {
  52. rlptr->rlsymptr->modptr = rlptr->rlmodptr;
  53. rlptr->rlsymptr->value = rlptr->rlvalue;
  54. if (rlptr == redfirst)
  55. redfirst = rlptr->rlnext;
  56. else
  57. prlptr->rlnext = rlptr->rlnext;
  58. needlink = TRUE;
  59. }
  60. }
  61. }
  62. while (needlink);
  63. }
  64. PRIVATE void linkrefs(modptr)
  65. struct modstruct *modptr;
  66. {
  67. register struct symstruct **symparray;
  68. register struct symstruct *symptr;
  69. modptr->loadflag = TRUE;
  70. for (symparray = modptr->symparray;
  71. (symptr = *symparray) != NUL_PTR; ++symparray)
  72. if (symptr->modptr->loadflag == FALSE)
  73. linkrefs(symptr->modptr);
  74. }