Sophie

Sophie

distrib > * > 2008.0 > x86_64 > by-pkgid > 87dc1a2706a77349d29456c1e1087866 > files > 13

binutils-2.17.50.0.12-1mdv2008.0.src.rpm

2006-12-11  Gwenole Beauchesne  <gbeauchesne@mandriva.com>

	* gas/config/tc-ppc.c (ppc_get_obj64): New. Handle run-time
	detection of 32-bit personality on Linux for ppc64 so that 32-bit
	code can be generated.
	(ppc_set_obj64): New.
	(md_parse_option): Use it.

2005-01-19  Gwenole Beauchesne  <gbeauchesne@mandrakesoft.com>

	* gas/config/tc-i386.c (is_linux32): New.
	(get_default_arch): Handle detection of 32-bit personality on
	Linux for x86-64 so that 32-bit code can be generated.
	(set_default_arch): New.
	(md_parse_option): Use it.
	(i386_mach): Use new default_arch accessors.
	(i386_target_format): Likewise.

--- binutils-2.17.50.0.8/gas/config/tc-ppc.c.linux32	2006-11-27 23:21:04.000000000 +0100
+++ binutils-2.17.50.0.8/gas/config/tc-ppc.c	2007-01-03 15:46:03.000000000 +0100
@@ -35,6 +35,10 @@
 #include "coff/pe.h"
 #endif
 
+#if defined(__linux__) && defined(__powerpc64__)
+#include <sys/utsname.h>
+#endif
+
 /* This is the assembler for the PowerPC or POWER (RS/6000) chips.  */
 
 /* Tell the main code what the endianness is.  */
@@ -92,6 +96,8 @@ static unsigned long ppc_insert_operand
 static void ppc_macro PARAMS ((char *str, const struct powerpc_macro *macro));
 static void ppc_byte PARAMS ((int));
 
+static void ppc_set_obj64 PARAMS ((int));
+
 #if defined (OBJ_XCOFF) || defined (OBJ_ELF)
 static int ppc_is_toc_sym PARAMS ((symbolS *sym));
 static void ppc_tc PARAMS ((int));
@@ -703,7 +709,7 @@ ppc_parse_name (name, expr)
 static unsigned long ppc_cpu = 0;
 
 /* Whether to target xcoff64/elf64.  */
-static unsigned int ppc_obj64 = BFD_DEFAULT_TARGET_SIZE == 64;
+static int g_ppc_obj64 = -1;
 
 /* Opcode hash table.  */
 static struct hash_control *ppc_hash;
@@ -995,13 +1001,13 @@ md_parse_option (c, arg)
       if (strcmp (arg, "64") == 0)
 	{
 #ifdef BFD64
-	  ppc_obj64 = 1;
+	  ppc_set_obj64 (1);
 #else
 	  as_fatal (_("%s unsupported"), "-a64");
 #endif
 	}
       else if (strcmp (arg, "32") == 0)
-	ppc_obj64 = 0;
+	ppc_set_obj64 (0);
       else
 	return 0;
       break;
@@ -1148,6 +1154,37 @@ PowerPC options:\n\
 #endif
 }
 
+/* Set ppc_obj64 if it is not already set.  */
+
+#define ppc_obj64 (ppc_get_obj64 ())
+
+static unsigned int
+ppc_get_obj64 (void)
+{
+  if (g_ppc_obj64 < 0)
+    {
+      g_ppc_obj64 = BFD_DEFAULT_TARGET_SIZE == 64;
+
+#if defined(__linux__) && defined(__powerpc64__)
+      /* Determine if we are running under a 32-bit personality. Don't
+	 use plain personality(0xffffffff) syscall because the kernel lies.  */
+      {
+	struct utsname buf;
+	if (uname(&buf) == 0 && strcmp(buf.machine, "ppc") == 0)
+	  g_ppc_obj64 = 0;
+      }
+#endif
+    }
+
+  return g_ppc_obj64;
+}
+
+static void
+ppc_set_obj64 (int obj64)
+{
+  g_ppc_obj64 = obj64;
+}
+
 /* Set ppc_cpu if it is not already set.  */
 
 static void
--- binutils-2.17.50.0.8/gas/config/tc-i386.c.linux32	2006-11-27 23:21:04.000000000 +0100
+++ binutils-2.17.50.0.8/gas/config/tc-i386.c	2007-01-03 15:48:19.000000000 +0100
@@ -35,6 +35,13 @@
 #include "opcode/i386.h"
 #include "elf/x86-64.h"
 
