Subject: Re: bin/33909: modload fails with "section .eh_frame ... overlaps
To: None <gnats-bugs@NetBSD.org>
From: Matthias Drochner <M.Drochner@fz-juelich.de>
List: netbsd-bugs
Date: 07/04/2006 15:00:50
This is a multipart MIME message.

--==_Exmh_2653437230080
Content-Type: text/plain; charset=us-ascii


There are two problems with LKMs on alpha. If you've fixed the first,
you'll run into the second...

The "section overlap" you reported is due to some strange
alignment behaviour of the linker. This was probably
introduced by the binutils update as you say.
Appearently, the alignment of a section does not only
apply to the start, but also to the length of an ELF
section.
I can't tell yet whether this complies to the ELF
specification.
However, modload doesn't deal with this. I'll append a patch
which changes modload to use the .text alignment to round
up the text section size.

Another problem is that the LKM space is mapped without
execute permission. This was appearently introduced more
than a year ago -- did you use LKMs on post-3.0/alpha
after April 2005?
The other appended patch provides a workaround. (This
is really just a workaround. There are inconsistencies in
the code which need to be fixed first.)

best regards
Matthias



--==_Exmh_2653437230080
Content-Type: text/plain ; name="modload.txt"; charset=us-ascii
Content-Description: modload.txt
Content-Disposition: attachment; filename="modload.txt"

Index: sbin/modload/elf.c
===================================================================
RCS file: /cvsroot/src/sbin/modload/elf.c,v
retrieving revision 1.18
diff -u -p -r1.18 elf.c
--- sbin/modload/elf.c	17 Mar 2006 15:53:46 -0000	1.18
+++ sbin/modload/elf.c	4 Jul 2006 12:42:47 -0000
@@ -255,6 +255,7 @@ elf_mod_sizes(int fd,
 	size_t data_hole = 0;
 	char *shstrtab, *strtb;
 	struct elf_section *head, *s;
+	size_t textalign = 0;
 
 	if (read_elf_header(fd, &ehdr) < 0)
 		return -1;
@@ -270,11 +271,13 @@ elf_mod_sizes(int fd,
 			fprintf(stderr,
 			    "%s: addr = %p size = %#lx align = %#lx\n",
 			    s->name, s->addr, (u_long)s->size, (u_long)s->align);
+		if (strcmp(s->name, ".text") == 0)
+			textalign = s->align;
 		/* XXX try to get rid of the hole before the data
 		   section that GNU-ld likes to put there */
 		if (strcmp(s->name, ".data") == 0 && s->addr > (void *)off) {
 #define	ROUND(V, S) (((V) + (S) - 1) & ~((S) - 1))
-			data_offset = ROUND(off, s->align);
+			data_offset = ROUND(off, MAX(s->align, textalign));
 			if (debug)
 				fprintf(stderr, ".data section forced to "
 				    "offset %p (was %p)\n",

--==_Exmh_2653437230080
Content-Type: text/plain ; name="kmalloc.txt"; charset=us-ascii
Content-Description: kmalloc.txt
Content-Disposition: attachment; filename="kmalloc.txt"

Index: sys/uvm/uvm_km.c
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_km.c,v
retrieving revision 1.88
diff -u -p -r1.88 uvm_km.c
--- sys/uvm/uvm_km.c	25 May 2006 14:27:28 -0000	1.88
+++ sys/uvm/uvm_km.c	4 Jul 2006 12:43:23 -0000
@@ -621,7 +621,7 @@ uvm_km_alloc(struct vm_map *map, vsize_t
 		 */
 
 		pmap_kenter_pa(loopva, VM_PAGE_TO_PHYS(pg),
-		    VM_PROT_READ | VM_PROT_WRITE);
+		    VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
 		loopva += PAGE_SIZE;
 		offset += PAGE_SIZE;
 		loopsize -= PAGE_SIZE;

--==_Exmh_2653437230080--