⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crt0.s

📁 操作系统SunOS 4.1.3版本的源码
💻 S
字号:
/* @(#)crt0.s 1.1 92/07/30 SMI *//* * "C" run-time program bootstrap. *//* * Copyright (c) 1987 Sun Microsystems, Inc. */#include <sys/syscall.h>#include <sys/mman.h>/* * Start a program by calling its "main" with argument list and environment * strings.  In addition, if program requires dynamic link editing, obtain * and hand control off to the link editor to do so. */	.text	.globl	startstart:					| Execution begins here	lea	0,a6			| Initial stack frame link is 0	movl	sp@,d2			| argc	lea	sp@(4),a3		| argv	movl	d2,d1			| Find end of argv[] as	asll	#2,d1			|   sizeof(argv[0]) * argc	lea	a3@(4,d1:l),a4		| Yields environment	movl	a4,_environ		| Save for program's use	tstl	__dp:l			| Does this program require editing?	beq	1f			|   No	bsr	__getrtld		| getrtld()1:	pea	a4@			| main(argc, argv, envp)	pea	a3@	movl	d2,sp@-	jsr	start_float		| Initialize floating point__main:	jsr	_main			| Do the program	addw	#12,sp			| Clean up#ifdef OLD	movl	#0,sp-			| Ignore main's return value#else	movl	d0,sp@-			| Use main's return value#endif OLD	jsr	_exit			| exit(status)	addql	#4,sp			| In the event exit doesn't	movl	d0,sp@-			|   then _exit(exit(status))	jsr	__exit	/*NOTREACHED*//* * __getrtld: load and call the link editor.  When a program is link edited * by "ld", a structure is created if the program is "incomplete".  Such * programs must "complete themselves" by getting the link editor involved * again. *//* XXX Derive these constants */#define	_RTLD_INTERFACE_	1	/* Interface version */#define	FRAME	0x38			/* sizeof (struct exec) + locals */#define	A_MACH	(-FRAME+0x0)		/* Offsets into struct exec */#define	A_MAGIC	(-FRAME+0x2)#define	A_TEXT	(-FRAME+0x4)#define	A_DATA	(-FRAME+0x8)#define	A_BSS	(-FRAME+0xc)#define	A_ENTRY	(-FRAME+0x14)#define	exec	a6@(-FRAME)		/* Symbols for stack offsets */#define	a_mach	a6@(A_MACH)#define	a_magic	a6@(A_MAGIC)#define	a_text	a6@(A_TEXT)#define	a_data	a6@(A_DATA)#define	a_bss	a6@(A_BSS)#define	a_entry	a6@(A_ENTRY)#define	ldba	a6@(-0x18)		/* ld.so base address */#define	fd_dz	a6@(-0x14)		/* fd on /dev/zero */#define	fd_ld	a6@(-0x10)		/* fd on link editor */#define	udp	a6@(-0xc)		/* &__DYNAMIC */#define	ep	a6@(-0x8)		/* environ */#define	break	a6@(-0x4)		/* &main */#define	SEGSIZ	0x20000#define	PAGSIZ	0x2000#define	ZMAGIC	0413__getrtld:	link	a6,#-FRAME		| Allocate frame	moveml	d2-d3,sp@-		| Save some registers| Find and map in the link editor	pea	__e_ld			| Find the link editor	pea	0			| No flags	pea	__link_editor		| File name	jsr	__open			| fd_ld = open(link_editor, 0)	addl	#0x8,sp	movl	d0,fd_ld| Read in its a.out header	pea	0x20			| Size of buffer	pea	exec			| Address of buffer	movl	d0,sp@-			| fd_ld	jsr	__read			| count = read(fd_ld, &exec, sizeof)	addl	#0x10,sp		| Clean	cmpl	#0x20,d0		| Get full count?	jeq	1f			|   Yes2:	lea	__e_ld,a0		| Otherwise	jra	__errxit		|   dispatch error| Determine if we've got a reasonable executable1:	cmpw	#ZMAGIC,a_magic		| Demand-paged executable?	jne	2b			|   Nope, this is fatal| Determine how much of the address space the link editor will occupy	movl	#(PAGSIZ-1),d2		| Starts one page up	addl	a_text,d2		| Now figure out how long the text is	andl	#~(SEGSIZ-1),d2		| Figure out last text segment and	addl	#SEGSIZ,d2		|   determine data segment start	movl	d2,d0			| d0 == amount for text + gap	addl	a_data,d0		| d0 == text + gap + data	addl	a_bss,d0		| d0 == text + gap + data + bss| Map in the link editor	pea	__e_mmap		| Set up for mapping	pea	0			| No offset	movl	fd_ld,sp@-		| fd on link editor	movl	__mmap_assign,sp@- 	| Specify mapping options	movl	__mmap_ro,sp@-		| Access protection	movl	d0,sp@-			| How much we're mapping	pea	0			| We don't care where it goes	jsr	__mmap			| mmap(all of link editor)	addl	#0x18,sp		| Clean up (but not error string)	movl	d0,ldba			| Save the address| Now, map in the data segment in its proper position	movl	a_text,sp@-		| Offset in file to data segment	movl	fd_ld,sp@-		| fd on link editor	movl	__mmap_fixed,sp@-	| Mapping options	movl	__mmap_prot,sp@-	| Protection	movl	a_data,sp@-		| Map in the whole data segment	movl	d2,d0			| Get relative start of data segment	addl	ldba,d0			| Calculate absolute address	movl	d0,sp@-	jsr	__mmap			| mmap(abs, data segment)	addl	#0x18,sp		| Clean up all but error string	movl	d0,d3			| Save address where data segment went| Unmap the gap between the text and data segments	subl	a_text,d2		| Calculate size of gap	movl	d2,sp@-			| Use that as length of unmapping	movl	ldba,d0			| Set starting address as base +	addl	a_text,d0		|   size of the text segment	movl	d0,sp@-	jsr	__munmap		| Unmap the gap	addl	#0xc,sp			| Clear arguments + error string| Obtain /dev/zero to build the bss from	pea	__e_zero		| Set up for failure	pea	0			| No flags	pea	__dev_zero		| File name	jsr	__open			| fd_dz = open(/dev/zero, 0)	addql	#0x8,sp			| Pop non-error arguments	movl	d0,fd_dz		|   and save file descriptor| Map in enough to build bss from	tstl	a_bss			| Any bss?	jne	1f			|   No, skip all this	addql	#4,sp			| Pop off error string	jra	2f			|   and join common code1:	pea	0			| Otherwise, map from offset 0	movl	d0,sp@-			| Using /dev/zero fd	movl	__mmap_fixed,sp@-	| PRIVATE, FIXED	movl	__mmap_prot,sp@-	| All access	movl	a_bss,sp@-		| Use a bss's worth	addl	a_data,d3		| Starting at the end of the	movl	d3,sp@-			|   data segment	jsr	__mmap			| mmap(/dev/zero, a_bss)	addl	#0x1c,sp		| Clear all arguments| Fill in rest of argument list and call link editor2:	lea	__main,a0		| Pass	movl	a0,break		|   breakpoint address	movl	_environ,ep		| Pass environment	movl	__dp,udp		|   and this program's __DYNAMIC	pea	ldba			| Prepare to call link editor	pea	_RTLD_INTERFACE_	| Tell interface number	movl	ldba,a0			| Get link editor base address	addl	a_entry,a0		| Offset by entry point	jsr	a0@			| Call it	addql	#8,sp			| Clean	moveml	sp@+,d2-d3		| Restore registers	unlk	a6			|   and clean frame	rts				|     and return| System call interfaces#define	STDERR	2			/* File descriptor for errors */#define	STATUS	0x7f			/* Exit status */#define	eo_open	sp@(0xc)		/* open() error pointer offset */#define	eo_mmap sp@(0x1c)		/* mmap() */#define	eo_munmap sp@(0xc)		/* munmap() */#define	eo_read sp@(0x10)		/* read */__open:	movl	eo_open,a0		| Get pointer to error structure	pea	SYS_open		| Push trap code	jra	__syscom		| Execute common code__mmap:	movl	eo_mmap,a0		| See above	pea	SYS_mmap	jra	__syscom__munmap:	movl	eo_munmap,a0	pea	SYS_munmap	jra	__syscom__read:	movl	eo_read,a0	pea	SYS_read__syscom:	trap	#0			| Do the system call	bcss	__errxit		| Error?	rts				|   No, return success__errxit:	movl	a0@+,sp@-		| Push character count	pea	a0@			|   and buffer address	pea	STDERR	pea	0			| Dummy	pea	SYS_write	trap	#0			| write(stderr, &msg, count)	movl	#STATUS,sp@(4)	pea	SYS_exit	trap	#0			| _exit(status)	/* NOTREACHED */| Initialized, read-only data	.even__dp:	.long	__DYNAMIC		| ld makes this 0 or a pointer__link_editor:				| Name of file containing link editor	.asciz	"/usr/lib/ld.so"__dev_zero:				| Name of source of zero'ed memory	.asciz	"/dev/zero"	.even__e_ld:	.long	0x18			| Missing/trashed link editor	.ascii	"crt0: no /usr/lib/ld.so\012"	.even__e_mmap:				| mmap/munmap don't work	.long	0x25	.ascii	"crt0: /usr/lib/ld.so mapping failure\012"	.even__e_zero:				| /dev/zero missing, unmappable	.long	0x13	.ascii	"crt0: no /dev/zero\012"	.even__mmap_assign:				| mmap flags for system assignment	.long	_MAP_NEW+MAP_PRIVATE__mmap_fixed:				| mmap flags for program assignment	.long	_MAP_NEW+MAP_FIXED+MAP_PRIVATE__mmap_prot:				| protection flags	.long	PROT_READ+PROT_WRITE+PROT_EXEC__mmap_ro:				| read only	.long	PROT_READ+PROT_EXEC| Writeable data	.data	.globl	_environ_environ:	.long	0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -