c++rt0.c (4408B)
1 /* $Id: //depot/blt/lib/c++rt0.c#5 $ 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 36 int main(int argc, char **argv); 37 static void _init(void); 38 39 char *__progname; 40 41 void _start(int argc, char **argv) 42 { 43 _init(); 44 __progname = *argv; 45 os_terminate (main (argc, argv)); 46 } 47 48 #define MAXINIT 8 49 50 void __libc_init_memory(unsigned int top_of_binary, 51 unsigned int start_bss, unsigned int bss_length); 52 53 static void _init(void) 54 { 55 char *strtab; 56 int symtablen, top, i, j, p; 57 elf32_hdr_t *hdr; 58 elf32_sym_t *symtab; 59 elf32_sec_hdr_t *last; 60 init_info *inits[MAXINIT]; 61 62 hdr = (elf32_hdr_t *) 0x1000; 63 symtab = _elf_find_section_data (hdr, ".symtab"); 64 strtab = _elf_find_section_data (hdr, ".strtab"); 65 symtablen = _elf_section_size (hdr, ".symtab") / sizeof (elf32_sym_t); 66 last = (elf32_sec_hdr_t *) ((unsigned int) hdr + hdr->e_shoff + 67 hdr->e_shentsize * (hdr->e_shnum - 1)); 68 top = (unsigned int) hdr + last->sh_offset + last->sh_size; 69 70 /* Find any __init_... symbols and build a list of 'em 71 ** These will all be called before main(), but after 72 ** the .bss is zero'd 73 */ 74 for (j = 0, i = 0; i < symtablen; i++){ 75 if (!strncmp(strtab + symtab[i].st_name, "__init_", 7) && 76 (symtab[i].st_shndx != SHN_UNDEF)){ 77 inits[j++] = (init_info *) symtab[i].st_value; 78 if(j == MAXINIT) break; 79 } 80 } 81 82 __libc_init_memory((unsigned int) top, (unsigned int) 83 _elf_find_section_data (hdr, ".bss"), _elf_section_size (hdr, ".bss")); 84 85 for(p=0;p<5;p++){ 86 for(i = 0; i < j; i++){ 87 if(inits[i]->priority == p) inits[i]->func(); 88 } 89 } 90 } 91 92 elf32_sec_hdr_t *_elf_find_section_hdr (elf32_hdr_t *hdr, char *name) 93 { 94 char *section_name; 95 int i; 96 elf32_sec_hdr_t *sec_hdr; 97 98 sec_hdr = (elf32_sec_hdr_t *) ((unsigned int) hdr + hdr->e_shoff + 99 hdr->e_shstrndx * hdr->e_shentsize); 100 section_name = (char *) ((unsigned int) hdr + sec_hdr->sh_offset); 101 sec_hdr = (elf32_sec_hdr_t *) ((unsigned int) hdr + hdr->e_shoff); 102 for (i = 0; i < hdr->e_shnum; i++, sec_hdr = (elf32_sec_hdr_t *) 103 ((unsigned int) sec_hdr + hdr->e_shentsize)) 104 if (!strcmp (section_name + sec_hdr->sh_name, name)) 105 return sec_hdr; 106 return NULL; 107 } 108 109 void *_elf_find_section_data (elf32_hdr_t *hdr, char *name) 110 { 111 elf32_sec_hdr_t *sec_hdr; 112 113 sec_hdr = _elf_find_section_hdr (hdr, name); 114 return (sec_hdr == NULL) ? NULL : (void *) ((unsigned int) hdr + 115 sec_hdr->sh_offset); 116 } 117 118 int _elf_section_size (elf32_hdr_t *hdr, char *name) 119 { 120 elf32_sec_hdr_t *sec_hdr; 121 122 sec_hdr = _elf_find_section_hdr (hdr, name); 123 return (sec_hdr == NULL) ? 0 : sec_hdr->sh_size; 124 } 125 126 /****** this crap is to make ld happy when we build shared executables ******/ 127 128 int ___brk_addr; 129 int __environ; 130 131 void __attribute__ ((noreturn)) abort () 132 { 133 for (;;) ; 134 } 135 136 void atexit () 137 { 138 } 139 140 /********************************* end crap *********************************/ 141