From d1778b88f8d8444f15ecf2dbbbf680c5659efb53 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 17 May 2001 03:58:45 +0000 Subject: [PATCH] Add a flag to asection, linker_has_input, and use it to reliably determine whether an input section is the first one assigned to an output section. --- bfd/ChangeLog | 7 +++++ bfd/bfd-in2.h | 4 +++ bfd/ecoff.c | 14 ++++++---- bfd/section.c | 15 +++++++--- ld/ChangeLog | 7 +++++ ld/ldlang.c | 89 +++++++++++++++++++++++++++++++++-------------------------- 6 files changed, 87 insertions(+), 49 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index b180d2e..85a6b13 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2001-05-16 Alan Modra + + * section.c (asection): Add linker_has_input field. + (STD_SECTION): Adjust initialization to suit. + * ecoff.c (bfd_debug_section): Likewise. + * bfd-in2.h: Regenerate. + 2001-05-15 Alexandre Oliva * elf-m10300.c (mn10300_elf_relax_section): Don't relax diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index bce9c0e..c94b097 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1127,6 +1127,10 @@ typedef struct sec /* A mark flag used by some of the linker backends. */ unsigned int linker_mark : 1; + /* Another mark flag used by some of the linker backends. Set for + output sections that have a input section. */ + unsigned int linker_has_input : 1; + /* A mark flag used by some linker backends for garbage collection. */ unsigned int gc_mark : 1; diff --git a/bfd/ecoff.c b/bfd/ecoff.c index 2237441..d05c15f 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -74,12 +74,14 @@ static unsigned int ecoff_armap_hash PARAMS ((CONST char *s, static asection bfd_debug_section = { - /* name, id, index, next, flags, user_set_vma, reloc_done, */ - "*DEBUG*", 0, 0, NULL, 0, 0, 0, - /* linker_mark, gc_mark, segment_mark, vma, lma, _cooked_size, */ - 0, 0, 0, 0, 0, 0, - /* _raw_size, output_offset, output_section, alignment_power, */ - 0, 0, NULL, 0, + /* name, id, index, next, flags, user_set_vma, reloc_done, */ + "*DEBUG*", 0, 0, NULL, 0, 0, 0, + /* linker_mark, linker_has_input, gc_mark, segment_mark, */ + 0, 0, 0, 0, + /* vma, lma, _cooked_size, _raw_size, */ + 0, 0, 0, 0, + /* output_offset, output_section, alignment_power, */ + 0, NULL, 0, /* relocation, orelocation, reloc_count, filepos, rel_filepos, */ NULL, NULL, 0, 0, 0, /* line_filepos, userdata, contents, lineno, lineno_count, */ diff --git a/bfd/section.c b/bfd/section.c index 623e8b6..ad90462 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -372,6 +372,10 @@ CODE_FRAGMENT . {* A mark flag used by some of the linker backends. *} . unsigned int linker_mark : 1; . +. {* Another mark flag used by some of the linker backends. Set for +. output sections that have a input section. *} +. unsigned int linker_has_input : 1; +. . {* A mark flag used by some linker backends for garbage collection. *} . unsigned int gc_mark : 1; . @@ -578,11 +582,14 @@ static const asymbol global_syms[] = /* name, id, index, next, flags, user_set_vma, reloc_done, */ \ { NAME, IDX, 0, NULL, FLAGS, 0, 0, \ \ - /* linker_mark, gc_mark, segment_mark, vma, lma, _cooked_size, */ \ - 0, 1, 0, 0, 0, 0, \ + /* linker_mark, linker_has_input, gc_mark, segment_mark, */ \ + 0, 0, 1, 0, \ + \ + /* vma, lma, _cooked_size, _raw_size, */ \ + 0, 0, 0, 0, \ \ - /* _raw_size, output_offset, output_section, alignment_power, */ \ - 0, 0, (struct sec *) &SEC, 0, \ + /* output_offset, output_section, alignment_power, */ \ + 0, (struct sec *) &SEC, 0, \ \ /* relocation, orelocation, reloc_count, filepos, rel_filepos, */ \ NULL, NULL, 0, 0, 0, \ diff --git a/ld/ChangeLog b/ld/ChangeLog index 60195f3..61dc757 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +2001-05-16 Alan Modra + + * ldlang.c (wild_doit): Use linker_has_input to reliably determine + whether an input section is the first one assigned to an output + section. + Assorted formatting fixes. + 2001-05-14 DJ Delorie * Makefile.am (ld.dvi): Search bfd/doc for texinfo files. diff --git a/ld/ldlang.c b/ld/ldlang.c index 6aea882..3ef9e51 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -42,9 +42,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include /* 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; @@ -192,18 +191,22 @@ struct unique_sections *unique_section_list; 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) @@ -245,14 +248,16 @@ walk_wild_section (ptr, section, file, callback, data) 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; @@ -275,9 +280,9 @@ walk_wild_section (ptr, section, file, callback, data) 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. */ @@ -450,7 +455,7 @@ new_statement (type, size, list) 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 * @@ -1136,12 +1141,10 @@ wild_doit (ptr, section, output, file) 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); @@ -1690,7 +1693,8 @@ closest_target_match (target, data) /* 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. */ @@ -1786,7 +1790,8 @@ open_output (name) /* 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. */ @@ -1924,9 +1929,9 @@ open_input_bfds (s, force) bfd_archive)) s->input_statement.loaded = false; - lang_list_init (& add); + lang_list_init (&add); - /* We need to know if an error occurs whilst loading the + /* 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); @@ -2687,8 +2692,10 @@ size_input_section (this_ptr, output_section_statement, fill, dot, relax) } #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. */ @@ -2699,7 +2706,6 @@ lang_check_section_addresses () 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) { @@ -2810,8 +2816,9 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) 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; @@ -2866,10 +2873,12 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) && ! 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; @@ -2878,7 +2887,8 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) 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"), @@ -3195,9 +3205,9 @@ lang_do_assignments (s, output_section_statement, fill, dot) 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; @@ -3370,8 +3380,10 @@ lang_set_startof () 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; @@ -3458,7 +3470,6 @@ lang_finish () } } - /* This is the routine to handle BFD error messages. */ #ifdef ANSI_PROTOTYPES @@ -3505,6 +3516,7 @@ record_bfd_errors (va_alist) } #endif /* ! defined (ANSI_PROTOTYPES) */ + /* This is a small function used when we want to ignore errors from BFD. */ @@ -4257,8 +4269,9 @@ lang_section_start (name, address) 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; } @@ -4651,9 +4664,7 @@ lang_record_phdrs () 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")); } -- 2.7.4