17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 55aefb655Srie * Common Development and Distribution License (the "License"). 65aefb655Srie * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 215aefb655Srie 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright (c) 1988 AT&T 247c478bd9Sstevel@tonic-gate * All Rights Reserved 257c478bd9Sstevel@tonic-gate * 26*1007fd6fSAli Bahrami * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. 277c478bd9Sstevel@tonic-gate */ 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * Utility functions 317c478bd9Sstevel@tonic-gate */ 327c478bd9Sstevel@tonic-gate #include <unistd.h> 337c478bd9Sstevel@tonic-gate #include <signal.h> 347c478bd9Sstevel@tonic-gate #include <locale.h> 357c478bd9Sstevel@tonic-gate #include <string.h> 367c478bd9Sstevel@tonic-gate #include "msg.h" 377c478bd9Sstevel@tonic-gate #include "_libld.h" 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate /* 407c478bd9Sstevel@tonic-gate * Exit after cleaning up. 417c478bd9Sstevel@tonic-gate */ 427c478bd9Sstevel@tonic-gate int 435aefb655Srie ld_exit(Ofl_desc *ofl) 447c478bd9Sstevel@tonic-gate { 457c478bd9Sstevel@tonic-gate /* 467c478bd9Sstevel@tonic-gate * If we have created an output file remove it. 477c478bd9Sstevel@tonic-gate */ 485aefb655Srie if ((ofl->ofl_fd > 0) && ((ofl->ofl_flags1 & FLG_OF1_NONREG) == 0)) 495aefb655Srie (void) unlink(ofl->ofl_name); 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate /* 527c478bd9Sstevel@tonic-gate * Inform any support library that the link-edit has failed. 537c478bd9Sstevel@tonic-gate */ 545aefb655Srie ld_sup_atexit(ofl, 1); 55e23c41c9SAli Bahrami 56e23c41c9SAli Bahrami /* 57e23c41c9SAli Bahrami * Wrap up debug output file if one is open 58e23c41c9SAli Bahrami */ 59e23c41c9SAli Bahrami dbg_cleanup(); 60e23c41c9SAli Bahrami 61*1007fd6fSAli Bahrami /* If any ERR_GUIDANCE messages were issued, add a summary */ 62*1007fd6fSAli Bahrami if (ofl->ofl_guideflags & FLG_OFG_ISSUED) 63*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_GUIDANCE, MSG_INTL(MSG_GUIDE_SUMMARY)); 64*1007fd6fSAli Bahrami 657c478bd9Sstevel@tonic-gate return (1); 667c478bd9Sstevel@tonic-gate } 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate /* 697c478bd9Sstevel@tonic-gate * Establish the signals we're interested in, and the handlers that need to be 707c478bd9Sstevel@tonic-gate * reinstalled should any of these signals occur. 717c478bd9Sstevel@tonic-gate */ 727c478bd9Sstevel@tonic-gate typedef struct { 737c478bd9Sstevel@tonic-gate int signo; 747c478bd9Sstevel@tonic-gate void (* defhdl)(); 757c478bd9Sstevel@tonic-gate } Signals; 767c478bd9Sstevel@tonic-gate 775aefb655Srie static Signals signals[] = { 785aefb655Srie { SIGHUP, SIG_DFL }, 797c478bd9Sstevel@tonic-gate { SIGINT, SIG_IGN }, 807c478bd9Sstevel@tonic-gate { SIGQUIT, SIG_DFL }, 817c478bd9Sstevel@tonic-gate { SIGBUS, SIG_DFL }, 827c478bd9Sstevel@tonic-gate { SIGTERM, SIG_IGN }, 837c478bd9Sstevel@tonic-gate { 0, 0 } }; 847c478bd9Sstevel@tonic-gate 85*1007fd6fSAli Bahrami static Ofl_desc *Ofl = NULL; 865aefb655Srie 877c478bd9Sstevel@tonic-gate /* 887c478bd9Sstevel@tonic-gate * Define our signal handler. 897c478bd9Sstevel@tonic-gate */ 907c478bd9Sstevel@tonic-gate static void 917c478bd9Sstevel@tonic-gate /* ARGSUSED2 */ 927c478bd9Sstevel@tonic-gate handler(int sig, siginfo_t *sip, void *utp) 937c478bd9Sstevel@tonic-gate { 947c478bd9Sstevel@tonic-gate struct sigaction nact; 957c478bd9Sstevel@tonic-gate Signals * sigs; 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate /* 987c478bd9Sstevel@tonic-gate * Reset all ignore handlers regardless of how we got here. 997c478bd9Sstevel@tonic-gate */ 1007c478bd9Sstevel@tonic-gate nact.sa_handler = SIG_IGN; 1017c478bd9Sstevel@tonic-gate nact.sa_flags = 0; 1027c478bd9Sstevel@tonic-gate (void) sigemptyset(&nact.sa_mask); 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate for (sigs = signals; sigs->signo; sigs++) { 1057c478bd9Sstevel@tonic-gate if (sigs->defhdl == SIG_IGN) 1067c478bd9Sstevel@tonic-gate (void) sigaction(sigs->signo, &nact, NULL); 1077c478bd9Sstevel@tonic-gate } 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate /* 1107c478bd9Sstevel@tonic-gate * The model for creating an output file is to ftruncate() it to the 1117c478bd9Sstevel@tonic-gate * required size and mmap() a mapping into which the new contents are 1127c478bd9Sstevel@tonic-gate * written. Neither of these operations guarantee that the required 1137c478bd9Sstevel@tonic-gate * disk blocks exist, and should we run out of disk space a bus error 1147c478bd9Sstevel@tonic-gate * is generated. 1157c478bd9Sstevel@tonic-gate * Other situations have been reported to result in ld catching a bus 1167c478bd9Sstevel@tonic-gate * error (one instance was a stale NFS handle from an unstable server). 1177c478bd9Sstevel@tonic-gate * Thus we catch all bus errors and hope we can decode a better error. 1187c478bd9Sstevel@tonic-gate */ 1195aefb655Srie if ((sig == SIGBUS) && sip && Ofl->ofl_name) { 120*1007fd6fSAli Bahrami ld_eprintf(Ofl, ERR_FATAL, MSG_INTL(MSG_FIL_INTERRUPT), 1215aefb655Srie Ofl->ofl_name, strerror(sip->si_errno)); 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate /* 1247c478bd9Sstevel@tonic-gate * This assert(0) causes DEBUG enabled linkers to produce a core file. 1257c478bd9Sstevel@tonic-gate */ 1267c478bd9Sstevel@tonic-gate if ((sig != SIGHUP) && (sig != SIGINT)) 1277c478bd9Sstevel@tonic-gate assert(0); 1287c478bd9Sstevel@tonic-gate 1295aefb655Srie exit(ld_exit(Ofl)); 1307c478bd9Sstevel@tonic-gate } 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate /* 1337c478bd9Sstevel@tonic-gate * Establish a signal handler for all signals we're interested in. 1347c478bd9Sstevel@tonic-gate */ 1357c478bd9Sstevel@tonic-gate void 13656e2cc86SAli Bahrami ld_init_sighandler(Ofl_desc *ofl) 1377c478bd9Sstevel@tonic-gate { 1387c478bd9Sstevel@tonic-gate struct sigaction nact, oact; 1397c478bd9Sstevel@tonic-gate Signals * sigs; 1407c478bd9Sstevel@tonic-gate 1415aefb655Srie Ofl = ofl; 1425aefb655Srie 1437c478bd9Sstevel@tonic-gate /* 14456e2cc86SAli Bahrami * Our heavy use of mmap() means that we are susceptible to 14556e2cc86SAli Bahrami * receiving a SIGBUS in low diskspace situations. The main 14656e2cc86SAli Bahrami * purpose of the signal handler is to handle that situation 14756e2cc86SAli Bahrami * gracefully, so that out of disk errors don't drop a core file. 14856e2cc86SAli Bahrami * 14956e2cc86SAli Bahrami * In rare cases, this will prevent us from getting a core from a 15056e2cc86SAli Bahrami * SIGBUS triggered by an internal alignment error in libld. 15156e2cc86SAli Bahrami * If -znosighandler is set, return without registering the 15256e2cc86SAli Bahrami * handler. This is primarily of use for debugging problems in 15356e2cc86SAli Bahrami * the field, and is not of general interest. 15456e2cc86SAli Bahrami */ 15556e2cc86SAli Bahrami if (ofl->ofl_flags1 & FLG_OF1_NOSGHND) 15656e2cc86SAli Bahrami return; 15756e2cc86SAli Bahrami 15856e2cc86SAli Bahrami /* 1597c478bd9Sstevel@tonic-gate * For each signal we're interested in set up a signal handler that 1607c478bd9Sstevel@tonic-gate * insures we clean up any output file we're in the middle of creating. 1617c478bd9Sstevel@tonic-gate */ 1627c478bd9Sstevel@tonic-gate nact.sa_sigaction = handler; 1637c478bd9Sstevel@tonic-gate (void) sigemptyset(&nact.sa_mask); 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate for (sigs = signals; sigs->signo; sigs++) { 1667c478bd9Sstevel@tonic-gate if ((sigaction(sigs->signo, NULL, &oact) == 0) && 1677c478bd9Sstevel@tonic-gate (oact.sa_handler != SIG_IGN)) { 1687c478bd9Sstevel@tonic-gate nact.sa_flags = SA_SIGINFO; 1697c478bd9Sstevel@tonic-gate if (sigs->defhdl == SIG_DFL) 1707c478bd9Sstevel@tonic-gate nact.sa_flags |= (SA_RESETHAND | SA_NODEFER); 1717c478bd9Sstevel@tonic-gate (void) sigaction(sigs->signo, &nact, NULL); 1727c478bd9Sstevel@tonic-gate } 1737c478bd9Sstevel@tonic-gate } 1747c478bd9Sstevel@tonic-gate } 175