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