Subject: Support for relocation type 10 in ld.elf_so
To: None <port-powerpc@netbsd.org>
From: Allen Briggs <briggs@wasabisystems.com>
List: port-powerpc
Date: 06/15/2002 23:30:41
I was looking at PR pkg/13771 which complains that Apache's mod_perl is
not usable because:

# apachectl configtest
Syntax error on line 1220 of /usr/pkg/etc/httpd/httpd.conf:
Cannot load /usr/pkg/lib/httpd/mod_perl.so into server: /usr/pkg/lib/httpd/mod_perl.so: Unsupported relocation type 10 in non-PLT relocations

I'm not sure how we're getting the R_PPC_REL24 relocations in
mod_perl.so, but that's really kind of unacceptable behavior.
Todd V. mentioned that, well, ld.elf_so could always be taught
about this relocation type, and I think the following patch
does this.

This allows apache+mod_perl to start and use a simple perl script.  I
don't know if the relocation is 100% correct or not, though, and I'm
not sure the best way to test.

Comments?

========================================================================
Index: reloc.c
===================================================================
RCS file: /cvsroot/basesrc/libexec/ld.elf_so/reloc.c,v
retrieving revision 1.51
diff -u -r1.51 reloc.c
--- reloc.c	2002/02/03 23:34:42	1.51
+++ reloc.c	2002/06/16 03:22:25
@@ -507,6 +507,40 @@
 		rdbg(dodebug, ("16_HA in %s --> %p", obj->path,
 		    (void *)*where));
 		break;
+
+	case R_TYPE(REL24): {	/* S + A - P >> 2 */
+                Elf32_Sword addend;
+                
+                /*      
+                 * Extract addend and sign-extend if needed.
+                 */ 
+                addend = *where & 0x03fffffc;
+                if (addend & 0x04000000)
+                        addend |= 0xfc000000; 
+
+		def = _rtld_find_symdef(_rtld_objlist, rela->r_info, NULL, obj,
+		    &defobj, false);
+		if (def == NULL)
+			return -1;
+
+		tmp = (Elf_Addr)obj->relocbase + def->st_value + addend
+		    - (Elf_Addr)where;
+		if ((tmp & 0xfc000000) != 0xfc000000 &&
+		    (tmp & 0xfc000000) != 0) {
+			_rtld_error(
+			"%s: R_PPC_REL24 relocation @ %p to %s failed "
+			"(displacement %ld (%#lx) out of range)",
+			    obj->path, where, defobj->strtab + def->st_name,
+			    (long) tmp, (long) tmp);
+			return -1;
+		}
+
+		*where = (*where & 0xfc000003) | (tmp & 0x03fffffc);
+		rdbg(dodebug, ("REL24 %s in %s --> %p @ %p in %s",
+		    defobj->strtab + def->st_name, obj->path,
+		    (void *)*where, where, defobj->path));
+		}
+		break;
 #endif /* __powerpc__ */
 
 #if defined(__arm__)
========================================================================

-allen

-- 
 Allen Briggs                     briggs@wasabisystems.com
 http://www.wasabisystems.com/    Quality NetBSD CDs, Sales, Support, Service
NetBSD development for Alpha, ARM, M68K, MIPS, PowerPC, SuperH, XScale, etc...