linux c之syscall示例原型和运行时入口_start

参考:https://github.com/lpsantil/rt0

/* Copyright (c) 2015, Louis P. Santillan 
 * All rights reserved.
 * See LICENSE for licensing details.
 */

#ifndef __RT0_SYSCALL__
#define __RT0_SYSCALL__

#include 
#include 

#ifdef __LP64__
   #include 
#else
   #include 
#endif

long syscall6( long n, long a0, long a1, long a2, long a3, long a4, long a5 );

#ifndef __RT0_WITH_FASTER_SYSCALL__

#define syscall5( m, b0, b1, b2, b3, b4 )                            \
   syscall6( ( m ), ( b0 ), ( b1 ), ( b2 ), ( b3 ), ( b4 ), 0 )
#define syscall4( m, b0, b1, b2, b3 )                                \
   syscall5( ( m ), ( b0 ), ( b1 ), ( b2 ), ( b3 ), 0 )
#define syscall3( m, b0, b1, b2 )                                    \
   syscall4( ( m ), ( b0 ), ( b1 ), ( b2 ), 0 )
#define syscall2( m, b0, b1 )                                        \
   syscall3( ( m ), ( b0 ), ( b1 ), 0 )
#define syscall1( m, b0 )                                            \
   syscall2( ( m ), ( b0 ), 0 )
#define syscall0( m )                                                \
   syscall1( ( m ), 0 )

#else

long syscall5( long n, long a0, long a1, long a2, long a3, long a4 );
long syscall4( long n, long a0, long a1, long a2, long a3 );
long syscall3( long n, long a0, long a1, long a2 );
long syscall2( long n, long a0, long a1 );
long syscall1( long n, long a0 );
long syscall0( long n );

#endif

#endif
syscall.c

/* Copyright (c) 2015, Louis P. Santillan 
 * All rights reserved.
 * See LICENSE for licensing details.
 */
#include 

#ifdef __LP64__
   #include 
#else
   #include 
#endif

#define __SYSCALL_OUTPUT_REG__            "=a" ( ret )

#define __SYSCALL_CHK_ERROR__()                      \
   ret = ( 0 > ret ? errno = -ret, -1 : ret )

#ifdef __LP64__
   #define __SYSCALL_OPCODE__                "syscall"

   #define __SYSCALL_PREAMBLE__()                    \
      register long r10 __asm__( "r10" ) = a3,       \
                    r08	__asm__( "r8" )  = a4,       \
                    r09 __asm__( "r9" )  = a5

   #define __SYSCALL_INPUT_REGS__                    \
      "a" ( n ), "D" ( a0 ), "S" ( a1 ), "d" ( a2 ), \
      "r" ( r08 ), "r" ( r09 ), "r" ( r10 )

   #define __SYSCALL_CLOBBERS__ "rcx", "r11", "memory"

#else
   #define __SYSCALL_OPCODE__              "int $0x80"

   #define __SYSCALL_PREAMBLE__()                    \
      register long ebp __asm__( "ebp" )  = a5

   #define __SYSCALL_INPUT_REGS__                    \
      "a" ( n ), "b" ( a0 ), "c" ( a1 ), "d" ( a2 ), \
      "S" ( a3 ), "D" ( a4 ), "r" ( ebp )

   #define __SYSCALL_CLOBBERS__               "memory"

#endif

long syscall6( long n, long a0, long a1, long a2, long a3, long a4, long a5 )
{
   long ret;
   __SYSCALL_PREAMBLE__();

   __asm__ volatile( __SYSCALL_OPCODE__
                     : __SYSCALL_OUTPUT_REG__
                     : __SYSCALL_INPUT_REGS__
                     : __SYSCALL_CLOBBERS__ );

   __SYSCALL_CHK_ERROR__();

   return( ret );
}

#ifdef __RT0_WITH_FASTER_SYSCALL__

#ifdef __LP64__
   #define __SYSCALL_PREAMBLE5__()                    \
      register long r10 __asm__( "r10" ) = a3,        \
                    r08	__asm__( "r8" )  = a4
   #define __SYSCALL_PREAMBLE4__()                    \
      register long r10 __asm__( "r10" ) = a3
   #define __SYSCALL_PREAMBLE3__()
   #define __SYSCALL_PREAMBLE2__()
   #define __SYSCALL_PREAMBLE1__()
   #define __SYSCALL_PREAMBLE0__()

   #define __SYSCALL_INPUT_REGS5__                    \
      "a" ( n ), "D" ( a0 ), "S" ( a1 ), "d" ( a2 ),  \
      "r" ( r08 ), "r" ( r10 )
   #define __SYSCALL_INPUT_REGS4__                    \
      "a" ( n ), "D" ( a0 ), "S" ( a1 ), "d" ( a2 ),  \
      "r" ( r10 )
   #define __SYSCALL_INPUT_REGS3__                    \
      "a" ( n ), "D" ( a0 ), "S" ( a1 ), "d" ( a2 )
   #define __SYSCALL_INPUT_REGS2__                    \
      "a" ( n ), "D" ( a0 ), "S" ( a1 )
   #define __SYSCALL_INPUT_REGS1__                    \
      "a" ( n ), "D" ( a0 )
   #define __SYSCALL_INPUT_REGS0__                    \
      "a" ( n )

#else
   #define __SYSCALL_PREAMBLE5__()
   #define __SYSCALL_PREAMBLE4__()
   #define __SYSCALL_PREAMBLE3__()
   #define __SYSCALL_PREAMBLE2__()
   #define __SYSCALL_PREAMBLE1__()
   #define __SYSCALL_PREAMBLE0__()

   #define __SYSCALL_INPUT_REGS5__                    \
      "a" ( n ), "b" ( a0 ), "c" ( a1 ), "d" ( a2 ),  \
      "S" ( a3 ), "D" ( a4 )
   #define __SYSCALL_INPUT_REGS4__                    \
      "a" ( n ), "b" ( a0 ), "c" ( a1 ), "d" ( a2 ),  \
      "S" ( a3 )
   #define __SYSCALL_INPUT_REGS3__                    \
      "a" ( n ), "b" ( a0 ), "c" ( a1 ), "d" ( a2 )
   #define __SYSCALL_INPUT_REGS2__                    \
      "a" ( n ), "b" ( a0 ), "c" ( a1 )
   #define __SYSCALL_INPUT_REGS1__                    \
      "a" ( n ), "b" ( a0 )
   #define __SYSCALL_INPUT_REGS0__                    \
      "a" ( n )

#endif

long syscall5( long n, long a0, long a1, long a2, long a3, long a4 )
{
   long ret;
   __SYSCALL_PREAMBLE5__();

   __asm__ volatile( __SYSCALL_OPCODE__
                     : __SYSCALL_OUTPUT_REG__
                     : __SYSCALL_INPUT_REGS5__
                     : __SYSCALL_CLOBBERS__ );

   __SYSCALL_CHK_ERROR__();

   return( ret );
}

long syscall4( long n, long a0, long a1, long a2, long a3 )
{
   long ret;
   __SYSCALL_PREAMBLE4__();

   __asm__ volatile( __SYSCALL_OPCODE__
                     : __SYSCALL_OUTPUT_REG__
                     : __SYSCALL_INPUT_REGS4__
                     : __SYSCALL_CLOBBERS__ );

   __SYSCALL_CHK_ERROR__();

   return( ret );
}

long syscall3( long n, long a0, long a1, long a2 )
{
   long ret;
   __SYSCALL_PREAMBLE3__();

   __asm__ volatile( __SYSCALL_OPCODE__
                     : __SYSCALL_OUTPUT_REG__
                     : __SYSCALL_INPUT_REGS3__
                     : __SYSCALL_CLOBBERS__ );

   __SYSCALL_CHK_ERROR__();

   return( ret );
}

