1 /* ld.c - linker for Introl format (6809 C) object files 6809/8086/80386 */
3 /* Copyright (C) 1994 Bruce Evans */
13 #define MAX_LIBS (NR_STDLIBS + 5)
20 PUBLIC bin_off_t text_base_value
= 0; /* XXX */
21 PUBLIC bin_off_t data_base_value
= 0; /* XXX */
22 PUBLIC bin_off_t heap_top_value
= 0; /* XXX */
23 PUBLIC
int headerless
= 0;
27 PUBLIC
char hexdigit
[] = "0123456789abcdef";
29 PRIVATE bool_t flag
[128];
30 PRIVATE
char *libs
[MAX_LIBS
] = {
32 "/usr/local/lib/m09/",
36 PRIVATE
int lastlib
= NR_STDLIBS
;
38 FORWARD
char *buildname
P((char *pre
, char *mid
, char *suf
));
39 FORWARD
char *expandlib
P((char *fn
));
41 PRIVATE
char *buildname(pre
, mid
, suf
)
48 name
= ourmalloc(strlen(pre
) + strlen(mid
) + strlen(suf
) + 1);
55 PRIVATE
char *expandlib(fn
)
61 for (i
= lastlib
- 1; i
>= 0; --i
)
63 path
= ourmalloc(strlen(libs
[i
]) + strlen(fn
) + 2);
64 strcpy(path
, libs
[i
]);
65 s
= path
+ strlen(path
);
66 if (s
!=path
&& s
[-1] != '/') strcat(path
, "/");
68 if (access(path
, R_OK
) == 0)
75 PUBLIC
int main(argc
, argv
)
81 static char crtprefix
[] = "crt";
82 static char crtsuffix
[] = ".o";
84 static char libprefix
[] = "lib";
85 static char libsuffix
[] = ".a";
93 typeconv_init(INT_BIG_ENDIAN
, LONG_BIG_ENDIAN
);
95 flag
['3'] = sizeof(char *) >= 4;
97 outfilename
= NUL_PTR
;
98 for (argn
= 1; argn
< argc
; ++argn
)
103 readsyms(arg
, flag
['t']);
111 case 'r': /* relocatable output */
112 case 't': /* trace modules linked */
113 if (icount
> 0) usage();
115 case 'B': /* Broken -r for dosemu. */
117 case '0': /* use 16-bit libraries */
118 case '3': /* use 32-bit libraries */
119 case 'M': /* print symbols linked */
120 case 'i': /* separate I & D output */
121 case 'm': /* print modules linked */
122 case 's': /* strip symbols */
123 case 'z': /* unmapped zero page */
124 case 'N': /* Native format a.out */
125 case 'd': /* Make a headerless outfile */
127 case 'c': /* Write header in CP/M-86 format */
129 case 'y': /* Use a newer symbol table */
131 flag
[(int) arg
[1]] = TRUE
;
132 else if (arg
[2] == '-' && arg
[3] == 0)
133 flag
[(int) arg
[1]] = FALSE
;
136 if (arg
[1] == '0') /* flag 0 is negative logic flag 3 */
137 flag
['3'] = !flag
['0'];
139 case 'C': /* startfile name */
140 tfn
= buildname(crtprefix
, arg
+ 2, crtsuffix
);
141 if ((infilename
= expandlib(tfn
)) == NUL_PTR
)
143 /*fatalerror(tfn); * XXX - need to describe failure */
144 readsyms(infilename
, flag
['t']);
147 case 'L': /* library path */
148 if (lastlib
< MAX_LIBS
)
149 libs
[lastlib
++] = arg
+ 2;
151 fatalerror("too many library paths");
153 case 'O': /* library file name */
154 if ((infilename
= expandlib(arg
+ 2)) == NUL_PTR
)
156 /* fatalerror(arg); * XXX */
157 readsyms(infilename
, flag
['t']);
159 case 'T': /* text base address */
160 if (arg
[2] == 0 && ++argn
>= argc
)
164 text_base_value
= strtoul(argv
[argn
], (char **)0, 16);
166 text_base_value
= strtoul(arg
+2, (char **)0, 16);
168 use_error("invalid text address");
170 case 'D': /* data base address */
171 if (arg
[2] == 0 && ++argn
>= argc
)
175 data_base_value
= strtoul(argv
[argn
], (char **)0, 16);
177 data_base_value
= strtoul(arg
+2, (char **)0, 16);
179 use_error("invalid data address");
181 case 'H': /* heap top address */
182 if (arg
[2] == 0 && ++argn
>= argc
)
186 heap_top_value
= strtoul(argv
[argn
], (char **)0, 16);
188 heap_top_value
= strtoul(arg
+2, (char **)0, 16);
190 use_error("invalid heap top");
192 case 'l': /* library name */
193 tfn
= buildname(libprefix
, arg
+ 2, libsuffix
);
194 if ((infilename
= expandlib(tfn
)) == NUL_PTR
)
196 /* fatalerror(tfn); * XXX */
197 readsyms(infilename
, flag
['t']);
200 case 'o': /* output file name */
201 if (arg
[2] != 0 || ++argn
>= argc
|| outfilename
!= NUL_PTR
)
203 outfilename
= argv
[argn
];
209 if(icount
==0) usage();
212 if( icount
==1 && ( flag
['r'] && !flag
['N'] ) ) {
220 if( flag
['r'] && !flag
['N'] )
222 /* Do a relocatable link -- actually fake it with 'ar.c' */
229 /* MSDOS Native is special, we make a COM file */
234 text_base_value
= 0x100;
238 /* Headerless executables can't use symbols. */
239 headerless
= flag
['d'];
240 if( headerless
) flag
['s'] = 1;
243 /* CP/M-86 executables can't use symbols. */
245 if ( cpm86
) flag
['s'] = 1;
248 linksyms(flag
['r'] | flag
['B']);
249 if (outfilename
== NUL_PTR
)
250 outfilename
= "a.out";
253 writebin(outfilename
, flag
['i'], flag
['3'], flag
['s'],
254 flag
['z'] & flag
['3']);
258 write_dosemu(outfilename
, flag
['i'], flag
['3'], flag
['s'],
259 flag
['z'] & flag
['3']);
261 write_elks(outfilename
, flag
['i'], flag
['3'], flag
['s'],
262 flag
['z'], flag
['y']);
268 return errcount
? 1 : 0;