From f1a77b01f4e3a80782171297120e77ab112ce85d Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 16 Mar 2012 15:03:37 -0700 Subject: [PATCH] Add x32 support to ldconfig --- ChangeLog | 19 ++++++ elf/cache.c | 4 ++ sysdeps/generic/ldconfig.h | 1 + sysdeps/unix/sysv/linux/i386/readelflib.c | 68 ++++++++++++--------- sysdeps/unix/sysv/linux/x86_64/dl-cache.h | 29 ++++++++- sysdeps/unix/sysv/linux/x86_64/ldconfig.h | 1 + sysdeps/unix/sysv/linux/x86_64/readelflib.c | 63 +------------------ 7 files changed, 95 insertions(+), 90 deletions(-) diff --git a/ChangeLog b/ChangeLog index 05aa925ed9..1664b9c020 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2012-03-16 H.J. Lu + + * sysdeps/generic/ldconfig.h (FLAG_X8664_LIBX32): New macro. + * elf/cache.c (print_entry): Handle FLAG_X8664_LIBX32. + + * sysdeps/unix/sysv/linux/i386/readelflib.c (process_elf_file): + Move e_machine check before EI_CLASS check. Handle x32 + libraries. Check EM_IA_64 only if SKIP_EM_IA_64 isn't defined. + * sysdeps/unix/sysv/linux/x86_64/readelflib.c: Just define + SKIP_EM_IA_64 and include + . + + * sysdeps/unix/sysv/linux/x86_64/dl-cache.h: + Don't include . + (add_system_dir): New macro. + + * sysdeps/unix/sysv/linux/x86_64/ldconfig.h + (SYSDEP_KNOWN_INTERPRETER_NAMES): Add /libx32/ld-linux-x32.so.2. + 2012-03-16 Joseph Myers [BZ #2551] diff --git a/elf/cache.c b/elf/cache.c index dadab9132b..db8b9fa2fa 100644 --- a/elf/cache.c +++ b/elf/cache.c @@ -90,6 +90,10 @@ print_entry (const char *lib, int flag, unsigned int osversion, break; case FLAG_MIPS64_LIBN64: fputs (",64bit", stdout); + break; + case FLAG_X8664_LIBX32: + fputs (",x32", stdout); + break; case 0: break; default: diff --git a/sysdeps/generic/ldconfig.h b/sysdeps/generic/ldconfig.h index 7e93ea8e50..ef3f4b99cb 100644 --- a/sysdeps/generic/ldconfig.h +++ b/sysdeps/generic/ldconfig.h @@ -33,6 +33,7 @@ #define FLAG_POWERPC_LIB64 0x0500 #define FLAG_MIPS64_LIBN32 0x0600 #define FLAG_MIPS64_LIBN64 0x0700 +#define FLAG_X8664_LIBX32 0x0800 /* Name of auxiliary cache. */ #define _PATH_LDCONFIG_AUX_CACHE "/var/cache/ldconfig/aux-cache" diff --git a/sysdeps/unix/sysv/linux/i386/readelflib.c b/sysdeps/unix/sysv/linux/i386/readelflib.c index bdd5e70bc8..fab830ef5b 100644 --- a/sysdeps/unix/sysv/linux/i386/readelflib.c +++ b/sysdeps/unix/sysv/linux/i386/readelflib.c @@ -32,40 +32,52 @@ process_elf_file (const char *file_name, const char *lib, int *flag, size_t file_length) { ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents; - int ret; + int ret, file_flag = 0; - if (elf_header->e_ident [EI_CLASS] == ELFCLASS32) - return process_elf32_file (file_name, lib, flag, osversion, soname, - file_contents, file_length); - else + switch (elf_header->e_machine) { - switch (elf_header->e_machine) + case EM_X86_64: + if (elf_header->e_ident[EI_CLASS] == ELFCLASS64) + /* X86-64 64bit libraries are always libc.so.6+. */ + file_flag = FLAG_X8664_LIB64|FLAG_ELF_LIBC6; + else + /* X32 libraries are always libc.so.6+. */ + file_flag = FLAG_X8664_LIBX32|FLAG_ELF_LIBC6; + break; +#ifndef SKIP_EM_IA_64 + case EM_IA_64: + if (elf_header->e_ident[EI_CLASS] == ELFCLASS64) { - case EM_IA_64: - case EM_X86_64: + /* IA64 64bit libraries are always libc.so.6+. */ + file_flag = FLAG_IA64_LIB64|FLAG_ELF_LIBC6; break; - default: - error (0, 0, _("%s is for unknown machine %d.\n"), - file_name, elf_header->e_machine); - return 1; } - - ret = process_elf64_file (file_name, lib, flag, osversion, soname, - file_contents, file_length); - /* IA64/X86-64 64bit libraries are always libc.so.6+. */ - if (!ret) - switch (elf_header->e_machine) - { - case EM_IA_64: - *flag = FLAG_IA64_LIB64|FLAG_ELF_LIBC6; - break; - case EM_X86_64: - *flag = FLAG_X8664_LIB64|FLAG_ELF_LIBC6; - break; - } - - return ret; + goto failed; +#endif + case EM_386: + if (elf_header->e_ident[EI_CLASS] == ELFCLASS32) + break; + /* Fall through. */ + default: +#ifndef SKIP_EM_IA_64 +failed: +#endif + error (0, 0, _("%s is for unknown machine %d.\n"), + file_name, elf_header->e_machine); + return 1; } + + if (elf_header->e_ident[EI_CLASS] == ELFCLASS32) + ret = process_elf32_file (file_name, lib, flag, osversion, soname, + file_contents, file_length); + else + ret = process_elf64_file (file_name, lib, flag, osversion, soname, + file_contents, file_length); + + if (!ret && file_flag) + *flag = file_flag; + + return ret; } #undef __ELF_NATIVE_CLASS diff --git a/sysdeps/unix/sysv/linux/x86_64/dl-cache.h b/sysdeps/unix/sysv/linux/x86_64/dl-cache.h index 8463fea3d9..e14151d42b 100644 --- a/sysdeps/unix/sysv/linux/x86_64/dl-cache.h +++ b/sysdeps/unix/sysv/linux/x86_64/dl-cache.h @@ -21,4 +21,31 @@ #define _dl_cache_check_flags(flags) \ ((flags) == _DL_CACHE_DEFAULT_ID) -#include +#define add_system_dir(dir) \ + do \ + { \ + size_t len = strlen (dir); \ + char path[len + 4]; \ + memcpy (path, dir, len + 1); \ + if (len >= 6 && ! memcmp (path + len - 6, "/lib64", 6)) \ + { \ + len -= 2; \ + path[len] = '\0'; \ + } \ + else if (len >= 7 \ + && ! memcmp (path + len - 7, "/libx32", 7)) \ + { \ + len -= 3; \ + path[len] = '\0'; \ + } \ + add_dir (path); \ + if (len >= 4 && ! memcmp (path + len - 4, "/lib", 4)) \ + { \ + memcpy (path + len, "64", 3); \ + add_dir (path); \ + memcpy (path + len, "x32", 4); \ + add_dir (path); \ + } \ + } while (0) + +#include diff --git a/sysdeps/unix/sysv/linux/x86_64/ldconfig.h b/sysdeps/unix/sysv/linux/x86_64/ldconfig.h index af4d1b5ad9..6f5b828f44 100644 --- a/sysdeps/unix/sysv/linux/x86_64/ldconfig.h +++ b/sysdeps/unix/sysv/linux/x86_64/ldconfig.h @@ -19,6 +19,7 @@ #define SYSDEP_KNOWN_INTERPRETER_NAMES \ { "/lib/ld-linux.so.2", FLAG_ELF_LIBC6 }, \ + { "/libx32/ld-linux-x32.so.2", FLAG_ELF_LIBC6 }, \ { "/lib64/ld-linux-x86-64.so.2", FLAG_ELF_LIBC6 }, #define SYSDEP_KNOWN_LIBRARY_NAMES \ { "libc.so.6", FLAG_ELF_LIBC6 }, \ diff --git a/sysdeps/unix/sysv/linux/x86_64/readelflib.c b/sysdeps/unix/sysv/linux/x86_64/readelflib.c index 7aa68ff7e5..4c4e5f9d1a 100644 --- a/sysdeps/unix/sysv/linux/x86_64/readelflib.c +++ b/sysdeps/unix/sysv/linux/x86_64/readelflib.c @@ -1,61 +1,2 @@ -/* Copyright (C) 1999, 2001, 2002, 2005 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Andreas Jaeger , 1999 and - Jakub Jelinek , 1999. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - - -int process_elf32_file (const char *file_name, const char *lib, int *flag, - unsigned int *osversion, char **soname, - void *file_contents, size_t file_length); -int process_elf64_file (const char *file_name, const char *lib, int *flag, - unsigned int *osversion, char **soname, - void *file_contents, size_t file_length); - -/* Returns 0 if everything is ok, != 0 in case of error. */ -int -process_elf_file (const char *file_name, const char *lib, int *flag, - unsigned int *osversion, char **soname, void *file_contents, - size_t file_length) -{ - ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents; - int ret; - - if (elf_header->e_ident [EI_CLASS] == ELFCLASS32) - return process_elf32_file (file_name, lib, flag, osversion, soname, - file_contents, file_length); - else - { - ret = process_elf64_file (file_name, lib, flag, osversion, soname, - file_contents, file_length); - /* x86-64 64bit libraries are always libc.so.6+. */ - if (!ret) - *flag = FLAG_X8664_LIB64|FLAG_ELF_LIBC6; - return ret; - } -} - -#undef __ELF_NATIVE_CLASS -#undef process_elf_file -#define process_elf_file process_elf32_file -#define __ELF_NATIVE_CLASS 32 -#include "elf/readelflib.c" - -#undef __ELF_NATIVE_CLASS -#undef process_elf_file -#define process_elf_file process_elf64_file -#define __ELF_NATIVE_CLASS 64 -#include "elf/readelflib.c" +#define SKIP_EM_IA_64 +#include