long syscall2( long n, long a0, long a1 )
{
   long ret;
   __SYSCALL_PREAMBLE2__();

   __asm__ volatile( __SYSCALL_OPCODE__
                     : __SYSCALL_OUTPUT_REG__
                     : __SYSCALL_INPUT_REGS2__
                     : __SYSCALL_CLOBBERS__ );

   __SYSCALL_CHK_ERROR__();

   return( ret );
}

long syscall1( long n, long a0 )
{
   long ret;
   __SYSCALL_PREAMBLE1__();

   __asm__ volatile( __SYSCALL_OPCODE__
                     : __SYSCALL_OUTPUT_REG__
                     : __SYSCALL_INPUT_REGS1__
                     : __SYSCALL_CLOBBERS__ );

   __SYSCALL_CHK_ERROR__();

   return( ret );
}

long syscall0( long n )
{
   long ret;
   __SYSCALL_PREAMBLE0__();

   __asm__ volatile( __SYSCALL_OPCODE__
                     : __SYSCALL_OUTPUT_REG__
                     : __SYSCALL_INPUT_REGS0__
                     : __SYSCALL_CLOBBERS__ );

   __SYSCALL_CHK_ERROR__();

   return( ret );
}

#endif
c语言运行时start函数入口。

/* Copyright (c) 2015, Louis P. Santillan 
 * All rights reserved.
 * See LICENSE for licensing details.
 */

#include 

#ifdef __LP64__
   #define __STARTUP_PREAMBLE__() register long rax __asm__( "rax" )

   /* Setup the base */
   /* argc = RDI = [ RSP ] */
   /* argv = RSI = [ RSP+8 ] */
   /* envp = RDX = [ argv+8*argc+8 ] */
   /* align the stack */
   #define __STARTUP_ASM__                                           \
                     "pop	%rbp\n\t"                            \
                     "mov	%rsp,	%rbp\n\t"                    \
                     "mov	(0)(%rbp),	%rdi\n\t"            \
                     "lea	(8)(%rbp),	%rsi\n\t"            \
                     "lea	(8)(%rsi,%rdi,8),	%rdx\n\t"    \
                     "and	$-16,	%rsp\n\t"

   #define __STARTUP_GETRETVAL__ "=a"( rax )

   #define __STARTUP_RETVAL__ rax
#else
   #define __STARTUP_PREAMBLE__() register long eax __asm__( "eax" )

   /* Setup the base */
   /* Fix GCC's 'helpful" 16-byte alignment */
   /* argc = ECX = [ ESP ] */
   /* argv = EDX = [ ESP+8 ] */
   /* envp = EAX = [ argv+8*argc+8 ] */
   /* align the stack */
   /* push args onto re-aligned stack */
   #define __STARTUP_ASM__                                           \
                     "mov	%esp,	%ebp\n\t"                    \
                     "add	$0x1c,	%ebp\n\t"                    \
                     "mov	(0)(%ebp),	%ecx\n\t"            \
                     "lea	(4)(%ebp),	%edx\n\t"            \
                     "lea	(4)(%edx,%ecx,4),	%eax\n\t"    \
                     "and	$-16,	%esp\n\t"                    \
                     "push	%eax\n\t"                            \
                     "push	%edx\n\t"                            \
                     "push	%ecx\n\t"

   #define __STARTUP_GETRETVAL__ "=a"( eax )

   #define __STARTUP_RETVAL__ eax
#endif

/* pointer to array of char* strings that define the current environment variables */
char **__environ;
int errno;

void _start( void ) __attribute__((noreturn));

void _start( void )
{
   __STARTUP_PREAMBLE__();

   __asm__ volatile( __STARTUP_ASM__
                     "call	main" );

   _exit( __STARTUP_RETVAL__ );

   for(;;);
}





你可能感兴趣的:(linux_c,c/c++)