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>