copyin() or copyout().
uvm_useracc() tells us whether the mapping permissions allow access to
the desired part of an address space, and many callers assume that
this is the same as knowing whether an attempt to access that part of
the address space will succeed. however, access to user space can
fail for reasons other than insufficient permission, most notably that
paging in any non-resident data can fail due to i/o errors. most of
the callers of uvm_useracc() make the above incorrect assumption. the
rest are all misguided optimizations, which optimize for the case
where an operation will fail. we'd rather optimize for operations
succeeding, in which case we should just attempt the access and handle
failures due to insufficient permissions the same way we handle i/o
errors. since there appear to be no good uses of uvm_useracc(), we'll
just remove it.
memory fault handler. IRIX uses irix_vm_fault, and all other emulation
use NULL, which means to use uvm_fault.
- While we are there, explicitely set to NULL the uninitialized fields in
struct emul: e_fault and e_sysctl on most ports
- e_fault is used by the trap handler, for now only on mips. In order to avoid
intrusive modifications in UVM, the function pointed by e_fault does not
has exactly the same protoype as uvm_fault:
int uvm_fault __P((struct vm_map *, vaddr_t, vm_fault_t, vm_prot_t));
int e_fault __P((struct proc *, vaddr_t, vm_fault_t, vm_prot_t));
- In IRIX share groups, all the VM space is shared, except one page.
This bounds us to have different VM spaces and synchronize modifications
to the VM space accross share group members. We need an IRIX specific hook
to the page fault handler in order to propagate VM space modifications
caused by page faults.
private area called PRDA that remains unshared. We implement this by using
different vmspace for each share group member, and keeping the memory
appings in sync on each mmap/munmap/mprotect/break...
We use irix_saddr_sync_vmcmd and irix_saddr_sync_syscall to apply a
vmcmd or a syscall to all share group member, this makes the job a bit
easier.
Also implements {get|set}rlimit{64}.
a SIGSEGV when sigaction(2) is used before a fork(2) and a signal is received
in the child.
- we now nearly correctly emulate PR_TERMCHILD in prctl(2). (the perfect
emulation would not send a SIGHUP if the parent is killed)
look for a block of free virtual memory big enough to hold all sections. The
blocks starts at the beginning of the first section and ends at the end of
the last section. In the previous version the block ended at the beginning
of the last section, hence creating situations where there was not enough
free space to map the section.
that the load addresses in the section array are increasing, and that no
section in the array overlap with each other. IRIX proably makes the same
assumptions, but this has not been tested.
The key point with relocation is to always use the same offset for each
section. Because userland gets only the load address off the first section, it
has to assume that all the remaining sections kept the same offset with
respect to the first section. By using fixed offset instead of finding
some free space for each section, we can eliminate the libX11 load hack.
even for program with a DSO using overlapping load virtual addresses.
The fix is a mean hack, see the comments in irix_syssgi.c. It would be nice to
get uvm_map_findspace() to return the page we suggest instead of the page which
is 16384 bytes away.
we used load_psection, then ran each vmcmd and tried to relocate the failing
ones. This fails if there is two vmcmd for one section, and the second is
not a mapping (for instance a map_pagedvn and a map_zero), because the first
one gets relocated, but not the second one.
Additionnaly, it was not necessary to update the userlevel psection array:
libc stubs seems to do the job themselves.
for the text section of libx11.so was overlapping with other ELF sections
aloready loaded, and this resulted into an ENOMEM error.
syssgi(MAPELF) uses elf32_load_psection() from syssrc/sys/kern/exec_subr.c
The problem was never experienced with load_psection() because it only has
to load one section, hence the requested address are not already allocated.
The fix is done when the initial mapping at the default address fails by
finding a free location in the VM space using uvm_map_findspace(), and then
retrying to load the section.
Other details:
- once the ELF section has been relocated, the ELF program header must be
updated with the new address and copied back to userland. For now we always
do it, maybe we could copy it only when it was modified.
- We are able to emulate the exact address where IRIX loads libX11.so instead
of the default location