+/* Return true iff target is the sought target. */
+
+static int
+get_target (target, data)
+ const bfd_target *target;
+ PTR data;
+{
+ const char *sought = (const char *) data;
+
+ return strcmp (target->name, sought) == 0;
+}
+
+/* Like strcpy() but convert to lower case as well. */
+
+static void
+stricpy (dest, src)
+ char *dest;
+ char *src;
+{
+ char c;
+
+ while ((c = *src++) != 0)
+ {
+ if (isupper ((unsigned char) c))
+ c = tolower (c);
+
+ *dest++ = c;
+ }
+
+ *dest = 0;
+}
+
+/* Remove the first occurance of needle (if any) in haystack
+ from haystack. */
+
+static void
+strcut (haystack, needle)
+ char *haystack;
+ char *needle;
+{
+ haystack = strstr (haystack, needle);
+
+ if (haystack)
+ {
+ char *src;
+
+ for (src = haystack + strlen (needle); *src;)
+ *haystack++ = *src++;
+
+ *haystack = 0;
+ }
+}
+
+/* Compare two target format name strings.
+ Return a value indicating how "similar" they are. */
+
+static int
+name_compare (first, second)
+ char *first;
+ char *second;
+{
+ char *copy1;
+ char *copy2;
+ int result;
+
+ copy1 = xmalloc (strlen (first) + 1);
+ copy2 = xmalloc (strlen (second) + 1);
+
+ /* Convert the names to lower case. */
+ stricpy (copy1, first);
+ stricpy (copy2, second);
+
+ /* Remove and endian strings from the name. */
+ strcut (copy1, "big");
+ strcut (copy1, "little");
+ strcut (copy2, "big");
+ strcut (copy2, "little");
+
+ /* Return a value based on how many characters match,
+ starting from the beginning. If both strings are
+ the same then return 10 * their length. */
+ for (result = 0; copy1[result] == copy2[result]; result++)
+ if (copy1[result] == 0)
+ {
+ result *= 10;
+ break;
+ }
+
+ free (copy1);
+ free (copy2);
+
+ return result;
+}
+
+/* Set by closest_target_match() below. */
+static const bfd_target *winner;
+
+/* Scan all the valid bfd targets looking for one that has the endianness
+ requirement that was specified on the command line, and is the nearest
+ match to the original output target. */
+
+static int
+closest_target_match (target, data)
+ const bfd_target *target;
+ PTR data;
+{
+ const bfd_target *original = (const bfd_target *) data;
+
+ if (command_line.endian == ENDIAN_BIG
+ && target->byteorder != BFD_ENDIAN_BIG)
+ return 0;
+
+ if (command_line.endian == ENDIAN_LITTLE
+ && target->byteorder != BFD_ENDIAN_LITTLE)
+ return 0;
+
+ /* Must be the same flavour. */
+ if (target->flavour != original->flavour)
+ return 0;
+
+ /* If we have not found a potential winner yet, then record this one. */
+ if (winner == NULL)
+ {
+ winner = target;
+ return 0;
+ }
+
+ /* Oh dear, we now have two potential candidates for a successful match.
+ Compare their names and choose the better one. */
+ if (name_compare (target->name, original->name)
+ > name_compare (winner->name, original->name))
+ winner = target;
+
+ /* Keep on searching until wqe have checked them all. */
+ return 0;
+}
+
+/* Return the BFD target format of the first input file. */
+
+static char *
+get_first_input_target ()
+{
+ char *target = NULL;
+
+ LANG_FOR_EACH_INPUT_STATEMENT (s)
+ {
+ if (s->header.type == lang_input_statement_enum
+ && s->real)
+ {
+ ldfile_open_file (s);
+
+ if (s->the_bfd != NULL
+ && bfd_check_format (s->the_bfd, bfd_object))
+ {
+ target = bfd_get_target (s->the_bfd);
+
+ if (target != NULL)
+ break;
+ }
+ }
+ }
+
+ return target;
+}
+