Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Apr 2004 18:44:45 -0800 (PST)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 50159 for review
Message-ID:  <200404020244.i322ij0p030318@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=50159

Change 50159 by peter@peter_hammer on 2004/04/01 18:44:07

	ok, we need the sparse_mapping code from link_elf.c to control the
	final address.  Otherwise we end up with the module out in the direct
	map region, which is out of PC32 reach of the kernel.

Affected files ...

.. //depot/projects/hammer/sys/kern/link_elf_obj.c#19 edit

Differences ...

==== //depot/projects/hammer/sys/kern/link_elf_obj.c#19 (text+ko) ====

@@ -48,6 +48,9 @@
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
+#include <vm/vm_object.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_extern.h>
 #include <vm/pmap.h>
 #include <vm/vm_map.h>
 
@@ -86,6 +89,7 @@
 typedef struct elf_file {
 	struct linker_file lf;		/* Common fields */
 	caddr_t		address;	/* Relocation address */
+	vm_object_t	object;		/* VM object to hold file pages */
 
 	Elf_progent	*progtab;
 	int		nprogtab;
@@ -458,11 +462,21 @@
 	 * This stuff needs to be in a single chunk so that profiling etc
 	 * can get the bounds and gdb can associate offsets with modules
 	 */
-	mapbase = malloc(mapsize, M_LINKER, M_WAITOK | M_ZERO);
-	if (mapbase == NULL) {
+	ef->object = vm_object_allocate(OBJT_DEFAULT, round_page(mapsize) >> PAGE_SHIFT);
+	if (ef->object == NULL) {
 		error = ENOMEM;
 		goto out;
 	}
+	vm_object_reference(ef->object);
+	ef->address = (caddr_t) vm_map_min(kernel_map);
+	error = vm_map_find(kernel_map, ef->object, 0,
+	    (vm_offset_t *) &ef->address, mapsize, 1, VM_PROT_ALL, VM_PROT_ALL, 0);
+	if (error) {
+		vm_object_deallocate(ef->object);
+		ef->object = 0;
+		goto out;
+	}
+	mapbase = ef->address;
 printf("final mapbase %p, final mapsize %ld\n", mapbase, mapsize);
 
 	/* Add the base address to the previously calculated/aligned offsets */
@@ -504,6 +518,10 @@
 		    &resid, td);
 		if (error)
 			goto out;
+		/* Wire the pages */
+		vm_map_wire(kernel_map, (vm_offset_t)ef->progtab[i].addr,
+		    (vm_offset_t)ef->progtab[i].addr + ef->progtab[i].filesz,
+		    VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES);
 	}
 
 	/*
@@ -586,6 +604,11 @@
 	/* Notify MD code that a module is being unloaded. */
 	elf_cpu_unload_file(file);
 
+	if (ef->object) {
+		vm_map_remove(kernel_map, (vm_offset_t) ef->address,
+		    (vm_offset_t) ef->address + (ef->object->size << PAGE_SHIFT));
+		vm_object_deallocate(ef->object);
+	}
 	if (ef->address)
 		free(ef->address, M_LINKER);
 	if (ef->ddbsymtab)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200404020244.i322ij0p030318>