home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.arch      Apparently more than just beeps & boops      131,241 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 129,379 of 131,241   
   Anton Ertl to Scott Lurndal   
   Re: System calls (was: VAX)   
   13 Aug 25 16:10:10   
   
   From: anton@mips.complang.tuwien.ac.at   
      
   scott@slp53.sl.home (Scott Lurndal) writes:   
   >anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:   
   >>scott@slp53.sl.home (Scott Lurndal) writes:   
   >>>That said, Unix generally defined -1 as the return value for all   
   >>>other system calls, and code that checked for "< 0" instead of   
   >>>-1 when calling a standard library function or system call was fundamentally   
   >>>broken.   
   >>   
   >>That may be the interface of the C system call wrapper,   
   >   
   >It _is_ the interface that the programmers need to be   
   >concerted with when using POSIX C language bindings.   
      
   True, but not relevant for the question at hand.   
      
   >>at the actual system call level, the error is indicated in   
   >>an architecture-specific way, and the ones I have looked at before   
   >>today use the sign of the result register or the carry flag.  On those   
   >>architectures, where the sign is used, mmap(2) cannot return negative   
   >>addresses, or must have a special wrapper.   
   >   
   >Why would the wrapper care if the system call failed?   
      
   The actual system call returns an error flag and a register.  On some   
   architectures, they support just a register.  If there is no error,   
   the wrapper returns the content of the register.  If the system call   
   indicates an error, you see from the value of the register which error   
   it is; the wrapper then typically transforms the register in some way   
   (e.g., by negating it) and stores the result in errno, and returns -1.   
      
   >lseek(2) and mmap(2) both require the return of arbitrary 32-bit   
   >or 64-bit values, including those which when interpreted as signed   
   >values are negative.   
      
   For lseek(2):   
      
   | Upon successful completion, lseek() returns the resulting offset   
   | location as measured in bytes from the beginning of the file.   
      
   Given that off_t is signed, lseek(2) can only return positive values.   
      
   For mmap(2):   
      
   | On success, mmap() returns a pointer to the mapped area.   
      
   So it's up to the kernel which user-level addresses it returns.  E.g.,   
   32-bit Linux originally only produced user-level addresses below 2GB.   
   When memories grew larger, on some architectures (e.g., i386) Linux   
   increased that to 3GB.   
      
   >Clearly POSIX defines the interfaces and the underlying OS and/or   
   >library functions implement the interfaces.   The kernel interface   
   >to the language library (e.g. libc) is irrelevent to typical programmers   
      
   Sure, but system calls are first introduced in real kernels using the   
   actual system call interface, and are limited by that interface.  And   
   that interface is remarkably similar between the early days of Unix   
   and recent Linux kernels for various architectures.  And when you look   
   closely, you find how the system calls are design to support returning   
   the error indication, success value, and errno in one register.   
      
   lseek64 on 32-bit platforms is an exception (the success value does   
   not fit in one register), and looking at the machine code of the   
   wrapper and comparing it with the machine code for the lseek wrapper,   
   some funny things are going on, but I would have to look at the source   
   code to understand what is going on.  One other interesting thing I   
   noticed is that the system call wrappers from libc-2.36 on i386 now   
   draws the boundary between success returns and error returns at   
   0xfffff000:   
      
      0xf7d853c4 :       call   *%gs:0x10   
      0xf7d853cb :       cmp    $0xfffff000,%eax   
      0xf7d853d0 :       ja     0xf7d85410    
      
   So now the kernel can produce 4095 error values, and the rest can be   
   success values.  In particular, mmap() can return all possible page   
   addresses as success values with these wrappers.  When I last looked   
   at how system calls are done, I found just a check of the N or the C   
   flag.  I wonder how the kernel is informed that it can now return more   
   addresses from mmap().   
      
   - anton   
   --   
   'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'   
     Mitch Alsup,    
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca