From 9d5bfe0b9467fc6f54f564648edbc9676106d08d Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Fri, 27 Apr 2001 17:23:26 +0000 Subject: Yet another large update to ld.so. In this iteration I finally got the C based syscalls working, which greatly simplifies what it takes to get new architectures running. -Erik --- ldso/ldso/i386/dl-syscalls.h | 94 ++++++++++++++++++++++++++++++++++++++++++++ ldso/ldso/i386/dl-sysdep.h | 5 +-- ldso/ldso/i386/ld_syscalls.h | 94 ++++++++++++++++++++++++++++++++++++++++++++ ldso/ldso/i386/ld_sysdep.h | 5 +-- ldso/ldso/i386/resolve.S | 36 ++++------------- ldso/ldso/i386/syscalls.h | 94 ++++++++++++++++++++++++++++++++++++++++++++ ldso/ldso/i386/sysdep.h | 5 +-- 7 files changed, 296 insertions(+), 37 deletions(-) create mode 100644 ldso/ldso/i386/dl-syscalls.h create mode 100644 ldso/ldso/i386/ld_syscalls.h create mode 100644 ldso/ldso/i386/syscalls.h (limited to 'ldso/ldso/i386') diff --git a/ldso/ldso/i386/dl-syscalls.h b/ldso/ldso/i386/dl-syscalls.h new file mode 100644 index 000000000..263dc5a1a --- /dev/null +++ b/ldso/ldso/i386/dl-syscalls.h @@ -0,0 +1,94 @@ +#include +#include + +/* Here are the macros which define how this platform makes + * system calls. This particular variant does _not_ set + * errno (note how it is disabled in __syscall_return) since + * these will get called before the errno symbol is dynamicly + * linked. + by the dynamic linker. The idea is that we want to be able + to call these before the errno symbol is dynamicly linked, so + we use our own version here. Note that we cannot assume any + dynamic linking at all, so we cannot return any error codes. + We just punt if there is an error. */ + + +#undef __syscall_return +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-125)) { \ + /*errno = -(res); */ \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + + +#if defined(__PIC__) + +/* + * PIC uses %ebx, so we need to save it during system calls + */ + +#undef _syscall1 +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall2 +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall3 +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall4 +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall5 +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"m" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \ +__syscall_return(type,__res); \ +} + +#endif /* __PIC__ */ + + diff --git a/ldso/ldso/i386/dl-sysdep.h b/ldso/ldso/i386/dl-sysdep.h index 9bbeef1fa..bf3d43be6 100644 --- a/ldso/ldso/i386/dl-sysdep.h +++ b/ldso/ldso/i386/dl-sysdep.h @@ -1,4 +1,3 @@ - /* * Various assmbly language/system dependent hacks that are required * so that we can minimize the amount of platform specific code. @@ -73,9 +72,9 @@ /* Here we define the magic numbers that this dynamic loader should accept */ #define MAGIC1 EM_386 -#define MAGIC2 EM_486 +#undef MAGIC2 /* Used for error messages */ -#define ELF_TARGET "386/486" +#define ELF_TARGET "386" extern unsigned int _dl_linux_resolver(int dummy, int i); diff --git a/ldso/ldso/i386/ld_syscalls.h b/ldso/ldso/i386/ld_syscalls.h new file mode 100644 index 000000000..263dc5a1a --- /dev/null +++ b/ldso/ldso/i386/ld_syscalls.h @@ -0,0 +1,94 @@ +#include +#include + +/* Here are the macros which define how this platform makes + * system calls. This particular variant does _not_ set + * errno (note how it is disabled in __syscall_return) since + * these will get called before the errno symbol is dynamicly + * linked. + by the dynamic linker. The idea is that we want to be able + to call these before the errno symbol is dynamicly linked, so + we use our own version here. Note that we cannot assume any + dynamic linking at all, so we cannot return any error codes. + We just punt if there is an error. */ + + +#undef __syscall_return +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-125)) { \ + /*errno = -(res); */ \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + + +#if defined(__PIC__) + +/* + * PIC uses %ebx, so we need to save it during system calls + */ + +#undef _syscall1 +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall2 +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall3 +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall4 +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall5 +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"m" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \ +__syscall_return(type,__res); \ +} + +#endif /* __PIC__ */ + + diff --git a/ldso/ldso/i386/ld_sysdep.h b/ldso/ldso/i386/ld_sysdep.h index 9bbeef1fa..bf3d43be6 100644 --- a/ldso/ldso/i386/ld_sysdep.h +++ b/ldso/ldso/i386/ld_sysdep.h @@ -1,4 +1,3 @@ - /* * Various assmbly language/system dependent hacks that are required * so that we can minimize the amount of platform specific code. @@ -73,9 +72,9 @@ /* Here we define the magic numbers that this dynamic loader should accept */ #define MAGIC1 EM_386 -#define MAGIC2 EM_486 +#undef MAGIC2 /* Used for error messages */ -#define ELF_TARGET "386/486" +#define ELF_TARGET "386" extern unsigned int _dl_linux_resolver(int dummy, int i); diff --git a/ldso/ldso/i386/resolve.S b/ldso/ldso/i386/resolve.S index db22e7b82..8ae2efa70 100644 --- a/ldso/ldso/i386/resolve.S +++ b/ldso/ldso/i386/resolve.S @@ -1,34 +1,14 @@ -#if 0 -#include -#endif /* * These are various helper routines that are needed to run an ELF image. */ -#ifndef ALIGN -#define ALIGN 4 -#endif - -#ifndef NO_UNDERSCORE -#define RUN _linux_run -#define RESOLVE __dl_linux_resolve -#define EXIT __interpreter_exit -#define RESOLVER __dl_linux_resolver -#define INIT ___loader_bootstrap -#else -#define RUN linux_run -#define RESOLVE _dl_linux_resolve -#define RESOLVER _dl_linux_resolver -#define EXIT _interpreter_exit -#define INIT __loader_bootstrap -#endif .text -.align ALIGN - .align 16 +.align 4 + +.globl _dl_linux_resolve +.type _dl_linux_resolve,@function -.globl RESOLVE - .type RESOLVE,@function -RESOLVE: +_dl_linux_resolve: pusha /* preserve all regs */ lea 0x20(%esp),%eax /* eax = tpnt and reloc_entry params */ pushl 4(%eax) /* push copy of reloc_entry param */ @@ -40,10 +20,10 @@ RESOLVE: .L24: popl %ebx addl $_GLOBAL_OFFSET_TABLE_+[.-.L24],%ebx - movl RESOLVER@GOT(%ebx),%ebx /* eax = resolved func */ + movl _dl_linux_resolver@GOT(%ebx),%ebx /* eax = resolved func */ call *%ebx #else - call RESOLVER + call _dl_linux_resolver #endif movl %eax,0x2C(%esp) /* store func addr over original * tpnt param */ @@ -52,4 +32,4 @@ RESOLVE: ret $4 /* jump to func removing original * reloc_entry param from stack */ .LFE2: - .size RESOLVE,.LFE2-RESOLVE + .size _dl_linux_resolve,.LFE2-_dl_linux_resolve diff --git a/ldso/ldso/i386/syscalls.h b/ldso/ldso/i386/syscalls.h new file mode 100644 index 000000000..263dc5a1a --- /dev/null +++ b/ldso/ldso/i386/syscalls.h @@ -0,0 +1,94 @@ +#include +#include + +/* Here are the macros which define how this platform makes + * system calls. This particular variant does _not_ set + * errno (note how it is disabled in __syscall_return) since + * these will get called before the errno symbol is dynamicly + * linked. + by the dynamic linker. The idea is that we want to be able + to call these before the errno symbol is dynamicly linked, so + we use our own version here. Note that we cannot assume any + dynamic linking at all, so we cannot return any error codes. + We just punt if there is an error. */ + + +#undef __syscall_return +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-125)) { \ + /*errno = -(res); */ \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + + +#if defined(__PIC__) + +/* + * PIC uses %ebx, so we need to save it during system calls + */ + +#undef _syscall1 +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall2 +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall3 +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall4 +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall5 +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"m" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \ +__syscall_return(type,__res); \ +} + +#endif /* __PIC__ */ + + diff --git a/ldso/ldso/i386/sysdep.h b/ldso/ldso/i386/sysdep.h index 9bbeef1fa..bf3d43be6 100644 --- a/ldso/ldso/i386/sysdep.h +++ b/ldso/ldso/i386/sysdep.h @@ -1,4 +1,3 @@ - /* * Various assmbly language/system dependent hacks that are required * so that we can minimize the amount of platform specific code. @@ -73,9 +72,9 @@ /* Here we define the magic numbers that this dynamic loader should accept */ #define MAGIC1 EM_386 -#define MAGIC2 EM_486 +#undef MAGIC2 /* Used for error messages */ -#define ELF_TARGET "386/486" +#define ELF_TARGET "386" extern unsigned int _dl_linux_resolver(int dummy, int i); -- cgit v1.2.3