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 29static void *__real_collector_sample = NULL; 30static void *__real_collector_pause = NULL; 31static void *__real_collector_resume = NULL; 32static void *__real_collector_terminate_expt = NULL; 33static void *__real_collector_func_load = NULL; 34static 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 41static int init_API = 0; 42 43void 44collectorAPI_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 */ 59static void collectorAPI_init () __attribute__ ((constructor)); 60 61static void 62collectorAPI_init (void) 63{ 64 collectorAPI_initAPI (); 65} 66 67/* C API */ 68void 69collector_pause (void) 70{ 71 CALL_IF_REAL (collector_pause)(); 72} 73 74void 75collector_resume (void) 76{ 77 CALL_IF_REAL (collector_resume)(); 78} 79 80void 81collector_sample (const char *name) 82{ 83 CALL_IF_REAL (collector_sample)(name); 84} 85 86void 87collector_terminate_expt (void) 88{ 89 CALL_IF_REAL (collector_terminate_expt)(); 90} 91 92void 93collector_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 100void 101collector_func_unload (void *vaddr) 102{ 103 CALL_IF_REAL (collector_func_unload)(vaddr); 104} 105 106/* Fortran API */ 107void 108collector_pause_ (void) 109{ 110 CALL_IF_REAL (collector_pause)(); 111} 112 113void 114collector_resume_ (void) 115{ 116 CALL_IF_REAL (collector_resume)(); 117} 118 119void 120collector_terminate_expt_ (void) 121{ 122 CALL_IF_REAL (collector_terminate_expt)(); 123} 124 125void 126collector_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