#include <ctype.h>
/* FORWARDS */
-static lang_statement_union_type *new_statement PARAMS ((enum statement_enum,
- size_t,
- lang_statement_list_type *));
+static lang_statement_union_type *new_statement
+ PARAMS ((enum statement_enum, size_t, lang_statement_list_type *));
/* LOCALS */
static struct obstack stat_obstack;
PARAMS ((lang_wild_statement_type *, asection *,
lang_input_statement_type *, PTR));
static lang_input_statement_type *lookup_name PARAMS ((const char *));
-static void load_symbols
+static boolean load_symbols
PARAMS ((lang_input_statement_type *, lang_statement_list_type *));
static void wild
PARAMS ((lang_wild_statement_type *, const char *, const char *,
fill_type, bfd_vma, boolean));
static void lang_finish PARAMS ((void));
static void ignore_bfd_errors PARAMS ((const char *, ...));
-static void record_bfd_errors PARAMS ((const char *, ...));
static void lang_check PARAMS ((void));
static void lang_common PARAMS ((void));
static boolean lang_one_common PARAMS ((struct bfd_link_hash_entry *, PTR));
etree_type *base; /* Relocation base - or null */
-#if defined(__STDC__) || defined(ALMOST_STDC)
+#if defined (__STDC__) || defined (ALMOST_STDC)
#define cat(a,b) a##b
#else
#define cat(a,b) a/**/b
#endif
-/* Don't beautify the line below with "innocent" whitespace, it breaks the K&R C preprocessor! */
-#define new_stat(x, y) (cat (x,_type)*) new_statement (cat (x,_enum), sizeof (cat (x,_type)), y)
+/* Don't beautify the line below with "innocent" whitespace, it breaks
+ the K&R C preprocessor! */
+#define new_stat(x, y) \
+ (cat (x,_type)*) new_statement (cat (x,_enum), sizeof (cat (x,_type)), y)
-#define outside_section_address(q) ((q)->output_offset + (q)->output_section->vma)
+#define outside_section_address(q) \
+ ((q)->output_offset + (q)->output_section->vma)
-#define outside_symbol_address(q) ((q)->value + outside_section_address (q->section))
+#define outside_symbol_address(q) \
+ ((q)->value + outside_section_address (q->section))
#define SECTION_NAME_MAP_LENGTH (16)
if (ptr->exclude_filename_list != NULL)
{
struct name_list *list_tmp;
- for (list_tmp = ptr->exclude_filename_list; list_tmp; list_tmp = list_tmp->next)
+ for (list_tmp = ptr->exclude_filename_list;
+ list_tmp;
+ list_tmp = list_tmp->next)
{
boolean match;
if (wildcardp (list_tmp->name))
- match = fnmatch (list_tmp->name, file->filename, 0) == 0 ? true : false;
+ match = fnmatch (list_tmp->name, file->filename, 0) == 0;
else
- match = strcmp (list_tmp->name, file->filename) == 0 ? true : false;
+ match = strcmp (list_tmp->name, file->filename) == 0;
if (match)
return;
if (section == NULL)
match = true;
else if (wildcard)
- match = fnmatch (section, sname, 0) == 0 ? true : false;
+ match = fnmatch (section, sname, 0) == 0;
else
- match = strcmp (section, sname) == 0 ? true : false;
+ match = strcmp (section, sname) == 0;
/* If this is a wild-card output section statement, exclude
sections that match UNIQUE_SECTION_LIST. */
/* Perform the iteration over a single file. */
f = lookup_name (file);
- walk_wild_file (s, section, f, callback, data);
+ if (f)
+ walk_wild_file (s, section, f, callback, data);
}
}
We can be supplied with requests for input files more than once;
they may, for example be split over serveral lines like foo.o(.text)
- foo.o(.data) etc, so when asked for a file we check that we havn't
+ foo.o(.data) etc, so when asked for a file we check that we haven't
got it already so we don't duplicate the bfd. */
static lang_input_statement_type *
return;
if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
- einfo (_("%P%F: Illegal use of `%s' section"), DISCARD_SECTION_NAME);
+ einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
new = ((section_userdata_type *)
stat_alloc (sizeof (section_userdata_type)));
flagword flags;
if (output->bfd_section == NULL)
- {
- init_os (output);
- first = true;
- }
- else
- first = false;
+ init_os (output);
+
+ first = ! output->bfd_section->linker_has_input;
+ output->bfd_section->linker_has_input = 1;
/* Add a section reference to the list. */
new = new_stat (lang_input_section, ptr);
|| search->filename == (const char *) NULL)
return search;
- load_symbols (search, (lang_statement_list_type *) NULL);
+ if (! load_symbols (search, (lang_statement_list_type *) NULL))
+ return NULL;
return search;
}
/* Get the symbols for an input file. */
-static void
+static boolean
load_symbols (entry, place)
lang_input_statement_type *entry;
lang_statement_list_type *place;
char **matching;
if (entry->loaded)
- return;
+ return true;
ldfile_open_file (entry);
{
bfd_error_type err;
lang_statement_list_type *hold;
-
+ boolean bad_load = true;
+
err = bfd_get_error ();
/* See if the emulation has some special knowledge. */
if (ldemul_unrecognized_file (entry))
- return;
+ return true;
if (err == bfd_error_file_ambiguously_recognized)
{
}
else if (err != bfd_error_file_not_recognized
|| place == NULL)
- einfo (_("%F%B: file not recognized: %E\n"), entry->the_bfd);
-
+ einfo (_("%F%B: file not recognized: %E\n"), entry->the_bfd);
+ else
+ bad_load = false;
+
bfd_close (entry->the_bfd);
entry->the_bfd = NULL;
stat_ptr = hold;
- return;
+ return ! bad_load;
}
if (ldemul_recognized_file (entry))
- return;
+ return true;
/* We don't call ldlang_add_file for an archive. Instead, the
add_symbols entry point will call ldlang_add_file, via the
case bfd_archive:
if (entry->whole_archive)
{
- bfd *member = bfd_openr_next_archived_file (entry->the_bfd,
- (bfd *) NULL);
- while (member != NULL)
+ bfd * member = NULL;
+ boolean loaded = true;
+
+ for (;;)
{
+ member = bfd_openr_next_archived_file (entry->the_bfd, member);
+
+ if (member == NULL)
+ break;
+
if (! bfd_check_format (member, bfd_object))
- einfo (_("%F%B: object %B in archive is not object\n"),
- entry->the_bfd, member);
+ {
+ einfo (_("%F%B: member %B in archive is not an object\n"),
+ entry->the_bfd, member);
+ loaded = false;
+ }
+
if (! ((*link_info.callbacks->add_archive_element)
(&link_info, member, "--whole-archive")))
abort ();
+
if (! bfd_link_add_symbols (member, &link_info))
- einfo (_("%F%B: could not read symbols: %E\n"), member);
- member = bfd_openr_next_archived_file (entry->the_bfd,
- member);
+ {
+ einfo (_("%F%B: could not read symbols: %E\n"), member);
+ loaded = false;
+ }
}
- entry->loaded = true;
-
- return;
+ entry->loaded = loaded;
+ return loaded;
}
+ break;
}
- if (! bfd_link_add_symbols (entry->the_bfd, &link_info))
+ if (bfd_link_add_symbols (entry->the_bfd, &link_info))
+ entry->loaded = true;
+ else
einfo (_("%F%B: could not read symbols: %E\n"), entry->the_bfd);
- entry->loaded = true;
+ return entry->loaded;
}
/* Handle a wild statement. SECTION or FILE or both may be NULL,
/* 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))
+ if (name_compare (target->name, original->name)
+ > name_compare (winner->name, original->name))
winner = target;
/* Keep on searching until wqe have checked them all. */
/* Try to find a target as similar as possible to
the default target, but which has the desired
endian characteristic. */
- (void) bfd_search_for_target (closest_target_match, (PTR) target);
+ (void) bfd_search_for_target (closest_target_match,
+ (PTR) target);
/* Oh dear - we could not find any targets that
satisfy our requirements. */
if (s->input_statement.real)
{
lang_statement_list_type add;
- bfd_error_handler_type pfn;
s->input_statement.target = current_target;
bfd_archive))
s->input_statement.loaded = false;
- lang_list_init (& add);
-
- /* We need to know if an error occurs whilst loading the
- symbols, since this means that a valid executable can
- not be produced. */
- pfn = bfd_set_error_handler (record_bfd_errors);
+ lang_list_init (&add);
- load_symbols (&s->input_statement, &add);
-
- bfd_set_error_handler (pfn);
+ if (! load_symbols (&s->input_statement, &add))
+ config.make_executable = false;
if (add.head != NULL)
{
}
#define IGNORE_SECTION(bfd, s) \
- (((bfd_get_section_flags (bfd, s) & (SEC_ALLOC | SEC_LOAD)) != (SEC_ALLOC | SEC_LOAD)) \
+ (((bfd_get_section_flags (bfd, s) & (SEC_ALLOC | SEC_LOAD)) \
+ != (SEC_ALLOC | SEC_LOAD)) \
|| bfd_section_size (bfd, s) == 0)
+
/* Check to see if any allocated sections overlap with other allocated
sections. This can happen when the linker script specifically specifies
the output section addresses of the two sections. */
asection *s;
unsigned opb = bfd_octets_per_byte (output_bfd);
-
/* Scan all sections in the output list. */
for (s = output_bfd->sections; s != NULL; s = s->next)
{
case lang_output_section_statement_enum:
{
bfd_vma after;
- lang_output_section_statement_type *os = &s->output_section_statement;
+ lang_output_section_statement_type *os;
+ os = &s->output_section_statement;
if (os->bfd_section == NULL)
/* This section was never actually created. */
break;
&& ! link_info.relocateable
&& strcmp (os->region->name, "*default*") == 0
&& lang_memory_region_list != NULL
- && (strcmp (lang_memory_region_list->name, "*default*") != 0
+ && (strcmp (lang_memory_region_list->name,
+ "*default*") != 0
|| lang_memory_region_list->next != NULL))
einfo (_("%P: warning: no memory region specified for section `%s'\n"),
- bfd_get_section_name (output_bfd, os->bfd_section));
+ bfd_get_section_name (output_bfd,
+ os->bfd_section));
dot = os->region->current;
bfd_vma olddot;
olddot = dot;
- dot = align_power (dot, os->bfd_section->alignment_power);
+ dot = align_power (dot,
+ os->bfd_section->alignment_power);
if (dot != olddot && config.warn_section_align)
einfo (_("%P: warning: changing start of section %s by %u bytes\n"),
case lang_output_section_statement_enum:
{
- lang_output_section_statement_type *os =
- &(s->output_section_statement);
+ lang_output_section_statement_type *os;
+ os = &(s->output_section_statement);
if (os->bfd_section != NULL)
{
dot = os->bfd_section->vma;
h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true);
if (h != NULL && h->type == bfd_link_hash_undefined)
{
- unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
- ldfile_output_machine);
+ unsigned opb;
+
+ opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
+ ldfile_output_machine);
h->type = bfd_link_hash_defined;
if (s->_cooked_size != 0)
h->u.def.value = s->_cooked_size / opb;
}
}
-
-/* This is the routine to handle BFD error messages. */
-
-#ifdef ANSI_PROTOTYPES
-
-static void
-record_bfd_errors (const char *s, ...)
-{
- va_list p;
-
- einfo ("%P: ");
-
- va_start (p, s);
-
- vfprintf (stderr, s, p);
-
- va_end (p);
-
- fprintf (stderr, "\n");
-
- einfo ("%X");
-}
-
-#else /* ! defined (ANSI_PROTOTYPES) */
-
-static void
-record_bfd_errors (va_alist)
- va_dcl
-{
- va_list p;
- const char *s;
-
- einfo ("%P: ");
-
- va_start (p);
-
- s = va_arg (p, const char *);
- vfprintf (stderr, s, p);
-
- va_end (p);
-
- fprintf (stderr, "\n");
-
- einfo ("%X");
-}
-
-#endif /* ! defined (ANSI_PROTOTYPES) */
/* This is a small function used when we want to ignore errors from
BFD. */
bfd_printable_name (input_bfd), input_bfd,
bfd_printable_name (output_bfd));
}
+ else if (link_info.relocateable
+ /* In general it is not possible to perform a relocatable
+ link between differing object formats when the input
+ file has relocations, because the relocations in the
+ input format may not have equivalent representations in
+ the output format (and besides BFD does not translate
+ relocs for other link purposes than a final link). */
+ && bfd_get_flavour (input_bfd) != bfd_get_flavour (output_bfd)
+ && (bfd_get_file_flags (input_bfd) & HAS_RELOC) != 0)
+ einfo (_("%P%F: Relocatable linking with relocations from format %s (%B) to format %s (%B) is not supported\n"),
+ bfd_get_target (input_bfd), input_bfd,
+ bfd_get_target (output_bfd), output_bfd);
else if (bfd_count_sections (input_bfd))
{
/* If the input bfd has no contents, it shouldn't set the
const char *name;
etree_type *address;
{
- lang_address_statement_type *ad = new_stat (lang_address_statement, stat_ptr);
+ lang_address_statement_type *ad;
+ ad = new_stat (lang_address_statement, stat_ptr);
ad->section_name = name;
ad->address = address;
}
lang_final_phase_enum);
if (! bfd_record_phdr (output_bfd, l->type,
- l->flags == NULL ? false : true,
- flags,
- l->at == NULL ? false : true,
+ l->flags != NULL, flags, l->at != NULL,
at, l->filehdr, l->phdrs, c, secs))
einfo (_("%F%P: bfd_record_phdr failed: %E\n"));
}
const char *lma_memspec;
{
lang_memory_region_type *region;
+ lang_memory_region_type * default_region;
lang_memory_region_type *lma_region;
struct overlay_list *l;
struct lang_nocrossref *nocrossref;
+ default_region = lang_memory_region_lookup ("*default*");
+
if (memspec == NULL)
region = NULL;
else
if (fill != 0 && l->os->fill == 0)
l->os->fill = fill;
- if (region != NULL && l->os->region == NULL)
+
+ /* Assign a region to the sections, if one has been specified.
+ Override the assignment of the default section, but not
+ other sections. */
+ if (region != NULL &&
+ (l->os->region == NULL ||
+ l->os->region == default_region))
l->os->region = region;
+
/* We only set lma_region for the first overlay section, as
subsequent overlay sections will have load_base set relative
to the first section. Also, don't set lma_region if
if (lma_region != NULL && l->os->lma_region == NULL
&& l->next == NULL && l->os->load_base == NULL)
l->os->lma_region = lma_region;
+
if (phdrs != NULL && l->os->phdrs == NULL)
l->os->phdrs = phdrs;
len = bfd_section_size (is->the_bfd, sec);
contents = xmalloc (len);
if (!bfd_get_section_contents (is->the_bfd, sec, contents, 0, len))
- einfo (_("%X%P: unable to read .exports section contents"), sec);
+ einfo (_("%X%P: unable to read .exports section contents\n"), sec);
p = contents;
while (p < contents + len)