From: Andreas K. <and...@ac...> - 2008-07-10 18:51:47
|
> ========================================================================== > > tclLoadDl.c > > > > MODULE_SCOPE void * > > TclpLoadMemoryGetBuffer( > > Tcl_Interp *interp, /* Used for error reporting. */ > > int size) /* Size of desired buffer. */ > > { > > void *buffer = NULL; > > > > /* > > * We do not need space from a specyfic address area > like in MacOS > > * so we can simply use ckalloc > > */ > > buffer = ckalloc(size); > > > > return buffer; > > } > > > > > > I should note that while we will get rid of mmap and its need for a > > page-aligned start address we very likely still have to use > 'mprotect' to > > set up the correct memory protection. That function works page-based as > > well. I.e. if we give it an address in the middle of a page it > will change > > the protection of the whole page. This may cause us to change the > > protections of unrelated data structures nearby in the heap, > causing the app > > to fail. Especially if write-access > > is removed to the page containing the code segment of the > library. Using a > > page-aligned address and size will make sure that other data > structures are > > far enough away on both sides to not get caught by protection changes. > > > I thought about in this way: > - we allocate a buffer somewhere in memory (TclpLoadMemoryGetBuffer) > - we read our library to this buffer (Tcl_Read) > - we load this library so that it is linked with the main application > (TclpLoadMemory) > The third function (TclpLoadMemory) will of course call elf_dlopen. Yes. > But this will be a changed > elf_dlopen (its argument will be a pointer to the buffer). Right. > I have > already made some changes in this direction. > Then elf_dlopen will call map_object whose argument will be also the > pointer to the buffer. > This mapping now uses mmap to allocate some data from the elf file. > For example in the line 154: > mapbase = mmap(base_addr, mapsize, convert_prot(segs[0]->p_flags), > convert_flags(segs[0]->p_flags), fd, base_offset); > I was thinking of changing it like: > mapbase = mmap(base_addr, mapsize, convert_prot(segs[0]->p_flags), > convert_flags(segs[0]->p_flags) | MAP_ANONYMOUS, -1, 0); > By this we will just allocate memory with all protection we want and > then we will copy the right data there from the buffer like: > memcpy(mapbase, buffer + base_offset, mapsize); I see. ... Reading the mmap manpage ... Right. > Of course this way is less effective but it requires less changes > which seems to be better at the beginning. I agree with you that doing it this way is both less efficient and done with less changes to the rtld code. I further agree to go with this because of the less changes part. Workable first, optimization later. > In particular, if we wanted to read data directly to the mapbase I > think we would have to call map_object before the actual elf_dlopen. I do not believe so. If our buffer is properly aligned we should be able to perform everything needed without mmap, just mprotect and such. -- Andreas Kupries <andreask@ActiveState.com> Developer @ http://www.ActiveState.com Tel: +1 778-786-1122 |