various fixes made when working with older gcc 3.2.3
[dyninst.git] / common / src / Annotatable.C
1 /*
2  * Copyright (c) 1996-2004 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: Annotatable.C,v 1.12 2008/11/03 15:19:23 jaw Exp $
43
44 #include "common/h/headers.h"
45 #include "dynutil/h/dyntypes.h"
46 #include "dynutil/h/Annotatable.h"
47 std::vector<void *> annotation_classes;
48
49 AnnotatableSparse::annos_t AnnotatableSparse::annos;
50
51 namespace Dyninst {
52 bool void_ptr_cmp_func(void *v1, void *v2)
53 {
54    return v1 == v2;
55 }
56 };
57
58 std::vector<AnnotationClassBase *> AnnotationClassBase::annotation_types;
59 AnnotationClassBase::AnnotationClassBase(anno_cmp_func_t cmp_func_)
60 {
61    if (NULL == cmp_func_)
62       cmp_func = void_ptr_cmp_func;
63    else
64       cmp_func = cmp_func_;
65
66    annotation_types.push_back(this);
67    id = (AnnotationClassID) annotation_types.size();
68 }
69
70 #if 0
71 int Dyninst::AnnotationClass_nextId;
72 int newAnnotationClass(void *ptr)
73 {
74    annotation_classes.push_back(ptr);
75    assert(annotation_classes.size() == AnnotationClass_nextID);
76    return AnnotationClass_nextID++;
77 }
78 #endif
79
80 #if 0
81
82
83 #if defined (cap_serialization)
84 #include "common/h/serialize.h"
85 #endif
86
87 using namespace Dyninst;
88
89 int AnnotatableBase::number;
90 int AnnotatableBase::metadataNum;
91 dyn_hash_map<std::string, AnnotatableBase::anno_info_t> AnnotatableBase::annotationTypes;
92 dyn_hash_map<std::string, int> AnnotatableBase::metadataTypes;
93 dyn_hash_map<std::string, std::string> AnnotatableBase::annotypes_to_typenames;
94 std::string AnnotatableBase::emptyString = std::string("");
95
96 AnnotatableBase::AnnotatableBase() 
97 {
98    number = -1;
99 }
100
101 SerializerBase *getSDAnno(std::string &anno_name)
102 {
103    SerializerBase *ret =  AnnotatableBase::getAnnotationSerializer(anno_name);
104
105    if (!ret) 
106    {
107       fprintf(stderr, "%s[%d]:  getAnnotationSerializer (%s) failed\n", 
108             FILE__, __LINE__, anno_name.c_str());
109    }
110
111    return ret;
112 }
113
114 void dumpSDAnno()
115 {
116    AnnotatableBase::dumpAnnotationSerializers();
117 }
118
119
120 int AnnotatableBase::createAnnotationType(std::string &name, 
121       const char *tname, const char *serializer_name) 
122 {
123    std::string n(name);
124    int num = getAnnotationType(name, tname);
125
126    if (num != -1) 
127    {
128       //  also check to see if we have set the tname and serializer fields
129
130 #if defined (cap_serialization)
131       SerializerBase *sb = NULL;
132
133       if (serializer_name) 
134       {
135          sb = SerializerBin::findSerializerByName(serializer_name);
136          if (!sb) 
137          {
138             fprintf(stderr, "%s[%d]:  WARNING:  cannot find serializer for name %s\n", 
139                   FILE__, __LINE__, serializer_name);
140          }
141       }
142
143       if (sb) 
144       {
145          dyn_hash_map<std::string, anno_info_t>::iterator iter = annotationTypes.find(n); 
146
147          if (iter != annotationTypes.end()) 
148          {
149             AnnotatableBase::anno_info_t &anno_rec = iter->second;
150
151             if (!anno_rec.anno_serializer) 
152             {
153                fprintf(stderr, "%s[%d]:  assigning serializer for type %s to %p\n",
154                      FILE__, __LINE__, name.c_str(), sb);
155                anno_rec.anno_serializer = sb;
156                anno_rec.anno_serializer_name = serializer_name;
157                fprintf(stderr, "%s[%d]:  assigning serializer for type %s to %s\n",
158                      FILE__, __LINE__, name.c_str(), sb->name().c_str());
159             }
160
161             assert(num == anno_rec.anno_id);
162          }
163       }
164 #endif
165
166       return num;
167    }
168
169    number++;
170    AnnotatableBase::anno_info_t anno_rec;
171    anno_rec.anno_id = number;
172
173 #if defined (cap_serialization)
174    SerializerBase *sb = NULL;
175
176    if (serializer_name) 
177    {
178       sb = SerializerBin::findSerializerByName(serializer_name);
179
180       if (!sb) 
181       {
182          fprintf(stderr, "%s[%d]:  WARNING:  cannot find serializer for name %s\n", 
183                FILE__, __LINE__, serializer_name);
184       }
185    }
186
187    fprintf(stderr, "%s[%d]:  assigning serializer for type %s to %p\n", 
188          FILE__, __LINE__, name.c_str(), sb);
189
190    anno_rec.anno_serializer = sb;
191    anno_rec.anno_serializer_name = serializer_name;
192 #endif
193
194    annotationTypes[n] = anno_rec;
195
196 #if defined (cap_serialization)
197    assert(annotationTypes[n].anno_serializer == sb);
198 #endif
199    
200    if (!tname) 
201    {
202       //  This should be OK, so long as we init the typename later on when we
203       //  call getOrCreate...  if we get an annotation with an empty type string
204       //  we should just fill it in.
205
206       fprintf(stderr, "%s[%d]:  FIXME:  NULL typename here\n", FILE__, __LINE__);
207       annotypes_to_typenames[name] = emptyString;
208    }
209    else
210       annotypes_to_typenames[name] = std::string(tname);
211
212    return number;
213 }
214
215 std::string &AnnotatableBase::findTypeName(std::string tname)
216 {
217    dyn_hash_map<std::string, std::string>::iterator iter;
218    iter = annotypes_to_typenames.find(tname);
219
220    if (iter != annotypes_to_typenames.end()) 
221    {
222       return iter->second;
223    }
224
225    return emptyString;
226 }
227
228 int AnnotatableBase::getAnnotationType(std::string &name, const char *tname) 
229 {
230    std::string str(name);
231
232    if (annotationTypes.find(name) == annotationTypes.end()) 
233       return -1;
234
235    AnnotatableBase::anno_info_t anno_rec = annotationTypes[name];
236
237    if (tname) 
238    {
239       //  check if we have typename, if not, add it
240       dyn_hash_map<std::string, std::string>::iterator iter;
241       iter  = annotypes_to_typenames.find(std::string(tname));
242
243       
244       if (iter == annotypes_to_typenames.end()) 
245       {
246          // add this typename (it is possible to create an annotation type without a typename
247          //  and patch it up later)
248          annotypes_to_typenames[std::string(tname)] = name;
249       }
250       else 
251       {
252          if (iter->second == emptyString) 
253          {
254             iter->second = std::string(tname);
255          }
256       }
257    }
258
259    return anno_rec.anno_id;
260 }
261
262 int AnnotatableBase::getOrCreateAnnotationType(std::string &anno_name, const char *tname,
263       const char *serializer_name = NULL) 
264 {
265    int anno_type = AnnotatableBase::getAnnotationType(anno_name, tname);
266
267    if (anno_type == -1) 
268    {
269       //  for serializable annotation types, we need to explicitly create 
270       //  these during init time to provide the proper serializer object for
271       //  serializing the annotation later
272
273       anno_type = AnnotatableBase::createAnnotationType(anno_name, tname, serializer_name);
274
275       //  fprintf(stderr, "%s[%d]:  created annotation type %s/%d\n", 
276       //       FILE__, __LINE__, anno_name.c_str(), anno_type);
277    }
278
279    return anno_type;
280 }
281
282 #if !defined (cap_serialization)
283
284 SerializerBase * AnnotatableBase::getAnnotationSerializer(std::string &) 
285 {
286    fprintf(stderr, "%s[%d]:  WARNING:  asking for annotation serializer is not defined\n", 
287          FILE__, __LINE__);
288    return NULL;
289 }
290
291 #else
292
293 SerializerBase * AnnotatableBase::getAnnotationSerializer(std::string &name) 
294 {
295   std::string str(name);
296
297   if (annotationTypes.find(name) == annotationTypes.end()) {
298      fprintf(stderr, "%s[%d]:  No serializer for type %s\n", FILE__, __LINE__, name.c_str());
299      return NULL;
300   }
301
302   AnnotatableBase::anno_info_t anno_rec = annotationTypes[name];
303
304   if (!anno_rec.anno_serializer) 
305   {
306      if (NULL != anno_rec.anno_serializer_name)
307      {
308         //  try to look it up by name:
309         SerializerBin *sb = SerializerBin::findSerializerByName(anno_rec.anno_serializer_name);
310         
311         if (!sb)
312         {
313            fprintf(stderr, "%s[%d]:  WARNING:  no serializers for anno_serializer_name %s\n", 
314                  FILE__, __LINE__, anno_rec.anno_serializer_name);
315         }
316         else
317         {
318            anno_rec.anno_serializer = sb;
319         }
320      }
321   }
322
323   if (!anno_rec.anno_serializer) 
324   {
325      fprintf(stderr, "%s[%d]:  WARNING:  anno_serializer not initialized\n", FILE__, __LINE__);
326      dyn_hash_map<std::string, anno_info_t>::iterator iter;
327
328      fprintf(stderr, "%s[%d]:  have serializers for:\n", FILE__, __LINE__);
329
330      for (iter = annotationTypes.begin(); iter != annotationTypes.end(); iter++)
331      {
332         std::string an = iter->first;
333         anno_info_t &at = iter->second;
334         fprintf(stderr, "\t%s[%d]: %s--%p\n", an.c_str(), at.anno_id, 
335               at.anno_serializer_name ? at.anno_serializer_name : "no_name_provided", 
336               at.anno_serializer);
337      }
338   }
339
340   SerializerBase *ret = NULL;
341   ret = anno_rec.anno_serializer;
342
343   if (!ret) 
344   {
345      fprintf(stderr, "%s[%d]:  WARNING:  annotation serializer is NULL here?\n",
346            FILE__, __LINE__);
347      return ret;
348   }
349
350   fprintf(stderr, "%s[%d]:  annotation serializer for %s is %p\n", 
351         FILE__, __LINE__, name.c_str(), ret );
352   fprintf(stderr, "%s[%d]:  annotation serializer for %s is %s\n", 
353         FILE__, __LINE__, name.c_str(), ret->name().c_str() );
354   fprintf(stderr, "%s[%d]:  annotation serializer for %s is %p\n", 
355         FILE__, __LINE__, name.c_str(), ret );
356
357   return ret;
358 }
359 #endif
360
361 void AnnotatableBase::dumpAnnotationSerializers() 
362 {
363    fprintf(stderr, "%s[%d]:  dump of serializers for annotations\n", FILE__, __LINE__);
364
365 #if defined (cap_serialization)
366
367    dyn_hash_map<std::string, anno_info_t>::iterator iter;
368
369    for (iter = annotationTypes.begin(); iter != annotationTypes.end(); iter++) 
370    {
371       std::string name = iter->first;
372       anno_info_t anno_rec = iter->second;
373       fprintf(stderr, "\t%s -- id: %d -- serializer %s--%p\n", 
374             name.c_str(), anno_rec.anno_id, 
375             anno_rec.anno_serializer_name ? anno_rec.anno_serializer_name: "no-name-provided",
376             anno_rec.anno_serializer);
377    }
378
379 #else
380
381   fprintf(stderr, "%s[%d]:  WARNING:  asking for annotation serializer dump is not defined\n", 
382         FILE__, __LINE__);
383
384 #endif
385 }
386
387 //  this is just a helper function to get a reference to gtranslate out of the
388 //  header files
389 bool serialize_int_param(SerializerBase *sb, int &param, const char *tag)
390 {
391    if (!sb) 
392    {
393       fprintf(stderr, "%s[%d]: FIXME\n", FILE__, __LINE__);
394       return false;
395    }
396
397    try 
398    {
399       gtranslate(sb, param, tag);
400    }
401    catch (const SerializerError &err)
402    {
403       fprintf(stderr, "%s[%d]:  %sserialization error here\n", FILE__, __LINE__,
404             sb->iomode() == sd_serialize ? "" : "de");
405       printSerErr(err);
406       return false;
407    }
408
409    return true;
410
411 }
412
413 bool getAndExecuteSerFunc(AnnotatableBase *ab, SerializerBin *ser, int anno_id, 
414       std::string anno_name, unsigned /*nelem*/)
415 {
416    SerDesBin &sdbin = ser->getSD_bin(); 
417
418 #if 0
419    if (!sdbin)
420    {
421       fprintf(stderr, "%s[%d]: Bulk serialize annotations broken serializer\n",
422             FILE__, __LINE__);
423       return false;
424    }
425 #endif
426
427    AnnoFunc *afp = sdbin.findAnnoFunc(anno_id, anno_name);
428
429    if (NULL == afp)
430    {
431       fprintf(stderr, "%s[%d]:  failed to findAnnoFunc for id %d\n",
432             FILE__, __LINE__, anno_id);
433       return false;
434    }
435
436    AnnoFunc &af = *afp;
437
438 #if 0
439    fprintf(stderr, "%s[%d]:  executing func %d times\n", FILE__, __LINE__, nelem);
440    for (unsigned int i = 0; i < nelem; ++i) 
441    {
442       bool res = af(ser, ab);
443
444       if (false == res)
445       {
446          fprintf(stderr, "%s[%d]:  failed execute function: %d out of %d\n", 
447                FILE__, __LINE__, i, nelem);
448          return false;
449       }
450    }
451 #endif
452
453    bool res = af(ser, ab);
454
455    if (false == res)
456    {
457       fprintf(stderr, "%s[%d]:  failed execute function\n", 
458             FILE__, __LINE__);
459       return false;
460       }
461
462    return true;
463 }
464
465 #endif
466
467 bool dummy_bs()
468 {
469    fprintf(stderr, "%s[%d]:  \n", FILE__, __LINE__);
470    return true;
471 }