Fixed size calculation of ldargs array allocation.
[AROS.git] / tools / collect-aros / collect-aros.c
blob0395cd3c8c654a3e5506612fb649bc2e3042f659
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #include <sys/stat.h>
7 #include "env.h"
8 #include "misc.h"
9 #include "docommand.h"
10 #include "backend.h"
11 #include "ldscript.h"
12 #include "gensets.h"
14 #define EXTRA_ARG_CNT 2
16 static char *ldscriptname, *tempoutput, *ld_name, *strip_name;
17 static FILE *ldscriptfile;
19 static void exitfunc(void)
21 if (ldscriptfile != NULL)
22 fclose(ldscriptfile);
24 if (ldscriptname != NULL)
25 remove(ldscriptname);
27 if (tempoutput != NULL)
28 remove(tempoutput);
31 int main(int argc, char *argv[])
33 int cnt, i;
34 char *output, **ldargs;
35 /* incremental = 1 -> don't do final linking.
36 incremental = 2 -> don't do final linking AND STILL produce symbol sets. */
37 int incremental = 0, ignore_undefined_symbols = 0;
38 int strip_all = 0;
39 char *do_verbose = NULL;
41 setnode *setlist = NULL;
43 program_name = argv[0];
44 ld_name = LD_NAME;
45 strip_name = STRIP_NAME;
47 /* Do some stuff with the arguments */
48 output = "a.out";
49 for (cnt = 1; argv[cnt]; cnt++)
51 /* We've encountered an option */
52 if (argv[cnt][0]=='-')
54 /* Get the output file name */
55 if (argv[cnt][1]=='o')
56 output = argv[cnt][2]?&argv[cnt][2]:argv[++cnt];
57 else
58 /* Incremental linking is requested */
59 if ((argv[cnt][1]=='r' || argv[cnt][1]=='i') && argv[cnt][2]=='\0')
60 incremental = 1;
61 else
62 /* Incremental, but produce the symbol sets */
63 if (strncmp(&argv[cnt][1], "Ur", 3) == 0)
65 incremental = 2;
67 argv[cnt][1] = 'r'; /* Just some non-harming option... */
68 argv[cnt][2] = '\0';
70 else
71 /* Ignoring of missing symbols is requested */
72 if (strncmp(&argv[cnt][1], "ius", 4) == 0)
74 ignore_undefined_symbols = 1;
75 argv[cnt][1] = 'r'; /* Just some non-harming option... */
76 argv[cnt][2] = '\0';
78 else
79 /* Complete stripping is requested, but we do it our own way */
80 if (argv[cnt][1]=='s' && argv[cnt][2]=='\0')
82 strip_all = 1;
83 argv[cnt][1] = 'r'; /* Just some non-harming option... */
85 else
86 /* The user just requested help info, don't do anything else */
87 if (strncmp(&argv[cnt][1], "-help", 6) == 0)
89 /* I know, it's not incremental linking we're after, but the end result
90 is the same */
91 incremental = 1;
92 break;
94 else
95 /* verbose output */
96 if (strncmp(&argv[cnt][1], "-verbose", 9) == 0)
98 do_verbose = argv[cnt];
99 break;
104 ldargs = xmalloc(sizeof(char *) * (argc + EXTRA_ARG_CNT
105 + ((incremental == 1) ? 0 : 2) + 1));
107 ldargs[0] = ld_name;
108 ldargs[1] = OBJECT_FORMAT;
109 ldargs[2] = "-r";
111 for (i = 1; i < argc; i++)
112 ldargs[i + EXTRA_ARG_CNT] = argv[i];
113 cnt = argc + EXTRA_ARG_CNT;
115 if (incremental != 1)
117 atexit(exitfunc);
120 !(tempoutput = make_temp_file(NULL)) ||
121 !(ldscriptname = make_temp_file(NULL)) ||
122 !(ldscriptfile = fopen(ldscriptname, "w"))
125 fatal(ldscriptname ? ldscriptname : "make_temp_file()", strerror(errno));
128 ldargs[cnt++] = "-o";
129 ldargs[cnt++] = tempoutput;
132 ldargs[cnt] = NULL;
134 docommandvp(ld_name, ldargs);
136 if (incremental == 1)
137 return EXIT_SUCCESS;
139 collect_sets(tempoutput, &setlist);
141 if (setlist != NULL)
142 fprintf(ldscriptfile, "EXTERN(__this_program_requires_symbol_sets_handling)\n");
144 fwrite(LDSCRIPT_PART1, sizeof(LDSCRIPT_PART1) - 1, 1, ldscriptfile);
145 emit_sets(setlist, ldscriptfile);
146 fwrite(LDSCRIPT_PART2, sizeof(LDSCRIPT_PART2) - 1, 1, ldscriptfile);
147 /* Append .eh_frame terminator only on final stage */
148 if (incremental == 0)
149 fputs("LONG(0)\n", ldscriptfile);
150 fwrite(LDSCRIPT_PART3, sizeof(LDSCRIPT_PART3) - 1, 1, ldscriptfile);
151 if (incremental == 0)
152 fputs("PROVIDE(SysBase = 0x515BA5E);\n", ldscriptfile);
153 fwrite(LDSCRIPT_PART4, sizeof(LDSCRIPT_PART4) - 1, 1, ldscriptfile);
155 fclose(ldscriptfile);
156 ldscriptfile = NULL;
158 docommandlp(ld_name, ld_name, OBJECT_FORMAT, "-r", "-o", output,
159 tempoutput, "-T", ldscriptname, do_verbose, NULL);
161 if (incremental != 0)
162 return EXIT_SUCCESS;
164 if (!ignore_undefined_symbols && check_and_print_undefined_symbols(output))
166 remove(output);
167 return EXIT_FAILURE;
170 chmod(output, 0766);
172 if (strip_all)
174 docommandlp(strip_name, strip_name, "--strip-unneeded", output, NULL);
177 return 0;