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:
parent
aaa4f6d96f
commit
d1778b88f8
6 changed files with 87 additions and 49 deletions
|
@ -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>
|
||||
|
||||
* elf-m10300.c (mn10300_elf_relax_section): Don't relax
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
14
bfd/ecoff.c
14
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, */
|
||||
|
|
|
@ -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, \
|
||||
\
|
||||
/* _raw_size, output_offset, output_section, alignment_power, */ \
|
||||
0, 0, (struct sec *) &SEC, 0, \
|
||||
/* vma, lma, _cooked_size, _raw_size, */ \
|
||||
0, 0, 0, 0, \
|
||||
\
|
||||
/* output_offset, output_section, alignment_power, */ \
|
||||
0, (struct sec *) &SEC, 0, \
|
||||
\
|
||||
/* relocation, orelocation, reloc_count, filepos, rel_filepos, */ \
|
||||
NULL, NULL, 0, 0, 0, \
|
||||
|
|
|
@ -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>
|
||||
|
||||
* Makefile.am (ld.dvi): Search bfd/doc for texinfo files.
|
||||
|
|
89
ld/ldlang.c
89
ld/ldlang.c
|
@ -42,9 +42,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#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;
|
||||
|
@ -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"));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue