From e56f61be758d90c463cc220c50ad7f30b955c2af Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 19 Jul 2004 16:40:52 +0000 Subject: bfd/ 2004-07-19 H.J. Lu * bfd-in.h (dynamic_lib_link_class): Add DYN_NO_ADD_NEEDED and DYN_NO_NEEDED. (bfd_elf_get_dyn_lib_class): New prototype. * elf.c (bfd_elf_get_dyn_lib_class): New function. * elflink.c (elf_link_add_object_symbols): Check DYN_AS_NEEDED, DYN_DT_NEEDED and DYN_NO_NEEDED bits to see if a DT_NEEDED entry is needed. Issue an error if a DT_NEEDED entry is needed for a file marked DYN_NO_NEEDED. (elf_link_check_versioned_symbol): Check the DYN_DT_NEEDED bit for DT_NEEDED tags. * bfd-in2.h: Regenerated. ld/ 2004-07-19 H.J. Lu * emultempl/elf32.em (gld${EMULATION_NAME}_load_symbols): Also check the add_needed field. (dt_needed): New struct. (gld${EMULATION_NAME}_try_needed): Change the first argument to a pointer to struct dt_needed. Check the DYN_NO_ADD_NEEDED bit in the file where the DT_NEEDED entry comes from. (gld${EMULATION_NAME}_search_needed): Change the second argument to a pointer to struct dt_needed. (gld${EMULATION_NAME}_check_ld_so_conf): Updated. (gld${EMULATION_NAME}_after_open): Likewise. * ld.texinfo: Add --add-needed document. * ldlang.c (new_afile): Set p->add_needed. * ldlang.h (lang_input_statement_type): Add add_needed field. * ldmain.h (add_needed): Declare. * ldmain.c (add_needed): New global var. * lexsup.c (option_values): Add OPTION_ADD_NEEDED and OPTION_NO_ADD_NEEDED. (ld_options): Likewise. (parse_args): Handle them. --- bfd/ChangeLog | 16 ++++++++++++++++ bfd/bfd-in.h | 6 +++++- bfd/bfd-in2.h | 8 ++++++-- bfd/elf.c | 12 ++++++++++++ bfd/elflink.c | 23 +++++++++++++++++++---- 5 files changed, 58 insertions(+), 7 deletions(-) (limited to 'bfd') diff --git a/bfd/ChangeLog b/bfd/ChangeLog index db7ada4..aa3f6f8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,19 @@ +2004-07-19 H.J. Lu + + * bfd-in.h (dynamic_lib_link_class): Add DYN_NO_ADD_NEEDED and + DYN_NO_NEEDED. + (bfd_elf_get_dyn_lib_class): New prototype. + * elf.c (bfd_elf_get_dyn_lib_class): New function. + + * elflink.c (elf_link_add_object_symbols): Check DYN_AS_NEEDED, + DYN_DT_NEEDED and DYN_NO_NEEDED bits to see if a DT_NEEDED + entry is needed. Issue an error if a DT_NEEDED entry is needed + for a file marked DYN_NO_NEEDED. + (elf_link_check_versioned_symbol): Check the DYN_DT_NEEDED bit + for DT_NEEDED tags. + + * bfd-in2.h: Regenerated. + 2004-07-14 John David Anglin * elflink.c (elf_section_complain_discarded): Don't complain in diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index 97296c8..f48e9d7 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -625,7 +625,9 @@ struct bfd_link_needed_list enum dynamic_lib_link_class { DYN_NORMAL = 0, DYN_AS_NEEDED = 1, - DYN_DT_NEEDED = 2 + DYN_DT_NEEDED = 2, + DYN_NO_ADD_NEEDED = 4, + DYN_NO_NEEDED = 8 }; extern bfd_boolean bfd_elf_record_link_assignment @@ -643,6 +645,8 @@ extern const char *bfd_elf_get_dt_soname (bfd *); extern void bfd_elf_set_dyn_lib_class (bfd *, int); +extern int bfd_elf_get_dyn_lib_class + (bfd *); extern struct bfd_link_needed_list *bfd_elf_get_runpath_list (bfd *, struct bfd_link_info *); extern bfd_boolean bfd_elf_discard_info diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index f3b1761..502a01b 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -632,7 +632,9 @@ struct bfd_link_needed_list enum dynamic_lib_link_class { DYN_NORMAL = 0, DYN_AS_NEEDED = 1, - DYN_DT_NEEDED = 2 + DYN_DT_NEEDED = 2, + DYN_NO_ADD_NEEDED = 4, + DYN_NO_NEEDED = 8 }; extern bfd_boolean bfd_elf_record_link_assignment @@ -650,6 +652,8 @@ extern const char *bfd_elf_get_dt_soname (bfd *); extern void bfd_elf_set_dyn_lib_class (bfd *, int); +extern int bfd_elf_get_dyn_lib_class + (bfd *); extern struct bfd_link_needed_list *bfd_elf_get_runpath_list (bfd *, struct bfd_link_info *); extern bfd_boolean bfd_elf_discard_info @@ -1756,7 +1760,7 @@ enum bfd_architecture #define bfd_mach_avr5 5 bfd_arch_cr16c, /* National Semiconductor CompactRISC. */ #define bfd_mach_cr16c 1 - bfd_arch_crx, /* National Semiconductor CRX. */ + bfd_arch_crx, /* National Semiconductor CRX. */ #define bfd_mach_crx 1 bfd_arch_cris, /* Axis CRIS */ bfd_arch_s390, /* IBM s390 */ diff --git a/bfd/elf.c b/bfd/elf.c index 1cf2dc0..4371f15 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1514,6 +1514,18 @@ bfd_elf_set_dt_needed_name (bfd *abfd, const char *name) elf_dt_name (abfd) = name; } +int +bfd_elf_get_dyn_lib_class (bfd *abfd) +{ + int lib_class; + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour + && bfd_get_format (abfd) == bfd_object) + lib_class = elf_dyn_lib_class (abfd); + else + lib_class = 0; + return lib_class; +} + void bfd_elf_set_dyn_lib_class (bfd *abfd, int lib_class) { diff --git a/bfd/elflink.c b/bfd/elflink.c index a6dafae..4920d9d 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -3064,8 +3064,13 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) /* 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. Similary for libs brought - in by another lib's DT_NEEDED. */ - add_needed = elf_dyn_lib_class (abfd) == DYN_NORMAL; + in by another lib's DT_NEEDED. When --no-add-needed is used + on a dynamic lib, we don't want to add a DT_NEEDED entry for + any dynamic library in DT_NEEDED tags in the dynamic lib at + all. */ + add_needed = (elf_dyn_lib_class (abfd) + & (DYN_AS_NEEDED | DYN_DT_NEEDED + | DYN_NO_NEEDED)) == 0; s = bfd_get_section_by_name (abfd, ".dynamic"); if (s != NULL) @@ -3846,7 +3851,17 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) /* 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 a DT_NEEDED entry for it. Issue an error if + --no-add-needed is used. */ + if ((elf_dyn_lib_class (abfd) & DYN_NO_NEEDED) != 0) + { + (*_bfd_error_handler) + (_("%s: invalid DSO for symbol `%s' definition"), + bfd_archive_filename (abfd), name); + bfd_set_error (bfd_error_bad_value); + goto error_free_vers; + } + add_needed = TRUE; ret = elf_add_dt_needed_tag (info, soname, add_needed); if (ret < 0) @@ -5818,7 +5833,7 @@ elf_link_check_versioned_symbol (struct bfd_link_info *info, case bfd_link_hash_undefweak: abfd = h->root.u.undef.abfd; if ((abfd->flags & DYNAMIC) == 0 - || elf_dyn_lib_class (abfd) != DYN_DT_NEEDED) + || (elf_dyn_lib_class (abfd) & DYN_DT_NEEDED) == 0) return FALSE; break; -- cgit v1.1