This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: reserving memory below 16MB
On 10/05/2009 05:29 PM, R. Matthew Emerson wrote:
On 32-bit x86 systems, I would like to ensure that no dynamically
allocated block of memory (obtained via malloc or mmap) will start below
2^24 (16 MB). See [1] below for why I want to do this.
I wonder if there is some way (assembler directives, linker commands)
that I could do this. That is, is there a way to say "make the text
section 16MB long" or some other way to say "take up the rest of the
space below 16MB."
You could place a SEGMENT of length (1<<24) at 0 with PROT_NONE by using
linker directives. However, at execve() the current Linux kernel will
instantiate only one .bss region [.p_filesz < .p_memsz], and the kernel
picks the Elf32_Phdr which has the highest (.p_memsz + .p_vaddr) to do so.
This implies that your static reservation at address 0 cannot use
(.p_filesz==0 && .p_memsz== (1<<24)) to save space. Your executable file
must have 16MiB of zeroes. It would simplify kernel code (and make it
more secure) to instantiate ".bss" whenever (.p_filesz < .p_memsz),
but the maintainers of linux/fs/binfmt_elf.c have not yet seen the light.
Thus it would be a better idea to set up your reservation dynamically.
Use your own call(s) to mmap(), with MAP_FIXED and PROT_NONE, to reserve
the area(s) you desire. This will protect the region(s) unless the
program intentionally destroys the reservation(s) with calls to munmap()
or mmap() with MAP_FIXED. The trick is to establish the reservation
early enough after execve().
The Wine project uses a "pre-loader" to do the related job of reserving
the Win32 user address space, typically [0, 0x68000000), before loading
non-Win32 shared libraries. Check out Wine source code (begin at
http://winehq.com) and look at file loader/preloader.c.
A simple modification to my 'rtldi' program, using mmap() with MAP_FIXED,
would also implement reservations. http://BitWagon.com/rtldi/rtldi.html.
--