[patch] unaligned traps in dynamic linker on alpha

Ivan Kokshaysky ink@jurassic.park.msu.ru
Mon Sep 18 08:36:00 GMT 2000


Hi!
Regarding the change in sysdeps/alpha/dl-machine.h:

(elf_machine_rela) [r_type == R_ALPHA_REFQUAD]: Use memcpy to load and
store value from relocation address to prevent unaligned trap.

Probably it was an attempt to fix long standing problem with
unaligned traps in dynamic linker loading libstdc++. There are
unaligned relocations in libstdc++ from gcc-2.95 and later
(dwarf2 info), but their type is R_ALPHA_RELATIVE, not R_ALPHA_REFQUAD.
Here is a fix.

Ivan.


2000-09-13 Ivan Kokshaysky <ink@jurassic.park.msu.ru>

	* sysdeps/alpha/dl-machine.h (elf_machine_rela)
	[r_type == R_ALPHA_RELATIVE]: Use memcpy to load and
	store value from relocation address to prevent unaligned
	traps. Back out change for R_ALPHA_REFQUAD.


Index: dl-machine.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/alpha/dl-machine.h,v
retrieving revision 1.44
diff -u -r1.44 dl-machine.h
--- dl-machine.h	2000/07/18 14:14:51	1.44
+++ dl-machine.h	2000/09/13 16:30:58
@@ -482,7 +482,17 @@
       /* Already done in dynamic linker.  */
       if (map != &_dl_rtld_map)
 #endif
-	*reloc_addr += map->l_addr;
+      {
+	void *reloc_addr_1 = reloc_addr;
+	Elf64_Addr reloc_addr_val;
+
+	/* Load value without causing unaligned trap. */
+	memcpy (&reloc_addr_val, reloc_addr_1, 8);
+	reloc_addr_val += map->l_addr;
+
+	/* Store value without causing unaligned trap. */
+	memcpy (reloc_addr_1, &reloc_addr_val, 8);
+      }
     }
   else if (r_type == R_ALPHA_NONE)
     return;
@@ -500,12 +510,7 @@
 	elf_machine_fixup_plt (map, 0, reloc, reloc_addr, sym_value);
       else if (r_type == R_ALPHA_REFQUAD)
 	{
-	  void *reloc_addr_1 = reloc_addr;
-	  Elf64_Addr reloc_addr_val;
-
-	  /* Load value without causing unaligned trap.  */
-	  memcpy (&reloc_addr_val, reloc_addr_1, 8);
-	  sym_value += reloc_addr_val;
+	  sym_value += *reloc_addr;
 #ifndef RTLD_BOOTSTRAP
 	  if (map == &_dl_rtld_map)
 	    {
@@ -521,8 +526,7 @@
 	      sym_value -= reloc->r_addend;
 	    }
 #endif
-	  /* Store value without causing unaligned trap.  */
-	  memcpy (reloc_addr_1, &sym_value, 8);
+	  *reloc_addr = sym_value;
 	}
       else
 	_dl_reloc_bad_type (map, r_type, 0);


More information about the Libc-alpha mailing list