Msg12138.html

From Linix VServer
Revision as of 23:30, 10 November 2025 by 192.168.65.1 (talk) (Restored content from Wayback Machine)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Vserver] dietlibc on hppa/parisc[edit]


  • From: Herbert Poetzl
  • Date: Tue, 17 Jan 2006 06:00:11 +0100 (CET)



Hi Felix!

stumbled over a strange issue (no patches available yet)
dietlibc has on hppa (or parisc), and it seems to me
that other archs could (should?) be affected too ...

syscalls.s/_llseek.S  defines the llseek function as
direct branch/call to the unified syscall wrapper
(which I think is wrong too, but to that later)

now, on hppa/parisc the calling convention uses r26-r23
for the first four arguments, the rest is spilled onto
the stack. however the Linux kernel passes the first 
six arguments in the registers r26-r21.

as the llseek syscall takes five arguments, this leads
to random arguments for the r22 (whence argument) and
strange failures like this:

_llseek(3, 0, 0xc00202d0, 0x4047f444 /* SEEK_??? */) = 
        -1 EINVAL (Invalid argument)

with the following test code

int     main(int argc, char *argv[])
{
        int fd, ret;
        loff_t lpos;
        char *name = argv[1];

        fd = open(name, O_RDONLY);
        ret = llseek(fd, 0, 0, &lpos, SEEK_END);
        printf("file %s has length %lld\n", name, (long long)lpos);
        close(fd);
        exit(0);        
}

a dirty hack (just to verify that this is true) is
to add the following:

  llseek:
+ ldw -0x34(%sp), %r22
  syscall(_llseek,_llseek)

which will load the r22 register with the proper value
from the stack ...


another issue I found for parisc/hppa is that
parisc/unified.S does

__unified_syscall:
        be,l 0x100(%sr2, %r0), %sr0, %r31
        nop

while the linux kernel says:

arch/parisc/kernel/signal.c

 * We need to be able to restore the syscall arguments (r21-r26) to
 * restart syscalls.  Thus, the syscall path should save them in the
 * pt_regs structure (it's okay to do so since they are caller-save
 * registers).  As noted below, the syscall number gets restored for
 * us due to the magic of delayed branching.

                /* Hooray for delayed branching.  We don't
                   have to restore %r20 (the system call
                   number) because it gets loaded in the delay
                   slot of the branch external instruction. */

so the following seems still to be true:

        The system call number MUST ALWAYS be loaded in the delay
        slot of the ble instruction, or restarting system calls
        WILL NOT WORK.

a possible 'workaround' would be to use some other
register and just 'copy' the syscall number to r20
in the delay slot, also on PIC code r19 has to be
saved as it will be clobberd

HTH,
Herbert