crt0.c (4427B)
1 /* $Id: //depot/blt/lib/crt0.c#20 $ 2 ** 3 ** Copyright 1998 Brian J. Swetland 4 ** All rights reserved. 5 ** Copyright 1998-1999 Sidney Cammeresi 6 ** All rights reserved. 7 ** 8 ** Redistribution and use in source and binary forms, with or without 9 ** modification, are permitted provided that the following conditions 10 ** are met: 11 ** 1. Redistributions of source code must retain the above copyright 12 ** notice, this list of conditions, and the following disclaimer. 13 ** 2. Redistributions in binary form must reproduce the above copyright 14 ** notice, this list of conditions, and the following disclaimer in the 15 ** documentation and/or other materials provided with the distribution. 16 ** 3. The name of the author may not be used to endorse or promote products 17 ** derived from this software without specific prior written permission. 18 ** 19 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <string.h> 32 #include <elf.h> 33 #include <blt/syscall.h> 34 #include <blt/libsyms.h> 35 #include <blt/os.h> 36 37 int main(int argc, char **argv); 38 static void _init(void); 39 40 char *__progname; 41 42 void _start(int argc, char **argv) 43 { 44 _init(); 45 __progname = *argv; 46 os_terminate (main (argc, argv)); 47 } 48 49 #define MAXINIT 8 50 51 void __libc_init_memory(unsigned int top_of_binary, 52 unsigned int start_bss, unsigned int bss_length); 53 54 static void _init(void) 55 { 56 char *strtab; 57 int symtablen, top, i, j, p; 58 elf32_hdr_t *hdr; 59 elf32_sym_t *symtab; 60 elf32_sec_hdr_t *last; 61 init_info *inits[MAXINIT]; 62 63 hdr = (elf32_hdr_t *) 0x1000; 64 symtab = _elf_find_section_data (hdr, ".symtab"); 65 strtab = _elf_find_section_data (hdr, ".strtab"); 66 symtablen = _elf_section_size (hdr, ".symtab") / sizeof (elf32_sym_t); 67 last = (elf32_sec_hdr_t *) ((unsigned int) hdr + hdr->e_shoff + 68 hdr->e_shentsize * (hdr->e_shnum - 1)); 69 top = (unsigned int) hdr + last->sh_offset + last->sh_size; 70 71 /* Find any __init_... symbols and build a list of 'em 72 ** These will all be called before main(), but after 73 ** the .bss is zero'd 74 */ 75 for (j = 0, i = 0; i < symtablen; i++){ 76 if (!strncmp(strtab + symtab[i].st_name, "__init_", 7) && 77 (symtab[i].st_shndx != SHN_UNDEF)){ 78 inits[j++] = (init_info *) symtab[i].st_value; 79 if(j == MAXINIT) break; 80 } 81 } 82 83 __libc_init_memory((unsigned int) top, (unsigned int) 84 _elf_find_section_data (hdr, ".bss"), _elf_section_size (hdr, ".bss")); 85 86 for(p=0;p<5;p++){ 87 for(i = 0; i < j; i++){ 88 if(inits[i]->priority == p) inits[i]->func(); 89 } 90 } 91 } 92 93 elf32_sec_hdr_t *_elf_find_section_hdr (elf32_hdr_t *hdr, char *name) 94 { 95 char *section_name; 96 int i; 97 elf32_sec_hdr_t *sec_hdr; 98 99 sec_hdr = (elf32_sec_hdr_t *) ((unsigned int) hdr + hdr->e_shoff + 100 hdr->e_shstrndx * hdr->e_shentsize); 101 section_name = (char *) ((unsigned int) hdr + sec_hdr->sh_offset); 102 sec_hdr = (elf32_sec_hdr_t *) ((unsigned int) hdr + hdr->e_shoff); 103 for (i = 0; i < hdr->e_shnum; i++, sec_hdr = (elf32_sec_hdr_t *) 104 ((unsigned int) sec_hdr + hdr->e_shentsize)) 105 if (!strcmp (section_name + sec_hdr->sh_name, name)) 106 return sec_hdr; 107 return NULL; 108 } 109 110 void *_elf_find_section_data (elf32_hdr_t *hdr, char *name) 111 { 112 elf32_sec_hdr_t *sec_hdr; 113 114 sec_hdr = _elf_find_section_hdr (hdr, name); 115 return (sec_hdr == NULL) ? NULL : (void *) ((unsigned int) hdr + 116 sec_hdr->sh_offset); 117 } 118 119 int _elf_section_size (elf32_hdr_t *hdr, char *name) 120 { 121 elf32_sec_hdr_t *sec_hdr; 122 123 sec_hdr = _elf_find_section_hdr (hdr, name); 124 return (sec_hdr == NULL) ? 0 : sec_hdr->sh_size; 125 } 126 127 /****** this crap is to make ld happy when we build shared executables ******/ 128 129 int ___brk_addr; 130 int __environ; 131 132 void __attribute__ ((noreturn)) abort () 133 { 134 for (;;) ; 135 } 136 137 void atexit () 138 { 139 } 140 141 /********************************* end crap *********************************/ 142