1232832Skib/*- 2232832Skib * Copyright 2012 Konstantin Belousov <kib@FreeBSD.org> 3232832Skib * All rights reserved. 4232832Skib * 5232832Skib * Redistribution and use in source and binary forms, with or without 6232832Skib * modification, are permitted provided that the following conditions 7232832Skib * are met: 8232832Skib * 1. Redistributions of source code must retain the above copyright 9232832Skib * notice, this list of conditions and the following disclaimer. 10232832Skib * 2. Redistributions in binary form must reproduce the above copyright 11232832Skib * notice, this list of conditions and the following disclaimer in the 12232832Skib * documentation and/or other materials provided with the distribution. 13232832Skib * 14232832Skib * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15232832Skib * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16232832Skib * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17232832Skib * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18232832Skib * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19232832Skib * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20232832Skib * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21232832Skib * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22232832Skib * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23232832Skib * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24232832Skib */ 25232832Skib 26232832Skib#include <sys/cdefs.h> 27232832Skib__FBSDID("$FreeBSD$"); 28232832Skib 29232832Skib#include "notes.h" 30232832Skib 31232832Skibextern int main(int, char **, char **); 32232832Skib 33232832Skibextern void (*__preinit_array_start[])(int, char **, char **) __hidden; 34232832Skibextern void (*__preinit_array_end[])(int, char **, char **) __hidden; 35232832Skibextern void (*__init_array_start[])(int, char **, char **) __hidden; 36232832Skibextern void (*__init_array_end[])(int, char **, char **) __hidden; 37232832Skibextern void (*__fini_array_start[])(void) __hidden; 38232832Skibextern void (*__fini_array_end[])(void) __hidden; 39232832Skibextern void _fini(void) __hidden; 40232832Skibextern void _init(void) __hidden; 41232832Skib 42232832Skibextern int _DYNAMIC; 43232832Skib#pragma weak _DYNAMIC 44232832Skib 45232832Skibchar **environ; 46232832Skibconst char *__progname = ""; 47232832Skib 48232832Skibstatic void 49232832Skibfinalizer(void) 50232832Skib{ 51232832Skib void (*fn)(void); 52232832Skib size_t array_size, n; 53232832Skib 54232832Skib array_size = __fini_array_end - __fini_array_start; 55232832Skib for (n = array_size; n > 0; n--) { 56232832Skib fn = __fini_array_start[n - 1]; 57232832Skib if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1) 58232832Skib (fn)(); 59232832Skib } 60232832Skib _fini(); 61232832Skib} 62232832Skib 63232832Skibstatic inline void 64232832Skibhandle_static_init(int argc, char **argv, char **env) 65232832Skib{ 66232832Skib void (*fn)(int, char **, char **); 67232832Skib size_t array_size, n; 68232832Skib 69232832Skib if (&_DYNAMIC != NULL) 70232832Skib return; 71232832Skib 72232832Skib atexit(finalizer); 73232832Skib 74232832Skib array_size = __preinit_array_end - __preinit_array_start; 75232832Skib for (n = 0; n < array_size; n++) { 76232832Skib fn = __preinit_array_start[n]; 77232832Skib if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1) 78232832Skib fn(argc, argv, env); 79232832Skib } 80232832Skib _init(); 81232832Skib array_size = __init_array_end - __init_array_start; 82232832Skib for (n = 0; n < array_size; n++) { 83232832Skib fn = __init_array_start[n]; 84232832Skib if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1) 85232832Skib fn(argc, argv, env); 86232832Skib } 87232832Skib} 88232832Skib 89232832Skibstatic inline void 90245133Skibhandle_argv(int argc, char *argv[], char **env) 91232832Skib{ 92232832Skib const char *s; 93232832Skib 94245133Skib if (environ == NULL) 95245133Skib environ = env; 96245133Skib if (argc > 0 && argv[0] != NULL) { 97245133Skib __progname = argv[0]; 98245133Skib for (s = __progname; *s != '\0'; s++) { 99245133Skib if (*s == '/') 100245133Skib __progname = s + 1; 101245133Skib } 102232832Skib } 103232832Skib} 104232832Skib 105232832Skibstatic const struct { 106232832Skib int32_t namesz; 107232832Skib int32_t descsz; 108232832Skib int32_t type; 109232832Skib char name[sizeof(NOTE_FREEBSD_VENDOR)]; 110232832Skib uint32_t desc; 111232832Skib} crt_noinit_tag __attribute__ ((section (NOTE_SECTION), 112232832Skib aligned(4))) __used = { 113232832Skib .namesz = sizeof(NOTE_FREEBSD_VENDOR), 114232832Skib .descsz = sizeof(uint32_t), 115232832Skib .type = CRT_NOINIT_NOTETYPE, 116232832Skib .name = NOTE_FREEBSD_VENDOR, 117232832Skib .desc = 0 118232832Skib}; 119