+
+ /* Executables and shared objects must always have .text, .data
+ and .bss output sections, so that the header can refer to them.
+ The kernel refuses to load objects that have missing sections. */
+ if (!bfd_link_relocatable (&link_info))
+ for (i = 0; i < ARRAY_SIZE (must_keep_sections); i++)
+ {
+ asection *sec;
+
+ sec = bfd_get_section_by_name (link_info.output_bfd,
+ must_keep_sections[i]);
+ if (sec == NULL)
+ einfo ("%P: can't find required output section %s\n", must_keep_sections[i]);
+ else
+ sec->flags |= SEC_KEEP;
+ }
+
+ before_allocation_default ();
+}
+
+static char *
+gld${EMULATION_NAME}_choose_target (int argc, char **argv)
+{
+ int i, j, jmax;
+ static char *from_outside;
+ static char *from_inside;
+ static char *argv_to_target[][2] = {
+ {NULL, "${OUTPUT_FORMAT}"},
+ {"-b32", "${OUTPUT_FORMAT_32BIT}"},
+ {"-b64", "${OUTPUT_FORMAT_64BIT}"},
+ };
+
+ jmax = 3;
+
+ from_outside = getenv (TARGET_ENVIRON);
+ if (from_outside != (char *) NULL)
+ return from_outside;
+
+ /* Set to default. */
+ from_inside = argv_to_target[0][1];
+ for (i = 1; i < argc; i++)
+ {
+ for (j = 1; j < jmax; j++)
+ {
+ if (0 == strcmp (argv[i], argv_to_target[j][0]))
+ from_inside = argv_to_target[j][1];
+ }
+ }
+
+ return from_inside;
+}
+
+/* Returns
+ 1 : state changed
+ 0 : no change */
+static int
+change_symbol_mode (char *input)
+{
+ char *symbol_mode_string[] = {
+ "# 32", /* 0x01 */
+ "# 64", /* 0x02 */
+ "# no32", /* 0x04 */
+ "# no64", /* 0x08 */
+ NULL,
+ };
+
+ unsigned int bit;
+ char *string;
+
+ for (bit = 0;; bit++)
+ {
+ string = symbol_mode_string[bit];
+ if (string == NULL)
+ return 0;
+
+ if (0 == strcmp (input, string))
+ {
+ symbol_mode = (1 << bit);
+ return 1;
+ }
+ }
+ /* should not be here */
+ return 0;
+}
+
+/* Returns
+ 1 : yes
+ 0 : ignore
+ -1 : error, try something else */
+static int
+is_syscall (char *input, unsigned int *flag)
+{
+ unsigned int bit;
+ char *string;
+
+ struct sc {
+ char *syscall_string;
+ unsigned int flag;
+ } s [] = {
+ { "svc" /* 0x01 */, XCOFF_SYSCALL32 },
+ { "svc32" /* 0x02 */, XCOFF_SYSCALL32 },
+ { "svc3264" /* 0x04 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 },
+ { "svc64" /* 0x08 */, XCOFF_SYSCALL64 },
+ { "syscall" /* 0x10 */, XCOFF_SYSCALL32 },
+ { "syscall32" /* 0x20 */, XCOFF_SYSCALL32 },
+ { "syscall3264" /* 0x40 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 },
+ { "syscall64" /* 0x80 */, XCOFF_SYSCALL64 },
+ { NULL, 0 },
+ };
+
+ *flag = 0;
+
+ for (bit = 0;; bit++)
+ {
+ string = s[bit].syscall_string;
+ if (string == NULL)
+ return -1;
+
+ if (0 == strcmp (input, string))
+ {
+ if (1 << bit & syscall_mask)
+ {
+ *flag = s[bit].flag;
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+ /* should not be here */
+ return -1;