Subject: toolchain/26858: id3tag in pkgsrc/audio/id3lib causes bus error on sparc
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <nakayama@netbsd.org>
List: netbsd-bugs
Date: 09/06/2004 00:40:16
>Number: 26858
>Category: toolchain
>Synopsis: id3tag in pkgsrc/audio/id3lib causes bus error on sparc
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: toolchain-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Sep 05 15:41:01 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator: Takeshi Nakayama
>Release: NetBSD 2.0_BETA
>Organization:
>Environment:
System: NetBSD nyx 2.0_BETA NetBSD 2.0_BETA (NYX32) #119: Mon Aug 30 21:17:28 JST 2004
Architecture: sparc
Machine: sparc64
>Description:
libid3-3.8.so.3.0 compiled by pkgsrc/audio/id3lib contains
a relocation type R_SPARC_UA32, but 32-bit sparc's
ld.elf_so cannot handle unaligned type. So it occurs bus
error.
% ldd /usr/pkg/bin/id3tag
/usr/pkg/bin/id3tag:
-lstdc++.5 => /usr/lib/libstdc++.so.5
-lm.0 => /usr/lib/libm.so.0
-lgcc_s.1 => /usr/lib/libgcc_s.so.1
-lid3-3.8.3 => /usr/pkg/lib/libid3-3.8.so.3
-lz.0 => /usr/lib/libz.so.0
-lc.12 => /usr/lib/libsparc_v8.so.0
-lc.12 => /usr/lib/libc.so.12
% objdump -R /usr/pkg/lib/libid3-3.8.so.3 | grep R_SPARC_UA32
0006435e R_SPARC_UA32 __gxx_personality_v0
00064e15 R_SPARC_UA32 __gxx_personality_v0
00064ea6 R_SPARC_UA32 __gxx_personality_v0
00065781 R_SPARC_UA32 __gxx_personality_v0
000657b2 R_SPARC_UA32 __gxx_personality_v0
000668dd R_SPARC_UA32 __gxx_personality_v0
0006693e R_SPARC_UA32 __gxx_personality_v0
00067935 R_SPARC_UA32 __gxx_personality_v0
>How-To-Repeat:
Run id3tag in pkgsrc/audio/id3lib on 32-bit sparc.
>Fix:
Following patch brought from sparc64 seems to fix this
problem.
Index: mdreloc.c
===================================================================
RCS file: /cvsroot/src/libexec/ld.elf_so/arch/sparc/mdreloc.c,v
retrieving revision 1.33
diff -u -d -r1.33 mdreloc.c
--- mdreloc.c 24 Jul 2003 10:12:29 -0000 1.33
+++ mdreloc.c 5 Sep 2004 15:10:36 -0000
@@ -66,6 +66,7 @@
#define _RF_P 0x20000000 /* Location relative */
#define _RF_G 0x10000000 /* GOT offset */
#define _RF_B 0x08000000 /* Load address relative */
+#define _RF_U 0x04000000 /* Unaligned */
#define _RF_SZ(s) (((s) & 0xff) << 8) /* memory target size */
#define _RF_RS(s) ( (s) & 0xff) /* right shift */
static const int reloc_target_flags[] = {
@@ -92,7 +93,7 @@
_RF_S|_RF_A| _RF_SZ(32) | _RF_RS(0), /* GLOB_DAT */
_RF_SZ(32) | _RF_RS(0), /* JMP_SLOT */
_RF_A| _RF_B| _RF_SZ(32) | _RF_RS(0), /* RELATIVE */
- _RF_S|_RF_A| _RF_SZ(32) | _RF_RS(0), /* UA_32 */
+ _RF_S|_RF_A| _RF_U| _RF_SZ(32) | _RF_RS(0), /* UA_32 */
/*unknown*/ _RF_SZ(32) | _RF_RS(0), /* PLT32 */
/*unknown*/ _RF_SZ(32) | _RF_RS(0), /* HIPLT22 */
@@ -107,6 +108,9 @@
_RF_S|_RF_A|/*unknown*/ _RF_SZ(32) | _RF_RS(0), /* HH22 */
_RF_S|_RF_A|/*unknown*/ _RF_SZ(32) | _RF_RS(0), /* HM10 */
_RF_S|_RF_A|/*unknown*/ _RF_SZ(32) | _RF_RS(0), /* LM22 */
+ _RF_S|_RF_A|_RF_P|/*unknown*/ _RF_SZ(32) | _RF_RS(0), /* PC_HH22 */
+ _RF_S|_RF_A|_RF_P|/*unknown*/ _RF_SZ(32) | _RF_RS(0), /* PC_HM10 */
+ _RF_S|_RF_A|_RF_P|/*unknown*/ _RF_SZ(32) | _RF_RS(0), /* PC_LM22 */
_RF_S|_RF_A|_RF_P|/*unknown*/ _RF_SZ(32) | _RF_RS(0), /* WDISP16 */
_RF_S|_RF_A|_RF_P|/*unknown*/ _RF_SZ(32) | _RF_RS(0), /* WDISP19 */
/*unknown*/ _RF_SZ(32) | _RF_RS(0), /* GLOB_JMP */
@@ -124,14 +128,16 @@
"GLOB_DAT", "JMP_SLOT", "RELATIVE", "UA_32", "PLT32",
"HIPLT22", "LOPLT10", "LOPLT10", "PCPLT22", "PCPLT32",
"10", "11", "64", "OLO10", "HH22",
- "HM10", "LM22", "WDISP16", "WDISP19", "GLOB_JMP",
- "7", "5", "6"
+ "HM10", "LM22", "PC_HH22", "PC_HM10", "PC_LM22",
+ "WDISP16", "WDISP19", "GLOB_JMP", "7", "5", "6"
};
#endif
#define RELOC_RESOLVE_SYMBOL(t) ((reloc_target_flags[t] & _RF_S) != 0)
#define RELOC_PC_RELATIVE(t) ((reloc_target_flags[t] & _RF_P) != 0)
#define RELOC_BASE_RELATIVE(t) ((reloc_target_flags[t] & _RF_B) != 0)
+#define RELOC_UNALIGNED(t) ((reloc_target_flags[t] & _RF_U) != 0)
+#define RELOC_USE_ADDEND(t) ((reloc_target_flags[t] & _RF_A) != 0)
#define RELOC_TARGET_SIZE(t) ((reloc_target_flags[t] >> 8) & 0xff)
#define RELOC_VALUE_RIGHTSHIFT(t) (reloc_target_flags[t] & 0xff)
@@ -153,6 +159,7 @@
_BM(10), _BM(11), -1, /* _10, _11, _64 */
_BM(10), _BM(22), /* _OLO10, _HH22 */
_BM(10), _BM(22), /* _HM10, _LM22 */
+ _BM(22), _BM(10), _BM(22), /* _PC_HH22, _PC_HM10, _PC_LM22 */
_BM(16), _BM(19), /* _WDISP16, _WDISP19 */
-1, /* GLOB_JMP */
_BM(7), _BM(5), _BM(6) /* _7, _5, _6 */
@@ -299,17 +306,41 @@
value >>= RELOC_VALUE_RIGHTSHIFT(type);
value &= mask;
- /* We ignore alignment restrictions here */
- *where &= ~mask;
- *where |= value;
+ if (RELOC_UNALIGNED(type)) {
+ /* Handle unaligned relocations. */
+ Elf_Addr tmp = 0;
+ char *ptr = (char *)where;
+ int i, size = RELOC_TARGET_SIZE(type)/8;
+
+ /* Read it in one byte at a time. */
+ for (i=0; i<size; i++)
+ tmp = (tmp << 8) | ptr[i];
+
+ tmp &= ~mask;
+ tmp |= value;
+
+ /* Write it back out. */
+ for (i=0; i<size; i++)
+ ptr[i] = ((tmp >> (8*i)) & 0xff);
+#ifdef RTLD_DEBUG_RELOC
+ value = (Elf_Word)tmp;
+#endif
+
+ } else {
+ *where &= ~mask;
+ *where |= value;
+#ifdef RTLD_DEBUG_RELOC
+ value = (Elf_Word)*where;
+#endif
+ }
#ifdef RTLD_DEBUG_RELOC
if (RELOC_RESOLVE_SYMBOL(type)) {
rdbg(("%s %s in %s --> %p in %s", reloc_names[type],
obj->strtab + obj->symtab[symnum].st_name,
- obj->path, (void *)*where, defobj->path));
+ obj->path, (void *)value, defobj->path));
} else {
rdbg(("%s in %s --> %p", reloc_names[type],
- obj->path, (void *)*where));
+ obj->path, (void *)value));
}
#endif
}
>Release-Note:
>Audit-Trail:
>Unformatted: