10Sduke/*- 21879Sstefank * Copyright 2012 Konstantin Belousov <kib@FreeBSD.org> 30Sduke * All rights reserved. 40Sduke * 50Sduke * Redistribution and use in source and binary forms, with or without 60Sduke * modification, are permitted provided that the following conditions 70Sduke * are met: 80Sduke * 1. Redistributions of source code must retain the above copyright 90Sduke * notice, this list of conditions and the following disclaimer. 100Sduke * 2. Redistributions in binary form must reproduce the above copyright 110Sduke * notice, this list of conditions and the following disclaimer in the 120Sduke * documentation and/or other materials provided with the distribution. 130Sduke * 140Sduke * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 150Sduke * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 160Sduke * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 170Sduke * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 180Sduke * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 191472Strims * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 201472Strims * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 211472Strims * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 220Sduke * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 230Sduke * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 240Sduke */ 251879Sstefank 261879Sstefank#include <sys/cdefs.h> 271879Sstefank__FBSDID("$FreeBSD$"); 281879Sstefank 291879Sstefank#include "notes.h" 301879Sstefank 311879Sstefankextern int main(int, char **, char **); 320Sduke 330Sdukeextern void (*__preinit_array_start[])(int, char **, char **) __hidden; 340Sdukeextern void (*__preinit_array_end[])(int, char **, char **) __hidden; 350Sdukeextern void (*__init_array_start[])(int, char **, char **) __hidden; 360Sdukeextern void (*__init_array_end[])(int, char **, char **) __hidden; 370Sdukeextern void (*__fini_array_start[])(void) __hidden; 380Sdukeextern void (*__fini_array_end[])(void) __hidden; 390Sdukeextern void _fini(void) __hidden; 400Sdukeextern void _init(void) __hidden; 410Sduke 420Sdukeextern int _DYNAMIC; 430Sduke#pragma weak _DYNAMIC 440Sduke 450Sdukechar **environ; 460Sdukeconst char *__progname = ""; 470Sduke 480Sdukestatic void 490Sdukefinalizer(void) 5010006Sthartmann{ 510Sduke void (*fn)(void); 520Sduke size_t array_size, n; 530Sduke 540Sduke array_size = __fini_array_end - __fini_array_start; 550Sduke for (n = array_size; n > 0; n--) { 560Sduke fn = __fini_array_start[n - 1]; 570Sduke if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1) 5810006Sthartmann (fn)(); 590Sduke } 600Sduke _fini(); 610Sduke} 620Sduke 630Sdukestatic inline void 640Sdukehandle_static_init(int argc, char **argv, char **env) 650Sduke{ 660Sduke void (*fn)(int, char **, char **); 670Sduke size_t array_size, n; 680Sduke 690Sduke if (&_DYNAMIC != NULL) 700Sduke return; 710Sduke 720Sduke atexit(finalizer); 730Sduke 740Sduke array_size = __preinit_array_end - __preinit_array_start; 750Sduke for (n = 0; n < array_size; n++) { 760Sduke fn = __preinit_array_start[n]; 770Sduke if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1) 780Sduke fn(argc, argv, env); 790Sduke } 800Sduke _init(); 810Sduke array_size = __init_array_end - __init_array_start; 820Sduke for (n = 0; n < array_size; n++) { 8310006Sthartmann fn = __init_array_start[n]; 840Sduke if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1) 850Sduke fn(argc, argv, env); 860Sduke } 870Sduke} 880Sduke 890Sdukestatic inline void 900Sdukehandle_argv(int argc, char *argv[], char **env) 910Sduke{ 920Sduke const char *s; 930Sduke 940Sduke if (environ == NULL) 950Sduke environ = env; 960Sduke if (argc > 0 && argv[0] != NULL) { 9710006Sthartmann __progname = argv[0]; 980Sduke for (s = __progname; *s != '\0'; s++) { 990Sduke if (*s == '/') 1000Sduke __progname = s + 1; 1010Sduke } 1020Sduke } 1030Sduke} 1040Sduke 1050Sdukestatic const struct { 1060Sduke int32_t namesz; 1070Sduke int32_t descsz; 1080Sduke int32_t type; 1090Sduke char name[sizeof(NOTE_FREEBSD_VENDOR)]; 1100Sduke uint32_t desc; 1110Sduke} crt_noinit_tag __attribute__ ((section (NOTE_SECTION), 11210006Sthartmann aligned(4))) __used = { 1130Sduke .namesz = sizeof(NOTE_FREEBSD_VENDOR), 1140Sduke .descsz = sizeof(uint32_t), 1150Sduke .type = CRT_NOINIT_NOTETYPE, 1160Sduke .name = NOTE_FREEBSD_VENDOR, 1170Sduke .desc = 0 1180Sduke}; 1190Sduke