summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-08-25 19:15:32 +0000
committerJakub Jelinek <jakub@redhat.com>2007-08-25 19:15:32 +0000
commit9abaa7d89fe873eeebda1bd227fde5d5bd6ab332 (patch)
treefa664da72118e93ec5204730a51dc2ebf62e99eb
parentdd3394742b3e2e01f403b1c1b41ed39273b2212e (diff)
workaround for ia64 /emul/ia32-linux crapcvs/fedora-glibc-2_6_90-12
-rw-r--r--fedora/glibc.spec.in1
-rw-r--r--fedora/glibc_post_upgrade.c44
2 files changed, 43 insertions, 2 deletions
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index 1292c84457..82f63be9ad 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -1013,6 +1013,7 @@ rm -f *.filelist*
* Sat Aug 25 2007 Jakub Jelinek <jakub@redhat.com> 2.6.90-12
- readd x86_64 gettimeofday stuff, initialize it earlier
- nis_list fix (#254115)
+- workaround for bugs in ia64 silly /emul/ia32-linux hack (#253961)
- misc fixes (BZ#3924, BZ#4566, BZ#4582, BZ#4588, BZ#4726, BZ#4946,
BZ#4905, BZ#4814, BZ#4925, BZ#4936, BZ#4896, BZ#4937, BZ#3842,
BZ#4554, BZ#4557, BZ#4938)
diff --git a/fedora/glibc_post_upgrade.c b/fedora/glibc_post_upgrade.c
index cde931bde3..150b9495ac 100644
--- a/fedora/glibc_post_upgrade.c
+++ b/fedora/glibc_post_upgrade.c
@@ -27,6 +27,39 @@ __attribute__((noinline)) void sayn (long num);
__attribute__((noinline)) void message (char *const path[]);
__attribute__((noinline)) int check_elf (const char *name);
+#ifdef __i386__
+static int
+is_ia64 (void)
+{
+ unsigned int fl1, fl2;
+
+ /* See if we can use cpuid. */
+ __asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
+ "pushl %0; popfl; pushfl; popl %0; popfl"
+ : "=&r" (fl1), "=&r" (fl2)
+ : "i" (0x00200000));
+ if (((fl1 ^ fl2) & 0x00200000) == 0)
+ return 0;
+
+ /* Host supports cpuid. See if cpuid gives capabilities, try
+ CPUID(0). Preserve %ebx and %ecx; cpuid insn clobbers these, we
+ don't need their CPUID values here, and %ebx may be the PIC
+ register. */
+ __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
+ : "=a" (fl1) : "0" (0) : "edx", "cc");
+ if (fl1 == 0)
+ return 0;
+
+ /* Invoke CPUID(1), return %edx; caller can examine bits to
+ determine what's supported. */
+ __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
+ : "=d" (fl2), "=a" (fl1) : "1" (1) : "cc");
+ return (fl2 & (1 << 30)) != 0;
+}
+#else
+#define is_ia64() 0
+#endif
+
int
main (void)
{
@@ -122,9 +155,16 @@ main (void)
#ifndef ICONVCONFIG
#define ICONVCONFIG "/usr/sbin/iconvconfig"
#endif
+ const char *iconv_cache = GCONV_MODULES_DIR"/gconv-modules.cache";
+ const char *iconv_dir = GCONV_MODULES_DIR;
+ if (is_ia64 ())
+ {
+ iconv_cache = "/emul/ia32-linux"GCONV_MODULES_DIR"/gconv-modules.cache";
+ iconv_dir = "/emul/ia32-linux"GCONV_MODULES_DIR;
+ }
verbose_exec (113, ICONVCONFIG, "/usr/sbin/iconvconfig",
- "-o", GCONV_MODULES_DIR"/gconv-modules.cache",
- "--nostdlib", GCONV_MODULES_DIR);
+ "-o", iconv_cache,
+ "--nostdlib", iconv_dir);
}
/* Check if telinit is available and the init fifo as well. */