
1: /* Profile PC and write result to FIFO. 2: Copyright (C) 1999, 2000 Free Software Foundation, Inc. 3: This file is part of the GNU C Library. 4: Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. 5: 6: The GNU C Library is free software; you can redistribute it and/or 7: modify it under the terms of the GNU Lesser General Public 8: License as published by the Free Software Foundation; either 9: version 2.1 of the License, or (at your option) any later version. 10: 11: The GNU C Library is distributed in the hope that it will be useful, 12: but WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: Lesser General Public License for more details. 15: 16: You should have received a copy of the GNU Lesser General Public 17: License along with the GNU C Library; if not, write to the Free 18: Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19: 02111-1307 USA. */ 20: 21: #include <errno.h> 22: #include <fcntl.h> 23: #include <stdint.h> 24: #include <stdlib.h> 25: #include <unistd.h> 26: #include <libc-internal.h> 27: 28: /* Nonzero if we are actually doing something. */ 29: static int active; 30: 31: /* The file descriptor of the FIFO. */ 32: static int fd; 33: 34: 35: static void 36: __attribute__ ((constructor)) 37: install (void) 38: { 39: /* See whether the environment variable `PCPROFILE_OUTPUT' is defined. 40: If yes, it should name a FIFO. We open it and mark ourself as active. */ 41: const char *outfile = getenv ("PCPROFILE_OUTPUT"); 42: 43: if (outfile != NULL && *outfile != '\0') 44: { 45: fd = open (outfile, O_RDWR | O_CREAT, 0666); 46: 47: if (fd != -1) 48: { 49: uint32_t word; 50: 51: active = 1; 52: 53: /* Write a magic word which tells the reader about the byte 54: order and the size of the following entries. */ 55: word = 0xdeb00000 | sizeof (void *); 56: if (TEMP_FAILURE_RETRY (write (fd, &word, 4)) != 4) 57: { 58: /* If even this fails we shouldn't try further. */ 59: close (fd); 60: fd = -1; 61: active = 0; 62: } 63: } 64: } 65: } 66: 67: 68: static void 69: __attribute__ ((destructor)) 70: uninstall (void) 71: { 72: if (active) 73: close (fd); 74: } 75: 76: 77: void 78: __cyg_profile_func_enter (void *this_fn, void *call_site) 79: { 80: void *buf[2]; 81: 82: if (! active) 83: return; 84: 85: /* Now write out the current position and that of the caller. We do 86: this now, and don't cache the because we want real-time output. */ 87: buf[0] = this_fn; 88: buf[1] = call_site; 89: 90: write (fd, buf, sizeof buf); 91: } 92: /* We don't handle entry and exit differently here. */ 93: strong_alias (__cyg_profile_func_enter, __cyg_profile_func_exit)