mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-17 13:10:12 +08:00
bfd/
* elf-bfd.h (struct elf_obj_tdata): Delete dt_soname field. Add dyn_lib_class field. Rearrange for better packing. (elf_dt_soname): Delete. (elf_dyn_lib_class): Define. * elf.c (bfd_elf_set_dt_needed_name): Update comment. (bfd_elf_set_dt_needed_soname): Delete. (bfd_elf_set_dyn_lib_class): New function. * elflink.h (add_dt_needed_tag): New function. Split out from.. (elf_link_add_object_symbols): ..here. Rename "name" to "soname". Use elf_dyn_lib_class to set dt_needed and add_needed. Move fallback initialization of soname. (elf_link_check_versioned_symbol): Test elf_dyn_lib_class instead of elf_dt_soname. * bfd-in.h (enum dynamic_lib_link_class): New. (bfd_elf_set_dt_needed_soname): Delete. (bfd_elf_set_dyn_lib_class): Declare. * bfd-in2.h: Regenerate. ld/ * ld.texinfo: Add --as-needed doco. * ldmain.c (as_needed): New global var. * ldmain.h (as_needed): Declare. * lexsup.c (option_values): Add OPTION_AS_NEEDED and OPTION_NO_AS_NEEDED. (ld_options): Likewise. (parse_args): Handle them. * ldlang.h (lang_input_statement_type): Add as_needed field. * ldlang.c (new_afile): Set p->as_needed. * emultempl/elf32.em (gld${EMULATION_NAME}_load_symbols): New function. (gld${EMULATION_NAME}_try_needed): Use bfd_elf_set_dyn_lib_class. (ld_${EMULATION_NAME}_emulation): Set LDEMUL_RECOGNIZED_FILE entry. * ldlang.c (open_input_bfds): Remove useless cast. (lang_do_assignments_1): Likewise. (lang_for_each_input_section): Delete.
This commit is contained in:
parent
3e4caed2b1
commit
4a43e768f1
@ -1,5 +1,23 @@
|
||||
2004-03-18 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf-bfd.h (struct elf_obj_tdata): Delete dt_soname field. Add
|
||||
dyn_lib_class field. Rearrange for better packing.
|
||||
(elf_dt_soname): Delete.
|
||||
(elf_dyn_lib_class): Define.
|
||||
* elf.c (bfd_elf_set_dt_needed_name): Update comment.
|
||||
(bfd_elf_set_dt_needed_soname): Delete.
|
||||
(bfd_elf_set_dyn_lib_class): New function.
|
||||
* elflink.h (add_dt_needed_tag): New function. Split out from..
|
||||
(elf_link_add_object_symbols): ..here. Rename "name" to "soname".
|
||||
Use elf_dyn_lib_class to set dt_needed and add_needed. Move fallback
|
||||
initialization of soname.
|
||||
(elf_link_check_versioned_symbol): Test elf_dyn_lib_class instead of
|
||||
elf_dt_soname.
|
||||
* bfd-in.h (enum dynamic_lib_link_class): New.
|
||||
(bfd_elf_set_dt_needed_soname): Delete.
|
||||
(bfd_elf_set_dyn_lib_class): Declare.
|
||||
* bfd-in2.h: Regenerate.
|
||||
|
||||
* elflink.c (_bfd_elf_merge_symbol): Rewrite weak symbol handling.
|
||||
(_bfd_elf_add_default_symbol): Remove indirect BFD_ASSERTs.
|
||||
* elflink.h (elf_link_add_object_symbols): Don't clear dt_needed in
|
||||
|
10
bfd/bfd-in.h
10
bfd/bfd-in.h
@ -599,6 +599,12 @@ struct bfd_link_needed_list
|
||||
const char *name;
|
||||
};
|
||||
|
||||
enum dynamic_lib_link_class {
|
||||
DYN_NORMAL = 0,
|
||||
DYN_AS_NEEDED = 1,
|
||||
DYN_DT_NEEDED = 2
|
||||
};
|
||||
|
||||
extern bfd_boolean bfd_elf_record_link_assignment
|
||||
(bfd *, struct bfd_link_info *, const char *, bfd_boolean);
|
||||
extern struct bfd_link_needed_list *bfd_elf_get_needed_list
|
||||
@ -613,10 +619,10 @@ extern bfd_boolean bfd_elf64_size_dynamic_sections
|
||||
struct bfd_link_info *, struct bfd_section **, struct bfd_elf_version_tree *);
|
||||
extern void bfd_elf_set_dt_needed_name
|
||||
(bfd *, const char *);
|
||||
extern void bfd_elf_set_dt_needed_soname
|
||||
(bfd *, const char *);
|
||||
extern const char *bfd_elf_get_dt_soname
|
||||
(bfd *);
|
||||
extern void bfd_elf_set_dyn_lib_class
|
||||
(bfd *, int);
|
||||
extern struct bfd_link_needed_list *bfd_elf_get_runpath_list
|
||||
(bfd *, struct bfd_link_info *);
|
||||
extern bfd_boolean bfd_elf32_discard_info
|
||||
|
@ -606,6 +606,12 @@ struct bfd_link_needed_list
|
||||
const char *name;
|
||||
};
|
||||
|
||||
enum dynamic_lib_link_class {
|
||||
DYN_NORMAL = 0,
|
||||
DYN_AS_NEEDED = 1,
|
||||
DYN_DT_NEEDED = 2
|
||||
};
|
||||
|
||||
extern bfd_boolean bfd_elf_record_link_assignment
|
||||
(bfd *, struct bfd_link_info *, const char *, bfd_boolean);
|
||||
extern struct bfd_link_needed_list *bfd_elf_get_needed_list
|
||||
@ -620,10 +626,10 @@ extern bfd_boolean bfd_elf64_size_dynamic_sections
|
||||
struct bfd_link_info *, struct bfd_section **, struct bfd_elf_version_tree *);
|
||||
extern void bfd_elf_set_dt_needed_name
|
||||
(bfd *, const char *);
|
||||
extern void bfd_elf_set_dt_needed_soname
|
||||
(bfd *, const char *);
|
||||
extern const char *bfd_elf_get_dt_soname
|
||||
(bfd *);
|
||||
extern void bfd_elf_set_dyn_lib_class
|
||||
(bfd *, int);
|
||||
extern struct bfd_link_needed_list *bfd_elf_get_runpath_list
|
||||
(bfd *, struct bfd_link_info *);
|
||||
extern bfd_boolean bfd_elf32_discard_info
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* BFD back-end data structures for ELF files.
|
||||
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003 Free Software Foundation, Inc.
|
||||
2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
@ -1132,9 +1132,6 @@ struct elf_obj_tdata
|
||||
bfd_vma gp; /* The gp value */
|
||||
unsigned int gp_size; /* The gp size */
|
||||
|
||||
Elf_Internal_Shdr **group_sect_ptr;
|
||||
int num_group;
|
||||
|
||||
/* Information grabbed from an elf core file. */
|
||||
int core_signal;
|
||||
int core_pid;
|
||||
@ -1142,10 +1139,6 @@ struct elf_obj_tdata
|
||||
char* core_program;
|
||||
char* core_command;
|
||||
|
||||
/* This is set to TRUE if the object was created by the backend
|
||||
linker. */
|
||||
bfd_boolean linker;
|
||||
|
||||
/* A mapping from external symbols to entries in the linker hash
|
||||
table, used when linking. This is indexed by the symbol index
|
||||
minus the sh_info field of the symbol table header. */
|
||||
@ -1171,21 +1164,6 @@ struct elf_obj_tdata
|
||||
one. */
|
||||
const char *dt_name;
|
||||
|
||||
/* When a reference in a regular object is resolved by a shared
|
||||
object is loaded into via the DT_NEEDED entries by the linker
|
||||
ELF emulation code, we need to add the shared object to the
|
||||
DT_NEEDED list of the resulting binary to indicate the dependency
|
||||
as if the -l option is passed to the linker. This field holds the
|
||||
name of the loaded shared object. */
|
||||
const char *dt_soname;
|
||||
|
||||
/* Irix 5 often screws up the symbol table, sorting local symbols
|
||||
after global symbols. This flag is set if the symbol table in
|
||||
this BFD appears to be screwed up. If it is, we ignore the
|
||||
sh_info field in the symbol table header, and always read all the
|
||||
symbols. */
|
||||
bfd_boolean bad_symtab;
|
||||
|
||||
/* Records the result of `get_program_header_size'. */
|
||||
bfd_size_type program_header_size;
|
||||
|
||||
@ -1213,8 +1191,8 @@ struct elf_obj_tdata
|
||||
created. */
|
||||
asection *eh_frame_hdr;
|
||||
|
||||
/* Used to determine if the e_flags field has been initialized */
|
||||
bfd_boolean flags_init;
|
||||
Elf_Internal_Shdr **group_sect_ptr;
|
||||
int num_group;
|
||||
|
||||
/* Number of symbol version definitions we are about to emit. */
|
||||
unsigned int cverdefs;
|
||||
@ -1237,6 +1215,25 @@ struct elf_obj_tdata
|
||||
asymbol *elf_text_symbol;
|
||||
asection *elf_data_section;
|
||||
asection *elf_text_section;
|
||||
|
||||
/* Whether a dyanmic object was specified normally on the linker
|
||||
command line, or was specified when --as-needed was in effect,
|
||||
or was found via a DT_NEEDED entry. */
|
||||
enum dynamic_lib_link_class dyn_lib_class;
|
||||
|
||||
/* This is set to TRUE if the object was created by the backend
|
||||
linker. */
|
||||
bfd_boolean linker;
|
||||
|
||||
/* Irix 5 often screws up the symbol table, sorting local symbols
|
||||
after global symbols. This flag is set if the symbol table in
|
||||
this BFD appears to be screwed up. If it is, we ignore the
|
||||
sh_info field in the symbol table header, and always read all the
|
||||
symbols. */
|
||||
bfd_boolean bad_symtab;
|
||||
|
||||
/* Used to determine if the e_flags field has been initialized */
|
||||
bfd_boolean flags_init;
|
||||
};
|
||||
|
||||
#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data)
|
||||
@ -1263,7 +1260,7 @@ struct elf_obj_tdata
|
||||
#define elf_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got.offsets)
|
||||
#define elf_local_got_ents(bfd) (elf_tdata(bfd) -> local_got.ents)
|
||||
#define elf_dt_name(bfd) (elf_tdata(bfd) -> dt_name)
|
||||
#define elf_dt_soname(bfd) (elf_tdata(bfd) -> dt_soname)
|
||||
#define elf_dyn_lib_class(bfd) (elf_tdata(bfd) -> dyn_lib_class)
|
||||
#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab)
|
||||
#define elf_flags_init(bfd) (elf_tdata(bfd) -> flags_init)
|
||||
|
||||
|
@ -1479,8 +1479,7 @@ _bfd_elf_link_hash_table_create (bfd *abfd)
|
||||
|
||||
/* This is a hook for the ELF emulation code in the generic linker to
|
||||
tell the backend linker what file name to use for the DT_NEEDED
|
||||
entry for a dynamic object. The generic linker passes name as an
|
||||
empty string to indicate that no DT_NEEDED entry should be made. */
|
||||
entry for a dynamic object. */
|
||||
|
||||
void
|
||||
bfd_elf_set_dt_needed_name (bfd *abfd, const char *name)
|
||||
@ -1491,11 +1490,11 @@ bfd_elf_set_dt_needed_name (bfd *abfd, const char *name)
|
||||
}
|
||||
|
||||
void
|
||||
bfd_elf_set_dt_needed_soname (bfd *abfd, const char *name)
|
||||
bfd_elf_set_dyn_lib_class (bfd *abfd, int lib_class)
|
||||
{
|
||||
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
|
||||
&& bfd_get_format (abfd) == bfd_object)
|
||||
elf_dt_soname (abfd) = name;
|
||||
elf_dyn_lib_class (abfd) = lib_class;
|
||||
}
|
||||
|
||||
/* Get the list of DT_NEEDED entries for a link. This is a hook for
|
||||
|
209
bfd/elflink.h
209
bfd/elflink.h
@ -68,6 +68,59 @@ sort_symbol (const void *arg1, const void *arg2)
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a DT_NEEDED entry for this dynamic object. Returns -1 on error,
|
||||
1 if a DT_NEEDED tag already exists, and 0 on success. */
|
||||
|
||||
static int
|
||||
add_dt_needed_tag (struct bfd_link_info *info, const char *soname,
|
||||
bfd_boolean do_it)
|
||||
{
|
||||
struct elf_link_hash_table *hash_table;
|
||||
bfd_size_type oldsize;
|
||||
bfd_size_type strindex;
|
||||
|
||||
hash_table = elf_hash_table (info);
|
||||
oldsize = _bfd_elf_strtab_size (hash_table->dynstr);
|
||||
strindex = _bfd_elf_strtab_add (hash_table->dynstr, soname, FALSE);
|
||||
if (strindex == (bfd_size_type) -1)
|
||||
return -1;
|
||||
|
||||
if (oldsize == _bfd_elf_strtab_size (hash_table->dynstr))
|
||||
{
|
||||
asection *sdyn;
|
||||
Elf_External_Dyn *dyncon, *dynconend;
|
||||
|
||||
sdyn = bfd_get_section_by_name (hash_table->dynobj, ".dynamic");
|
||||
BFD_ASSERT (sdyn != NULL);
|
||||
|
||||
dyncon = (Elf_External_Dyn *) sdyn->contents;
|
||||
dynconend = (Elf_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
|
||||
for (; dyncon < dynconend; dyncon++)
|
||||
{
|
||||
Elf_Internal_Dyn dyn;
|
||||
|
||||
elf_swap_dyn_in (hash_table->dynobj, dyncon, & dyn);
|
||||
if (dyn.d_tag == DT_NEEDED
|
||||
&& dyn.d_un.d_val == strindex)
|
||||
{
|
||||
_bfd_elf_strtab_delref (hash_table->dynstr, strindex);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (do_it)
|
||||
{
|
||||
if (! elf_add_dynamic_entry (info, DT_NEEDED, strindex))
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
/* We were just checking for existence of the tag. */
|
||||
_bfd_elf_strtab_delref (hash_table->dynstr, strindex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add symbols from an ELF object file to the linker hash table. */
|
||||
|
||||
static bfd_boolean
|
||||
@ -202,7 +255,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|
||||
}
|
||||
|
||||
dt_needed = FALSE;
|
||||
add_needed = FALSE;
|
||||
add_needed = TRUE;
|
||||
if (! dynamic)
|
||||
{
|
||||
/* If we are creating a shared library, create all the dynamic
|
||||
@ -224,10 +277,9 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|
||||
else
|
||||
{
|
||||
asection *s;
|
||||
const char *name;
|
||||
bfd_size_type oldsize;
|
||||
bfd_size_type strindex;
|
||||
const char *soname = NULL;
|
||||
struct bfd_link_needed_list *rpath = NULL, *runpath = NULL;
|
||||
int ret;
|
||||
|
||||
/* ld --just-symbols and dynamic objects don't mix very well.
|
||||
Test for --just-symbols by looking at info set up by
|
||||
@ -236,26 +288,22 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|
||||
&& s->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
|
||||
goto error_return;
|
||||
|
||||
/* Find the name to use in a DT_NEEDED entry that refers to this
|
||||
object. If the object has a DT_SONAME entry, we use it.
|
||||
Otherwise, if the generic linker stuck something in
|
||||
elf_dt_name, we use that. Otherwise, we just use the file
|
||||
name. If the generic linker put a null string into
|
||||
elf_dt_name, we don't make a DT_NEEDED entry at all, even if
|
||||
there is a DT_SONAME entry. */
|
||||
add_needed = TRUE;
|
||||
name = bfd_get_filename (abfd);
|
||||
if (elf_dt_name (abfd) != NULL)
|
||||
/* If this dynamic lib was specified on the command line with
|
||||
--as-needed in effect, then we don't want to add a DT_NEEDED
|
||||
tag unless the lib is actually used.
|
||||
For libs brought in by another lib's DT_NEEDED we do the same,
|
||||
and also modify handling of weak syms. */
|
||||
switch elf_dyn_lib_class (abfd)
|
||||
{
|
||||
name = elf_dt_name (abfd);
|
||||
if (*name == '\0')
|
||||
{
|
||||
if (elf_dt_soname (abfd) != NULL)
|
||||
dt_needed = TRUE;
|
||||
|
||||
add_needed = FALSE;
|
||||
}
|
||||
case DYN_NORMAL:
|
||||
break;
|
||||
case DYN_DT_NEEDED:
|
||||
dt_needed = TRUE;
|
||||
/* Fall thru */
|
||||
case DYN_AS_NEEDED:
|
||||
add_needed = FALSE;
|
||||
}
|
||||
|
||||
s = bfd_get_section_by_name (abfd, ".dynamic");
|
||||
if (s != NULL)
|
||||
{
|
||||
@ -287,8 +335,8 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|
||||
if (dyn.d_tag == DT_SONAME)
|
||||
{
|
||||
unsigned int tagv = dyn.d_un.d_val;
|
||||
name = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
|
||||
if (name == NULL)
|
||||
soname = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
|
||||
if (soname == NULL)
|
||||
goto error_free_dyn;
|
||||
}
|
||||
if (dyn.d_tag == DT_NEEDED)
|
||||
@ -405,53 +453,31 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|
||||
if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
|
||||
goto error_return;
|
||||
|
||||
if (add_needed)
|
||||
/* Find the name to use in a DT_NEEDED entry that refers to this
|
||||
object. If the object has a DT_SONAME entry, we use it.
|
||||
Otherwise, if the generic linker stuck something in
|
||||
elf_dt_name, we use that. Otherwise, we just use the file
|
||||
name. */
|
||||
if (soname == NULL || *soname == '\0')
|
||||
{
|
||||
/* Add a DT_NEEDED entry for this dynamic object. */
|
||||
oldsize = _bfd_elf_strtab_size (hash_table->dynstr);
|
||||
strindex = _bfd_elf_strtab_add (hash_table->dynstr, name, FALSE);
|
||||
if (strindex == (bfd_size_type) -1)
|
||||
goto error_return;
|
||||
|
||||
if (oldsize == _bfd_elf_strtab_size (hash_table->dynstr))
|
||||
{
|
||||
asection *sdyn;
|
||||
Elf_External_Dyn *dyncon, *dynconend;
|
||||
|
||||
/* The hash table size did not change, which means that
|
||||
the dynamic object name was already entered. If we
|
||||
have already included this dynamic object in the
|
||||
link, just ignore it. There is no reason to include
|
||||
a particular dynamic object more than once. */
|
||||
sdyn = bfd_get_section_by_name (hash_table->dynobj, ".dynamic");
|
||||
BFD_ASSERT (sdyn != NULL);
|
||||
|
||||
dyncon = (Elf_External_Dyn *) sdyn->contents;
|
||||
dynconend = (Elf_External_Dyn *) (sdyn->contents +
|
||||
sdyn->_raw_size);
|
||||
for (; dyncon < dynconend; dyncon++)
|
||||
{
|
||||
Elf_Internal_Dyn dyn;
|
||||
|
||||
elf_swap_dyn_in (hash_table->dynobj, dyncon, & dyn);
|
||||
if (dyn.d_tag == DT_NEEDED
|
||||
&& dyn.d_un.d_val == strindex)
|
||||
{
|
||||
_bfd_elf_strtab_delref (hash_table->dynstr, strindex);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! elf_add_dynamic_entry (info, DT_NEEDED, strindex))
|
||||
goto error_return;
|
||||
soname = elf_dt_name (abfd);
|
||||
if (soname == NULL || *soname == '\0')
|
||||
soname = bfd_get_filename (abfd);
|
||||
}
|
||||
|
||||
/* Save the SONAME, if there is one, because sometimes the
|
||||
linker emulation code will need to know it. */
|
||||
if (*name == '\0')
|
||||
name = basename (bfd_get_filename (abfd));
|
||||
elf_dt_name (abfd) = name;
|
||||
/* Save the SONAME because sometimes the linker emulation code
|
||||
will need to know it. */
|
||||
elf_dt_name (abfd) = soname;
|
||||
|
||||
ret = add_dt_needed_tag (info, soname, add_needed);
|
||||
if (ret < 0)
|
||||
goto error_return;
|
||||
|
||||
/* If we have already included this dynamic object in the
|
||||
link, just ignore it. There is no reason to include a
|
||||
particular dynamic object more than once. */
|
||||
if (ret > 0)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* If this is a dynamic object, we always link against the .dynsym
|
||||
@ -1051,49 +1077,21 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|
||||
break;
|
||||
}
|
||||
|
||||
if (dt_needed && !add_needed && definition
|
||||
if (!add_needed && definition
|
||||
&& (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_REF_REGULAR) != 0)
|
||||
{
|
||||
bfd_size_type oldsize;
|
||||
bfd_size_type strindex;
|
||||
|
||||
/* The symbol from a DT_NEEDED object is referenced from
|
||||
the regular object to create a dynamic executable. We
|
||||
have to make sure there is a DT_NEEDED entry for it. */
|
||||
int ret;
|
||||
|
||||
/* A symbol from a library loaded via DT_NEEDED of some
|
||||
other library is referenced by a regular object.
|
||||
Add a DT_NEEDED entry for it. */
|
||||
add_needed = TRUE;
|
||||
oldsize = _bfd_elf_strtab_size (hash_table->dynstr);
|
||||
strindex = _bfd_elf_strtab_add (hash_table->dynstr,
|
||||
elf_dt_soname (abfd), FALSE);
|
||||
if (strindex == (bfd_size_type) -1)
|
||||
ret = add_dt_needed_tag (info, elf_dt_name (abfd), add_needed);
|
||||
if (ret < 0)
|
||||
goto error_free_vers;
|
||||
|
||||
if (oldsize == _bfd_elf_strtab_size (hash_table->dynstr))
|
||||
{
|
||||
asection *sdyn;
|
||||
Elf_External_Dyn *dyncon, *dynconend;
|
||||
|
||||
sdyn = bfd_get_section_by_name (hash_table->dynobj,
|
||||
".dynamic");
|
||||
BFD_ASSERT (sdyn != NULL);
|
||||
|
||||
dyncon = (Elf_External_Dyn *) sdyn->contents;
|
||||
dynconend = (Elf_External_Dyn *) (sdyn->contents +
|
||||
sdyn->_raw_size);
|
||||
for (; dyncon < dynconend; dyncon++)
|
||||
{
|
||||
Elf_Internal_Dyn dyn;
|
||||
|
||||
elf_swap_dyn_in (hash_table->dynobj,
|
||||
dyncon, &dyn);
|
||||
BFD_ASSERT (dyn.d_tag != DT_NEEDED ||
|
||||
dyn.d_un.d_val != strindex);
|
||||
}
|
||||
}
|
||||
|
||||
if (! elf_add_dynamic_entry (info, DT_NEEDED, strindex))
|
||||
goto error_free_vers;
|
||||
BFD_ASSERT (ret == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3950,7 +3948,8 @@ elf_link_check_versioned_symbol (struct bfd_link_info *info,
|
||||
case bfd_link_hash_undefined:
|
||||
case bfd_link_hash_undefweak:
|
||||
abfd = h->root.u.undef.abfd;
|
||||
if ((abfd->flags & DYNAMIC) == 0 || elf_dt_soname (abfd) == NULL)
|
||||
if ((abfd->flags & DYNAMIC) == 0
|
||||
|| elf_dyn_lib_class (abfd) != DYN_DT_NEEDED)
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
|
19
ld/ChangeLog
19
ld/ChangeLog
@ -1,3 +1,22 @@
|
||||
2004-03-18 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* ld.texinfo: Add --as-needed doco.
|
||||
* ldmain.c (as_needed): New global var.
|
||||
* ldmain.h (as_needed): Declare.
|
||||
* lexsup.c (option_values): Add OPTION_AS_NEEDED and
|
||||
OPTION_NO_AS_NEEDED.
|
||||
(ld_options): Likewise.
|
||||
(parse_args): Handle them.
|
||||
* ldlang.h (lang_input_statement_type): Add as_needed field.
|
||||
* ldlang.c (new_afile): Set p->as_needed.
|
||||
* emultempl/elf32.em (gld${EMULATION_NAME}_load_symbols): New function.
|
||||
(gld${EMULATION_NAME}_try_needed): Use bfd_elf_set_dyn_lib_class.
|
||||
(ld_${EMULATION_NAME}_emulation): Set LDEMUL_RECOGNIZED_FILE entry.
|
||||
|
||||
* ldlang.c (open_input_bfds): Remove useless cast.
|
||||
(lang_do_assignments_1): Likewise.
|
||||
(lang_for_each_input_section): Delete.
|
||||
|
||||
2004-03-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
||||
|
||||
* configure.tgt: Switch sh-*-rtems* to ELF. Add sh-*-rtemscoff*.
|
||||
|
@ -89,6 +89,28 @@ gld${EMULATION_NAME}_before_parse (void)
|
||||
EOF
|
||||
fi
|
||||
|
||||
if test x"$LDEMUL_RECOGNIZED_FILE" != xgld"${EMULATION_NAME}"_load_symbols; then
|
||||
cat >>e${EMULATION_NAME}.c <<EOF
|
||||
/* Handle as_needed DT_NEEDED. */
|
||||
|
||||
static bfd_boolean
|
||||
gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *entry)
|
||||
{
|
||||
if (!entry->as_needed
|
||||
|| (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) == 0)
|
||||
return FALSE;
|
||||
|
||||
/* Tell the ELF linker that we don't want the output file to have a
|
||||
DT_NEEDED entry for this file, unless it is used to resolve
|
||||
references in a regular object. */
|
||||
bfd_elf_set_dyn_lib_class (entry->the_bfd, DYN_AS_NEEDED);
|
||||
|
||||
/* Continue on with normal load_symbols processing. */
|
||||
return FALSE;
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat >>e${EMULATION_NAME}.c <<EOF
|
||||
|
||||
/* These variables are required to pass information back and forth
|
||||
@ -336,14 +358,13 @@ cat >>e${EMULATION_NAME}.c <<EOF
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Tell the ELF backend that we don't want the output file to have a
|
||||
DT_NEEDED entry for this file. */
|
||||
bfd_elf_set_dt_needed_name (abfd, "");
|
||||
/* Specify the soname to use. */
|
||||
bfd_elf_set_dt_needed_name (abfd, soname);
|
||||
|
||||
/* Tell the ELF backend that the output file needs a DT_NEEDED
|
||||
entry for this file if it is used to resolve the reference in
|
||||
a regular object. */
|
||||
bfd_elf_set_dt_needed_soname (abfd, soname);
|
||||
/* Tell the ELF linker that we don't want the output file to have a
|
||||
DT_NEEDED entry for this file, unless it is used to resolve
|
||||
references in a regular object. */
|
||||
bfd_elf_set_dyn_lib_class (abfd, DYN_DT_NEEDED);
|
||||
|
||||
/* Add this file into the symbol table. */
|
||||
if (! bfd_link_add_symbols (abfd, &link_info))
|
||||
@ -1752,7 +1773,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
|
||||
gld${EMULATION_NAME}_handle_option,
|
||||
${LDEMUL_UNRECOGNIZED_FILE-NULL},
|
||||
${LDEMUL_LIST_OPTIONS-gld${EMULATION_NAME}_list_options},
|
||||
${LDEMUL_RECOGNIZED_FILE-NULL},
|
||||
${LDEMUL_RECOGNIZED_FILE-gld${EMULATION_NAME}_load_symbols},
|
||||
${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
|
||||
${LDEMUL_NEW_VERS_PATTERN-NULL}
|
||||
};
|
||||
|
@ -972,6 +972,18 @@ behaviour from release 2.14 onwards is to reject such input files, and
|
||||
so the @samp{--accept-unknown-input-arch} option has been added to
|
||||
restore the old behaviour.
|
||||
|
||||
@kindex --as-needed
|
||||
@kindex --no-as-needed
|
||||
@item --as-needed
|
||||
@itemx --no-as-needed
|
||||
This option affects ELF DT_NEEDED tags for dynamic libraries mentioned
|
||||
on the command line after the @option{--as-needed} option. Normally,
|
||||
the linker will add a DT_NEEDED tag for each dynamic library mentioned
|
||||
on the command line, regardless of whether the library is actually
|
||||
needed. @option{--as-needed} causes DT_NEEDED tags to only be emitted
|
||||
for libraries that satisfy some reference from regular objects.
|
||||
@option{--no-as-needed} restores the default behaviour.
|
||||
|
||||
@kindex -assert @var{keyword}
|
||||
@item -assert @var{keyword}
|
||||
This option is ignored for SunOS compatibility.
|
||||
|
24
ld/ldlang.c
24
ld/ldlang.c
@ -445,6 +445,7 @@ new_afile (const char *name,
|
||||
p->next = NULL;
|
||||
p->symbol_count = 0;
|
||||
p->dynamic = config.dynamic_link;
|
||||
p->as_needed = as_needed;
|
||||
p->whole_archive = whole_archive;
|
||||
p->loaded = FALSE;
|
||||
lang_statement_append (&input_file_chain,
|
||||
@ -1842,7 +1843,7 @@ open_input_bfds (lang_statement_union_type *s, bfd_boolean force)
|
||||
/* Maybe we should load the file's symbols. */
|
||||
if (s->wild_statement.filename
|
||||
&& ! wildcardp (s->wild_statement.filename))
|
||||
(void) lookup_name (s->wild_statement.filename);
|
||||
lookup_name (s->wild_statement.filename);
|
||||
open_input_bfds (s->wild_statement.children.head, force);
|
||||
break;
|
||||
case lang_group_statement_enum:
|
||||
@ -3348,8 +3349,7 @@ lang_do_assignments_1
|
||||
if (os->bfd_section != NULL)
|
||||
{
|
||||
dot = os->bfd_section->vma;
|
||||
(void) lang_do_assignments_1 (os->children.head, os,
|
||||
os->fill, dot);
|
||||
lang_do_assignments_1 (os->children.head, os, os->fill, dot);
|
||||
dot = (os->bfd_section->vma
|
||||
+ TO_ADDR (os->bfd_section->_raw_size));
|
||||
|
||||
@ -3938,24 +3938,6 @@ lang_for_each_file (void (*func) (lang_input_statement_type *))
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/* Not used. */
|
||||
|
||||
void
|
||||
lang_for_each_input_section (void (*func) (bfd *ab, asection *as))
|
||||
{
|
||||
LANG_FOR_EACH_INPUT_STATEMENT (f)
|
||||
{
|
||||
asection *s;
|
||||
|
||||
for (s = f->the_bfd->sections; s != NULL; s = s->next)
|
||||
func (f->the_bfd, s);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
ldlang_add_file (lang_input_statement_type *entry)
|
||||
{
|
||||
|
@ -264,6 +264,10 @@ typedef struct lang_input_statement_struct
|
||||
/* Whether to search for this entry as a dynamic archive. */
|
||||
bfd_boolean dynamic;
|
||||
|
||||
/* Whether this entry should cause a DT_NEEDED tag only when
|
||||
satisfying references from regular files, or always. */
|
||||
bfd_boolean as_needed;
|
||||
|
||||
/* Whether to include the entire contents of an archive. */
|
||||
bfd_boolean whole_archive;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Main program of GNU linker.
|
||||
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003
|
||||
2002, 2003, 2004
|
||||
Free Software Foundation, Inc.
|
||||
Written by Steve Chamberlain steve@cygnus.com
|
||||
|
||||
@ -93,6 +93,10 @@ bfd_boolean version_printed;
|
||||
/* Nonzero means link in every member of an archive. */
|
||||
bfd_boolean whole_archive;
|
||||
|
||||
/* Nonzero means create DT_NEEDED entries only if a dynamic library
|
||||
actually satisfies some reference in a regular object. */
|
||||
bfd_boolean as_needed;
|
||||
|
||||
/* TRUE if we should demangle symbol names. */
|
||||
bfd_boolean demangling;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ldmain.h -
|
||||
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2002, 2003
|
||||
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2002, 2003, 2004
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GLD, the Gnu Linker.
|
||||
@ -32,6 +32,7 @@ extern bfd_boolean trace_files;
|
||||
extern bfd_boolean trace_file_tries;
|
||||
extern bfd_boolean version_printed;
|
||||
extern bfd_boolean whole_archive;
|
||||
extern bfd_boolean as_needed;
|
||||
extern bfd_boolean demangling;
|
||||
extern int g_switch_value;
|
||||
extern const char *output_filename;
|
||||
|
14
ld/lexsup.c
14
ld/lexsup.c
@ -1,6 +1,6 @@
|
||||
/* Parse options for the GNU linker.
|
||||
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||
2001, 2002, 2003
|
||||
2001, 2002, 2003, 2004
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GLD, the Gnu Linker.
|
||||
@ -112,6 +112,8 @@ enum option_values
|
||||
OPTION_SPLIT_BY_RELOC,
|
||||
OPTION_SPLIT_BY_FILE ,
|
||||
OPTION_WHOLE_ARCHIVE,
|
||||
OPTION_AS_NEEDED,
|
||||
OPTION_NO_AS_NEEDED,
|
||||
OPTION_WRAP,
|
||||
OPTION_FORCE_EXE_SUFFIX,
|
||||
OPTION_GC_SECTIONS,
|
||||
@ -438,6 +440,10 @@ static const struct ld_option ld_options[] =
|
||||
TWO_DASHES },
|
||||
{ {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE},
|
||||
'\0', NULL, N_("Include all objects from following archives"), TWO_DASHES },
|
||||
{ {"as-needed", no_argument, NULL, OPTION_AS_NEEDED},
|
||||
'\0', NULL, N_("Only set DT_NEEDED for following dynamic libs if used"), TWO_DASHES },
|
||||
{ {"no-as-needed", no_argument, NULL, OPTION_NO_AS_NEEDED},
|
||||
'\0', NULL, N_("Always set DT_NEEDED for following dynamic libs"), TWO_DASHES },
|
||||
{ {"wrap", required_argument, NULL, OPTION_WRAP},
|
||||
'\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES }
|
||||
};
|
||||
@ -1156,6 +1162,12 @@ parse_args (unsigned argc, char **argv)
|
||||
case OPTION_WHOLE_ARCHIVE:
|
||||
whole_archive = TRUE;
|
||||
break;
|
||||
case OPTION_AS_NEEDED:
|
||||
as_needed = TRUE;
|
||||
break;
|
||||
case OPTION_NO_AS_NEEDED:
|
||||
as_needed = FALSE;
|
||||
break;
|
||||
case OPTION_WRAP:
|
||||
add_wrap (optarg);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user