HPCToolkit
overrides.h
Go to the documentation of this file.
1 #ifndef OVERRIDES_H
2 #define OVERRIDES_H
3 
4 // Need macro-ized token-pasting and stringizing operations
5 
7 
8 //
9 // All overriden functions need a few pieces of syntactic functionality:
10 // 1) How to syntactically refer to the real function
11 // (??_FN)
12 // 2) How to declare the typedef of the real function
13 // (??_TYPEDEF)
14 // 3) How to declare the syntactic object for the real function
15 // (should use 1&2 as components)
16 // (??_DCL)
17 // 4) How to do the lazy initialization of the real function
18 // (Some functions need no initialization, others need some kind of lookup)
19 // (??_INIT)
20 //
21 // The exact syntax, however, may be different for each overridden function.
22 // In the typical case, the overriden functions fall into a few classes, rather than
23 // all functions having unique syntax for the components.
24 //
25 // NOTE: an additional wrinkle is that static and dynamic linking may require distinct
26 // syntax as well.
27 //
28 // The client code refers to the syntactic component via the "REAL" prefix
29 // Ex: REAL_FN(n) expands to the appropriate syntax for the real function,
30 // no matter what the override class of "n" is.
31 //
32 // The macro set below covers 2 different strategies/classes for overrides. The technique
33 // for selecting the appropriate strategy, however, is extensible. The covered classes
34 // are:
35 //
36 // 1) ALT : There is a canonically-named alternative function
37 // to duplicate the functionality of the overriden function.
38 //
39 // Example: "pthread_mutex_lock" has "__pthred_mutex_lock" as
40 // an alternate entry point
41 //
42 // 2) DL : The real function must be looked up (likely using a dlsym variant)
43 // in the dynamic case. (Static case behaves like ALT, but has a
44 // different canonical name).
45 //
46 // For a given class, there is a syntactic token name prefix (example: ALT and DL)
47 // The *specific* expansion for each of the functionalities above are embodied in
48 // a #define macro with the prefix.
49 // Ex: ALT_FN is syntax for an "ALT"-style real function name.
50 // DL_INIT is syntax for lazy initialization of a "DL"-style lazy initialization
51 //
52 // The client code defines special macros that specify the style of a given overridden
53 // function. Suppose "foo" and "bar" are the overridden functions; "foo" is ALT, and "bar"
54 // is "DL". Then the client code would put these macros in:
55 //
56 // #define foo_REAL ALT
57 // #define bar_REAL DL
58 //
59 //
60 // Below is an extremely simple client. The expansion can be see by invoking
61 // prompt>gcc -std=gnu99 -E -o example.E example.c
62 //
63 // #include <stdio.h>
64 // #include <string.h>
65 //
66 // #include "overrides.h"
67 //
68 // #define foo_REAL ALT
69 // #define bar_REAL DL
70 //
71 // REAL_TYPEDEF(int, foo)(int a, int b);
72 // REAL_TYPEDEF(int, bar)(int a, int b);
73 //
74 // REAL_DCL(foo);
75 // REAL_DCL(bar);
76 //
77 // int
78 // OVERRIDE_NM(foo)(int x, int y)
79 // {
80 // REAL_INIT(foo);
81 // REAL_INIT(bar);
82 //
83 // if (x == 5) {
84 // return REAL_FN(foo)(x, x+y);
85 // }
86 // return REAL_FN(bar)(y, x);
87 // }
88 
89 //
90 // The macro source code
91 //
92 #define ALT_FN(n) PPCAT(__, n)
93 #define ALT_DCL(n) extern REAL_TYPE(n) ALT_FN(n)
94 #define ALT_TYPEDEF(rt, n) typedef rt REAL_TYPE(n)
95 #define ALT_INIT(n)
96 
97 #ifdef HPCRUN_STATIC_LINK
98 #define DL_FN(n) PPCAT(__real_, n)
99 #define DL_DCL(n) extern REAL_TYPE(n) DL_FN(n)
100 #define DL_TYPEDEF(rt, n) typedef rt REAL_TYPE(n)
101 #define DL_INIT(n)
102 #define DLV_INIT(n)
103 #define OVERRIDE_NM(n) PPCAT(__wrap_, n)
104 #else
105 #define DL_FN(n) PPCAT(real_, n)
106 #define DL_DCL(n) static REAL_TYPE(n) DL_FN(n)
107 #define DL_TYPEDEF(rt, n) typedef rt (*REAL_TYPE(n))
108 #define DL_INIT(n) if (! DL_FN(n) ){DL_FN(n) = override_lookup(PPSTR(n));}
109 #define DLV_INIT(n) if (! DL_FN(n) ){DL_FN(n) = override_lookupv(PPSTR(n));}
110 #define OVERRIDE_NM(n) n
111 #endif // STATIC_LINK
112 
113 //
114 // DLV class is same as DL, except for dynamic case (lookup is different)
115 // (see #else case above)
116 //
117 
118 #define DLV_FN(n) DL_FN(n)
119 #define DLV_DCL(n) DL_DCL(n)
120 #define DLV_TYPEDEF(rt, n) DL_TYPEDEF(rt, n)
121 
122 #define REAL_TYPE(n) PPCAT(n, _t)
123 
124 #define REAL_FN(n) PPCAT(PPCAT(n, _REAL),_FN)(n)
125 #define REAL_TYPEDEF(rt, n) PPCAT(PPCAT(n, _REAL), _TYPEDEF)(rt, n)
126 #define REAL_DCL(n) PPCAT(PPCAT(n, _REAL), _DCL)(n)
127 #define REAL_INIT(n) PPCAT(PPCAT(n, _REAL), _INIT)(n)
128 
129 extern void* override_lookup(char* fname);
130 extern void* override_lookupv(char* fname);
131 
132 #endif // OVERRIDES_H
void * override_lookupv(char *fname)
void * override_lookup(char *fname)