This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Renesas __trap34() system calls broken - possibly on other platforms, too


Hello,

I am experiencing problems customizing newlib via __trap34 () on a
little endian, SH3-DSP core using Renesas calling convention. What I can
see is that newlib passes parameters via R4 to R7 while my program
expects to see the variable argument list entirely on the stack.

I am using a precompiled newlib supplied together with a gcc package
from KPIT Cummins (GNUSH-v0603, http://www.kpitgnutools.com). The gcc
identifies itself as "sh-elf-gcc.exe (GCC) 4.2-GNUSH_v0603". The newlib
source code supplied is 1.14.0. 

Looking at the problem I realized that at the point where for example
__trap34 (SYS_write, ...) is called there is no prototype declaring
__trap34 () as using a variable parameter list. According to my
experience that leads to the C compiler assuming that __trap34 () has a
fixed parameter list. The result is that __trap34 () parameters are
passed via registers instead of putting them all on the stack.

Sadly, I am locked on a Windows machine so compiling newlib is extremely
painful. It would be very kind if someone could acknowledge this bug and
supply a patch. This is the line that is missing in
libc/sys/sh/syscalls.c and also in libc/sys/sh/truncate.c:

        __trap34 (int cmd, ...);

Most likely a very similar problem can be found on other platforms using
a similar system call scheme.

Regards,
Mark Jonas


Further details:

This is the newlib code where __trap34 (SYS_write, ...) is called.
libc/sys/sh/syscalls.c
----------
int
_write ( int file,
         char *ptr,
         int len)
{
  return __trap34 (SYS_write, file, ptr, len);
}
----------

This is the disassembly of the _write() function above. I commented it
to show how the parameters are passed via registers.
sh-elf-objdump -S
c:/KPIT_Cummins/GNUSHv0603-ELF/sh-elf/sh-elf/lib/mrenesas/ml/m2/libc.a
----------
00000270 <__write>:
 270:   43 61           mov     r4,r1                      ; given file
to r1
 272:   e6 2f           mov.l   r14,@-r15
 274:   53 62           mov     r5,r2                      ; given ptr
to r2
 276:   13 65           mov     r1,r5                      ; r1 (file)
to r5 (2nd param)
 278:   03 d1           mov.l   288 <__write+0x18>,r1   ! 0x0 <__link> ;
r1 = address of __trap34()
 27a:   63 67           mov     r6,r7                      ; given len
to r7 (4th param)
 27c:   f3 6e           mov     r15,r14
 27e:   04 e4           mov     #4,r4                      ; SYS_write
to r4 (1st param)
 280:   23 66           mov     r2,r6                      ; r2 (ptr) to
r6 (3rd param)
 282:   e3 6f           mov     r14,r15
 284:   2b 41           jmp     @r1                        ; call
__trap34()
 286:   f6 6e           mov.l   @r15+,r14
 288:   00 00           .word 0x0000
 28a:   00 00           .word 0x0000
 28c:   09 00           nop     
 28e:   09 00           nop     
----------

This is mixed source and disassembly of my __trap34 () implementation.
You can see that a_code is expected to be on the stack.
----------
// Dummy handler for __trap34 system calls.
// All calls do nothing and return what the application most likely keep
running.
int __trap34(int a_code, ...)
{
 290:   e6 2f           mov.l   r14,@-r15
 292:   f0 7f           add     #-16,r15
 294:   f3 6e           mov     r15,r14
   int len = 0;
 296:   e3 62           mov     r14,r2
 298:   d0 72           add     #-48,r2
 29a:   00 e1           mov     #0,r1
 29c:   1d 12           mov.l   r1,@(52,r2)
   va_list argList;

   va_start(argList, a_code);
 29e:   e3 62           mov     r14,r2
 2a0:   18 72           add     #24,r2
 2a2:   e3 61           mov     r14,r1
 2a4:   d0 71           add     #-48,r1
 2a6:   2c 11           mov.l   r2,@(48,r1)
   switch (a_code)
 2a8:   e5 50           mov.l   @(20,r14),r0
 2aa:   04 88           cmp/eq  #4,r0
 2ac:   01 89           bt      2b2 <___trap34+0x22>
 2ae:   27 a0           bra     300 <___trap34+0x70>
 2b0:   09 00           nop     
   {
      case SYS_write:
      {
         // vargs are (int file, char* ptr, int len)
         int file = va_arg(argList, int);
 2b2:   e3 61           mov     r14,r1
 2b4:   d0 71           add     #-48,r1
 2b6:   1c 53           mov.l   @(48,r1),r3
 2b8:   33 62           mov     r3,r2
 2ba:   04 72           add     #4,r2
 2bc:   e3 61           mov     r14,r1
 2be:   d0 71           add     #-48,r1
 2c0:   2c 11           mov.l   r2,@(48,r1)
 2c2:   33 61           mov     r3,r1
 2c4:   e3 62           mov     r14,r2
 2c6:   d0 72           add     #-48,r2
 2c8:   12 61           mov.l   @r1,r1
 2ca:   1e 12           mov.l   r1,@(56,r2)
         char *ptr = va_arg(argList, char *);
 2cc:   e3 61           mov     r14,r1
 2ce:   d0 71           add     #-48,r1
 2d0:   1c 53           mov.l   @(48,r1),r3
 2d2:   33 62           mov     r3,r2
 2d4:   04 72           add     #4,r2
 2d6:   e3 61           mov     r14,r1
 2d8:   d0 71           add     #-48,r1
 2da:   2c 11           mov.l   r2,@(48,r1)
 2dc:   33 61           mov     r3,r1
 2de:   e3 62           mov     r14,r2
 2e0:   d0 72           add     #-48,r2
 2e2:   12 61           mov.l   @r1,r1
 2e4:   1f 12           mov.l   r1,@(60,r2)
         len = va_arg(argList, int);
 2e6:   e3 61           mov     r14,r1
 2e8:   d0 71           add     #-48,r1
 2ea:   1c 53           mov.l   @(48,r1),r3
 2ec:   33 62           mov     r3,r2
 2ee:   04 72           add     #4,r2
 2f0:   e3 61           mov     r14,r1
 2f2:   d0 71           add     #-48,r1
 2f4:   2c 11           mov.l   r2,@(48,r1)
 2f6:   33 61           mov     r3,r1
 2f8:   e3 62           mov     r14,r2
 2fa:   d0 72           add     #-48,r2
 2fc:   12 61           mov.l   @r1,r1
 2fe:   1d 12           mov.l   r1,@(52,r2)
         // serial_printn(ptr, len);
       }
       break;
         
      default:
         break;
   }
   va_end(argList);

   return len;
 300:   e3 61           mov     r14,r1
 302:   d0 71           add     #-48,r1
 304:   1d 51           mov.l   @(52,r1),r1
 306:   13 60           mov     r1,r0
}
 308:   10 7e           add     #16,r14
 30a:   e3 6f           mov     r14,r15
 30c:   f6 6e           mov.l   @r15+,r14
 30e:   0b 00           rts     
 310:   09 00           nop     
 312:   09 00           nop     
----------


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]