collectorAPI.c 3.6 KB

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