11 #include "docommand.h"
16 #define EXTRA_ARG_CNT 2
19 #define EI_ABIVERSION 8
21 #define ELFOSABI_AROS 15
24 static char *ldscriptname
, *tempoutput
, *ld_name
, *strip_name
;
25 static FILE *ldscriptfile
;
27 static void exitfunc(void)
29 if (ldscriptfile
!= NULL
)
32 if (ldscriptname
!= NULL
)
35 if (tempoutput
!= NULL
)
39 static int set_os_and_abi(const char *file
)
42 const unsigned char osabi
= ELFOSABI_AROS
;
43 const unsigned char abiversion
= 1;
45 /* Modify OS and ABI fields */
47 f
= open(file
, O_RDWR
);
49 lseek(f
, EI_OSABI
, SEEK_SET
);
50 if (write(f
, &osabi
, 1) == 1) {
51 lseek(f
, EI_ABIVERSION
, SEEK_SET
);
52 if (write(f
, &abiversion
, 1) == 1) {
65 int main(int argc
, char *argv
[])
68 char *output
, **ldargs
;
69 /* incremental = 1 -> don't do final linking.
70 incremental = 2 -> don't do final linking AND STILL produce symbol sets. */
71 int incremental
= 0, ignore_undefined_symbols
= 0;
73 char *do_verbose
= NULL
;
75 setnode
*setlist
= NULL
, *liblist
= NULL
;
77 program_name
= argv
[0];
79 strip_name
= STRIP_NAME
;
81 /* Do some stuff with the arguments */
83 for (cnt
= 1; argv
[cnt
]; cnt
++)
85 /* We've encountered an option */
86 if (argv
[cnt
][0]=='-')
88 /* Get the output file name */
89 if (argv
[cnt
][1]=='o')
90 output
= argv
[cnt
][2]?&argv
[cnt
][2]:argv
[++cnt
];
92 /* Incremental linking is requested */
93 if ((argv
[cnt
][1]=='r' || argv
[cnt
][1]=='i') && argv
[cnt
][2]=='\0')
96 /* Incremental, but produce the symbol sets */
97 if (strncmp(&argv
[cnt
][1], "Ur", 3) == 0)
101 argv
[cnt
][1] = 'r'; /* Just some non-harming option... */
105 /* Ignoring of missing symbols is requested */
106 if (strncmp(&argv
[cnt
][1], "ius", 4) == 0)
108 ignore_undefined_symbols
= 1;
109 argv
[cnt
][1] = 'r'; /* Just some non-harming option... */
113 /* Complete stripping is requested, but we do it our own way */
114 if (argv
[cnt
][1]=='s' && argv
[cnt
][2]=='\0')
117 argv
[cnt
][1] = 'r'; /* Just some non-harming option... */
120 /* The user just requested help info, don't do anything else */
121 if (strncmp(&argv
[cnt
][1], "-help", 6) == 0)
123 /* I know, it's not incremental linking we're after, but the end result
130 if (strncmp(&argv
[cnt
][1], "-verbose", 9) == 0)
132 do_verbose
= argv
[cnt
];
138 ldargs
= xmalloc(sizeof(char *) * (argc
+ EXTRA_ARG_CNT
139 + ((incremental
== 1) ? 0 : 2) + 1));
142 ldargs
[1] = OBJECT_FORMAT
;
145 for (i
= 1; i
< argc
; i
++)
146 ldargs
[i
+ EXTRA_ARG_CNT
] = argv
[i
];
147 cnt
= argc
+ EXTRA_ARG_CNT
;
149 if (incremental
!= 1)
154 !(tempoutput
= make_temp_file(NULL
)) ||
155 !(ldscriptname
= make_temp_file(NULL
)) ||
156 !(ldscriptfile
= fopen(ldscriptname
, "w"))
159 fatal(ldscriptname
? ldscriptname
: "make_temp_file()", strerror(errno
));
162 ldargs
[cnt
++] = "-o";
163 ldargs
[cnt
++] = tempoutput
;
168 docommandvp(ld_name
, ldargs
);
170 if (incremental
== 1)
171 return set_os_and_abi(output
) ? EXIT_SUCCESS
: EXIT_FAILURE
;
173 collect_libs(tempoutput
, &liblist
);
174 collect_sets(tempoutput
, &setlist
);
178 for (n
= setlist
; n
; n
= n
->next
) {
179 if (strncmp(n
->secname
,".aros.set.",10) == 0) {
180 fprintf(ldscriptfile
, "EXTERN(__%s__symbol_set_handler_missing)\n", &n
->secname
[10]);
185 fwrite(LDSCRIPT_PART1
, sizeof(LDSCRIPT_PART1
) - 1, 1, ldscriptfile
);
186 emit_sets(setlist
, ldscriptfile
);
187 emit_libs(liblist
, ldscriptfile
);
188 fwrite(LDSCRIPT_PART2
, sizeof(LDSCRIPT_PART2
) - 1, 1, ldscriptfile
);
189 /* Append .eh_frame terminator only on final stage */
190 if (incremental
== 0)
191 fputs("LONG(0)\n", ldscriptfile
);
192 fwrite(LDSCRIPT_PART3
, sizeof(LDSCRIPT_PART3
) - 1, 1, ldscriptfile
);
193 fwrite(LDSCRIPT_PART4
, sizeof(LDSCRIPT_PART4
) - 1, 1, ldscriptfile
);
195 fclose(ldscriptfile
);
198 docommandlp(ld_name
, ld_name
, OBJECT_FORMAT
, "-r", "-o", output
,
199 tempoutput
, "-T", ldscriptname
, do_verbose
, NULL
);
201 if (incremental
!= 0)
202 return set_os_and_abi(output
) ? EXIT_SUCCESS
: EXIT_FAILURE
;
204 if (!ignore_undefined_symbols
&& check_and_print_undefined_symbols(output
))
214 docommandlp(strip_name
, strip_name
, "--strip-unneeded", output
, NULL
);
217 if (!set_os_and_abi(output
))