From mboxrd@z Thu Jan 1 00:00:00 1970 From: hjl@nynexst.com (H.J. Lu) To: ian@cygnus.com (Ian Lance Taylor) Cc: gas2@cygnus.com, eric@aib.com (Eric Youngdale) Subject: A patch for gas-950313 Date: Mon, 13 Mar 1995 13:17:00 -0000 Message-id: <9503132109.AA27504@titanic.nynexst.com> X-SW-Source: 1995/msg00050.html There are two patches. One fixed a bug for SunOS. The other added the SunOS style of searching .so files to ELF. -- H.J. Lu NYNEX Science and Technology, Inc. hjl@nynexst.com --- *** sunos.em.orig Fri Dec 2 17:25:52 1994 --- sunos.em Mon Mar 13 16:00:59 1995 *************** *** 116,121 **** --- 116,123 ---- len = strlen (filename); else { + /* Get the major number */ + force_maj = strtoul (dot [1], NULL, 10); len = dot - filename; alc = (char *) alloca (len + 1); strncpy (alc, filename, len); *** elf32.em.orig Mon Mar 13 08:35:46 1995 --- elf32.em Mon Mar 13 16:01:02 1995 *************** *** 43,48 **** --- 43,55 ---- #include "ldlang.h" #include "ldgram.h" + + /* FIXME: On some hosts we will need to include a different file. + This is correct for ELF/SVR4, which is the only place this file will + typically be compiled. However, if somebody configures the linker + for all targets, they will run into trouble here. */ + #include + static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); static boolean gld${EMULATION_NAME}_open_dynamic_archive PARAMS ((const char *, lang_input_statement_type *)); *************** *** 63,68 **** --- 70,220 ---- config.dynamic_link = ${DYNAMIC_LINK-true}; } + /* Try to open a BFD for a lang_input_statement. */ + + static boolean + try_open_bfd (attempt, entry) + const char *attempt; + lang_input_statement_type *entry; + { + entry->the_bfd = bfd_openr (attempt, entry->target); + + if (trace_file_tries) + info_msg ("attempt to open %s %s\n", attempt, + entry->the_bfd == NULL ? "failed" : "succeeded"); + + if (entry->the_bfd != NULL) + return true; + else + return false; + } + + /* Search for and open the .so file specified by ENTRY. */ + + static boolean + gld${EMULATION_NAME}_find_so (entry) + lang_input_statement_type *entry; + { + search_dirs_type *search; + int max_maj, max_min, max_patch; + int force_maj; + const char *filename; + const char *dot; + char *alc; + unsigned int len; + #ifndef PATH_MAX + #ifdef MAXPATHLEN + #define PATH_MAX MAXPATHLEN + #else + #define PATH_MAX 1024 + #endif + #endif + char string [PATH_MAX + 4]; + char found [PATH_MAX + 4]; + + force_maj = -1; + filename = entry->filename; + dot = strchr (filename, '.'); + if (dot == NULL) + len = strlen (filename); + else + { + /* Get the major number */ + force_maj = strtoul (dot [1], NULL, 10); + len = dot - filename; + alc = (char *) alloca (len + 1); + strncpy (alc, filename, len); + alc[len] = '\0'; + filename = alc; + } + + found [0] = '\0'; + max_maj = max_min = max_patch = 0; + for (search = search_head; + search != (search_dirs_type *)NULL; + search = search->next) + { + DIR *dir; + struct dirent *ent; + + /* No forced major release number. */ + if (dot == NULL) + { + sprintf (string, "%s/lib%s.so", search->name, filename); + + /* First try the straight .so file. */ + if (try_open_bfd (string, entry)) + { + entry->filename = strdup (string); + return true; + } + } + + /* Then we try the fancy ones. */ + dir = opendir (search->name); + if (dir == NULL) + continue; + + while ((ent = readdir (dir)) != NULL) + { + int found_maj, found_min, found_patch; + + /* We are looking for libxxxx.so.x.x.x and not libxxxx.so. */ + if (ent->d_name [6 + len] == '\0' + || strncmp (ent->d_name, "lib", 3) != 0 + || strncmp (ent->d_name + 3, filename, len) != 0 + || strncmp (ent->d_name + 3 + len, ".so", 3) != 0) + continue; + + /* We've found a .so.x.x.x file. Work out the major, minor and + patch numbers. */ + found_maj = found_min = found_patch = 0; + if (sscanf (ent->d_name + 3 + len, ".so.%d.%d.%d", + &found_maj, &found_min, &found_patch) <= 0) + continue; + + if (force_maj != -1 && force_maj != found_maj) + continue; + + /* We've found a match for the name we are searching for. + See if this is the version we should use. */ + if (found [0] == '\0' || (found_maj > max_maj) + || (found_maj == max_maj + && (found_min > max_min + || (found_min == max_min + && found_patch > max_patch)))) + { + strcpy (found, ent->d_name); + max_maj = found_maj; + max_min = found_min; + max_patch = found_patch; + } + } + + closedir (dir); + + if (found [0] != '\0') + { + /* Give it a try */ + sprintf (string, "%s/%s", search->name, found); + + if (try_open_bfd (string, entry)) + { + entry->filename = strdup (string); + return true; + } + else + { + /* We have to start all over again. */ + found [0] = '\0'; + max_maj = max_min = max_patch = 0; + } + } + } + + return false; + } + /* Try to open a dynamic archive. This is where we know that ELF dynamic libraries have an extension of .so. */ *************** *** 75,81 **** filename = entry->filename; ! if (! ldfile_open_file_search (arch, entry, "lib", ".so")) return false; /* We have found a dynamic object to include in the link. The ELF --- 227,233 ---- filename = entry->filename; ! if (! gld${EMULATION_NAME}_find_so (entry)) return false; /* We have found a dynamic object to include in the link. The ELF