export more serializer interface to allow for finer grain testing
[dyninst.git] / testsuite / src / symtab / test_symtab_ser_funcs.C
1 /*
2  * Copyright (c) 1996-2008 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 #include "symtab_comp.h"
43 #include "test_lib.h"
44
45 #include "Symtab.h"
46 #include "Symbol.h"
47 #include "Function.h"
48 #include "Variable.h"
49 #include "Module.h"
50 #include "Region.h"
51 #include "Type.h"
52 #include "Archive.h"
53 #include "Serialization.h"
54
55 using namespace Dyninst;
56 using namespace SymtabAPI;
57
58 bool debugPrint = false;
59 #ifndef dprintf
60 #define dprintf if (debugPrint) fprintf
61 #endif
62
63 class test_symtab_ser_funcs_Mutator : public SymtabMutator {
64         std::vector<relocationEntry> relocations;
65         std::vector<ExceptionBlock *> exceptions;
66         std::vector<Type *> *stdtypes;
67         std::vector<Type *> *builtintypes;
68         std::vector<Region *> regions;
69         std::vector<SymtabAPI::Module *> modules;
70         std::vector<SymtabAPI::Function *> functions;
71         std::vector<SymtabAPI::Variable *> variables;
72         std::vector<Symbol *> symbols;
73
74         typeEnum *type_enum;
75         typePointer *type_pointer;
76         typeTypedef *type_typedef;
77         typeStruct *type_struct;
78         typeUnion *type_union;
79         typeArray *type_array;
80         typeRef *type_ref;
81         typeCommon *type_common;
82         typeFunction *type_function;
83
84         void parse() THROW_SPEC (LocErr);
85
86         static void location_list_report(const std::vector<VariableLocation> *l1, 
87                         const std::vector<VariableLocation> *l2)
88         {
89                 if (l1 && !l2) fprintf(stderr, "%s[%d]:  loc list discrep\n", FILE__, __LINE__);
90                 if (!l1 && l2) fprintf(stderr, "%s[%d]:  loc list discrep\n", FILE__, __LINE__);
91                 if (l1)
92                 {
93                         int max_length = l1->size();
94
95                         if (l2->size() > max_length) 
96                                 max_length = l2->size();
97
98                         for (unsigned int i = 0; i < max_length; ++i)
99                         {
100                                 const VariableLocation *loc1 = (i < l1->size()) ? (& (*l1)[i]) : NULL;
101                                 const VariableLocation *loc2 = (i < l2->size()) ? (& (*l2)[i]) : NULL;
102
103                                 if (loc1)
104                                 {
105                                         fprintf(stderr, "\t\t[%d, %d, %d, %l, %lu, %lu]\n", 
106                                                         loc1->stClass, loc1->refClass, loc1->reg, loc1->frameOffset, 
107                                                         loc1->hiPC, loc1->lowPC);
108                                 }
109                                 else
110                                 {
111                                         fprintf(stderr, "\t\t[no location at this index]\n");
112                                 }
113
114                                 if (loc2)
115                                 {
116                                         fprintf(stderr, "\t  ==  [%d, %d, %d, %l, %lu, %lu]\n", 
117                                                         loc2->stClass, loc2->refClass, loc2->reg, loc2->frameOffset, 
118                                                         loc2->hiPC, loc2->lowPC);
119                                 }
120                                 else
121                                 {
122                                         fprintf(stderr, "\t  ==  [no location at this index]\n");
123                                 }
124                         }
125                 }
126         }
127
128         static void namelist_report(const std::vector<std::string> &v1, 
129                         const std::vector<std::string> &v2, const char *label)
130         {
131                 assert(label);
132
133                 fprintf(stderr, "%s[%d]:  namelist '%s':\n", FILE__, __LINE__, label);
134
135                 int maxlen = v1.size() > v2.size() ? v1.size() : v2.size();
136
137                 for (unsigned int i = 0; i < maxlen; ++i)
138                 {
139                         const std::string &s1 = (i < v1.size()) ? v1[i] : std::string("no_string");
140                         const std::string &s2 = (i < v2.size()) ? v2[i] : std::string("no_string");
141                         fprintf(stderr, "\t%s -- %s\n", s1.c_str(),  s2.c_str());
142                 }
143         }
144
145         static void aggregate_report(const Aggregate &a1, const Aggregate &a2)
146         {
147                 fprintf(stderr, "%s[%d]:  Aggregate:\n", FILE__, __LINE__);
148
149                 SymtabAPI::Module * m1 = a1.getModule();
150                 SymtabAPI::Module * m2 = a2.getModule();
151
152                 if (m1 && !m2)  fprintf(stderr, "%s[%d]:  module discrep\n", FILE__, __LINE__);
153                 if (!m1 && m2)  fprintf(stderr, "%s[%d]:  module discrep\n", FILE__, __LINE__);
154                 if (m1)
155                 {
156                         fprintf(stderr, "%s[%d]:  moduleName:  %s -- %s\n", FILE__, __LINE__, 
157                                         m1->fullName().c_str(), m2->fullName().c_str());
158                         fprintf(stderr, "%s[%d]:  moduleOffset:  %p -- %p\n", FILE__, __LINE__, 
159                                         m1->addr(), m2->addr());
160                 }
161
162                 const std::vector<std::string> & mn1 = const_cast<Aggregate &>(a1).getAllMangledNames();
163                 const std::vector<std::string> & mn2 = const_cast<Aggregate &>(a2).getAllMangledNames();
164                 const std::vector<std::string> & pn1 = const_cast<Aggregate &>(a1).getAllPrettyNames();
165                 const std::vector<std::string> & pn2 = const_cast<Aggregate &>(a2).getAllPrettyNames();
166                 const std::vector<std::string> & tn1 = const_cast<Aggregate &>(a1).getAllTypedNames();
167                 const std::vector<std::string> & tn2 = const_cast<Aggregate &>(a2).getAllTypedNames();
168
169                 namelist_report(mn1, mn2, "mangled");
170                 namelist_report(pn1, pn2, "pretty");
171                 namelist_report(tn1, tn2, "typed");
172
173                 std::vector<Symbol *> syms1;
174                 std::vector<Symbol *> syms2;
175
176                 bool r1 = a1.getSymbols(syms1);
177                 bool r2 = a2.getSymbols(syms1);
178
179                 if (r1 != r2) fprintf(stderr, "%s[%d]:  getSymbols discrep\n", FILE__, __LINE__);
180
181                 int maxsym = syms1.size() > syms2.size() ? syms1.size() : syms2.size();
182
183                 fprintf(stderr, "%s[%d]:  Symbol List:\n", FILE__, __LINE__);
184
185                 for (unsigned int i = 0; i < maxsym; ++i)
186                 {
187                         Symbol *s1 = (i < syms1.size()) ? syms1[i] : NULL;
188                         Symbol *s2 = (i < syms2.size()) ? syms2[i] : NULL;
189
190                         fprintf(stderr, "\t[%s-%p] -- [%s-%p]\n", 
191                                         s1 ? s1->getName().c_str() : "no_sym",
192                                         s1 ? s1->getOffset() : 0xdeadbeef,
193                                         s2 ? s2->getName().c_str() : "no_sym",
194                                         s2 ? s2->getOffset() : 0xdeadbeef);
195
196                 }
197         }
198
199         static void localvar_report(const localVar &lv1, const localVar &lv2)
200         {
201                 fprintf(stderr, "%s[%d]:  welcome to localVar report\n", FILE__, __LINE__);
202         }
203
204         static void relocation_report(const relocationEntry &r1, const relocationEntry &r2)
205         {
206                 fprintf(stderr, "%s[%d]:  Relcoation\n", FILE__, __LINE__);
207                 cerr << "     " << r1 << endl;
208                 cerr << "     " << r2 << endl;
209         }
210
211         static void type_report( const Type & ct1, const Type &ct2)
212         {
213                 Type &t1 = const_cast<Type &>(ct1);
214                 Type &t2 = const_cast<Type &>(ct2);
215                 fprintf(stderr, "%s[%d]:  Type report:\n", FILE__, __LINE__);
216                 fprintf(stderr, "\t id: %d -- %d\n", t1.getID(), t2.getID());
217                 fprintf(stderr, "\t size: %d -- %d\n", t1.getSize(), t2.getSize());
218                 fprintf(stderr, "\t name: %s -- %s\n", t1.getName().c_str(), t2.getName().c_str());
219                 fprintf(stderr, "\t dataclass: %d -- %d\n", (int)t1.getDataClass(), (int)t2.getDataClass());
220         }
221
222         static void derived_type_report( const derivedType & ct1, const derivedType &ct2)
223         {
224                 type_report(ct1, ct2);
225
226                 derivedType &t1 = const_cast<derivedType &>(ct1);
227                 derivedType &t2 = const_cast<derivedType &>(ct2);
228
229                 Type *st1 = t1.getConstituentType();
230                 Type *st2 = t2.getConstituentType();
231
232                 if (st1 && !st2)
233                 {
234                         fprintf(stderr, "%s[%d]:  inconsistent constituent types\n", FILE__, __LINE__);
235                         return;
236                 }
237
238                 if (!st1 && st2)
239                 {
240                         fprintf(stderr, "%s[%d]:  inconsistent constituent types\n", FILE__, __LINE__);
241                         return;
242                 }
243
244                 if (!st1) 
245                         return;
246
247                 fprintf(stderr, "%s[%d]:  derived from '%s' -- '%s'\n", FILE__, __LINE__, 
248                                 st1->getName().c_str(), st2->getName().c_str());
249         }
250
251         static void type_pointer_report( const typePointer & ct1, const typePointer &ct2)
252         {
253                 derived_type_report(ct1, ct2);
254         }
255
256         static void field_report(Field * f1, Field * &f2)
257         {
258                 //Field *f1 = const_cast<Field *>(ct1);
259                 //Field *f2 = const_cast<Field *>(ct2);
260                 if (f1)
261                 {
262                         Type *t = f1->getType();
263                         std::string tname = t ? t->getName() : std::string("no_type");
264                         fprintf(stderr, "[%s %s %u %d %s]", tname.c_str(), f1->getName().c_str(), 
265                                         f1->getOffset(), f1->getSize(), visibility2Str(f1->getVisibility()));
266                 }
267                 if (f2)
268                 {
269                         Type *t = f2->getType();
270                         std::string tname = t ? t->getName() : std::string("no_type");
271                         fprintf(stderr, "--[%s %s %u %d %s]", tname.c_str(), f2->getName().c_str(), 
272                                         f2->getOffset(), f2->getSize(), visibility2Str(f2->getVisibility()));
273                 }
274                 fprintf(stderr, "\n");
275         }
276
277         static void field_list_type_report( const fieldListType & ct1, const fieldListType &ct2)
278         {
279                 type_report(ct1, ct2);
280
281                 fieldListType &t1 = const_cast<fieldListType &>(ct1);
282                 fieldListType &t2 = const_cast<fieldListType &>(ct2);
283
284                 std::vector<Field *> *c1 = t1.getComponents();
285                 std::vector<Field *> *c2 = t2.getComponents();
286
287                 if (c1 && !c2)
288                 {
289                         fprintf(stderr, "%s[%d]: component discrep\n", FILE__, __LINE__);
290                 }
291
292                 if (!c1 && c2)
293                 {
294                         fprintf(stderr, "%s[%d]: component discrep\n", FILE__, __LINE__);
295                 }
296
297                 if (c1)
298                 {
299
300                         unsigned int m = (c1->size() > c2->size()) ? c1->size() : c2->size();
301
302                         fprintf(stderr, "%s[%d]:  components:\n", FILE__, __LINE__);
303
304                         for (unsigned int i = 0; i < m; ++i)
305                         {
306                                 Field *f1 = (c1->size() > i) ? (*c1)[i] : NULL;
307                                 Field *f2 = (c2->size() > i) ? (*c2)[i] : NULL;
308                                 field_report(f1, f2);
309                         }
310                 }
311
312                 std::vector<Field *> *ff1 = t1.getFields();
313                 std::vector<Field *> *ff2 = t2.getFields();
314
315                 if (ff1 && !ff2)
316                 {
317                         fprintf(stderr, "%s[%d]: field discrep\n", FILE__, __LINE__);
318                 }
319
320                 if (!ff1 && ff2)
321                 {
322                         fprintf(stderr, "%s[%d]: field discrep\n", FILE__, __LINE__);
323                 }
324
325                 if (ff1)
326                 {
327                         unsigned int m = (ff1->size() > ff2->size()) ? ff1->size() : ff2->size();
328
329                         fprintf(stderr, "%s[%d]:  fields:\n", FILE__, __LINE__);
330                         for (unsigned int i = 0; i < m; ++i)
331                         {
332                                 Field *f1 = (ff1->size() > i) ? (*ff1)[i] : NULL;
333                                 Field *f2 = (ff2->size() > i) ? (*ff2)[i] : NULL;
334                                 field_report(f1, f2);
335                         }
336                 }
337         }
338
339         static void type_struct_report( const typeStruct & ct1, const typeStruct &ct2)
340         {
341                 field_list_type_report(ct1, ct2);
342         }
343
344         static void type_union_report( const typeUnion & ct1, const typeUnion &ct2)
345         {
346                 field_list_type_report(ct1, ct2);
347         }
348
349         static void ranged_type_report( const rangedType & ct1, const rangedType &ct2)
350         {
351                 type_report(ct1, ct2);
352
353                 rangedType &t1 = const_cast<rangedType &>(ct1);
354                 rangedType &t2 = const_cast<rangedType &>(ct2);
355
356                 fprintf(stderr, "%s[%d]:  ranged (high):  %lu -- %lu\n", FILE__, __LINE__, 
357                                 t1.getHigh(), t2.getHigh());
358                 fprintf(stderr, "%s[%d]:  ranged (low):  %lu -- %lu\n", FILE__, __LINE__, 
359                                 t1.getLow(), t2.getLow());
360         }
361
362         static void type_array_report( const typeArray & ct1, const typeArray &ct2)
363         {
364                 ranged_type_report(ct1, ct2);
365                 typeArray &t1 = const_cast<typeArray &>(ct1);
366                 typeArray &t2 = const_cast<typeArray &>(ct2);
367                 Type *st1 = t1.getBaseType();
368                 Type *st2 = t2.getBaseType();
369                 std::string tname1 = st1 ? st1->getName() : std::string("no_base_type");
370                 std::string tname2 = st2 ? st2->getName() : std::string("no_base_type");
371                 fprintf(stderr, "%s[%d]:  array subtype: %s -- %s\n", FILE__, __LINE__, 
372                                 tname1.c_str(), tname2.c_str());
373         }
374
375         static void type_enum_report( const typeEnum & ct1, const typeEnum &ct2)
376         {
377                 type_report(ct1, ct2);
378
379                 typeEnum &t1 = const_cast<typeEnum &>(ct1);
380                 typeEnum &t2 = const_cast<typeEnum &>(ct2);
381
382                 std::vector<std::pair<std::string, int> > &consts1 = t1.getConstants();
383                 std::vector<std::pair<std::string, int> > &consts2 = t2.getConstants();
384                 int max_len = consts1.size() > consts2.size() ? consts1.size() : consts2.size();
385
386                 for (unsigned int i = 0; i < max_len; ++i)
387                 {
388                         if (i < consts1.size())
389                         {
390                                 std::pair<std::string, int>  &c = consts1[i];
391                                 fprintf(stderr, "\t const %d: %s=%d:", i, c.first.c_str(), c.second);
392                         }
393                         else
394                         {
395                                 fprintf(stderr, "\t const %d: no-entry:", i);
396                         }
397
398                         if (i < consts2.size())
399                         {
400                                 std::pair<std::string, int>  &c = consts2[i];
401                                 fprintf(stderr, "\t:%s=%d", c.first.c_str(), c.second);
402                         }
403                         else
404                         {
405                                 fprintf(stderr, "\t:no-entry", i);
406                         }
407                 }
408
409         }
410
411         static void region_report(const Region &r1, const Region &r2)
412         {
413                 fprintf(stderr, "%s[%d]:  NONEQUAL Regions\n", FILE__, __LINE__);
414                 fprintf(stderr, "\t name: %s -- %s\n", 
415                                 r1.getRegionName().c_str(), r2.getRegionName().c_str());
416                 fprintf(stderr, "\t number: %u -- %u\n", 
417                                 r1.getRegionNumber(), r2.getRegionNumber());
418                 fprintf(stderr, "\t type: %u -- %u\n", 
419                                 r1.getRegionType(), r2.getRegionType());
420                 fprintf(stderr, "\t perms: %u -- %u\n", 
421                                 r1.getRegionPermissions(), r2.getRegionPermissions());
422                 fprintf(stderr, "\t disk offset: %p -- %p\n", 
423                                 r1.getDiskOffset(), r2.getDiskOffset());
424                 fprintf(stderr, "\t disk size: %lu -- %lu\n", 
425                                 r1.getDiskSize(), r2.getDiskSize());
426                 fprintf(stderr, "\t mem offset: %p -- %p\n", 
427                                 r1.getMemOffset(), r2.getMemOffset());
428                 fprintf(stderr, "\t isText: %s -- %s\n", 
429                                 r1.isText() ? "true" : "false",
430                                 r2.isText() ? "true" : "false");
431                 fprintf(stderr, "\t isData: %s -- %s\n", 
432                                 r1.isData() ? "true" : "false",
433                                 r2.isData() ? "true" : "false");
434                 fprintf(stderr, "\t isBSS: %s -- %s\n", 
435                                 r1.isBSS() ? "true" : "false",
436                                 r2.isBSS() ? "true" : "false");
437                 fprintf(stderr, "\t isLoadable: %s -- %s\n", 
438                                 r1.isLoadable() ? "true" : "false",
439                                 r2.isLoadable() ? "true" : "false");
440                 fprintf(stderr, "\t isDirty: %s -- %s\n", 
441                                 r1.isDirty() ? "true" : "false",
442                                 r2.isDirty() ? "true" : "false");
443         }
444
445         static void function_report(const Function &f1, const Function &f2)
446         {
447                 fprintf(stderr, "%s[%d]:  NONEQUAL functions\n", FILE__, __LINE__);
448
449                 Type *t1 = f1.getReturnType();
450                 Type *t2 = f2.getReturnType();
451
452                 if (t1 && !t2) fprintf(stderr, "%s[%d]:  ret type discrep\n", FILE__, __LINE__);
453                 if (!t1 && t2) fprintf(stderr, "%s[%d]:  ret type discrep\n", FILE__, __LINE__);
454
455                 if (t1)
456                 {
457                         fprintf(stderr, "\t%d--%d\n", t1->getID(), t2->getID());
458                 }
459                 
460                 fprintf(stderr, "\t%d--%d\n", f1.getFramePtrRegnum(), f2.getFramePtrRegnum());
461
462                 std::vector<VariableLocation> &l1 = const_cast<Function &>(f1).getFramePtr();
463                 std::vector<VariableLocation> &l2 = const_cast<Function &>(f2).getFramePtr();
464
465                 location_list_report(&l1, &l2);
466
467                 const Aggregate &a1 = (const Aggregate &) f1;
468                 const Aggregate &a2 = (const Aggregate &) f2;
469                 aggregate_report(a1, a2);
470         }
471
472         static void module_report(const SymtabAPI::Module &m1, const SymtabAPI::Module &m2)
473         {
474                 fprintf(stderr, "%s[%d]:  welcome to module report\n", FILE__, __LINE__);
475         }
476
477         static void variable_report(const Variable &v1, const Variable &v2)
478         {
479                 fprintf(stderr, "%s[%d]:  NONEQUAL Variables\n", FILE__, __LINE__);
480
481                 Type *t1 = const_cast<Variable &>(v1).getType();
482                 Type *t2 = const_cast<Variable &>(v2).getType();
483                 if (t1 && !t2) fprintf(stderr, "%s[%d]:  type discrep\n", FILE__, __LINE__);
484                 if (!t1 && t2) fprintf(stderr, "%s[%d]:  type discrep\n", FILE__, __LINE__);
485                 if (t1)
486                 {
487                         fprintf(stderr, "\t%d--%d\n", t1->getID(), t2->getID());
488                 }
489
490                 const Aggregate &a1 = (const Aggregate &) v1;
491                 const Aggregate &a2 = (const Aggregate &) v2;
492                 aggregate_report(a1, a2);
493         }
494
495         static void symbol_report(const Symbol &s1, const Symbol &s2)
496         {
497                 fprintf(stderr, "%s[%d]:  NONEQUAL symbols:\n", FILE__, __LINE__);
498                 fprintf(stderr, "\t%s--%s\n", s1.getModuleName().c_str(), s2.getModuleName().c_str());
499                 fprintf(stderr, "\t%s--%s\n", s1.getMangledName().c_str(), s2.getMangledName().c_str());
500                 fprintf(stderr, "\t%s--%s\n", s1.getPrettyName().c_str(), s2.getPrettyName().c_str());
501                 fprintf(stderr, "\t%s--%s\n", s1.getTypedName().c_str(), s2.getTypedName().c_str());
502                 fprintf(stderr, "\t%d--%d\n", s1.getType(), s2.getType());
503                 fprintf(stderr, "\t%d--%d\n", s1.getLinkage(), s2.getLinkage());
504                 fprintf(stderr, "\t%d--%d\n", s1.getVisibility(), s2.getVisibility());
505                 fprintf(stderr, "\t%d--%d\n", s1.isInDynSymtab(), s2.isInDynSymtab());
506                 fprintf(stderr, "\t%d--%d\n", s1.isAbsolute(), s2.isAbsolute());
507                 fprintf(stderr, "\t%d--%d\n", s1.isFunction(), s2.isFunction());
508                 fprintf(stderr, "\t%d--%d\n", s1.isVariable(), s2.isVariable());
509                 fprintf(stderr, "\t%p--%p\n", s1.getAddr(), s2.getAddr());
510                 fprintf(stderr, "\t%d--%d\n", s1.getSize(), s2.getSize());
511                 fprintf(stderr, "\t%d--%d\n", s1.tag(), s2.tag());
512                 Region *r1 = s1.getSec();
513                 Region *r2 = s2.getSec();
514                 if (r1 && !r2) fprintf(stderr, "%s[%d]:  region discrep\n", FILE__, __LINE__);
515                 if (!r1 && r2) fprintf(stderr, "%s[%d]:  region discrep\n", FILE__, __LINE__);
516                 if (r1)
517                 {
518                         fprintf(stderr, "\t%p--%p\n", r1->getDiskOffset(), r2->getDiskOffset());
519                 }
520         }
521
522         typedef void (*symrep_t)(const Symbol &, const Symbol &);
523         typedef void (*varrep_t)(const Variable &, const Variable &);
524         typedef void (*funcrep_t)(const Function &, const Function &);
525         typedef void (*modrep_t)(const SymtabAPI::Module &, const SymtabAPI::Module &);
526         typedef void (*regrep_t)(const Region &, const Region &);
527         typedef void (*relrep_t)(const relocationEntry &, const relocationEntry &);
528         typedef void (*lvarrep_t)(const localVar &, const localVar &);
529
530         template <class C>
531         void serialize_test(Symtab *st, C &control, void (*report)(const C &, const C &) ) THROW_SPEC (LocErr)
532         {
533                 dprintf(stderr, "%s[%d]: welcome to serialize test for type %s\n",
534                                 FILE__, __LINE__, typeid(C).name());
535
536                 Tempfile tf;
537                 std::string file(tf.getName());
538
539                 SerializerBase* sb_serializer_ptr;
540 #if 1
541
542                 sb_serializer_ptr = nonpublic_make_bin_symtab_serializer(st, file);
543 #else
544                 SerializerBin<Symtab> *sb_serializer_ptr;
545                 sb_serializer_ptr = new SerializerBin<Symtab>(st, "SerializerBin2", file, sd_serialize, true);
546                 Symtab *test_st = sb_serializer_ptr->getScope();
547                 assert(test_st == st);
548
549                 sb_serializer_ptr = nonpublic_make_bin_serializer<Symtab>(st, file);
550 #endif
551                 assert(sb_serializer_ptr);
552
553 #if 0
554                 Dyninst::ScopedSerializerBase<Dyninst::SymtabAPI::Symtab> *ssb = dynamic_cast<Dyninst::ScopedSerializerBase<Dyninst::SymtabAPI::Symtab> *>(sb_serializer_ptr);
555                 if (!ssb)
556                         EFAIL("bad c++ inheritance hierarchy");
557                 fprintf(stderr, "%s[%d]:  ssb name = %s\n", FILE__, __LINE__, typeid(ssb).name());
558                 Dyninst::SerializerBase *sb_serializer2 =  (Dyninst::SerializerBase *) sb_serializer_ptr;
559 #endif
560
561                 Dyninst::SerializerBase &sb_serializer = * (Dyninst::SerializerBase *) sb_serializer_ptr;
562
563                 dprintf(stderr, "%s[%d]:  before serialize: &sb_serializer = %p\n", FILE__, __LINE__, &sb_serializer);
564
565                 Serializable *sable = &control;
566                 try 
567                 {
568                         sable->serialize(&sb_serializer);
569                 }
570                 catch (const SerializerError &serr)
571                 {
572                         fprintf(stderr, "%s[%d]:  serializer function threw exception:\n", FILE__, __LINE__);
573                         fprintf(stderr, "\tfrom %s[%d]: %s\n", serr.file().c_str(), serr.line(), serr.what());
574                         EFAIL("serialize failed\n");
575                 }
576
577                 dprintf(stderr, "%s[%d]:  after serialize\n", FILE__, __LINE__);
578                 fflush(NULL);
579
580 #if 1
581                 nonpublic_free_bin_symtab_serializer(sb_serializer_ptr);
582
583 #else
584                 SerializerBin<Symtab> *sbin = dynamic_cast<SerializerBin<Symtab> *>(sb_serializer_ptr);
585                 if (sbin)
586                 {
587                         delete(sbin);
588                 }
589                 else
590                         EFAIL("delete serializer");
591
592                 nonpublic_free_bin_serializer<Symtab>(sb_serializer_ptr);
593 #endif
594
595
596                 C deserialize_result;
597                 SerializerBase *sb_deserializer_ptr;
598 #if 1
599                 sb_deserializer_ptr = nonpublic_make_bin_symtab_deserializer(st, file);
600
601 #else
602                 SerializerBin<Symtab> *sb_deserializer_ptr;
603                 sb_deserializer_ptr = new SerializerBin<Symtab>(st, "DeserializerBin", file, sd_deserialize, true);
604                 test_st = sb_deserializer_ptr->getScope();
605                 assert(test_st == st);
606
607                 sb_deserializer_ptr = nonpublic_make_bin_deserializer<Symtab>(st, file);
608 #endif
609                 assert(sb_deserializer_ptr);
610 #if 0
611                 ssb = dynamic_cast<ScopedSerializerBase<Symtab> *>(sb_deserializer_ptr);
612                 if (!ssb)
613                         EFAIL("bad c++ inheritance hierarchy");
614 #endif
615                 SerializerBase &sb_deserializer = (SerializerBase &) *sb_deserializer_ptr;
616
617                 dprintf(stderr, "\n\n%s[%d]: about to deserialize: ---- %s\n\n",
618                                 FILE__, __LINE__, typeid(C).name());
619
620                 try
621                 {
622                         Serializable *des_result_ptr= &deserialize_result;
623                         des_result_ptr->serialize(sb_deserializer_ptr, NULL);
624                         //deserialize_result.serialize(sb_deserializer_ptr, NULL);
625                 }
626                 catch (const SerializerError &serr)
627                 {
628                         fprintf(stderr, "%s[%d]:  deserializer function threw exception:\n", FILE__, __LINE__);
629                         fprintf(stderr, "\tfrom %s[%d]: %s\n", serr.file().c_str(), serr.line(), serr.what());
630                         EFAIL("serialize failed\n");
631                 }
632
633 #if 1
634
635                 nonpublic_free_bin_symtab_serializer(sb_deserializer_ptr);
636 #else
637                 SerializerBin<Symtab> *dbin = dynamic_cast<SerializerBin<Symtab> *>(sb_deserializer_ptr);
638                 if (dbin)
639                 {
640                         delete(dbin);
641                 }
642                 else
643                         EFAIL("delete deserializer");
644
645                 nonpublic_free_bin_serializer<Symtab>(sb_deserializer_ptr);
646 #endif
647
648                 //  First check whether operator== (which must exist) returns equivalence
649
650                 if (!(deserialize_result == control))
651                 {
652                         if (report)
653                                 (*report)(deserialize_result, control);
654
655                         fprintf(stderr, "%s[%d]:  deserialize for %s failing\n", 
656                                         FILE__, __LINE__, typeid(C).name());
657                         EFAIL("deserialize failed\n");
658                 }
659
660 #if 0
661                 //  Next (since we can't trust operator==() 100%, do a raw mem compare
662
663                 if (memcmp(&control, &deserialize_result, sizeof(C)))
664                         EFAIL("deserialize and operator== failed\n");
665 #endif
666
667                 dprintf(stderr, "%s[%d]:  deserialize succeeded\n", __FILE__, __LINE__);
668         }
669
670         template <class T>
671                 void serialize_test_vector(Symtab *st, std::vector<T> &vec, 
672                                 void (*report)(const T &, const T &) )
673                 {
674                         for (unsigned int i = 0; i < vec.size(); ++i)
675                         {
676                                 T &t = vec[i];
677                                 serialize_test(st, t, report);
678                         }
679                 }
680
681         template <class T>
682                 void serialize_test_vector(Symtab *st, std::vector<T *> &vec, 
683                                 void (*report)(const T &, const T &) )
684                 {
685                         for (unsigned int i = 0; i < vec.size(); ++i)
686                         {
687                                 T *t = vec[i];
688                                 if (!t)
689                                         EFAIL("null array elem\n");
690                                 serialize_test(st, *t, report);
691                         }
692                 }
693
694         public:
695
696         test_symtab_ser_funcs_Mutator() { };
697         virtual test_results_t executeTest();
698 };
699
700 extern "C" DLLEXPORT TestMutator* test_symtab_ser_funcs_factory()
701 {
702         return new test_symtab_ser_funcs_Mutator();
703 }
704
705 void test_symtab_ser_funcs_Mutator::parse() THROW_SPEC (LocErr)
706 {
707         bool result = symtab->getFuncBindingTable(relocations);
708
709 #if !defined(os_aix_test) && !defined (os_windows_test)
710         if (!result || !relocations.size() )
711                 EFAIL("relocations");
712 #endif
713
714 #if 0
715         //  need to make this a c++ test to get exceptions
716         result = symtab->getAllExceptions(exceptions);
717
718         if (!result || !exceptions.size() )
719                 EFAIL("exceptions");
720 #endif
721
722         result = symtab->getAllRegions(regions);
723
724         if (!result || !regions.size() )
725                 EFAIL("regions");
726
727         result = symtab->getAllModules(modules);
728
729         if (!result || !modules.size() )
730                 EFAIL("modules");
731
732         result = symtab->getAllVariables(variables);
733
734         if (!result || !variables.size() )
735                 EFAIL("variables");
736
737         result = symtab->getAllFunctions(functions);
738
739         if (!result || !functions.size() )
740                 EFAIL("functions");
741
742         result = symtab->getAllDefinedSymbols(symbols);
743
744         if (!result || !symbols.size() )
745                 EFAIL("symbols");
746
747         stdtypes = symtab->getAllstdTypes();
748
749         if (!stdtypes)
750                 EFAIL("stdtypes");
751
752         builtintypes = symtab->getAllbuiltInTypes();
753
754         if (!builtintypes)
755         {
756                 EFAIL("builtintypes");
757         }
758
759         Type *t = NULL;
760
761         std::string tname = "sf_enum1";
762         if (!symtab->findType(t, tname) || (NULL == t))
763         {
764                 EFAIL(tname.c_str());
765         }
766
767         if (NULL == (type_enum = t->getEnumType()))
768         {
769                 EFAIL(tname.c_str());
770         }
771
772         tname = "sf_my_union";
773         if (!symtab->findType(t, tname) || (NULL == t))
774         {
775                 EFAIL(tname.c_str());
776         }
777
778         if (NULL == (type_union = t->getUnionType()))
779         {
780                 EFAIL(tname.c_str());
781         }
782
783         tname = "sf_mystruct";
784         if (!symtab->findType(t, tname) || (NULL == t))
785         {
786                 EFAIL(tname.c_str());
787         }
788
789         if (NULL == (type_struct = t->getStructType()))
790         {
791                 EFAIL(tname.c_str());
792         }
793         
794         tname = "sf_int_alias_t";
795         if (!symtab->findType(t, tname) || (NULL == t))
796         {
797                 EFAIL(tname.c_str());
798         }
799
800         if (NULL == (type_typedef = t->getTypedefType()))
801         {
802                 EFAIL(tname.c_str());
803         }
804
805         typeTypedef *tt  = NULL;
806
807         tname = "sf_int_array_t";
808         if (!symtab->findType(t, tname) || (NULL == t))
809         {
810                 EFAIL(tname.c_str());
811         }
812
813         if (NULL == (tt = t->getTypedefType()))
814         {
815                 EFAIL(tname.c_str());
816         }
817
818         if (NULL == (t = tt->getConstituentType()))
819         {
820                 EFAIL(tname.c_str());
821         }
822
823         if (NULL == (type_array = t->getArrayType()))
824         {
825                 EFAIL(tname.c_str());
826         }
827
828         tname = "sf_my_intptr_t";
829         if (!symtab->findType(t, tname) || (NULL == t))
830         {
831                 EFAIL(tname.c_str());
832         }
833
834         if (NULL == (tt = t->getTypedefType()))
835         {
836                 EFAIL(tname.c_str());
837         }
838
839         if (NULL == (t = tt->getConstituentType()))
840         {
841                 EFAIL(tname.c_str());
842         }
843
844         if (NULL == (type_pointer = t->getPointerType()))
845         {
846                 EFAIL(tname.c_str());
847         }
848
849         //  don't handle c++ or fortran yet...
850         type_ref = NULL;
851         type_common = NULL;
852         type_function = NULL;
853 }
854
855 test_results_t test_symtab_ser_funcs_Mutator::executeTest()
856 {
857
858         try 
859         {
860                 parse();
861
862                 serialize_test(symtab, *variables[0], &variable_report);
863                 serialize_test(symtab, *functions[0], &function_report);
864                 serialize_test(symtab, *symbols[0], &symbol_report);
865                 serialize_test(symtab, *modules[0], &module_report);
866 #if !defined (os_aix_test) && !defined (os_windows)
867                 serialize_test(symtab, relocations[0], &relocation_report);
868 #endif
869                 serialize_test(symtab, *regions[0], &region_report);
870                 serialize_test(symtab, *type_enum, &type_enum_report);
871                 serialize_test(symtab, *type_pointer, &type_pointer_report);
872                 serialize_test(symtab, *type_struct, &type_struct_report);
873                 serialize_test(symtab, *type_union, &type_union_report);
874                 serialize_test(symtab, *type_array, &type_array_report);
875                 //  type_subrange??
876                 //  type_scalar??
877                 //  type_common_block??
878 #if 0
879         typeEnum *type_enum;
880         typePointer *type_pointer;
881         typeTypedef *type_typedef;
882         typeStruct *type_struct;
883         typeUnion *type_union;
884         typeArray *type_array;
885 #endif
886
887 #if 0
888                 serialize_test_vector(symtab, symbols);
889                 serialize_test_vector(symtab, functions);
890                 serialize_test_vector(symtab, variables);
891                 serialize_test_vector(symtab, exceptions);
892 #if !defined (os_aix_test)
893                 serialize_test_vector(symtab, relocations);
894 #endif
895                 serialize_test_vector(symtab, regions);
896                 serialize_test_vector(symtab, modules);
897
898                 serialize_test(symtab, *symtab);
899 #endif
900         }
901         REPORT_EFAIL;
902
903         return PASSED;
904 }