mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-10-13 19:06:54 +08:00
Extend "ld --unique" functionality.
This commit is contained in:
22
ld/ChangeLog
22
ld/ChangeLog
@ -1,3 +1,25 @@
|
|||||||
|
2001-01-14 Alan Modra <alan@linuxcare.com.au>
|
||||||
|
|
||||||
|
* emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Don't
|
||||||
|
rummage through the script for sections on the unique list.
|
||||||
|
Correct length of strncmp for ".note".
|
||||||
|
(gld${EMULATION_NAME}_check_needed): Rearrange function.
|
||||||
|
|
||||||
|
* ldlang.c (unique_section_list): New var.
|
||||||
|
(unique_section_p): New function.
|
||||||
|
(walk_wild_section): Don't match sections on unique_section_list.
|
||||||
|
(lang_add_unique): New function.
|
||||||
|
|
||||||
|
* ldlang.h (struct unique_sections): Declare.
|
||||||
|
(unique_section_list): Declare.
|
||||||
|
(unique_section_p): Declare.
|
||||||
|
(lang_add_unique): Declare.
|
||||||
|
|
||||||
|
* lexsup.c (ld_options): Allow --unique to take an optional arg.
|
||||||
|
(parse_args [OPTION_UNIQUE]): Call lang_add_unique.
|
||||||
|
|
||||||
|
* ld.texinfo (--unique): Update.
|
||||||
|
|
||||||
2001-01-13 Nick Clifton <nickc@redhat.com>
|
2001-01-13 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* lexsup.c (parse_args): Remove spurious white space.
|
* lexsup.c (parse_args): Remove spurious white space.
|
||||||
|
@ -7,7 +7,7 @@ cat >e${EMULATION_NAME}.c <<EOF
|
|||||||
/* This file is is generated by a shell script. DO NOT EDIT! */
|
/* This file is is generated by a shell script. DO NOT EDIT! */
|
||||||
|
|
||||||
/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
|
/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
|
||||||
Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 99, 2000
|
Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 99, 2000, 2001
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
Written by Steve Chamberlain <sac@cygnus.com>
|
Written by Steve Chamberlain <sac@cygnus.com>
|
||||||
ELF support by Ian Lance Taylor <ian@cygnus.com>
|
ELF support by Ian Lance Taylor <ian@cygnus.com>
|
||||||
@ -527,13 +527,28 @@ gld${EMULATION_NAME}_check_needed (s)
|
|||||||
if (global_found)
|
if (global_found)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (s->filename != NULL
|
if (s->filename != NULL)
|
||||||
&& strcmp (s->filename, global_needed->name) == 0)
|
{
|
||||||
|
const char *f;
|
||||||
|
|
||||||
|
if (strcmp (s->filename, global_needed->name) == 0)
|
||||||
{
|
{
|
||||||
global_found = true;
|
global_found = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s->search_dirs_flag)
|
||||||
|
{
|
||||||
|
f = strrchr (s->filename, '/');
|
||||||
|
if (f != NULL
|
||||||
|
&& strcmp (f + 1, global_needed->name) == 0)
|
||||||
|
{
|
||||||
|
global_found = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (s->the_bfd != NULL)
|
if (s->the_bfd != NULL)
|
||||||
{
|
{
|
||||||
const char *soname;
|
const char *soname;
|
||||||
@ -546,21 +561,6 @@ gld${EMULATION_NAME}_check_needed (s)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->search_dirs_flag
|
|
||||||
&& s->filename != NULL
|
|
||||||
&& strchr (global_needed->name, '/') == NULL)
|
|
||||||
{
|
|
||||||
const char *f;
|
|
||||||
|
|
||||||
f = strrchr (s->filename, '/');
|
|
||||||
if (f != NULL
|
|
||||||
&& strcmp (f + 1, global_needed->name) == 0)
|
|
||||||
{
|
|
||||||
global_found = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
@ -1030,7 +1030,7 @@ gld${EMULATION_NAME}_place_orphan (file, s)
|
|||||||
|
|
||||||
secname = bfd_get_section_name (s->owner, s);
|
secname = bfd_get_section_name (s->owner, s);
|
||||||
|
|
||||||
if (! config.unique_orphan_sections)
|
if (! config.unique_orphan_sections && ! unique_section_p (secname))
|
||||||
{
|
{
|
||||||
/* Look through the script to see where to place this section. */
|
/* Look through the script to see where to place this section. */
|
||||||
os = lang_output_section_find (secname);
|
os = lang_output_section_find (secname);
|
||||||
@ -1075,7 +1075,7 @@ gld${EMULATION_NAME}_place_orphan (file, s)
|
|||||||
if ((s->flags & SEC_ALLOC) == 0)
|
if ((s->flags & SEC_ALLOC) == 0)
|
||||||
;
|
;
|
||||||
else if ((s->flags & SEC_LOAD) != 0
|
else if ((s->flags & SEC_LOAD) != 0
|
||||||
&& strncmp (secname, ".note", 4) == 0
|
&& strncmp (secname, ".note", 5) == 0
|
||||||
&& HAVE_SECTION (hold_interp, ".interp"))
|
&& HAVE_SECTION (hold_interp, ".interp"))
|
||||||
place = &hold_interp;
|
place = &hold_interp;
|
||||||
else if ((s->flags & SEC_HAS_CONTENTS) == 0
|
else if ((s->flags & SEC_HAS_CONTENTS) == 0
|
||||||
|
@ -695,13 +695,15 @@ with @samp{-Ur}; once the constructor table has been built, it cannot
|
|||||||
be added to. Use @samp{-Ur} only for the last partial link, and
|
be added to. Use @samp{-Ur} only for the last partial link, and
|
||||||
@samp{-r} for the others.
|
@samp{-r} for the others.
|
||||||
|
|
||||||
@kindex --unique
|
@kindex --unique[=@var{SECTION}]
|
||||||
@item --unique
|
@item --unique[=@var{SECTION}]
|
||||||
Creates a separate output section for every orphan input section. This
|
Creates a separate output section for every input section matching
|
||||||
option prevents the normal merging of orphan input sections with the same
|
@var{SECTION}, or if the optional wildcard @var{SECTION} argument is
|
||||||
name. An orphan section is one not specifically mentioned in a linker
|
missing, for every orphan input section. An orphan section is one not
|
||||||
script, so this option along with a custom linker script allows any
|
specifically mentioned in a linker script. You may use this option
|
||||||
selection of input sections to be merged while others are kept separate.
|
multiple times on the command line; It prevents the normal merging of
|
||||||
|
input sections with the same name, overriding output section assignments
|
||||||
|
in a linker script.
|
||||||
|
|
||||||
@kindex -v
|
@kindex -v
|
||||||
@kindex -V
|
@kindex -V
|
||||||
|
65
ld/ldlang.c
65
ld/ldlang.c
@ -1,5 +1,5 @@
|
|||||||
/* Linker command language support.
|
/* Linker command language support.
|
||||||
Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000
|
Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GLD, the Gnu Linker.
|
This file is part of GLD, the Gnu Linker.
|
||||||
@ -186,6 +186,7 @@ boolean had_output_filename = false;
|
|||||||
boolean lang_float_flag = false;
|
boolean lang_float_flag = false;
|
||||||
boolean delete_output_file_on_failure = false;
|
boolean delete_output_file_on_failure = false;
|
||||||
struct lang_nocrossrefs *nocrossref_list;
|
struct lang_nocrossrefs *nocrossref_list;
|
||||||
|
struct unique_sections *unique_section_list;
|
||||||
|
|
||||||
etree_type *base; /* Relocation base - or null */
|
etree_type *base; /* Relocation base - or null */
|
||||||
|
|
||||||
@ -211,6 +212,23 @@ stat_alloc (size)
|
|||||||
return obstack_alloc (&stat_obstack, size);
|
return obstack_alloc (&stat_obstack, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
unique_section_p (secnam)
|
||||||
|
const char *secnam;
|
||||||
|
{
|
||||||
|
struct unique_sections *unam;
|
||||||
|
|
||||||
|
for (unam = unique_section_list; unam; unam = unam->next)
|
||||||
|
if (wildcardp (unam->name)
|
||||||
|
? fnmatch (unam->name, secnam, 0) == 0
|
||||||
|
: strcmp (unam->name, secnam) == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Generic traversal routines for finding matching sections. */
|
/* Generic traversal routines for finding matching sections. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -242,31 +260,26 @@ walk_wild_section (ptr, section, file, callback, data)
|
|||||||
if (file->just_syms_flag == false)
|
if (file->just_syms_flag == false)
|
||||||
{
|
{
|
||||||
register asection *s;
|
register asection *s;
|
||||||
boolean wildcard;
|
boolean wildcard = false;
|
||||||
|
|
||||||
if (section == NULL)
|
if (section != NULL)
|
||||||
wildcard = false;
|
|
||||||
else
|
|
||||||
wildcard = wildcardp (section);
|
wildcard = wildcardp (section);
|
||||||
|
|
||||||
for (s = file->the_bfd->sections; s != NULL; s = s->next)
|
for (s = file->the_bfd->sections; s != NULL; s = s->next)
|
||||||
{
|
{
|
||||||
boolean match;
|
boolean match;
|
||||||
|
const char *sname = bfd_get_section_name (file->the_bfd, s);
|
||||||
|
|
||||||
if (section == NULL)
|
if (section == NULL)
|
||||||
match = true;
|
match = true;
|
||||||
|
else if (wildcard)
|
||||||
|
match = fnmatch (section, sname, 0) == 0 ? true : false;
|
||||||
else
|
else
|
||||||
{
|
match = strcmp (section, sname) == 0 ? true : false;
|
||||||
const char *name;
|
|
||||||
|
|
||||||
name = bfd_get_section_name (file->the_bfd, s);
|
/* If this is a wild-card output section statement, exclude
|
||||||
if (wildcard)
|
sections that match UNIQUE_SECTION_LIST. */
|
||||||
match = fnmatch (section, name, 0) == 0 ? true : false;
|
if (match && (data == NULL || !unique_section_p (sname)))
|
||||||
else
|
|
||||||
match = strcmp (section, name) == 0 ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match)
|
|
||||||
(*callback) (ptr, s, file, data);
|
(*callback) (ptr, s, file, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -925,20 +938,20 @@ section_already_linked (abfd, sec, data)
|
|||||||
if ((flags & SEC_LINK_ONCE) == 0)
|
if ((flags & SEC_LINK_ONCE) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* FIXME: When doing a relocateable link, we may have trouble
|
/* FIXME: When doing a relocatable link, we may have trouble
|
||||||
copying relocations in other sections that refer to local symbols
|
copying relocations in other sections that refer to local symbols
|
||||||
in the section being discarded. Those relocations will have to
|
in the section being discarded. Those relocations will have to
|
||||||
be converted somehow; as of this writing I'm not sure that any of
|
be converted somehow; as of this writing I'm not sure that any of
|
||||||
the backends handle that correctly.
|
the backends handle that correctly.
|
||||||
|
|
||||||
It is tempting to instead not discard link once sections when
|
It is tempting to instead not discard link once sections when
|
||||||
doing a relocateable link (technically, they should be discarded
|
doing a relocatable link (technically, they should be discarded
|
||||||
whenever we are building constructors). However, that fails,
|
whenever we are building constructors). However, that fails,
|
||||||
because the linker winds up combining all the link once sections
|
because the linker winds up combining all the link once sections
|
||||||
into a single large link once section, which defeats the purpose
|
into a single large link once section, which defeats the purpose
|
||||||
of having link once sections in the first place.
|
of having link once sections in the first place.
|
||||||
|
|
||||||
Also, not merging link once sections in a relocateable link
|
Also, not merging link once sections in a relocatable link
|
||||||
causes trouble for MIPS ELF, which relies in link once semantics
|
causes trouble for MIPS ELF, which relies in link once semantics
|
||||||
to handle the .reginfo section correctly. */
|
to handle the .reginfo section correctly. */
|
||||||
|
|
||||||
@ -5044,3 +5057,19 @@ lang_do_version_exports_section ()
|
|||||||
lang_register_vers_node (command_line.version_exports_section,
|
lang_register_vers_node (command_line.version_exports_section,
|
||||||
lang_new_vers_node (greg, lreg), NULL);
|
lang_new_vers_node (greg, lreg), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lang_add_unique (name)
|
||||||
|
const char *name;
|
||||||
|
{
|
||||||
|
struct unique_sections *ent;
|
||||||
|
|
||||||
|
for (ent = unique_section_list; ent; ent = ent->next)
|
||||||
|
if (strcmp (ent->name, name) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ent = (struct unique_sections *) xmalloc (sizeof *ent);
|
||||||
|
ent->name = xstrdup (name);
|
||||||
|
ent->next = unique_section_list;
|
||||||
|
unique_section_list = ent;
|
||||||
|
}
|
||||||
|
14
ld/ldlang.h
14
ld/ldlang.h
@ -1,5 +1,5 @@
|
|||||||
/* ldlang.h - linker command language support
|
/* ldlang.h - linker command language support
|
||||||
Copyright 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000
|
Copyright 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GLD, the Gnu Linker.
|
This file is part of GLD, the Gnu Linker.
|
||||||
@ -340,6 +340,16 @@ struct lang_nocrossrefs {
|
|||||||
|
|
||||||
extern struct lang_nocrossrefs *nocrossref_list;
|
extern struct lang_nocrossrefs *nocrossref_list;
|
||||||
|
|
||||||
|
/* This structure is used to hold a list of input section names which
|
||||||
|
will not match an output section in the linker script. */
|
||||||
|
|
||||||
|
struct unique_sections {
|
||||||
|
struct unique_sections *next;
|
||||||
|
const char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct unique_sections *unique_section_list;
|
||||||
|
|
||||||
extern lang_output_section_statement_type *abs_output_section;
|
extern lang_output_section_statement_type *abs_output_section;
|
||||||
extern lang_statement_list_type lang_output_section_statement;
|
extern lang_statement_list_type lang_output_section_statement;
|
||||||
extern boolean lang_has_input_file;
|
extern boolean lang_has_input_file;
|
||||||
@ -462,5 +472,7 @@ extern struct bfd_elf_version_deps *lang_add_vers_depend
|
|||||||
extern void lang_register_vers_node
|
extern void lang_register_vers_node
|
||||||
PARAMS ((const char *, struct bfd_elf_version_tree *,
|
PARAMS ((const char *, struct bfd_elf_version_tree *,
|
||||||
struct bfd_elf_version_deps *));
|
struct bfd_elf_version_deps *));
|
||||||
|
boolean unique_section_p PARAMS ((const char *));
|
||||||
|
extern void lang_add_unique PARAMS ((const char *));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -236,8 +236,8 @@ static const struct ld_option ld_options[] =
|
|||||||
'T', N_("FILE"), N_("Read linker script"), TWO_DASHES },
|
'T', N_("FILE"), N_("Read linker script"), TWO_DASHES },
|
||||||
{ {"undefined", required_argument, NULL, 'u'},
|
{ {"undefined", required_argument, NULL, 'u'},
|
||||||
'u', N_("SYMBOL"), N_("Start with undefined reference to SYMBOL"), TWO_DASHES },
|
'u', N_("SYMBOL"), N_("Start with undefined reference to SYMBOL"), TWO_DASHES },
|
||||||
{ {"unique", no_argument, NULL, OPTION_UNIQUE},
|
{ {"unique", optional_argument, NULL, OPTION_UNIQUE},
|
||||||
'\0', NULL, N_("Don't merge orphan sections with the same name"), TWO_DASHES },
|
'\0', N_("[=SECTION]"), N_("Don't merge input [SECTION | orphan] sections"), TWO_DASHES },
|
||||||
{ {"Ur", no_argument, NULL, OPTION_UR},
|
{ {"Ur", no_argument, NULL, OPTION_UR},
|
||||||
'\0', NULL, N_("Build global constructor/destructor tables"), ONE_DASH },
|
'\0', NULL, N_("Build global constructor/destructor tables"), ONE_DASH },
|
||||||
{ {"version", no_argument, NULL, OPTION_VERSION},
|
{ {"version", no_argument, NULL, OPTION_VERSION},
|
||||||
@ -965,6 +965,9 @@ parse_args (argc, argv)
|
|||||||
ldlang_add_undef (optarg);
|
ldlang_add_undef (optarg);
|
||||||
break;
|
break;
|
||||||
case OPTION_UNIQUE:
|
case OPTION_UNIQUE:
|
||||||
|
if (optarg != NULL)
|
||||||
|
lang_add_unique (optarg);
|
||||||
|
else
|
||||||
config.unique_orphan_sections = true;
|
config.unique_orphan_sections = true;
|
||||||
break;
|
break;
|
||||||
case OPTION_VERBOSE:
|
case OPTION_VERBOSE:
|
||||||
|
Reference in New Issue
Block a user