1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 1988 AT&T 24 * All Rights Reserved 25 * 26 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. 27 */ 28 29 /* 30 * Utility functions 31 */ 32 #include <unistd.h> 33 #include <signal.h> 34 #include <locale.h> 35 #include <string.h> 36 #include "msg.h" 37 #include "_libld.h" 38 39 /* 40 * Exit after cleaning up. 41 */ 42 int 43 ld_exit(Ofl_desc *ofl) 44 { 45 /* 46 * If we have created an output file remove it. 47 */ 48 if ((ofl->ofl_fd > 0) && ((ofl->ofl_flags1 & FLG_OF1_NONREG) == 0)) 49 (void) unlink(ofl->ofl_name); 50 51 /* 52 * Inform any support library that the link-edit has failed. 53 */ 54 ld_sup_atexit(ofl, 1); 55 56 /* 57 * Wrap up debug output file if one is open 58 */ 59 dbg_cleanup(); 60 61 /* If any ERR_GUIDANCE messages were issued, add a summary */ 62 if (ofl->ofl_guideflags & FLG_OFG_ISSUED) 63 ld_eprintf(ofl, ERR_GUIDANCE, MSG_INTL(MSG_GUIDE_SUMMARY)); 64 65 return (1); 66 } 67 68 /* 69 * Establish the signals we're interested in, and the handlers that need to be 70 * reinstalled should any of these signals occur. 71 */ 72 typedef struct { 73 int signo; 74 void (* defhdl)(); 75 } Signals; 76 77 static Signals signals[] = { 78 { SIGHUP, SIG_DFL }, 79 { SIGINT, SIG_IGN }, 80 { SIGQUIT, SIG_DFL }, 81 { SIGBUS, SIG_DFL }, 82 { SIGTERM, SIG_IGN }, 83 { 0, 0 } }; 84 85 static Ofl_desc *Ofl = NULL; 86 87 /* 88 * Define our signal handler. 89 */ 90 static void 91 /* ARGSUSED2 */ 92 handler(int sig, siginfo_t *sip, void *utp) 93 { 94 struct sigaction nact; 95 Signals * sigs; 96 97 /* 98 * Reset all ignore handlers regardless of how we got here. 99 */ 100 nact.sa_handler = SIG_IGN; 101 nact.sa_flags = 0; 102 (void) sigemptyset(&nact.sa_mask); 103 104 for (sigs = signals; sigs->signo; sigs++) { 105 if (sigs->defhdl == SIG_IGN) 106 (void) sigaction(sigs->signo, &nact, NULL); 107 } 108 109 /* 110 * The model for creating an output file is to ftruncate() it to the 111 * required size and mmap() a mapping into which the new contents are 112 * written. Neither of these operations guarantee that the required 113 * disk blocks exist, and should we run out of disk space a bus error 114 * is generated. 115 * Other situations have been reported to result in ld catching a bus 116 * error (one instance was a stale NFS handle from an unstable server). 117 * Thus we catch all bus errors and hope we can decode a better error. 118 */ 119 if ((sig == SIGBUS) && sip && Ofl->ofl_name) { 120 ld_eprintf(Ofl, ERR_FATAL, MSG_INTL(MSG_FIL_INTERRUPT), 121 Ofl->ofl_name, strerror(sip->si_errno)); 122 } 123 /* 124 * This assert(0) causes DEBUG enabled linkers to produce a core file. 125 */ 126 if ((sig != SIGHUP) && (sig != SIGINT)) 127 assert(0); 128 129 exit(ld_exit(Ofl)); 130 } 131 132 /* 133 * Establish a signal handler for all signals we're interested in. 134 */ 135 void 136 ld_init_sighandler(Ofl_desc *ofl) 137 { 138 struct sigaction nact, oact; 139 Signals * sigs; 140 141 Ofl = ofl; 142 143 /* 144 * Our heavy use of mmap() means that we are susceptible to 145 * receiving a SIGBUS in low diskspace situations. The main 146 * purpose of the signal handler is to handle that situation 147 * gracefully, so that out of disk errors don't drop a core file. 148 * 149 * In rare cases, this will prevent us from getting a core from a 150 * SIGBUS triggered by an internal alignment error in libld. 151 * If -znosighandler is set, return without registering the 152 * handler. This is primarily of use for debugging problems in 153 * the field, and is not of general interest. 154 */ 155 if (ofl->ofl_flags1 & FLG_OF1_NOSGHND) 156 return; 157 158 /* 159 * For each signal we're interested in set up a signal handler that 160 * insures we clean up any output file we're in the middle of creating. 161 */ 162 nact.sa_sigaction = handler; 163 (void) sigemptyset(&nact.sa_mask); 164 165 for (sigs = signals; sigs->signo; sigs++) { 166 if ((sigaction(sigs->signo, NULL, &oact) == 0) && 167 (oact.sa_handler != SIG_IGN)) { 168 nact.sa_flags = SA_SIGINFO; 169 if (sigs->defhdl == SIG_DFL) 170 nact.sa_flags |= (SA_RESETHAND | SA_NODEFER); 171 (void) sigaction(sigs->signo, &nact, NULL); 172 } 173 } 174 } 175