This is the mail archive of the libc-ports@sources.redhat.com mailing list for the libc-ports project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[ARM] Alignment trap in dynamic linker


I sent this issue to crossgcc mailing list with no luck, so lets give it
a try here...

I built ARM EABI toolchain using OSELAS.Toolchain
arm-v4t-linux-gnueabi_gcc-4.4.0_glibc-2.9_binutils-2.19.1_kernel-2.6.29-sanitized.ptxconfig
and run freshly built userland with 2.6.32-rc5 kernel on OMAP5910 (ARM925)
based board. Running every single binary triggers alignment trap.
Here's illustrative example (after boot):

# cat /proc/cpu/alignment
User:           201
System:         0
Skipped:        0
Half:           0
Word:           0
Multi:          0
User faults:    0 (ignored)
# echo 3 > /proc/cpu/alignment
# cat /proc/cpu/alignment
Alignment trap: cat (236) PC=0x4000aba8 Instr=0xe7951002 Address=0x4022b9a7 FSR 0x001
Alignment trap: cat (236) PC=0x4000abb4 Instr=0xe7851002 Address=0x4022b9a7 FSR 0x811
Alignment trap: cat (236) PC=0x4000aba8 Instr=0xe7951002 Address=0x4022bffa FSR 0x001
Alignment trap: cat (236) PC=0x4000abb4 Instr=0xe7851002 Address=0x4022bffa FSR 0x801
User:           205
System:         0
Skipped:        0
Half:           0
Word:           4
Multi:          0
User faults:    3 (fixup+warn)

Looking at process map shows that 0x4000aba8 belongs to /lib/ld-2.9.so address
space and objdump finds out alignment trap is triggered from
elf_machine_rel_relative. I found similar problem described here:
http://www.opensubscriber.com/message/fedora-devel-list@redhat.com/5545902.html
and blindly modified it for arm and unaligned access went away...

--- glibc-ports-2.9/sysdeps/arm/dl-machine.h.orig	2009-11-03 22:03:57.000000000 +0100
+++ glibc-ports-2.9/sysdeps/arm/dl-machine.h	2009-11-03 22:11:45.000000000 +0100
@@ -568,13 +568,22 @@
 }
 # endif
 
+union arm_unaligned_data {
+  Elf32_Addr l_addr;
+} __attribute__ ((packed));
+
 auto inline void
 __attribute__ ((always_inline))
 elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
 			  void *const reloc_addr_arg)
 {
-  Elf32_Addr *const reloc_addr = reloc_addr_arg;
-  *reloc_addr += l_addr;
+  if (((long)reloc_addr_arg) & 0x3) {
+    union arm_unaligned_data *const lpdata = reloc_addr_arg;
+    lpdata->l_addr += l_addr;
+  } else {
+    Elf32_Addr *const reloc_addr = reloc_addr_arg;
+    *reloc_addr += l_addr;
+  }
 }
 
 # ifndef RTLD_BOOTSTRAP

However this solution didn't went into repository so the right fix is probably
different. Anyone seen this? I will happily RTFM, just point me where to find
it.

Thanks,
	ladis


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]