ignore_init.c revision 245133
1/*- 2 * Copyright 2012 Konstantin Belousov <kib@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> 27__FBSDID("$FreeBSD: head/lib/csu/common/ignore_init.c 245133 2013-01-07 17:58:27Z kib $"); 28 29#include "notes.h" 30 31extern int main(int, char **, char **); 32 33extern void (*__preinit_array_start[])(int, char **, char **) __hidden; 34extern void (*__preinit_array_end[])(int, char **, char **) __hidden; 35extern void (*__init_array_start[])(int, char **, char **) __hidden; 36extern void (*__init_array_end[])(int, char **, char **) __hidden; 37extern void (*__fini_array_start[])(void) __hidden; 38extern void (*__fini_array_end[])(void) __hidden; 39extern void _fini(void) __hidden; 40extern void _init(void) __hidden; 41 42extern int _DYNAMIC; 43#pragma weak _DYNAMIC 44 45char **environ; 46const char *__progname = ""; 47 48static void 49finalizer(void) 50{ 51 void (*fn)(void); 52 size_t array_size, n; 53 54 array_size = __fini_array_end - __fini_array_start; 55 for (n = array_size; n > 0; n--) { 56 fn = __fini_array_start[n - 1]; 57 if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1) 58 (fn)(); 59 } 60 _fini(); 61} 62 63static inline void 64handle_static_init(int argc, char **argv, char **env) 65{ 66 void (*fn)(int, char **, char **); 67 size_t array_size, n; 68 69 if (&_DYNAMIC != NULL) 70 return; 71 72 atexit(finalizer); 73 74 array_size = __preinit_array_end - __preinit_array_start; 75 for (n = 0; n < array_size; n++) { 76 fn = __preinit_array_start[n]; 77 if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1) 78 fn(argc, argv, env); 79 } 80 _init(); 81 array_size = __init_array_end - __init_array_start; 82 for (n = 0; n < array_size; n++) { 83 fn = __init_array_start[n]; 84 if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1) 85 fn(argc, argv, env); 86 } 87} 88 89static inline void 90handle_argv(int argc, char *argv[], char **env) 91{ 92 const char *s; 93 94 if (environ == NULL) 95 environ = env; 96 if (argc > 0 && argv[0] != NULL) { 97 __progname = argv[0]; 98 for (s = __progname; *s != '\0'; s++) { 99 if (*s == '/') 100 __progname = s + 1; 101 } 102 } 103} 104 105static const struct { 106 int32_t namesz; 107 int32_t descsz; 108 int32_t type; 109 char name[sizeof(NOTE_FREEBSD_VENDOR)]; 110 uint32_t desc; 111} crt_noinit_tag __attribute__ ((section (NOTE_SECTION), 112 aligned(4))) __used = { 113 .namesz = sizeof(NOTE_FREEBSD_VENDOR), 114 .descsz = sizeof(uint32_t), 115 .type = CRT_NOINIT_NOTETYPE, 116 .name = NOTE_FREEBSD_VENDOR, 117 .desc = 0 118}; 119