summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-02-20 13:40:59 -0800
committerDavid S. Miller <davem@davemloft.net>2010-02-20 13:48:06 -0800
commit5c866a8b9be0bd8dff97dd8143e55dd228617c23 (patch)
tree4ff0d2cb41595f5252997879c04baaaef02a4953
parent1d204bf2945617be272f88ee233adbceeffd5315 (diff)
downloadglibc-5c866a8b9be0bd8dff97dd8143e55dd228617c23.tar.gz
glibc-5c866a8b9be0bd8dff97dd8143e55dd228617c23.tar.xz
glibc-5c866a8b9be0bd8dff97dd8143e55dd228617c23.zip
Fix PLT rewrite when prelinking fails on 32-bit sparc.
When prelinking fails we have to rewrite the PLT, but the code
doing so forgets to adjust all rela->r_offset addresses by the
location of where the object was actually mapped.
-rw-r--r--ChangeLog5
-rw-r--r--sysdeps/sparc/sparc32/dl-machine.h16
2 files changed, 15 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 85327329ff..cd1be57595 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-02-20  David S. Miller  <davem@davemloft.net>
+
+	* sysdeps/sparc/sparc32/dl-machine.h (elf_machine_runtime_setup):
+	Adjust rela->r_offset by l->l_addr when rewriting PLT.
+
 2009-02-20  Joseph Myers  <joseph@codesourcery.com>
 
 	* sysdeps/sparc/sparc64/dl-machine.h (elf_machine_runtime_setup):
diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
index e1385f7aca..53257104a6 100644
--- a/sysdeps/sparc/sparc32/dl-machine.h
+++ b/sysdeps/sparc/sparc32/dl-machine.h
@@ -166,15 +166,19 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 	     in .rela.plt.  */
 	  while (rela < relaend)
 	    {
-	      *(unsigned int *) rela->r_offset
-		= OPCODE_SETHI_G1 | (rela->r_offset - (Elf32_Addr) plt);
-	      *(unsigned int *) (rela->r_offset + 4)
+	      *(unsigned int *) (rela->r_offset + l->l_addr)
+		= OPCODE_SETHI_G1 | (rela->r_offset + l->l_addr
+				     - (Elf32_Addr) plt);
+	      *(unsigned int *) (rela->r_offset + l->l_addr + 4)
 		= OPCODE_BA | ((((Elf32_Addr) plt
-				 - rela->r_offset - 4) >> 2) & 0x3fffff);
+				 - rela->r_offset - l->l_addr - 4) >> 2)
+			       & 0x3fffff);
 	      if (do_flush)
 		{
-		  __asm __volatile ("flush %0" : : "r"(rela->r_offset));
-		  __asm __volatile ("flush %0+4" : : "r"(rela->r_offset));
+		  __asm __volatile ("flush %0" : : "r" (rela->r_offset
+							+ l->l_addr));
+		  __asm __volatile ("flush %0+4" : : "r" (rela->r_offset
+							  + l->l_addr));
 		}
 	      ++rela;
 	    }