ld.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /* ld.c - linker for Introl format (6809 C) object files 6809/8086/80386 */
  2. /* Copyright (C) 1994 Bruce Evans */
  3. #include "syshead.h"
  4. #include "const.h"
  5. #include "byteord.h"
  6. #include "type.h"
  7. #include "globvar.h"
  8. #define MAX_LIBS (NR_STDLIBS + 5)
  9. #ifdef MC6809
  10. #define NR_STDLIBS 1
  11. #else
  12. #define NR_STDLIBS 0
  13. #endif
  14. PUBLIC bin_off_t text_base_value = 0; /* XXX */
  15. PUBLIC bin_off_t data_base_value = 0; /* XXX */
  16. PUBLIC bin_off_t heap_top_value = 0; /* XXX */
  17. PUBLIC int headerless = 0;
  18. #ifndef VERY_SMALL_MEMORY
  19. PUBLIC int v7 = 0;
  20. #endif
  21. #ifndef MSDOS
  22. PUBLIC int cpm86 = 0;
  23. #endif
  24. PUBLIC char hexdigit[] = "0123456789abcdef";
  25. PRIVATE bool_t flag[128];
  26. PRIVATE char *libs[MAX_LIBS] = {
  27. #ifdef MC6809
  28. "/usr/local/lib/m09/",
  29. #endif
  30. 0
  31. };
  32. PRIVATE int lastlib = NR_STDLIBS;
  33. FORWARD char *buildname P((char *pre, char *mid, char *suf));
  34. FORWARD char *expandlib P((char *fn));
  35. PRIVATE char *buildname(pre, mid, suf)
  36. char *pre;
  37. char *mid;
  38. char *suf;
  39. {
  40. char *name;
  41. name = ourmalloc(strlen(pre) + strlen(mid) + strlen(suf) + 1);
  42. strcpy(name, pre);
  43. strcat(name, mid);
  44. strcat(name, suf);
  45. return name;
  46. }
  47. PRIVATE char *expandlib(fn)
  48. char *fn;
  49. {
  50. char *path, *s;
  51. int i;
  52. for (i = lastlib - 1; i >= 0; --i)
  53. {
  54. path = ourmalloc(strlen(libs[i]) + strlen(fn) + 2);
  55. strcpy(path, libs[i]);
  56. s = path + strlen(path);
  57. if (s!=path && s[-1] != '/') strcat(path, "/");
  58. strcat(path, fn);
  59. if (access(path, R_OK) == 0)
  60. return path;
  61. ourfree(path);
  62. }
  63. return NUL_PTR;
  64. }
  65. PUBLIC int main(argc, argv)
  66. int argc;
  67. char **argv;
  68. {
  69. register char *arg;
  70. int argn;
  71. static char crtprefix[] = "crt";
  72. static char crtsuffix[] = ".o";
  73. char *infilename;
  74. static char libprefix[] = "lib";
  75. static char libsuffix[] = ".a";
  76. char *outfilename;
  77. char *tfn;
  78. int icount=0;
  79. ioinit(argv[0]);
  80. objinit();
  81. syminit();
  82. typeconv_init(INT_BIG_ENDIAN, LONG_BIG_ENDIAN);
  83. #ifndef MC6809
  84. flag['3'] = sizeof(char *) >= 4;
  85. #endif
  86. outfilename = NUL_PTR;
  87. for (argn = 1; argn < argc; ++argn)
  88. {
  89. arg = argv[argn];
  90. if (*arg != '-')
  91. {
  92. readsyms(arg, flag['t']);
  93. icount++;
  94. }
  95. else
  96. switch (arg[1])
  97. {
  98. case 'v':
  99. version_msg();
  100. case 'r': /* relocatable output */
  101. case 't': /* trace modules linked */
  102. if (icount > 0) usage();
  103. #ifdef REL_OUTPUT
  104. case 'B': /* Broken -r for dosemu. */
  105. #endif
  106. case '0': /* use 16-bit libraries */
  107. case '3': /* use 32-bit libraries */
  108. case 'M': /* print symbols linked */
  109. case 'i': /* separate I & D output */
  110. case 'm': /* print modules linked */
  111. case 's': /* strip symbols */
  112. case 'z': /* unmapped zero page */
  113. case 'N': /* Native format a.out */
  114. case 'd': /* Make a headerless outfile */
  115. #ifndef MSDOS
  116. case 'c': /* Write header in CP/M-86 format */
  117. #endif
  118. case 'y': /* Use a newer symbol table */
  119. #ifndef VERY_SMALL_MEMORY
  120. case '7': /* Produce a UNIX v7 a.out header */
  121. #endif
  122. if (arg[2] == 0)
  123. flag[(int) arg[1]] = TRUE;
  124. else if (arg[2] == '-' && arg[3] == 0)
  125. flag[(int) arg[1]] = FALSE;
  126. else
  127. usage();
  128. if (arg[1] == '0') /* flag 0 is negative logic flag 3 */
  129. flag['3'] = !flag['0'];
  130. break;
  131. case 'C': /* startfile name */
  132. tfn = buildname(crtprefix, arg + 2, crtsuffix);
  133. if ((infilename = expandlib(tfn)) == NUL_PTR)
  134. infilename = tfn;
  135. /*fatalerror(tfn); * XXX - need to describe failure */
  136. readsyms(infilename, flag['t']);
  137. icount++;
  138. break;
  139. case 'L': /* library path */
  140. if (lastlib < MAX_LIBS)
  141. libs[lastlib++] = arg + 2;
  142. else
  143. fatalerror("too many library paths");
  144. break;
  145. case 'O': /* library file name */
  146. if ((infilename = expandlib(arg + 2)) == NUL_PTR)
  147. infilename = arg+2;
  148. /* fatalerror(arg); * XXX */
  149. readsyms(infilename, flag['t']);
  150. break;
  151. case 'T': /* text base address */
  152. if (arg[2] == 0 && ++argn >= argc)
  153. usage();
  154. errno = 0;
  155. if (arg[2] == 0 )
  156. text_base_value = strtoul(argv[argn], (char **)0, 16);
  157. else
  158. text_base_value = strtoul(arg+2, (char **)0, 16);
  159. if (errno != 0)
  160. use_error("invalid text address");
  161. break;
  162. case 'D': /* data base address */
  163. if (arg[2] == 0 && ++argn >= argc)
  164. usage();
  165. errno = 0;
  166. if (arg[2] == 0 )
  167. data_base_value = strtoul(argv[argn], (char **)0, 16);
  168. else
  169. data_base_value = strtoul(arg+2, (char **)0, 16);
  170. if (errno != 0)
  171. use_error("invalid data address");
  172. break;
  173. case 'H': /* heap top address */
  174. if (arg[2] == 0 && ++argn >= argc)
  175. usage();
  176. errno = 0;
  177. if (arg[2] == 0 )
  178. heap_top_value = strtoul(argv[argn], (char **)0, 16);
  179. else
  180. heap_top_value = strtoul(arg+2, (char **)0, 16);
  181. if (errno != 0)
  182. use_error("invalid heap top");
  183. break;
  184. case 'l': /* library name */
  185. tfn = buildname(libprefix, arg + 2, libsuffix);
  186. if ((infilename = expandlib(tfn)) == NUL_PTR)
  187. infilename = tfn;
  188. /* fatalerror(tfn); * XXX */
  189. readsyms(infilename, flag['t']);
  190. icount+=2;
  191. break;
  192. case 'o': /* output file name */
  193. if (arg[2] != 0 || ++argn >= argc || outfilename != NUL_PTR)
  194. usage();
  195. outfilename = argv[argn];
  196. break;
  197. default:
  198. usage();
  199. }
  200. }
  201. if(icount==0) usage();
  202. #ifdef BUGCOMPAT
  203. if( icount==1 && ( flag['r'] && !flag['N'] ) ) {
  204. flag['r'] = 0;
  205. flag['B'] = 1;
  206. }
  207. #endif
  208. #ifdef REL_OUTPUT
  209. #ifndef MSDOS
  210. if( flag['r'] && !flag['N'] )
  211. {
  212. /* Do a relocatable link -- actually fake it with 'ar.c' */
  213. ld86r(argc, argv);
  214. }
  215. #endif
  216. #endif
  217. #ifdef MSDOS
  218. /* MSDOS Native is special, we make a COM file */
  219. if( flag['N'] )
  220. {
  221. flag['N'] = 0;
  222. flag['d'] = 1;
  223. text_base_value = 0x100;
  224. }
  225. #endif
  226. /* Headerless executables can't use symbols. */
  227. headerless = flag['d'];
  228. if( headerless ) flag['s'] = 1;
  229. #ifndef VERY_SMALL_MEMORY
  230. /* UNIX seventh edition executables */
  231. v7 = flag['7'];
  232. #endif
  233. #ifndef MSDOS
  234. /* CP/M-86 executables can't use symbols. */
  235. cpm86 = flag['c'];
  236. if ( cpm86 ) flag['s'] = 1;
  237. #endif
  238. linksyms(flag['r'] | flag['B']);
  239. if (outfilename == NUL_PTR)
  240. outfilename = "a.out";
  241. #ifndef MSDOS
  242. if( flag['N'] )
  243. writebin(outfilename, flag['i'], flag['3'], flag['s'],
  244. flag['z'] & flag['3']);
  245. else
  246. #endif
  247. if( flag['B'] )
  248. write_dosemu(outfilename, flag['i'], flag['3'], flag['s'],
  249. flag['z'] & flag['3']);
  250. else
  251. write_elks(outfilename, flag['i'], flag['3'], flag['s'],
  252. flag['z'], flag['y']);
  253. if (flag['m'])
  254. dumpmods();
  255. if (flag['M'])
  256. dumpsyms();
  257. flusherr();
  258. return errcount ? 1 : 0;
  259. }