1 /* Copyright (C) 2021 Free Software Foundation, Inc. 2 Contributed by Oracle. 3 4 This file is part of GNU Binutils. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 This program 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 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, 51 Franklin Street - Fifth Floor, Boston, 19 MA 02110-1301, USA. */ 20 21 /* C and Fortran stubs for collector API */ 22 23 #include "config.h" 24 #include <dlfcn.h> 25 #include "gp-defs.h" 26 #include "collectorAPI.h" 27 #include "gp-experiment.h" 28 29 static void *__real_collector_sample = NULL; 30 static void *__real_collector_pause = NULL; 31 static void *__real_collector_resume = NULL; 32 static void *__real_collector_terminate_expt = NULL; 33 static void *__real_collector_func_load = NULL; 34 static void *__real_collector_func_unload = NULL; 35 36 #define INIT_API if (init_API == 0) collectorAPI_initAPI() 37 #define NULL_PTR(x) (__real_##x == NULL) 38 #define CALL_REAL(x) (*(void(*)())__real_##x) 39 #define CALL_IF_REAL(x) INIT_API; if (!NULL_PTR(x)) CALL_REAL(x) 40 41 static int init_API = 0; 42 43 void 44 collectorAPI_initAPI (void) 45 { 46 void *libcollector = dlopen (SP_LIBCOLLECTOR_NAME, RTLD_NOLOAD); 47 if (libcollector == NULL) 48 libcollector = RTLD_DEFAULT; 49 __real_collector_sample = dlsym (libcollector, "__collector_sample"); 50 __real_collector_pause = dlsym (libcollector, "__collector_pause"); 51 __real_collector_resume = dlsym (libcollector, "__collector_resume"); 52 __real_collector_terminate_expt = dlsym (libcollector, "__collector_terminate_expt"); 53 __real_collector_func_load = dlsym (libcollector, "__collector_func_load"); 54 __real_collector_func_unload = dlsym (libcollector, "__collector_func_unload"); 55 init_API = 1; 56 } 57 58 /* initialization -- init section routine */ 59 static void collectorAPI_init () __attribute__ ((constructor)); 60 61 static void 62 collectorAPI_init (void) 63 { 64 collectorAPI_initAPI (); 65 } 66 67 /* C API */ 68 void 69 collector_pause (void) 70 { 71 CALL_IF_REAL (collector_pause)(); 72 } 73 74 void 75 collector_resume (void) 76 { 77 CALL_IF_REAL (collector_resume)(); 78 } 79 80 void 81 collector_sample (const char *name) 82 { 83 CALL_IF_REAL (collector_sample)(name); 84 } 85 86 void 87 collector_terminate_expt (void) 88 { 89 CALL_IF_REAL (collector_terminate_expt)(); 90 } 91 92 void 93 collector_func_load (const char *name, const char *alias, const char *sourcename, 94 void *vaddr, int size, int lntsize, Lineno *lntable) 95 { 96 CALL_IF_REAL (collector_func_load)(name, alias, sourcename, 97 vaddr, size, lntsize, lntable); 98 } 99 100 void 101 collector_func_unload (void *vaddr) 102 { 103 CALL_IF_REAL (collector_func_unload)(vaddr); 104 } 105 106 /* Fortran API */ 107 void 108 collector_pause_ (void) 109 { 110 CALL_IF_REAL (collector_pause)(); 111 } 112 113 void 114 collector_resume_ (void) 115 { 116 CALL_IF_REAL (collector_resume)(); 117 } 118 119 void 120 collector_terminate_expt_ (void) 121 { 122 CALL_IF_REAL (collector_terminate_expt)(); 123 } 124 125 void 126 collector_sample_ (char *name, long name_length) 127 { 128 INIT_API; 129 if (!NULL_PTR (collector_sample)) 130 { 131 char name_string[256]; 132 long length = sizeof (name_string) - 1; 133 if (name_length < length) 134 length = name_length; 135 for (long i = 0; i < length; i++) 136 name_string[i] = name[i]; 137 name_string[length] = '\0'; 138 CALL_REAL (collector_sample)(name_string); 139 } 140 } 141