[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#59789: Patch for Alpha glibc to fix some unaligned accesses



Package: glibc
Version: 2.1.3-6

Below is a patch from David Huggins-Daines that fixes some C++ related
unaligned access issues that we've had on Alpha.  We each thought that the
other was going to submit it before, so I apologise for sending it now :-)

If this can make it into potato, we would be most appreciative since
without it, every C++ programme spits out a few unaligned traps to the
console...

C

--- glibc-2.1.3/sysdeps/alpha/dl-machine.h~	Sat Feb 20 13:20:58 1999
+++ glibc-2.1.3/sysdeps/alpha/dl-machine.h	Mon Feb 21 14:10:15 2000
@@ -424,6 +424,20 @@
 
 #ifdef RESOLVE
 
+/* Stolen from gcc - quite obviously gcc-specific */
+union unaligned {
+  void *p;
+  unsigned b2 __attribute__ ((mode (HI)));
+  unsigned b4 __attribute__ ((mode (SI)));
+  unsigned b8 __attribute__ ((mode (DI)));
+} __attribute__ ((packed));
+static inline unsigned long
+read_8byte (void *p)
+{ union unaligned *up = p; return up->b8; }
+static inline void
+write_8byte (void *p, unsigned long val)
+{ union unaligned *up = p; up->b8 = val; }
+
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 static inline void
@@ -453,7 +467,13 @@
       /* Already done in dynamic linker.  */
       if (map != &_dl_rtld_map)
 #endif
-	*reloc_addr += map->l_addr;
+	{
+	  /* Because DWARF2 exception handling is broken by design,
+             these are often unaligned. */
+	  Elf64_Addr tmp = read_8byte(reloc_addr);
+	  tmp += map->l_addr;
+	  write_8byte(reloc_addr, tmp);
+	}
     }
   else if (r_type == R_ALPHA_NONE)
     return;




Reply to: