diff options
-rw-r--r-- | trunk/ChangeLog.cross | 12 | ||||
-rw-r--r-- | trunk/src/layout.c | 6 | ||||
-rw-r--r-- | trunk/src/ld-libs.c | 43 |
3 files changed, 51 insertions, 10 deletions
diff --git a/trunk/ChangeLog.cross b/trunk/ChangeLog.cross index 62f7f26..183f962 100644 --- a/trunk/ChangeLog.cross +++ b/trunk/ChangeLog.cross @@ -4,6 +4,18 @@ 2006-11-28 Mark Shinwell <shinwell@codesourcery.com> + * src/layout.c (layout_libs): Add assertion to check for buffer + overflow. + * src/ld-libs.c (find_lib_in_path): Add "machine" argument. + Skip libraries whose ELF machine type field does not match + that argument. + (find_lib_by_soname): Add "machine" argument. Pass it to + find_lib_in_path. + (load_dsos): Determine machine type of input DSO. Pass it + to find_lib_by_soname. + + 2006-11-28 Mark Shinwell <shinwell@codesourcery.com> + * src/gather.c (maybe_pie): New. (gather_func): Use it. diff --git a/trunk/src/layout.c b/trunk/src/layout.c index 9292425..9e521e1 100644 --- a/trunk/src/layout.c +++ b/trunk/src/layout.c @@ -23,6 +23,7 @@ #include <string.h> #include <time.h> #include <unistd.h> +#include <assert.h> #include "prelinktab.h" #include "layout.h" @@ -298,7 +299,10 @@ layout_libs (void) for (j = 0, k = 0; j < l.binlibs[i]->ndepends; ++j) if (l.binlibs[i]->depends[j]->type == ET_DYN && l.binlibs[i]->depends[j]->done) - deps[k++] = l.binlibs[i]->depends[j]; + { + assert (k < l.nlibs); + deps[k++] = l.binlibs[i]->depends[j]; + } if (k) { qsort (deps, k, sizeof (struct prelink_entry *), deps_cmp); diff --git a/trunk/src/ld-libs.c b/trunk/src/ld-libs.c index f36eee1..d159821 100644 --- a/trunk/src/ld-libs.c +++ b/trunk/src/ld-libs.c @@ -384,10 +384,24 @@ string_to_path (struct search_path *path, const char *string) char * find_lib_in_path (struct search_path *path, const char *soname, - int elfclass) + int elfclass, int machine) { char *ret; int i; + int alt_machine; + + switch (machine) + { + case EM_SPARC: + alt_machine = EM_SPARC32PLUS; + break; + case EM_SPARC32PLUS: + alt_machine = EM_SPARC; + break; + default: + alt_machine = machine; + break; + } ret = malloc (strlen (soname) + 2 + path->maxlen); @@ -396,13 +410,19 @@ find_lib_in_path (struct search_path *path, const char *soname, sprintf (ret, "%s/%s", path->dirs[i], soname); if (wrap_access (ret, F_OK) == 0) { - /* Skip 32-bit libraries when looking for 64-bit. */ DSO *dso = open_dso (ret); + int dso_class = gelf_getclass (dso->elf); + int dso_machine = (dso_class == ELFCLASS32) ? + elf32_getehdr (dso->elf)->e_machine : + elf64_getehdr (dso->elf)->e_machine; if (dso == NULL) continue; - if (gelf_getclass (dso->elf) != elfclass) + /* Skip 32-bit libraries when looking for 64-bit. Also + skip libraries for alternative machines. */ + if (gelf_getclass (dso->elf) != elfclass + || (dso_machine != machine && dso_machine != alt_machine)) { close_dso (dso); continue; @@ -419,7 +439,7 @@ find_lib_in_path (struct search_path *path, const char *soname, char * find_lib_by_soname (const char *soname, struct dso_list *loader, - int elfclass) + int elfclass, int machine) { char *ret; @@ -441,7 +461,7 @@ find_lib_by_soname (const char *soname, struct dso_list *loader, NULL, NULL); memset (&r_path, 0, sizeof (r_path)); string_to_path (&r_path, rpath); - ret = find_lib_in_path (&r_path, soname, elfclass); + ret = find_lib_in_path (&r_path, soname, elfclass, machine); free_path (&r_path); if (ret) return ret; @@ -450,7 +470,7 @@ find_lib_by_soname (const char *soname, struct dso_list *loader, } } - ret = find_lib_in_path (&ld_library_search_path, soname, elfclass); + ret = find_lib_in_path (&ld_library_search_path, soname, elfclass, machine); if (ret) return ret; @@ -463,13 +483,13 @@ find_lib_by_soname (const char *soname, struct dso_list *loader, NULL, NULL); memset (&r_path, 0, sizeof (r_path)); string_to_path (&r_path, rpath); - ret = find_lib_in_path (&r_path, soname, elfclass); + ret = find_lib_in_path (&r_path, soname, elfclass, machine); free_path (&r_path); if (ret) return ret; } - ret = find_lib_in_path (&ld_dirs, soname, elfclass); + ret = find_lib_in_path (&ld_dirs, soname, elfclass, machine); if (ret) return ret; @@ -527,8 +547,13 @@ load_dsos (DSO *dso) new_dso_ent = in_dso_list (dso_list, soname, NULL); if (new_dso_ent == NULL) { + int machine; + int class = gelf_getclass (dso->elf); + machine = (class == ELFCLASS32) ? + elf32_getehdr (dso->elf)->e_machine : + elf64_getehdr (dso->elf)->e_machine; new_name = find_lib_by_soname (soname, cur_dso_ent, - gelf_getclass (dso->elf)); + class, machine); if (new_name == 0 || wrap_access (new_name, R_OK) < 0) { dso_open_error ++; |