2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
16 #include "docommand.h"
21 #define EXTRA_ARG_CNT 2
24 #define EI_ABIVERSION 8
26 #define ELFOSABI_AROS 15
29 static char *ldscriptname
, *tempoutput
, *ld_name
, *strip_name
;
30 static FILE *ldscriptfile
;
32 static void exitfunc(void)
34 if (ldscriptfile
!= NULL
)
37 if (ldscriptname
!= NULL
)
40 if (tempoutput
!= NULL
)
44 static int set_os_and_abi(const char *file
)
47 const unsigned char osabi
= ELFOSABI_AROS
;
48 const unsigned char abiversion
= 1;
50 /* Modify OS and ABI fields */
52 f
= open(file
, O_RDWR
);
54 lseek(f
, EI_OSABI
, SEEK_SET
);
55 if (write(f
, &osabi
, 1) == 1) {
56 lseek(f
, EI_ABIVERSION
, SEEK_SET
);
57 if (write(f
, &abiversion
, 1) == 1) {
70 int main(int argc
, char *argv
[])
73 char *output
, **ldargs
;
74 /* incremental = 1 -> don't do final linking.
75 incremental = 2 -> don't do final linking AND STILL produce symbol sets. */
76 int incremental
= 0, ignore_undefined_symbols
= 0;
78 char *do_verbose
= NULL
;
80 setnode
*setlist
= NULL
, *liblist
= NULL
;
82 program_name
= argv
[0];
84 strip_name
= STRIP_NAME
;
86 /* Do some stuff with the arguments */
88 for (cnt
= 1; argv
[cnt
]; cnt
++)
90 /* We've encountered an option */
91 if (argv
[cnt
][0]=='-')
93 /* Get the output file name */
94 if (argv
[cnt
][1]=='o')
95 output
= argv
[cnt
][2]?&argv
[cnt
][2]:argv
[++cnt
];
97 /* Incremental linking is requested */
98 if ((argv
[cnt
][1]=='r' || argv
[cnt
][1]=='i') && argv
[cnt
][2]=='\0')
101 /* Incremental, but produce the symbol sets */
102 if (strncmp(&argv
[cnt
][1], "Ur", 3) == 0)
106 argv
[cnt
][1] = 'r'; /* Just some non-harming option... */
110 /* Ignoring of missing symbols is requested */
111 if (strncmp(&argv
[cnt
][1], "ius", 4) == 0)
113 ignore_undefined_symbols
= 1;
114 argv
[cnt
][1] = 'r'; /* Just some non-harming option... */
118 /* Complete stripping is requested, but we do it our own way */
119 if (argv
[cnt
][1]=='s' && argv
[cnt
][2]=='\0')
122 argv
[cnt
][1] = 'r'; /* Just some non-harming option... */
125 /* The user just requested help info, don't do anything else */
126 if (strncmp(&argv
[cnt
][1], "-help", 6) == 0)
128 /* I know, it's not incremental linking we're after, but the end result
135 if (strncmp(&argv
[cnt
][1], "-verbose", 9) == 0)
137 do_verbose
= argv
[cnt
];
143 ldargs
= xmalloc(sizeof(char *) * (argc
+ EXTRA_ARG_CNT
144 + ((incremental
== 1) ? 0 : 2) + 1));
147 ldargs
[1] = OBJECT_FORMAT
;
150 for (i
= 1; i
< argc
; i
++)
151 ldargs
[i
+ EXTRA_ARG_CNT
] = argv
[i
];
152 cnt
= argc
+ EXTRA_ARG_CNT
;
154 if (incremental
!= 1)
159 !(tempoutput
= make_temp_file(NULL
)) ||
160 !(ldscriptname
= make_temp_file(NULL
)) ||
161 !(ldscriptfile
= fopen(ldscriptname
, "w"))
164 fatal(ldscriptname
? ldscriptname
: "make_temp_file()", strerror(errno
));
167 ldargs
[cnt
++] = "-o";
168 ldargs
[cnt
++] = tempoutput
;
173 docommandvp(ld_name
, ldargs
);
175 if (incremental
== 1)
176 return set_os_and_abi(output
) ? EXIT_SUCCESS
: EXIT_FAILURE
;
178 collect_libs(tempoutput
, &liblist
);
179 collect_sets(tempoutput
, &setlist
);
183 for (n
= setlist
; n
; n
= n
->next
) {
184 if (strncmp(n
->secname
,".aros.set.",10) == 0) {
185 fprintf(ldscriptfile
, "EXTERN(__%s__symbol_set_handler_missing)\n", &n
->secname
[10]);
190 fwrite(LDSCRIPT_PART1
, sizeof(LDSCRIPT_PART1
) - 1, 1, ldscriptfile
);
191 emit_sets(setlist
, ldscriptfile
);
192 emit_libs(liblist
, ldscriptfile
);
193 fwrite(LDSCRIPT_PART2
, sizeof(LDSCRIPT_PART2
) - 1, 1, ldscriptfile
);
194 /* Append .eh_frame terminator only on final stage */
195 if (incremental
== 0)
196 fputs("LONG(0)\n", ldscriptfile
);
197 fwrite(LDSCRIPT_PART3
, sizeof(LDSCRIPT_PART3
) - 1, 1, ldscriptfile
);
198 fwrite(LDSCRIPT_PART4
, sizeof(LDSCRIPT_PART4
) - 1, 1, ldscriptfile
);
200 fclose(ldscriptfile
);
203 docommandlp(ld_name
, ld_name
, OBJECT_FORMAT
, "-r", "-o", output
,
204 tempoutput
, "-T", ldscriptname
, do_verbose
, NULL
);
206 if (incremental
!= 0)
207 return set_os_and_abi(output
) ? EXIT_SUCCESS
: EXIT_FAILURE
;
209 if (!ignore_undefined_symbols
&& check_and_print_undefined_symbols(output
))
219 docommandlp(strip_name
, strip_name
, "--strip-unneeded", output
, NULL
);
222 if (!set_os_and_abi(output
))