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.
This commit is contained in:
Ulrich Drepper 1998-04-01 09:15:07 +00:00
parent 1d97d6ac3b
commit 652e8a1e1b
5 changed files with 97 additions and 68 deletions

View File

@ -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> 1998-04-01 Ulrich Drepper <drepper@cygnus.com>
* iconvdata/Makefile: Remove extra dependencies for EUC-KR.so and * iconvdata/Makefile: Remove extra dependencies for EUC-KR.so and

View File

@ -24,19 +24,19 @@
This includes _init and _libc_init 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 This is how the dynamic linker arranges to have DT_FINI
functions called for shared libraries that have been loaded functions called for shared libraries that have been loaded
before this code runs. before this code runs.
sp The stack contains the arguments and environment: sp The stack contains the arguments and environment:
0(%esp) argc 0(sp) argc
4(%esp) argv[0] 4(sp) argv[0]
... ...
(4*argc)(%esp) NULL (4*argc)(sp) NULL
(4*(argc+1))(%esp) envp[0] (4*(argc+1))(sp) envp[0]
... ...
NULL NULL
*/ */
@ -44,62 +44,29 @@
.text .text
.globl _start .globl _start
_start: _start:
/* Clear the frame pointer. The Intel ABI suggests this be done, /* Clear the frame pointer since this is the outermost frame. */
to mark the outermost frame obviously. This seems like a
sensible thing to do */
mov fp, #0 mov fp, #0
/* r0 contains the address of the shared library termination /* Pop argc off the stack and save a pointer to argv */
function, which we will register with `atexit' to be called by ldmfd sp!, {a2}
`exit'. I suspect that on some systems, and when statically mov a3, sp
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 /* Push the last arguments to main() onto the stack */
programs under the GNU Hurd, this is what sets up the stmfd sp!, {a1}
arguments on the stack for the code below. For dyn-link ldr a1, =_fini
programs, this has been run already, in the .init code. */ stmfd sp!, {a1}
#ifndef PIC
bl __libc_init_first
/* Extract the arguments and environment as encoded on the stack /* Set up the other arguments for main() that go in registers */
and set up the arguments for `main': argc, argv, envp. */ ldr a1, =main
ldr r0,[sp] ldr a4, =_init
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' /* __libc_start_main (main, argc, argv, init, fini, rtld_fini) */
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 /* Let the libc call main and exit with its return code. */
L_environ: .word _environ bl __libc_start_main
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
/* should never get here....*/ /* should never get here....*/
bl abort bl abort
/* Define a symbol for the first piece of initialized data. */ /* Define a symbol for the first piece of initialized data. */
.data .data
.globl __data_start .globl __data_start

View File

@ -43,7 +43,7 @@ ENTRY (__socket)
/* r0 is < 0 if there was an error. */ /* r0 is < 0 if there was an error. */
cmn r0, $124 cmn r0, $124
bge syscall_error(PLT) bhs PLTJMP(syscall_error)
/* Successful; return the syscall's value. */ /* Successful; return the syscall's value. */
RETINSTR(mov,pc,r14) RETINSTR(mov,pc,r14)

View File

@ -45,28 +45,64 @@
is a real error number. Linus said he will make sure the no syscall 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 returns a value in -1 .. -4095 as a valid result so we can savely
test with -4095. */ test with -4095. */
#undef PSEUDO #undef PSEUDO
#define PSEUDO(name, syscall_name, args) \ #define PSEUDO(name, syscall_name, args) \
.text; \ .text; \
.type syscall_error,%function \
ENTRY (name) \ ENTRY (name) \
DO_CALL (args, syscall_name); \ DO_CALL (args, syscall_name); \
cmn r0, $4096; \ cmn r0, $4096; \
bgt syscall_error; bhs PLTJMP(syscall_error);
#undef PSEUDO_END #undef PSEUDO_END
#define PSEUDO_END(name) \ #define PSEUDO_END(name) \
SYSCALL_ERROR_HANDLER \ SYSCALL_ERROR_HANDLER \
END (name) END (name)
#ifndef PIC
#define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */ #define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
#else
#error Aiee /* Linux takes system call args in registers:
#endif /* PIC */ 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 #undef DO_CALL
#define DO_CALL(args, syscall_name) \ #define DO_CALL(args, syscall_name) \
swi SYS_ify (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 */ #endif /* ASSEMBLER */

View File

@ -17,18 +17,24 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
#ifndef __NETASH_ASH_H #ifndef _NETASH_ASH_H
#define __NETASH_ASH_H 1 #define _NETASH_ASH_H 1
#include <features.h> #include <features.h>
#include <sys/socket.h> #include <bits/sockaddr.h>
#include <sys/types.h>
struct sockaddr_ash struct sockaddr_ash
{ {
_SOCKADDR_COMMON (sash_); /* Common data: address family etc. */ __SOCKADDR_COMMON (sash_); /* Common data: address family etc. */
int if_index; /* Interface to use. */ int sash_ifindex; /* Interface to use. */
int channel; /* Realtime or control. */ 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 */ #endif /* netash/ash.h */