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>
* iconvdata/Makefile: Remove extra dependencies for EUC-KR.so and

View File

@ -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)
/* Pop argc off the stack and save a pointer to argv */
ldmfd sp!, {a2}
mov a3, sp
/* 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
/* Push the last arguments to main() onto the stack */
stmfd sp!, {a1}
ldr a1, =_fini
stmfd sp!, {a1}
/* 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]
/* Set up the other arguments for main() that go in registers */
ldr a1, =main
ldr a4, =_init
/* 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
/* __libc_start_main (main, argc, argv, init, fini, rtld_fini) */
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
/* 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

View File

@ -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)

View File

@ -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 */

View File

@ -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 */