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.
This commit is contained in:
Alan Modra
2001-05-17 03:58:45 +00:00
parent aaa4f6d96f
commit d1778b88f8
6 changed files with 87 additions and 49 deletions

View File

@ -1,3 +1,10 @@
2001-05-16 Alan Modra <amodra@one.net.au>
* 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 <aoliva@redhat.com> 2001-05-15 Alexandre Oliva <aoliva@redhat.com>
* elf-m10300.c (mn10300_elf_relax_section): Don't relax * elf-m10300.c (mn10300_elf_relax_section): Don't relax

View File

@ -1127,6 +1127,10 @@ typedef struct sec
/* A mark flag used by some of the linker backends. */ /* A mark flag used by some of the linker backends. */
unsigned int linker_mark : 1; 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. */ /* A mark flag used by some linker backends for garbage collection. */
unsigned int gc_mark : 1; unsigned int gc_mark : 1;

View File

@ -76,10 +76,12 @@ static asection bfd_debug_section =
{ {
/* name, id, index, next, flags, user_set_vma, reloc_done, */ /* name, id, index, next, flags, user_set_vma, reloc_done, */
"*DEBUG*", 0, 0, NULL, 0, 0, 0, "*DEBUG*", 0, 0, NULL, 0, 0, 0,
/* linker_mark, gc_mark, segment_mark, vma, lma, _cooked_size, */ /* linker_mark, linker_has_input, gc_mark, segment_mark, */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* _raw_size, output_offset, output_section, alignment_power, */ /* vma, lma, _cooked_size, _raw_size, */
0, 0, NULL, 0, 0, 0, 0, 0,
/* output_offset, output_section, alignment_power, */
0, NULL, 0,
/* relocation, orelocation, reloc_count, filepos, rel_filepos, */ /* relocation, orelocation, reloc_count, filepos, rel_filepos, */
NULL, NULL, 0, 0, 0, NULL, NULL, 0, 0, 0,
/* line_filepos, userdata, contents, lineno, lineno_count, */ /* line_filepos, userdata, contents, lineno, lineno_count, */

View File

@ -372,6 +372,10 @@ CODE_FRAGMENT
. {* A mark flag used by some of the linker backends. *} . {* A mark flag used by some of the linker backends. *}
. unsigned int linker_mark : 1; . 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. *} . {* A mark flag used by some linker backends for garbage collection. *}
. unsigned int gc_mark : 1; . 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, id, index, next, flags, user_set_vma, reloc_done, */ \
{ NAME, IDX, 0, NULL, FLAGS, 0, 0, \ { NAME, IDX, 0, NULL, FLAGS, 0, 0, \
\ \
/* linker_mark, gc_mark, segment_mark, vma, lma, _cooked_size, */ \ /* linker_mark, linker_has_input, gc_mark, segment_mark, */ \
0, 1, 0, 0, 0, 0, \ 0, 0, 1, 0, \
\ \
/* _raw_size, output_offset, output_section, alignment_power, */ \ /* vma, lma, _cooked_size, _raw_size, */ \
0, 0, (struct sec *) &SEC, 0, \ 0, 0, 0, 0, \
\
/* output_offset, output_section, alignment_power, */ \
0, (struct sec *) &SEC, 0, \
\ \
/* relocation, orelocation, reloc_count, filepos, rel_filepos, */ \ /* relocation, orelocation, reloc_count, filepos, rel_filepos, */ \
NULL, NULL, 0, 0, 0, \ NULL, NULL, 0, 0, 0, \

View File

@ -1,3 +1,10 @@
2001-05-16 Alan Modra <amodra@one.net.au>
* 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 <dj@delorie.com> 2001-05-14 DJ Delorie <dj@delorie.com>
* Makefile.am (ld.dvi): Search bfd/doc for texinfo files. * Makefile.am (ld.dvi): Search bfd/doc for texinfo files.

View File

@ -42,9 +42,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include <ctype.h> #include <ctype.h>
/* FORWARDS */ /* FORWARDS */
static lang_statement_union_type *new_statement PARAMS ((enum statement_enum, static lang_statement_union_type *new_statement
size_t, PARAMS ((enum statement_enum, size_t, lang_statement_list_type *));
lang_statement_list_type *));
/* LOCALS */ /* LOCALS */
static struct obstack stat_obstack; static struct obstack stat_obstack;
@ -192,18 +191,22 @@ struct unique_sections *unique_section_list;
etree_type *base; /* Relocation base - or null */ 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 #define cat(a,b) a##b
#else #else
#define cat(a,b) a/**/b #define cat(a,b) a/**/b
#endif #endif
/* Don't beautify the line below with "innocent" whitespace, it breaks the K&R C preprocessor! */ /* Don't beautify the line below with "innocent" whitespace, it breaks
#define new_stat(x, y) (cat (x,_type)*) new_statement (cat (x,_enum), sizeof (cat (x,_type)), y) 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) #define SECTION_NAME_MAP_LENGTH (16)
@ -245,14 +248,16 @@ walk_wild_section (ptr, section, file, callback, data)
if (ptr->exclude_filename_list != NULL) if (ptr->exclude_filename_list != NULL)
{ {
struct name_list *list_tmp; 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; boolean match;
if (wildcardp (list_tmp->name)) 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 else
match = strcmp (list_tmp->name, file->filename) == 0 ? true : false; match = strcmp (list_tmp->name, file->filename) == 0;
if (match) if (match)
return; return;
@ -275,9 +280,9 @@ walk_wild_section (ptr, section, file, callback, data)
if (section == NULL) if (section == NULL)
match = true; match = true;
else if (wildcard) else if (wildcard)
match = fnmatch (section, sname, 0) == 0 ? true : false; match = fnmatch (section, sname, 0) == 0;
else else
match = strcmp (section, sname) == 0 ? true : false; match = strcmp (section, sname) == 0;
/* If this is a wild-card output section statement, exclude /* If this is a wild-card output section statement, exclude
sections that match UNIQUE_SECTION_LIST. */ 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; 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) 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. */ got it already so we don't duplicate the bfd. */
static lang_input_statement_type * static lang_input_statement_type *
@ -1136,12 +1141,10 @@ wild_doit (ptr, section, output, file)
flagword flags; flagword flags;
if (output->bfd_section == NULL) if (output->bfd_section == NULL)
{
init_os (output); init_os (output);
first = true;
} first = ! output->bfd_section->linker_has_input;
else output->bfd_section->linker_has_input = 1;
first = false;
/* Add a section reference to the list. */ /* Add a section reference to the list. */
new = new_stat (lang_input_section, ptr); 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. /* Oh dear, we now have two potential candidates for a successful match.
Compare their names and choose the better one. */ 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; winner = target;
/* Keep on searching until wqe have checked them all. */ /* 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 /* Try to find a target as similar as possible to
the default target, but which has the desired the default target, but which has the desired
endian characteristic. */ 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 /* Oh dear - we could not find any targets that
satisfy our requirements. */ satisfy our requirements. */
@ -1924,7 +1929,7 @@ open_input_bfds (s, force)
bfd_archive)) bfd_archive))
s->input_statement.loaded = false; 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 symbols, since this means that a valid executable can
@ -2687,8 +2692,10 @@ size_input_section (this_ptr, output_section_statement, fill, dot, relax)
} }
#define IGNORE_SECTION(bfd, s) \ #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) || bfd_section_size (bfd, s) == 0)
/* Check to see if any allocated sections overlap with other allocated /* Check to see if any allocated sections overlap with other allocated
sections. This can happen when the linker script specifically specifies sections. This can happen when the linker script specifically specifies
the output section addresses of the two sections. */ the output section addresses of the two sections. */
@ -2699,7 +2706,6 @@ lang_check_section_addresses ()
asection *s; asection *s;
unsigned opb = bfd_octets_per_byte (output_bfd); unsigned opb = bfd_octets_per_byte (output_bfd);
/* Scan all sections in the output list. */ /* Scan all sections in the output list. */
for (s = output_bfd->sections; s != NULL; s = s->next) 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: case lang_output_section_statement_enum:
{ {
bfd_vma after; 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) if (os->bfd_section == NULL)
/* This section was never actually created. */ /* This section was never actually created. */
break; break;
@ -2866,10 +2873,12 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
&& ! link_info.relocateable && ! link_info.relocateable
&& strcmp (os->region->name, "*default*") == 0 && strcmp (os->region->name, "*default*") == 0
&& lang_memory_region_list != NULL && 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)) || lang_memory_region_list->next != NULL))
einfo (_("%P: warning: no memory region specified for section `%s'\n"), 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; dot = os->region->current;
@ -2878,7 +2887,8 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
bfd_vma olddot; bfd_vma olddot;
olddot = dot; 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) if (dot != olddot && config.warn_section_align)
einfo (_("%P: warning: changing start of section %s by %u bytes\n"), 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: case lang_output_section_statement_enum:
{ {
lang_output_section_statement_type *os = lang_output_section_statement_type *os;
&(s->output_section_statement);
os = &(s->output_section_statement);
if (os->bfd_section != NULL) if (os->bfd_section != NULL)
{ {
dot = os->bfd_section->vma; dot = os->bfd_section->vma;
@ -3370,7 +3380,9 @@ lang_set_startof ()
h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true); h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true);
if (h != NULL && h->type == bfd_link_hash_undefined) if (h != NULL && h->type == bfd_link_hash_undefined)
{ {
unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, unsigned opb;
opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
ldfile_output_machine); ldfile_output_machine);
h->type = bfd_link_hash_defined; h->type = bfd_link_hash_defined;
if (s->_cooked_size != 0) if (s->_cooked_size != 0)
@ -3458,7 +3470,6 @@ lang_finish ()
} }
} }
/* This is the routine to handle BFD error messages. */ /* This is the routine to handle BFD error messages. */
#ifdef ANSI_PROTOTYPES #ifdef ANSI_PROTOTYPES
@ -3505,6 +3516,7 @@ record_bfd_errors (va_alist)
} }
#endif /* ! defined (ANSI_PROTOTYPES) */ #endif /* ! defined (ANSI_PROTOTYPES) */
/* This is a small function used when we want to ignore errors from /* This is a small function used when we want to ignore errors from
BFD. */ BFD. */
@ -4257,8 +4269,9 @@ lang_section_start (name, address)
const char *name; const char *name;
etree_type *address; 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->section_name = name;
ad->address = address; ad->address = address;
} }
@ -4651,9 +4664,7 @@ lang_record_phdrs ()
lang_final_phase_enum); lang_final_phase_enum);
if (! bfd_record_phdr (output_bfd, l->type, if (! bfd_record_phdr (output_bfd, l->type,
l->flags == NULL ? false : true, l->flags != NULL, flags, l->at != NULL,
flags,
l->at == NULL ? false : true,
at, l->filehdr, l->phdrs, c, secs)) at, l->filehdr, l->phdrs, c, secs))
einfo (_("%F%P: bfd_record_phdr failed: %E\n")); einfo (_("%F%P: bfd_record_phdr failed: %E\n"));
} }