+#if defined(__linux__) && defined(__x86_64__)
+#include <sys/syscall.h>
+#include <sys/personality.h>
+
+#define is_linux32() ((syscall(SYS_personality, 0xffffffff) & PER_MASK) == PER_LINUX32)
+#endif
+
 #ifndef REGISTER_WARNINGS
 #define REGISTER_WARNINGS 1
 #endif
@@ -117,7 +124,16 @@ static void s_bss PARAMS ((int));
 static void handle_large_common (int small ATTRIBUTE_UNUSED);
 #endif
 
-static const char *default_arch = DEFAULT_ARCH;
+enum x86_arch
+  {
+    ARCH_default,
+    ARCH_i386,
+    ARCH_x86_64
+  };
+
+static enum x86_arch g_default_arch = ARCH_default;
+static enum x86_arch get_default_arch PARAMS ((void));
+static INLINE void set_default_arch PARAMS ((enum x86_arch arch));
 
 /* 'md_assemble ()' gathers together information and puts it into a
    i386_insn.  */
@@ -1204,15 +1220,46 @@ set_cpu_arch (dummy)
   demand_empty_rest_of_line ();
 }
 
+static enum x86_arch
+get_default_arch ()
+{
+  const char *default_arch_str = DEFAULT_ARCH;
+
+  if (g_default_arch != ARCH_default)
+    return g_default_arch;
+
+#ifdef is_linux32
+  if (is_linux32 ())
+    default_arch_str = "i386";
+#endif
+
+  if (!strcmp (default_arch_str, "x86_64"))
+    g_default_arch = ARCH_x86_64;
+  else if (!strcmp (default_arch_str, "i386"))
+    g_default_arch = ARCH_i386;
+
+  return g_default_arch;
+}
+
+static INLINE void
+set_default_arch (arch)
+     enum x86_arch arch;
+{
+  g_default_arch = arch;
+}
+
 unsigned long
 i386_mach ()
 {
-  if (!strcmp (default_arch, "x86_64"))
-    return bfd_mach_x86_64;
-  else if (!strcmp (default_arch, "i386"))
-    return bfd_mach_i386_i386;
-  else
-    as_fatal (_("Unknown architecture"));
+  switch (get_default_arch ())
+    {
+    case ARCH_x86_64:
+      return bfd_mach_x86_64;
+    case ARCH_i386:
+      return bfd_mach_i386_i386;
+    default:
+      as_fatal (_("Unknown architecture"));
+    }
 }
 
 void
@@ -5887,7 +5934,7 @@ md_parse_option (int c, char *arg)
 	      || strcmp (*l, "pe-x86-64") == 0
 	      || strcmp (*l, "pei-x86-64") == 0)
 	    {
-	      default_arch = "x86_64";
+	      set_default_arch (ARCH_x86_64);
 	      break;
 	    }
 	if (*l == NULL)
@@ -5898,7 +5945,7 @@ md_parse_option (int c, char *arg)
 #endif
 
     case OPTION_32:
-      default_arch = "i386";
+      set_default_arch (ARCH_i386);
       break;
 
     case OPTION_DIVIDE:
@@ -6021,8 +6068,9 @@ x86_64_target_format (void)
 const char *
 i386_target_format ()
 {
-  if (!strcmp (default_arch, "x86_64"))
+  switch (get_default_arch ())
     {
+    case ARCH_x86_64:
       set_code_flag (CODE_64BIT);
       if (cpu_arch_isa_flags == 0)
 	cpu_arch_isa_flags = Cpu186|Cpu286|Cpu386|Cpu486
@@ -6032,17 +6080,18 @@ i386_target_format ()
 	cpu_arch_tune_flags = Cpu186|Cpu286|Cpu386|Cpu486
 			      |Cpu586|Cpu686|CpuP4|CpuMMX|CpuMMX2
 			      |CpuSSE|CpuSSE2;
-    }
-  else if (!strcmp (default_arch, "i386"))
-    {
+      break;
+    case ARCH_i386:
       set_code_flag (CODE_32BIT);
       if (cpu_arch_isa_flags == 0)
 	cpu_arch_isa_flags = Cpu186|Cpu286|Cpu386;
       if (cpu_arch_tune_flags == 0)
 	cpu_arch_tune_flags = Cpu186|Cpu286|Cpu386;
+      break;
+    default:
+      as_fatal (_("Unknown architecture"));
+      break;
     }
-  else
-    as_fatal (_("Unknown architecture"));
   switch (OUTPUT_FLAVOR)
     {
 #ifdef OBJ_MAYBE_AOUT