From 8055e7a883528d953d6c6bac61a40df86b24ccb5 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 2 Oct 1995 17:59:14 +0000 Subject: [PATCH] * emultempl/elf32.em (global_stat): New file static variable. (gld${EMULATION_NAME}_try_needed): Call stat_needed to make sure that the file has not already been included under another name. (gld${EMULATION_NAME}_stat_needed): New static function. --- ld/ChangeLog | 7 ++++++ ld/emultempl/elf32.em | 56 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index 3323762746..237c941c2e 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +Mon Oct 2 13:56:09 1995 Ian Lance Taylor + + * emultempl/elf32.em (global_stat): New file static variable. + (gld${EMULATION_NAME}_try_needed): Call stat_needed to make sure + that the file has not already been included under another name. + (gld${EMULATION_NAME}_stat_needed): New static function. + Fri Sep 29 12:00:18 1995 Doug Evans * scripttempl/armcoff.sc: Start .text at 0x8000. diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 6f11bbf144..d55b8f51f0 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -48,6 +48,8 @@ static boolean gld${EMULATION_NAME}_open_dynamic_archive static void gld${EMULATION_NAME}_after_open PARAMS ((void)); static void gld${EMULATION_NAME}_check_needed PARAMS ((lang_input_statement_type *)); +static void gld${EMULATION_NAME}_stat_needed + PARAMS ((lang_input_statement_type *)); static boolean gld${EMULATION_NAME}_search_needed PARAMS ((const char *, const char *)); static boolean gld${EMULATION_NAME}_try_needed PARAMS ((const char *)); @@ -130,9 +132,10 @@ gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) } /* These variables are required to pass information back and forth - between after_open and check_needed. */ + between after_open and check_needed and stat_needed. */ static struct bfd_elf_link_needed_list *global_needed; +static struct stat global_stat; static boolean global_found; /* This is called after all the input files have been opened. */ @@ -275,6 +278,25 @@ gld${EMULATION_NAME}_try_needed (name) /* We've found a dynamic object matching the DT_NEEDED entry. */ + /* We have already checked that there is no other input file of the + same name. We must now check again that we are not including the + same file twice. We need to do this because on many systems + libc.so is a symlink to, e.g., libc.so.1. The SONAME entry will + reference libc.so.1. If we have already included libc.so, we + don't want to include libc.so.1 if they are the same file, and we + can only check that using stat. */ + + if (bfd_stat (abfd, &global_stat) != 0) + einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd); + global_found = false; + lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed); + if (global_found) + { + /* Return true to indicate that we found the file, even though + we aren't going to do anything with it. */ + return true; + } + /* Tell the ELF backend that don't want the output file to have a DT_NEEDED entry for this file. */ bfd_elf_set_dt_needed_name (abfd, ""); @@ -286,7 +308,7 @@ gld${EMULATION_NAME}_try_needed (name) return true; } -/* See if an input file matches a DT_NEEDED entry. */ +/* See if an input file matches a DT_NEEDED entry by name. */ static void gld${EMULATION_NAME}_check_needed (s) @@ -308,6 +330,30 @@ gld${EMULATION_NAME}_check_needed (s) } } +/* See if an input file matches a DT_NEEDED entry by running stat on + the file. */ + +static void +gld${EMULATION_NAME}_stat_needed (s) + lang_input_statement_type *s; +{ + if (global_found) + return; + if (s->the_bfd != NULL) + { + struct stat st; + + if (bfd_stat (s->the_bfd, &st) != 0) + einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd); + else + { + if (st.st_dev == global_stat.st_dev + && st.st_ino == global_stat.st_ino) + global_found = true; + } + } +} + /* This is called after the sections have been attached to output sections, but before any sizes or addresses have been set. */ @@ -365,8 +411,10 @@ gld${EMULATION_NAME}_before_allocation () einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n", is->the_bfd); msg[sz] = '\0'; - ret = link_info.callbacks->warning (&link_info, msg, is->the_bfd, - (asection *) NULL, (bfd_vma) 0); + ret = link_info.callbacks->warning (&link_info, msg, + (const char *) NULL, + is->the_bfd, (asection *) NULL, + (bfd_vma) 0); ASSERT (ret); free (msg);