diff options
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | sysdeps/arm/elf/start.S | 81 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/arm/socket.S | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/arm/sysdep.h | 50 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/netash/ash.h | 20 |
5 files changed, 101 insertions, 72 deletions
@@ -1,3 +1,23 @@ +1998-04-1 16:52 Philip Blundell <pb@nexus.co.uk> + + * sysdeps/unix/sysv/linux/arm/socket.S: Correct test for error and + use PLTJMP() rather than explicit (PLT). + + * sysdeps/arm/elf/start.S: Leave most of the initialisation for + __libc_start_main(). + + Based on patch from Pat Beirne: + * sysdeps/unix/sysv/linux/arm/sysdep.h (SYSCALL_ERROR_HANDLER): + Always define, not only #ifndef PIC. + (DO_CALL): Pass fifth argument correctly in R4. + (PSEUDO): Correct test for error, call syscall_error through PLT + if PIC. + +1998-03-31 10:51 Philip Blundell <pb@nexus.co.uk> + + * sysdeps/unix/sysv/linux/netash/ash.h: Fix typos and add new + definitions. + 1998-04-01 Ulrich Drepper <drepper@cygnus.com> * iconvdata/Makefile: Remove extra dependencies for EUC-KR.so and diff --git a/sysdeps/arm/elf/start.S b/sysdeps/arm/elf/start.S index e0964a1..13b9c78 100644 --- a/sysdeps/arm/elf/start.S +++ b/sysdeps/arm/elf/start.S @@ -24,19 +24,19 @@ This includes _init and _libc_init - At this entry point, most registers' values are unspecified, except for: + At this entry point, most registers' values are unspecified, except: - r0 Contains a function pointer to be registered with `atexit'. + a1 Contains a function pointer to be registered with `atexit'. This is how the dynamic linker arranges to have DT_FINI functions called for shared libraries that have been loaded before this code runs. sp The stack contains the arguments and environment: - 0(%esp) argc - 4(%esp) argv[0] + 0(sp) argc + 4(sp) argv[0] ... - (4*argc)(%esp) NULL - (4*(argc+1))(%esp) envp[0] + (4*argc)(sp) NULL + (4*(argc+1))(sp) envp[0] ... NULL */ @@ -44,62 +44,29 @@ .text .globl _start _start: - /* Clear the frame pointer. The Intel ABI suggests this be done, - to mark the outermost frame obviously. This seems like a - sensible thing to do */ + /* Clear the frame pointer since this is the outermost frame. */ mov fp, #0 - /* r0 contains the address of the shared library termination - function, which we will register with `atexit' to be called by - `exit'. I suspect that on some systems, and when statically - linked, this will not be set by anything to any function - pointer; hopefully it will be zero so we don't try to call - random pointers. */ - cmp r0,#0 - blne atexit(PLT) - - /* Do essential libc initialization. In statically linked - programs under the GNU Hurd, this is what sets up the - arguments on the stack for the code below. For dyn-link - programs, this has been run already, in the .init code. */ -#ifndef PIC - bl __libc_init_first - - /* Extract the arguments and environment as encoded on the stack - and set up the arguments for `main': argc, argv, envp. */ - ldr r0,[sp] - add r1,sp,#4 - add r2,r1,r0,lsl #2 - add r2,r2,#4 - /* save a copy of envp while we have it */ - ldr r3,L_environ - str r2,[r3] - - /* Call `_init', which is the entry point to our own `.init' - section; and register with `atexit' to have `exit' call - `_fini', which is the entry point to our own `.fini' section. */ - bl _init - ldr r0,L_fini - bl atexit - b L_pfini - -L_fini: .word _fini -L_environ: .word _environ -L_pfini: -#endif - /* rebuild the arg list for main() */ - ldr r0,[sp] - add r1,sp,#4 - add r2,r1,r0,lsl #2 - add r2,r2,#4 - - /* Call the user's main function, and exit with its value. */ - bl main - bl exit + /* Pop argc off the stack and save a pointer to argv */ + ldmfd sp!, {a2} + mov a3, sp + + /* Push the last arguments to main() onto the stack */ + stmfd sp!, {a1} + ldr a1, =_fini + stmfd sp!, {a1} + + /* Set up the other arguments for main() that go in registers */ + ldr a1, =main + ldr a4, =_init + + /* __libc_start_main (main, argc, argv, init, fini, rtld_fini) */ + + /* Let the libc call main and exit with its return code. */ + bl __libc_start_main /* should never get here....*/ bl abort - /* Define a symbol for the first piece of initialized data. */ .data .globl __data_start diff --git a/sysdeps/unix/sysv/linux/arm/socket.S b/sysdeps/unix/sysv/linux/arm/socket.S index 0ff6dd0..1ebec9c 100644 --- a/sysdeps/unix/sysv/linux/arm/socket.S +++ b/sysdeps/unix/sysv/linux/arm/socket.S @@ -43,7 +43,7 @@ ENTRY (__socket) /* r0 is < 0 if there was an error. */ cmn r0, $124 - bge syscall_error(PLT) + bhs PLTJMP(syscall_error) /* Successful; return the syscall's value. */ RETINSTR(mov,pc,r14) diff --git a/sysdeps/unix/sysv/linux/arm/sysdep.h b/sysdeps/unix/sysv/linux/arm/sysdep.h index 3b7ffe0..dd1b6f4 100644 --- a/sysdeps/unix/sysv/linux/arm/sysdep.h +++ b/sysdeps/unix/sysv/linux/arm/sysdep.h @@ -45,28 +45,64 @@ is a real error number. Linus said he will make sure the no syscall returns a value in -1 .. -4095 as a valid result so we can savely test with -4095. */ + #undef PSEUDO #define PSEUDO(name, syscall_name, args) \ .text; \ + .type syscall_error,%function \ ENTRY (name) \ DO_CALL (args, syscall_name); \ cmn r0, $4096; \ - bgt syscall_error; + bhs PLTJMP(syscall_error); #undef PSEUDO_END #define PSEUDO_END(name) \ SYSCALL_ERROR_HANDLER \ END (name) -#ifndef PIC #define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */ -#else -#error Aiee -#endif /* PIC */ + +/* Linux takes system call args in registers: + syscall number in the SWI instruction + arg 1 r0 + arg 2 r1 + arg 3 r2 + arg 4 r3 + arg 5 r4 (this is different from the APCS convention) + + The compiler is going to form a call by coming here, through PSEUDO, with + arguments + syscall number in the DO_CALL macro + arg 1 r0 + arg 2 r1 + arg 3 r2 + arg 4 r3 + arg 5 [sp] + + We need to shuffle values between R4 and the stack so that the caller's + R4 is not corrupted, and the kernel sees the right argument there. + +*/ #undef DO_CALL -#define DO_CALL(args, syscall_name) \ - swi SYS_ify (syscall_name); +#define DO_CALL(args, syscall_name) \ + DOARGS_##args \ + swi SYS_ify (syscall_name); \ + UNDOARGS_##args + +#define DOARGS_0 /* nothing */ +#define DOARGS_1 /* nothing */ +#define DOARGS_2 /* nothing */ +#define DOARGS_3 /* nothing */ +#define DOARGS_4 /* nothing */ +#define DOARGS_5 ldr ip, [sp]; str r4, [sp]; mov r4, ip; + +#define UNDOARGS_0 /* nothing */ +#define UNDOARGS_1 /* nothing */ +#define UNDOARGS_2 /* nothing */ +#define UNDOARGS_3 /* nothing */ +#define UNDOARGS_4 /* nothing */ +#define UNDOARGS_5 ldr r4, [sp]; #endif /* ASSEMBLER */ diff --git a/sysdeps/unix/sysv/linux/netash/ash.h b/sysdeps/unix/sysv/linux/netash/ash.h index e4feec4..52bd398 100644 --- a/sysdeps/unix/sysv/linux/netash/ash.h +++ b/sysdeps/unix/sysv/linux/netash/ash.h @@ -17,18 +17,24 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __NETASH_ASH_H -#define __NETASH_ASH_H 1 +#ifndef _NETASH_ASH_H +#define _NETASH_ASH_H 1 #include <features.h> -#include <sys/socket.h> -#include <sys/types.h> +#include <bits/sockaddr.h> struct sockaddr_ash { - _SOCKADDR_COMMON (sash_); /* Common data: address family etc. */ - int if_index; /* Interface to use. */ - int channel; /* Realtime or control. */ + __SOCKADDR_COMMON (sash_); /* Common data: address family etc. */ + int sash_ifindex; /* Interface to use. */ + unsigned char sash_channel; /* Realtime or control. */ + unsigned int sash_plen; + unsigned char sash_prefix[16]; }; +/* Values for `channel' member. */ +#define ASH_CHANNEL_ANY 0 +#define ASH_CHANNEL_CONTROL 1 +#define ASH_CHANNEL_REALTIME 2 + #endif /* netash/ash.h */ |