File: cprt0.as

package info (click to toggle)
fpc 3.0.4%2Bdfsg-22
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 291,080 kB
  • sloc: pascal: 3,216,108; xml: 161,992; ansic: 9,637; asm: 8,297; java: 5,346; sh: 4,137; yacc: 3,747; php: 3,283; makefile: 2,711; lex: 2,538; sql: 267; cpp: 145; perl: 134; sed: 132; csh: 34; tcl: 7
file content (160 lines) | stat: -rw-r--r-- 4,445 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/* This is the canonical entry point, usually the first thing in the text
   segment.  The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
   point runs, most registers' values are unspecified, except for:

   %rdx		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.

   %rsp		The stack contains the arguments and environment:
		0(%rsp)			argc
		8(%rsp)			argv[0]
		...
		(8*argc)(%rsp)		NULL
		(8*(argc+1))(%rsp)	envp[0]
		...
					NULL
*/

	.text
	.globl _start
	.type _start,@function
_start:
	/* Clear the frame pointer.  The ABI suggests this be done, to mark
	   the outermost frame obviously.  */
	xorq %rbp, %rbp

	/* Extract the arguments as encoded on the stack and set up
	   the arguments for __libc_start_main (int (*main) (int, char **, char **),
		   int argc, char *argv,
		   void (*init) (void), void (*fini) (void),
		   void (*rtld_fini) (void), void *stack_end).
	   The arguments are passed via registers and on the stack:
	main:		%rdi
	argc:		%rsi
	argv:		%rdx
	init:		%rcx
	fini:		%r8
	rtld_fini:	%r9
	stack_end:	stack.	*/

	movq %rdx, %r9		/* Address of the shared library termination
				   function.  */
	popq %rsi		/* Pop the argument count.  */
	movq %rsp, %rdx		/* argv starts just at the current stack top.  */

        movq    operatingsystem_parameter_argc@GOTPCREL(%rip),%rax
        movq    %rsi,(%rax)
        movq    operatingsystem_parameter_argv@GOTPCREL(%rip),%rax
        movq    %rsp,(%rax)   /* argv starts just at the current stack top.  */
        leaq    8(,%rsi,8),%rax
        addq    %rsp,%rax
        movq    operatingsystem_parameter_envp@GOTPCREL(%rip),%rcx
        movq    %rax,(%rcx)

	/* Align the stack to a 16 byte boundary to follow the ABI.  */
	andq  $~15, %rsp

	pushq %rax		/* Push garbage because we push 8 more bytes.  */

	/* Provide the highest stack address to the user code (for stacks
	   which grow downwards).  */
	pushq %rsp

	/* Pass address of our own entry points to .fini and .init.  */
	movq __libc_csu_init@GOTPCREL(%rip), %rcx
	movq __libc_csu_fini@GOTPCREL(%rip), %r8

	movq main_stub@GOTPCREL(%rip), %rdi

	/* Call the user's main function, and exit with its value.
	   But let the libc call main.	  */
	call __libc_start_main@PLT

	hlt			/* Crash if somehow `exit' does return.	 */

/* fake main routine which will be run from libc */
	.globl main_stub
        .type main_stub,@function
main_stub:
        /* save return address */
        popq    %rax

	// stack alignment
	pushq	%rax

	movq    ___fpc_ret_rbp@GOTPCREL(%rip),%rcx
        movq    %rbp,(%rcx)
	movq    ___fpc_ret@GOTPCREL(%rip),%rcx
        movq    %rax,(%rcx)
        pushq   %rax

        /* Save initial stackpointer */
        movq    __stkptr@GOTPCREL(%rip),%rax
        movq    %rsp,(%rax)

        /* start the program */
        xorq    %rbp,%rbp
        call    PASCALMAIN@PLT
        hlt
	.size   main_stub,.-main_stub


        .globl _haltproc
        .type _haltproc,@function
_haltproc:
        movq    operatingsystem_result@GOTPCREL(%rip),%rax
        movzwl  (%rax),%eax

        /* return to libc */
	movq    ___fpc_ret_rbp@GOTPCREL(%rip),%rcx
        movq    (%rcx),%rbp
	movq    ___fpc_ret@GOTPCREL(%rip),%rcx
        popq    %rdx
        movq    (%rcx),%rdx
        pushq    %rdx
	ret
	.size   _haltproc,.-_haltproc

/* Define a symbol for the first piece of initialized data.  */
	.data
	.globl __data_start
__data_start:
	.long 0
	.weak data_start
	data_start = __data_start

        .globl  ___fpc_brk_addr         /* heap management */
        .type   ___fpc_brk_addr,@object
        .size   ___fpc_brk_addr,8
___fpc_brk_addr:
        .quad   0

___fpc_ret:                             /* return address to libc */
        .quad   0
___fpc_ret_rbp:
        .quad   0

.bss
        .comm __stkptr,8

        .comm operatingsystem_parameter_envp,8
        .comm operatingsystem_parameter_argc,8
        .comm operatingsystem_parameter_argv,8

/* We need this stuff to make gdb behave itself, otherwise
   gdb will chokes with SIGILL when trying to debug apps.
*/
        .section ".note.ABI-tag", "a"
        .align 4
        .long 1f - 0f
        .long 3f - 2f
        .long  1
0:      .asciz "GNU"
1:      .align 4
2:      .long 0
        .long 2,4,0
3:      .align 4

	.section	.note.GNU-stack,"",@progbits