diff options
author | Ian Lance Taylor <ian@airs.com> | 1995-10-02 17:59:14 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1995-10-02 17:59:14 +0000 |
commit | 8055e7a883528d953d6c6bac61a40df86b24ccb5 (patch) | |
tree | 39a7077ad8e3567bf1164888f29fab68f5bb3675 /ld | |
parent | a6eed1d25f5fa83cfa4e56f2ac8e35792ab44266 (diff) | |
download | gdb-8055e7a883528d953d6c6bac61a40df86b24ccb5.zip gdb-8055e7a883528d953d6c6bac61a40df86b24ccb5.tar.gz gdb-8055e7a883528d953d6c6bac61a40df86b24ccb5.tar.bz2 |
* 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.
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ChangeLog | 7 | ||||
-rw-r--r-- | ld/emultempl/elf32.em | 56 |
2 files changed, 59 insertions, 4 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 3323762..237c941 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +Mon Oct 2 13:56:09 1995 Ian Lance Taylor <ian@cygnus.com> + + * 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 <dje@deneb.cygnus.com> * scripttempl/armcoff.sc: Start .text at 0x8000. diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 6f11bbf..d55b8f5 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); |