Update copyright to LGPL on all files
[dyninst.git] / common / src / serialize-bin.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 <stdio.h>
33 #include <vector>
34
35 #include "dynutil/h/dyntypes.h"
36 #include "dynutil/h/Annotatable.h"
37 #include "common/h/serialize.h"
38 #include "common/h/Types.h"
39 #include "common/h/headers.h"
40
41 using namespace Dyninst;
42
43 //COMMON_EXPORT dyn_hash_map<Address, AnnotatableBase *> SerDesBin::annotatable_id_map;
44
45
46 COMMON_EXPORT dyn_hash_map<std::string, SerializerBase::subsystem_serializers_t> SerializerBase::all_serializers;
47
48
49 dyn_hash_map<void *, AnnotationContainerBase *> AnnotationContainerBase::containers_by_id;
50 void AnnotationContainerBase::clearContainersByID()
51 {
52         containers_by_id.clear();
53 }
54 void Serializable::clearContainersByID()
55 {
56         AnnotationContainerBase::clearContainersByID();
57 }
58
59 namespace Dyninst 
60 {
61 bool dyn_debug_serializer = false;
62 bool &serializer_debug_flag()
63 {
64    //  This function exists to get around problems with exporting the variable
65    //  across library boundaries on windows...   there's probably a better way to do this...
66    return dyn_debug_serializer;
67 }
68
69 Serializable * ser_func_wrapper(void *it, SerializerBase *sb, 
70                 const char *tag)
71 {   
72         assert(it);
73         assert(sb);
74         Serializable *s = (Serializable *) (it);
75         return s->serialize(sb, tag);
76 }   
77
78
79 void serialize_debug_init()
80 {
81    char *p;
82    if ( (p=getenv("DYNINST_DEBUG_SERIALIZER"))) {
83       fprintf(stderr, "Enabling DyninstAPI serializer debug\n");
84       dyn_debug_serializer = true;
85    }
86 }
87
88
89 int serializer_printf(const char *format, ...) 
90 {   
91    if (!dyn_debug_serializer) return 0;
92    if (NULL == format) return -1;
93
94    //debugPrintLock->_Lock(FILE__, __LINE__);
95
96    //  probably want to have basic thread-id routines in libcommon...
97    //  uh...  later....
98
99    //fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
100    va_list va;
101    va_start(va, format);
102    int ret = vfprintf(stderr, format, va);
103    va_end(va);
104
105    //debugPrintLock->_Unlock(FILE__, __LINE__);
106
107    return ret;
108
109
110 #ifndef CASE_RETURN_STR 
111 #define CASE_RETURN_STR(x) case x: return #x;
112 #endif
113 const char *serPostOp2Str(ser_post_op_t s)
114 {
115         switch (s)
116         {
117                 CASE_RETURN_STR(sp_add_anno);
118                 CASE_RETURN_STR(sp_rem_anno);
119                 CASE_RETURN_STR(sp_add_cont_item);
120                 CASE_RETURN_STR(sp_rem_cont_item);
121         }
122         return "bad_op";
123 }
124
125 std::vector<std::pair<std::string, dyn_hash_map<std::string, short>*> >  SerContextBase::ser_control_map;
126 dyn_hash_map<std::string, short> *SerContextBase::getMapForType(std::string tname)
127 {
128         for (unsigned int i = 0; i < ser_control_map.size(); ++i)
129         {
130                 if (std::string(tname) == ser_control_map[i].first)
131                         return ser_control_map[i].second;
132         }
133         return NULL;
134 }
135
136 SerContextBase::SerContextBase(std::string tname, std::string fname_) :
137         fname(fname_)
138 {
139         dyn_hash_map<std::string, short> *map_p = getMapForType(tname);
140         if (!map_p)
141         {
142                 map_p = new dyn_hash_map<std::string, short>();
143                 ser_control_map.push_back(std::make_pair(std::string(tname), map_p));
144                 (*map_p)[fname] = 0;
145         }
146         //  If we already have a serialize control specification for this file
147         //  do not reset it here.  This allows us to specify serializer behavior
148         //  in the testsuite apriori.
149 }
150
151 void SerContextBase::enableSerialize(std::string tname, std::string filename, bool val)
152 {
153         dyn_hash_map<std::string, short> *map_p = getMapForType(tname);
154         if (!map_p)
155         {
156                 //  This case should not be able to happen, but, anyways....
157                 map_p = new dyn_hash_map<std::string, short>();
158                 ser_control_map.push_back(std::make_pair(tname, map_p));
159         }
160
161         dyn_hash_map<std::string, short>::iterator iter = map_p->find(filename);
162         if (iter == map_p->end())
163         {
164                 if (val)
165                         (*map_p)[filename] = SERIALIZE_ENABLE_FLAG;
166                 else
167                         (*map_p)[filename] = 0;
168         }
169         else
170         {
171                 short &flags = iter->second;
172                 if (val)
173                         flags |= SERIALIZE_ENABLE_FLAG;
174                 else
175                         flags &= ~SERIALIZE_ENABLE_FLAG;
176         }
177 }
178
179 void SerContextBase::enableSerialize(bool val)
180 {
181         SerContextBase::enableDeserialize(std::string(getRootTypename()), fname, val);
182 }
183
184 void SerContextBase::enableDeserialize(std::string tname, std::string filename, bool val)
185 {
186         dyn_hash_map<std::string, short> *map_p = getMapForType(tname);
187         if (!map_p)
188         {
189                 //  This case should not be able to happen, but, anyways....
190                 map_p = new dyn_hash_map<std::string, short>();
191                 ser_control_map.push_back(std::make_pair(tname, map_p));
192         }
193
194         dyn_hash_map<std::string, short>::iterator iter = map_p->find(filename);
195         if (iter == map_p->end())
196         {
197                 if (val)
198                         (*map_p)[filename] = DESERIALIZE_ENABLE_FLAG;
199                 else
200                         (*map_p)[filename] = 0;
201         }
202         else
203         {
204                 short &flags = iter->second;
205                 if (val)
206                         flags |= DESERIALIZE_ENABLE_FLAG;
207                 else
208                         flags &= ~DESERIALIZE_ENABLE_FLAG;
209         }
210 }
211
212 void SerContextBase::enableDeserialize(bool val)
213 {
214         SerContextBase::enableDeserialize(std::string(getRootTypename()), fname, val);
215 }
216
217 void SerContextBase::enforceDeserialize(std::string tname, std::string filename, bool val)
218 {
219         dyn_hash_map<std::string, short> *map_p = getMapForType(tname);
220         if (!map_p)
221         {
222                 //  This case should not be able to happen, but, anyways....
223                 map_p = new dyn_hash_map<std::string, short>();
224                 ser_control_map.push_back(std::make_pair(tname, map_p));
225         }
226
227         dyn_hash_map<std::string, short>::iterator iter = map_p->find(filename);
228         if (iter == map_p->end())
229         {
230                 if (val)
231                         (*map_p)[filename] = DESERIALIZE_ENFORCE_FLAG;
232                 else
233                         (*map_p)[filename] = 0;
234         }
235         else
236         {
237                 short &flags = iter->second;
238                 if (val)
239                         flags |= DESERIALIZE_ENFORCE_FLAG;
240                 else
241                         flags &= ~DESERIALIZE_ENFORCE_FLAG;
242         }
243 }
244
245 void SerContextBase::enforceDeserialize(bool val)
246 {
247         SerContextBase::enforceDeserialize(std::string(getRootTypename()), fname, val);
248 }
249
250 void SerContextBase::enableSerDes(std::string tname, std::string filename, bool val)
251 {
252         dyn_hash_map<std::string, short> *map_p = getMapForType(tname);
253         if (!map_p)
254         {
255                 //  This case should not be able to happen, but, anyways....
256                 map_p = new dyn_hash_map<std::string, short>();
257                 ser_control_map.push_back(std::make_pair(tname, map_p));
258         }
259
260         dyn_hash_map<std::string, short>::iterator iter = map_p->find(filename);
261         if (iter == map_p->end())
262         {
263                 if (val)
264                         (*map_p)[filename] = DESERIALIZE_ENABLE_FLAG | SERIALIZE_ENABLE_FLAG;
265                 else
266                         (*map_p)[filename] = 0;
267         }
268         else
269         {
270                 short &flags = iter->second;
271                 if (val)
272                 {
273                         flags |= SERIALIZE_ENABLE_FLAG;
274                         flags |= DESERIALIZE_ENABLE_FLAG;
275                 }
276                 else
277                         flags = 0;
278         }
279 }
280
281 void SerContextBase::enableSerDes(bool val)
282 {
283         SerContextBase::enableSerDes(std::string(getRootTypename()), fname, val);
284 }
285
286 bool SerContextBase::serializeEnabled()
287 {
288         dyn_hash_map<std::string, short> *map_p = getMapForType(std::string(getRootTypename()));
289         if (!map_p)
290         {
291                 //  This case should not be able to happen, but, anyways....
292                 return false;
293         }
294
295         dyn_hash_map<std::string, short>::iterator iter = map_p->find(fname);
296         if (iter == map_p->end())
297         {
298                 //  This case should not be able to happen, but, anyways....
299                 return false;
300         }
301
302         short &flags = iter->second;
303         return (0 != (flags & SERIALIZE_ENABLE_FLAG));
304 }
305
306 bool SerContextBase::deserializeEnabled()
307 {
308         dyn_hash_map<std::string, short> *map_p = getMapForType(std::string(getRootTypename()));
309         if (!map_p)
310         {
311                 //  This case should not be able to happen, but, anyways....
312                 return false;
313         }
314
315         dyn_hash_map<std::string, short>::iterator iter = map_p->find(fname);
316         if (iter == map_p->end())
317         {
318                 //  This case should not be able to happen, but, anyways....
319                 return false;
320         }
321
322         short &flags = iter->second;
323         return (0 != (flags & DESERIALIZE_ENABLE_FLAG));
324 }
325
326 bool SerContextBase::deserializeEnforced(std::string tname, std::string filename)
327 {
328         dyn_hash_map<std::string, short> *map_p = getMapForType(tname);
329         if (!map_p)
330         {
331                 //  This case should not be able to happen, but, anyways....
332                 return false;
333         }
334
335         dyn_hash_map<std::string, short>::iterator iter = map_p->find(filename);
336         if (iter == map_p->end())
337         {
338                 //  This case should not be able to happen, but, anyways....
339                 return false;
340         }
341
342         short &flags = iter->second;
343         return (0 != (flags & DESERIALIZE_ENFORCE_FLAG));
344 }
345
346 bool SerContextBase::deserializeEnforced()
347 {
348         return SerContextBase::deserializeEnforced(std::string(getRootTypename()), fname);
349 }
350
351 std::string SerContextBase::getSerFileName()
352 {
353         return serfilename;
354 }
355
356 SerializerBase *createSerializer(SerContextBase *scs, 
357                 std::string ser_name, std::string file, ser_type_t ser_type, 
358                 iomode_t mode, bool verbose)
359
360 {
361         if (!scs->serializeEnabled() && (mode == sd_serialize))
362         {
363                 serialize_printf("%s[%d]:  serialization not enabled\n", FILE__, __LINE__);
364                 return NULL;
365         }
366
367         if (!scs->deserializeEnabled() && (mode == sd_deserialize))
368         {
369                 serialize_printf("%s[%d]:  deserialization not enabled\n", FILE__, __LINE__);
370                 return NULL;
371         }
372
373         SerializerBase *ret = NULL;
374         try {
375                 if (!scs)
376                 {
377                         fprintf(stderr, "%s[%d]:  ERROR context object not given for serialiezr\n", 
378                                         FILE__, __LINE__);
379                         return NULL;
380                 }
381
382                 if (ser_type == ser_bin)
383                 {
384                         serialize_printf("%s[%d]:  creating bin serializer %s/%s, %p\n", 
385                                         FILE__, __LINE__, ser_name.c_str(), file.c_str(), scs);
386                         ret = new SerializerBin(scs, ser_name, file, mode, verbose);
387                 }
388                 else if (ser_type == ser_xml)
389                 {
390                         ret = new SerializerXML(scs, ser_name, file, mode, verbose);
391                 }
392                 else
393                 {
394                         serialize_printf("%s[%d]:  bad serializer type provided\n", 
395                                         FILE__, __LINE__);
396                         return NULL;
397                 }
398         }
399         catch(const SerializerError &err) 
400         {
401                 fprintf(stderr, "%s[%d]:  %sserialize failed init...  \n\t%s[%d]: %s\n",
402                                 FILE__, __LINE__, mode == sd_serialize ? "" : "de", 
403                                 err.file().c_str(), err.line(), err.what());
404                 return NULL;
405         }
406         return ret;
407 }
408
409 SerDes *SerFile::getSD()
410 {
411         return sd;
412 }
413
414 SerFile::SerFile(std::string fname, iomode_t mode, bool verbose) :
415         writer (NULL), 
416         f(NULL), 
417         iomode_(mode), 
418         noisy(verbose) 
419 {
420         char file_path[PATH_MAX];
421
422         if (!resolve_file_path(fname.c_str(), file_path)) 
423         {
424                 char msg[128];
425                 sprintf(msg, "failed to resolve path for '%s'\n", fname.c_str());
426                 SER_ERR(msg);
427         }
428
429         filename = std::string(file_path);
430         serialize_debug_init();
431
432         if (strstr(filename.c_str(), "xml")) 
433         {
434                 fprintf(stderr, "%s[%d]:  opening xml file %s for %s\n", FILE__, __LINE__, 
435                                 filename.c_str(), mode == sd_serialize ? "output" : "input");
436
437                 if (mode == sd_deserialize) 
438                 {
439                         fprintf(stderr, "%s[%d]:  ERROR:  deserializing xml not supported\n", 
440                                         FILE__, __LINE__);
441                         assert(0);
442                 }
443
444 #if defined (cap_have_libxml)
445                 writer = SerDesXML::init(fname, mode, verbose);
446
447                 if (!writer) 
448                 {
449                         fprintf(stderr, "%s[%d]:  ERROR:  failed to init xml writer\n", 
450                                         FILE__, __LINE__);
451                         assert(0);
452                 }
453 #else
454
455                 writer = NULL;
456 #endif
457
458                 sd = new SerDesXML(writer, mode);
459
460         }
461         else 
462         {
463                 serialize_printf("%s[%d]:  opening %s file for %s\n", FILE__, __LINE__, 
464                                 filename.c_str(), mode == sd_serialize ? "output" : "input");
465
466                 f = SerDesBin::init(std::string(fname), mode, verbose);
467
468                 if (!f) 
469                 {
470                         fprintf(stderr, "%s[%d]:  failed to init file i/o\n", FILE__, __LINE__);
471                         assert(0);
472                 }
473
474                 sd = new SerDesBin(f,mode, verbose);
475         }
476 }
477
478 iomode_t SerFile::iomode()
479 {
480         return iomode_;
481 }
482
483 std::string SerFile::getCacheFileName()
484 {
485         std::string cache_name;
486         SerDes *sd = getSD();
487         if (!sd) return std::string();
488         SerDesBin *sdb = dynamic_cast<SerDesBin *>(sd);
489         if (!sdb) return std::string();
490         sdb->resolveCachePath(filename, cache_name); 
491         return cache_name;
492 }
493
494 bool Serializable::serialize(std::string file, SerContextBase *scb, ser_type_t mode)
495 {
496         std::string sername = file;
497         SerializerBase *serializer = createSerializer(scb, sername, file, mode, sd_serialize, false);
498
499         if (!serializer)
500         {
501                 serialize_printf("%s[%d]:  failed to create serializer\n", FILE__, __LINE__);
502                 return false;
503         }
504
505         try 
506         {
507                 //  Do the serialization
508                 serialize(serializer, NULL);
509                 void *barrier_magic = (void *)0xdeadbeef;
510                 serialize_annotatable_id(serializer, barrier_magic, NULL);
511                 if (barrier_magic != (void *)0xdeadbeef)
512                 {
513                         fprintf(stderr, "%s[%d]:  FIXME:  failed to read magic barrier val\n", 
514                                         FILE__, __LINE__);
515                 }
516
517         }
518         catch (const SerializerError &err_)
519         {
520                 fprintf(stderr, "%s[%d]:  serialize failed\n", FILE__, __LINE__);
521                 printSerErr(err_);
522                 return false;
523         }
524
525         return true;
526
527 }
528
529 AnnotatableSparse *find_sparse_annotatable(SerializerBase *serializer, void *id)
530 {
531         assert(serializer);
532         return serializer->findSparseAnnotatable(id);
533 }
534
535 AnnotatableDense *find_dense_annotatable(SerializerBase *serializer,void *id)
536 {
537         assert(serializer);
538         return serializer->findDenseAnnotatable(id);
539 }
540
541 bool isEOF(SerializerBase *sb)
542 {
543         if (!sb)
544         {
545                 fprintf(stderr, "%s[%d]:  FIXME\n", FILE__, __LINE__);
546                 return false;
547         }
548         return sb->isEOF();
549 }
550
551 bool SerializerBase::isEOF()
552 {
553         return sd->isEOF();
554 }
555
556 void SerializerBase::clearAnnotationMaps()
557 {
558         if (sparse_annotatable_map) 
559         {
560                 sparse_annotatable_map->clear();
561                 //delete sparse_annotatable_map;
562                 //sparse_annotatable_map = NULL;
563         }
564         if (dense_annotatable_map) 
565         {
566                 dense_annotatable_map->clear();
567                 //delete dense_annotatable_map;
568                 //dense_annotatable_map = NULL;
569         }
570 }
571
572 AnnotatableSparse *SerializerBase::findSparseAnnotatable(void *id)
573 {
574         dyn_hash_map<void *, AnnotatableSparse *>::iterator iter;
575         iter = sparse_annotatable_map->find(id);
576         if (iter == sparse_annotatable_map->end())
577         {
578                 serialize_printf("%s[%d]:  ERROR:  cannot find parent to assign annotation to\n",
579                                 __FILE__, __LINE__);
580                 return NULL;
581         }
582         return iter->second;
583 }
584
585 AnnotatableDense *SerializerBase::findDenseAnnotatable(void *id)
586 {
587         dyn_hash_map<void *, AnnotatableDense *>::iterator iter;
588         iter = dense_annotatable_map->find(id);
589         if (iter == dense_annotatable_map->end())
590         {
591                 serialize_printf("%s[%d]:  ERROR:  cannot find parent to assign annotation to\n",
592                                 __FILE__, __LINE__);
593                 return NULL;
594         }
595         return iter->second;
596 }
597
598 void printSerErr(const SerializerError &err) 
599 {
600         fprintf(stderr, "\tserializer exception %s from \n\t%s[%d]\n", 
601                         err.what(), err.file().c_str(), err.line());
602 }
603
604
605 bool isOutput(SerializerBase *ser)
606 {
607         return (ser->iomode() == sd_serialize);
608 }
609
610 bool isBinary(SerializerBase *ser)
611 {
612         return ser->isBin();
613 }
614
615 #if 0
616 void trans_adapt(SerializerBase *ser, Serializable &it, const char *tag)
617 {
618         it.serialize(ser, tag);
619 }
620
621 void trans_adapt(SerializerBase *ser, Serializable  *itp, const char *tag)
622 {
623    assert(itp);
624    trans_adapt(ser, *itp, tag);
625 }
626
627 void trans_adapt(SerializerBase *ser, bool &it, const char *tag)
628 {
629    assert(ser);
630    ser->translate_base(it, tag);
631 }
632
633 void trans_adapt(SerializerBase *ser, int &it, const char *tag)
634 {
635    assert(ser);
636    ser->translate_base(it, tag);
637 }
638
639 void trans_adapt(SerializerBase *ser, unsigned int &it, const char *tag)
640 {
641    assert(ser);
642    ser->translate_base(it, tag);
643 }
644
645 void trans_adapt(SerializerBase *ser, long &it, const char *tag)
646 {
647    assert(ser);
648    ser->translate_base(it, tag);
649 }
650
651 void trans_adapt(SerializerBase *ser, unsigned long &it, const char *tag)
652 {
653    assert(ser);
654    ser->translate_base(it, tag);
655 }
656
657 void trans_adapt(SerializerBase *ser, char &it, const char *tag)
658 {
659    assert(ser);
660    ser->translate_base(it, tag);
661 }
662
663 void trans_adapt(SerializerBase *ser, char *&it, const char *tag)
664 {
665    assert(ser);
666    assert(it);
667    int s_len = strlen(it);
668    ser->translate_base(const_cast<const char *&>(it), s_len, tag);
669 }
670
671 void trans_adapt(SerializerBase *ser, std::string &it, const char *tag)
672 {
673    assert(ser);
674    ser->translate_base(it, tag);
675 }
676
677 void trans_adapt(SerializerBase *ser, float &it, const char *tag)
678 {
679    assert(ser);
680    ser->translate_base(it, tag);
681 }
682
683 void trans_adapt(SerializerBase *ser, double  &it, const char *tag)
684 {
685    assert(ser);
686    ser->translate_base(it, tag);
687 }
688 #endif
689
690 bool sb_is_input(SerializerBase *sb) 
691 {
692    return  (sb->iomode() == sd_deserialize);
693 }
694
695 bool sb_is_output(SerializerBase *sb) 
696 {
697    return  (sb->iomode() == sd_serialize);
698 }
699
700
701 SerializerBase *getExistingOutputSB(Serializable *s)
702 {
703         return s->lookupExistingSerializer();
704 }
705
706 SerializerBase *getExistingOutputSB(unsigned short ndx)
707 {
708         if (SerializerBase::active_serializers.size() <= ndx)
709                 return NULL;
710         return SerializerBase::active_serializers[ndx];
711 }
712
713 } /* namespace Dyninst */
714
715 bool SerializerBase::removeSerializer(unsigned short ndx)
716 {
717         if (SerializerBase::active_serializers.size() <= ndx)
718                 return false;
719         SerializerBase::active_serializers[ndx] = NULL;
720         if (ndx == (unsigned short) (active_serializers.size() - 1))
721                 active_serializers.pop_back();
722         return true;
723 }
724 bool SerializerBase::global_disable = false;
725
726 #if 0
727 COMMON_EXPORT dyn_hash_map<std::string, SerializerBase *> SerializerBase::active_bin_serializers;
728 #endif
729 COMMON_EXPORT std::vector<SerializerBase *> SerializerBase::active_serializers;
730
731 SerDesBin &SerializerBin::getSD_bin()
732 {
733         SerializerBase *sb = this;
734    SerDes &sd = sb->getSD();
735    SerDesBin *sdbin = dynamic_cast<SerDesBin *> (&sd);
736    assert(sdbin);
737    return *sdbin;
738 }
739
740 SerializerBin::SerializerBin(SerContextBase *s, std::string name_, std::string filename,
741                 iomode_t dir, bool verbose) :
742         SerializerBase(s, std::string(name_), std::string(filename), dir, verbose)
743
744         SerializerBase *sb = this;
745         if (sb->serializationDisabled())
746         {
747                 fprintf(stderr, "%s[%d]:  Failing to construct Bin Translator:  global disable set\n"
748                                 ,       
749                                 FILE__, __LINE__);
750
751                 throw SerializerError(FILE__, __LINE__,
752                                 std::string("serialization disabled"),
753                                 SerializerError::ser_err_disabled);
754         }
755 }
756
757 SerializerBin::~SerializerBin()
758 {
759         serialize_printf("%s[%d]:  WELCOME TO SERIALIZER_BIN dtor\n", FILE__, __LINE__);
760         //dyn_hash_map<std::string, SerializerBase *>::iterator iter;
761 }
762
763 void SerializerBase::dumpActiveBinSerializers()
764 {
765         fprintf(stderr, "%s[%d]:  have serializers: FIXME\n", FILE__, __LINE__);
766 }
767
768 FILE *SerDesBin::init(std::string filename, iomode_t mode, bool /*verbose*/) 
769 {
770    if (SerializerBase::serializationDisabled()) 
771    {
772       fprintf(stderr, "%s[%d]:  Failing BinTranslator:  global disable set\n", 
773                           FILE__, __LINE__);
774       throw SerializerError(FILE__, __LINE__, 
775             std::string("serialization disabled"), 
776             SerializerError::ser_err_disabled);
777    }
778
779    //  NOTE:  fname is path-resolved and turned into "filename" by the SerDes ctor
780    FILE *f = NULL;
781    std::string cache_name;
782
783    if (! SerDesBin::resolveCachePath(filename, cache_name)) 
784    {
785       serialize_printf("%s[%d]:  no cache file exists for %s\n", 
786             FILE__, __LINE__, filename.c_str());
787
788       if (mode == sd_deserialize) 
789           {
790          //  can't deserialize from a file that does not exist
791          char msg[128];
792          sprintf(msg, "%s[%d]:  no cache file exists for %s\n", 
793                FILE__, __LINE__, filename.c_str());
794          SER_ERR(msg);
795       }
796    }
797
798    errno = 0;
799    serialize_printf("%s[%d]:  opening cache file %s for %s\n", FILE__, __LINE__, cache_name.c_str(), (mode == sd_serialize) ? "serialize" : "deserialize");
800
801    f = fopen(cache_name.c_str(), (mode == sd_serialize) ? "w+" : "r");
802
803    if (!f) 
804    {
805       char msg[128];
806       serialize_printf("%s[%d]: fopen(%s, %s): %s\n", FILE__, __LINE__, 
807             cache_name.c_str(), (mode == sd_serialize) ? "w+" : "r", strerror(errno));
808       sprintf(msg, "fopen(%s, %s): %s", cache_name.c_str(), 
809             (mode == sd_serialize) ? "w+" : "r", strerror(errno));
810       SER_ERR(msg);
811    }
812
813    serialize_printf("%s[%d]:  opened cache file %s: %s\n", 
814                    FILE__, __LINE__, cache_name.c_str(), strerror(errno));
815
816    try 
817    {
818       if (mode == sd_serialize)
819           {
820          writeHeaderPreamble(f, filename, cache_name);
821       }
822       else 
823           {
824          readHeaderAndVerify(filename, cache_name, f);
825       }
826    }
827    catch(const SerializerError &err) 
828    {
829       fclose(f);
830       serialize_printf("%s[%d]:  %sserialize failed init.\n\t%s[%d]: %s\n\trethrowing.\n",
831             FILE__, __LINE__, mode == sd_serialize ? "" : "de", 
832             err.file().c_str(), err.line(), err.what());
833       throw(err);
834    }
835
836    return f;
837 }
838
839 SerDesBin::~SerDesBin()
840 {
841 }
842
843 bool SerDesBin::isEOF()
844 {
845         return (0 != feof(f));
846 }
847
848 bool SerDesBin::getDefaultCacheDir(std::string &path)
849 {
850    char *home_dir = getenv("HOME");
851
852    if (!home_dir) 
853    {
854       fprintf(stderr, "%s[%d]:  weird, no $HOME dir\n", FILE__, __LINE__);
855       return false;
856    }
857
858    std::string dot_dyninst_dir = std::string(home_dir) + std::string("/")
859       + std::string(DEFAULT_DYNINST_DIR);
860
861    struct stat statbuf;
862
863    if (0 != stat(dot_dyninst_dir.c_str(), &statbuf)) 
864    {
865       if (errno == ENOENT) 
866           {
867 #if defined (os_windows)
868          if (0 != P_mkdir(dot_dyninst_dir.c_str(), 0)) 
869                  {
870             fprintf(stderr, "%s[%d]:  failed to make %s\n", FILE__, __LINE__, 
871                   dot_dyninst_dir.c_str(), strerror(errno));
872             return false;
873          } 
874 #else
875          if (0 != mkdir(dot_dyninst_dir.c_str(), S_IRWXU)) 
876                  {
877             fprintf(stderr, "%s[%d]:  failed to make %s: %s\n", FILE__, __LINE__, 
878                   dot_dyninst_dir.c_str(), strerror(errno));
879             return false;
880          } 
881 #endif
882       }
883       else 
884           {
885          fprintf(stderr, "%s[%d]:  stat(%s) failed: %s\n", FILE__, __LINE__, 
886                dot_dyninst_dir.c_str(), strerror(errno));
887          return false;
888       }
889    }
890    else 
891    {
892 #if !defined (os_windows)
893       //  sanity check that its a dir
894       if (!S_ISDIR(statbuf.st_mode)) 
895           {
896          fprintf(stderr, "%s[%d]:  ERROR:  %s is not a dir\n", FILE__, __LINE__, 
897                dot_dyninst_dir.c_str());
898          return false;
899       }
900 #else
901       //  windows equiv to S_ISDIR??
902 #endif
903    }
904
905    path = dot_dyninst_dir + std::string("/") + std::string(DEFAULT_CACHE_DIR);
906
907    if (0 != stat(path.c_str(), &statbuf)) 
908    {
909       if (errno == ENOENT) 
910           {
911 #if defined (os_windows)
912          if (0 != P_mkdir(path.c_str(), 0)) 
913                  {
914             fprintf(stderr, "%s[%d]:  failed to make %s\n", FILE__, __LINE__, 
915                   path.c_str(), strerror(errno));
916             return false;
917          } 
918 #else
919          if (0 != mkdir(path.c_str(), S_IRWXU)) 
920                  {
921             fprintf(stderr, "%s[%d]:  failed to make %s: %s\n", FILE__, __LINE__, 
922                   path.c_str(), strerror(errno));
923             return false;
924          } 
925 #endif
926       }
927       else 
928           {
929          fprintf(stderr, "%s[%d]:  stat(%s) failed: %s\n", FILE__, __LINE__, 
930                path.c_str(), strerror(errno));
931          return false;
932       }
933    }
934    else 
935    {
936 #if !defined (os_windows)
937       //  sanity check that its a dir
938       if (!S_ISDIR(statbuf.st_mode)) 
939           {
940          fprintf(stderr, "%s[%d]:  ERROR:  %s is not a dir\n", FILE__, __LINE__, 
941                path.c_str());
942          return false;
943       }
944 #else
945       //  windows equiv to S_ISDIR??
946 #endif
947    }
948
949    serialize_printf("%s[%d]:  using default cache dir: %s\n", 
950                    FILE__, __LINE__, path.c_str());
951
952    return true;
953 }
954
955 bool SerDesBin::resolveCachePath(std::string full_file_path, std::string &cache_name)
956 {
957    std::string path;
958    char *path_dir = getenv(CACHE_DIR_VAR); 
959
960    if (!path_dir) 
961    {
962       if (!getDefaultCacheDir(path)) 
963           {
964          fprintf(stderr, "%s[%d]:  weird, failed to make $HOME/.dyninst/caches\n",
965                FILE__, __LINE__);
966          return false;
967       }
968    }
969
970    // get size of file (this is encoded into cache name)
971    struct stat statbuf;
972
973    if (0 != stat(full_file_path.c_str(), &statbuf)) 
974    {
975       fprintf(stderr, "%s[%d]:  stat %s failed: %s\n", FILE__, __LINE__, 
976             full_file_path.c_str(), strerror(errno));
977       return false;
978    }
979
980    std::string short_name = extract_pathname_tail(full_file_path);
981    serialize_printf("%s[%d]:  file %s short name: %s\n", FILE__, __LINE__, 
982          full_file_path.c_str(), short_name.c_str());
983
984    // construct cache name from cache path, cache prefix, short name, and size
985    char sizestr[16];
986    sprintf(sizestr, "%d", (int)statbuf.st_size);
987    cache_name = path + std::string("/") + std::string(CACHE_PREFIX) + short_name 
988       + std::string("_") 
989       + std::string(sizestr);
990
991    serialize_printf("%s[%d]:  constructed cache name: %s\n", FILE__, __LINE__, cache_name.c_str());
992
993    if (0 != stat(cache_name.c_str(), &statbuf)) 
994    {
995       if (errno != ENOENT) 
996           {
997          //  Its OK if the file doesn't exist, but complain if we get a different
998          // error
999          fprintf(stderr, "%s[%d]:  stat %s failed: %s\n", FILE__, __LINE__, 
1000                cache_name.c_str(), strerror(errno));
1001       }
1002       serialize_printf("%s[%d]:  cache file %s does not exist\n", FILE__, __LINE__, 
1003             cache_name.c_str());
1004       return false;
1005    }
1006
1007    serialize_printf("%s[%d]:  cache file %s exists\n", FILE__, __LINE__, cache_name.c_str());
1008    return true;
1009 }
1010
1011 bool SerDesBin::cacheFileExists(std::string fname)
1012 {
1013    std::string cache_name;
1014    return resolveCachePath(fname, cache_name); 
1015 }
1016
1017 void SerDesBin::readHeaderAndVerify(std::string full_file_path, std::string cache_name, FILE *fptr)
1018 {
1019    struct stat statbuf;
1020
1021    if (0 != stat(full_file_path.c_str(), &statbuf)) 
1022    {
1023       char msg[128];
1024       if (errno != ENOENT) 
1025           {
1026          //  Its OK if the file doesn't exist, but complain if we get a different
1027          // error
1028          sprintf(msg, "%s[%d]:  stat %s failed: %s\n", FILE__, __LINE__, 
1029                full_file_path.c_str(), strerror(errno));
1030       }
1031       SER_ERR(msg);
1032    }
1033
1034    FILE *f = NULL;
1035    if (fptr) 
1036       f = fptr;
1037    else 
1038    {
1039            serialize_printf("%s[%d]:  trying to open %s\n", FILE__, __LINE__, 
1040                            cache_name.c_str());
1041
1042       f = fopen(cache_name.c_str(), "r");
1043
1044       if (!f) 
1045           {
1046          char msg[128];
1047          sprintf(msg, "%s[%d]:  failed to open file %s: %s\n", 
1048                FILE__, __LINE__, full_file_path.c_str(), strerror(errno));
1049          SER_ERR(msg);
1050       }
1051    }
1052
1053    size_t source_file_size = statbuf.st_size;
1054
1055    cache_header_t header;
1056
1057    int rc = fread(&header, sizeof(cache_header_t), 1, f);
1058
1059    if (1 != rc) 
1060    {
1061       char msg[128];
1062       sprintf(msg, "%s[%d]:  failed to read header struct for %s: %s, rc = %d\n", 
1063             FILE__, __LINE__, cache_name.c_str(), strerror(errno), rc);
1064       SER_ERR(msg);
1065    }
1066
1067    if (header.cache_magic != (unsigned) CACHE_MAGIC) 
1068    {
1069       char msg[128];
1070       sprintf(msg, "%s[%d]:  magic number check failure for %s--%s: got %d, expected %d\n", 
1071             FILE__, __LINE__, full_file_path.c_str(), cache_name.c_str(), 
1072                         header.cache_magic, CACHE_MAGIC);
1073       SER_ERR(msg);
1074    }
1075
1076    if (header.source_file_size != source_file_size) 
1077    {
1078       char msg[128];
1079       sprintf(msg, "%s[%d]:  size discrepancy found for %s/%s\n", 
1080             FILE__, __LINE__, full_file_path.c_str(), cache_name.c_str());
1081       SER_ERR(msg);
1082    }
1083
1084    if (!verifyChecksum(full_file_path, header.sha1)) 
1085    {
1086       char msg[128];
1087       sprintf(msg, "%s[%d]:  checksum discrepancy found for %s/%s\n", 
1088             FILE__, __LINE__, full_file_path.c_str(), cache_name.c_str());
1089
1090       if (!invalidateCache(cache_name)) 
1091           {
1092          fprintf(stderr, "%s[%d]:  failed to invalidate cache for file %s/%s\n", 
1093                FILE__, __LINE__, full_file_path.c_str(), cache_name.c_str());
1094       }
1095
1096       SER_ERR(msg);
1097    }
1098
1099    if (!fptr)
1100    {
1101            fprintf(stderr, "%s[%d]:  closing file pointer here\n", FILE__, __LINE__);
1102       fclose (f);
1103    }
1104 }
1105
1106
1107 void SerDesBin::writeHeaderPreamble(FILE *f, std::string full_file_path, 
1108                 std::string /*cache_name*/)
1109 {
1110    serialize_printf("%s[%d]:  welcome to write header preamble for %s\n", 
1111                    FILE__, __LINE__, full_file_path.c_str());
1112
1113    //  get a few bits of info on this file to construct the header of the cache
1114    //  file...  checksum, size, ...  not mtime, since we don't care if someone 
1115    //  copies the file around
1116
1117    struct stat statbuf;
1118
1119    if (0 != stat(full_file_path.c_str(), &statbuf)) 
1120    {
1121       char msg[128];
1122       sprintf(msg, "%s[%d]:  stat %s failed: %s\n", FILE__, __LINE__, 
1123             full_file_path.c_str(), strerror(errno));
1124       SER_ERR(msg);
1125    }
1126
1127    cache_header_t header;
1128    header.cache_magic = CACHE_MAGIC;
1129    header.source_file_size = statbuf.st_size;
1130
1131    if (NULL == sha1_file(full_file_path.c_str(), header.sha1)) 
1132    {
1133       char msg[128];
1134       sprintf(msg, "sha1_file failed\n");
1135       SER_ERR(msg);
1136    }
1137
1138    int rc = fwrite(&header, sizeof(cache_header_t), 1, f);
1139
1140    if (1 != rc) 
1141       SER_ERR("fwrite");
1142
1143 }
1144
1145 bool SerDesBin::verifyChecksum(std::string &full_file_path, 
1146       const char comp_checksum[SHA1_DIGEST_LEN*2])
1147 {
1148    char new_checksum[SHA1_DIGEST_LEN*2]; 
1149
1150    if (NULL == sha1_file(full_file_path.c_str(), new_checksum)) 
1151    {
1152       fprintf(stderr, "%s[%d]:  sha1_file(%s) failed \n", 
1153             FILE__, __LINE__, full_file_path.c_str());
1154       return false;
1155    }
1156
1157    if (strncmp(comp_checksum, new_checksum, SHA1_DIGEST_LEN*2)) 
1158    {
1159       fprintf(stderr, "%s[%d]:  sha1_file(%s): checksum mismatch: \n\told:%s\n\tnew:%s\n", 
1160             FILE__, __LINE__, full_file_path.c_str(), comp_checksum, new_checksum);
1161       return false;
1162    }
1163
1164    return true;
1165 }
1166
1167 bool SerDesBin::invalidateCache(std::string cache_name) 
1168 {
1169    if (-1 == P_unlink(cache_name.c_str())) 
1170    {
1171       fprintf(stderr, "%s[%d]:  unlink(%s): %s\n", FILE__, __LINE__, 
1172             cache_name.c_str(), strerror(errno));
1173       return false;
1174    }
1175
1176    return true;
1177 }
1178
1179 void SerDesBin::file_start(std::string &/*full_file_path*/)
1180 {
1181 }
1182
1183 void SerDesBin::vector_start(unsigned long &size, const char *) DECLTHROW (SerializerError)
1184 {
1185         if (iomode_ == sd_deserialize) 
1186                 size = 0UL;
1187
1188    //  before reading/writing a vector, we need to read its size
1189    //  (so we know how many elements to read/alloc on deserialize
1190
1191         magic_check(FILE__, __LINE__);
1192    translate(size);
1193         magic_check(FILE__, __LINE__);
1194         if (iomode_ == sd_deserialize) 
1195         {
1196                 serialize_printf("%s[%d]:  DESERIALIZE VECTOR START:  size = %lu\n", 
1197                                 FILE__, __LINE__, size);
1198         }
1199         else
1200                 serialize_printf("%s[%d]:  SERIALIZE VECTOR START:  size = %lu\n", 
1201                                 FILE__, __LINE__, size);
1202 }
1203
1204 void SerDesBin::vector_end()
1205 {
1206    //  don't need to do anything
1207 }
1208
1209 void SerDesBin::multimap_start(unsigned long &size, const char *) DECLTHROW (SerializerError)
1210 {
1211    //  before reading/writing a multimap, we need to read its size
1212    //  (so we know how many elements to read/alloc on deserialize
1213    translate(size);
1214 }
1215
1216 void SerDesBin::multimap_end()
1217 {
1218    //  don't need to do anything
1219 }
1220
1221 void SerDesBin::pair_start(const char *) DECLTHROW (SerializerError)
1222 {
1223 }
1224
1225 void SerDesBin::pair_end()
1226 {
1227    //  don't need to do anything
1228 }
1229
1230 void SerDesBin::hash_map_start(unsigned long &size, const char *) DECLTHROW (SerializerError)
1231 {
1232    //  before reading/writing a hash map, we need to read its size
1233    //  (so we know how many elements to read/alloc on deserialize
1234    translate(size);
1235 }
1236
1237 void SerDesBin::hash_map_end() 
1238 {
1239 }
1240
1241 void SerDesBin::annotation_start(AnnotationClassID &a_id, void *&parent_id, 
1242                 sparse_or_dense_anno_t &sod, const char *, const char *)
1243 {
1244         //serialize_printf("%s[%d]:  welcome to  annotation_start: aid = %d\n", FILE__, __LINE__, a_id);
1245
1246         unsigned int lsod = 0;
1247         lsod = (int)sod;
1248         magic_check(FILE__, __LINE__);
1249         translate(a_id);
1250         assert(sizeof(Address) == sizeof(void *));
1251         translate((Address &)parent_id);
1252         //translate((unsigned short &)sod);
1253         translate(lsod);
1254         magic_check(FILE__, __LINE__);
1255
1256         if (iomode() == sd_deserialize)
1257                 sod = (sparse_or_dense_anno_t)lsod;
1258
1259         serialize_printf("%s[%d]:  leaving %s annotation_start: aid = %d, id = %p\n", 
1260                         FILE__, __LINE__, 
1261                         (iomode_ == sd_serialize) ? "serialize" : "deserialize", a_id, parent_id);
1262 }
1263
1264 void SerDesBin::annotation_end()
1265 {
1266         //magic_check(FILE__, __LINE__);
1267    //  don't need to do anything
1268 }
1269
1270 void SerDesBin::annotation_container_start(void *&id)
1271 {
1272         magic_check(FILE__, __LINE__);
1273         assert(sizeof(Address) == sizeof(void *));
1274         translate((Address &)id);
1275         magic_check(FILE__, __LINE__);
1276 }
1277
1278 void SerDesBin::annotation_container_end()
1279 {
1280         magic_check(FILE__, __LINE__);
1281    //  don't need to do anything
1282 }
1283 void SerDesBin::annotation_container_item_start(void *&id)
1284 {
1285         magic_check(FILE__, __LINE__);
1286         assert(sizeof(Address) == sizeof(void *));
1287         translate((Address &)id);
1288         magic_check(FILE__, __LINE__);
1289 }
1290
1291 void SerDesBin::annotation_container_item_end()
1292 {
1293         magic_check(FILE__, __LINE__);
1294    //  don't need to do anything
1295 }
1296
1297 void SerDesBin::magic_check(const char *file__, unsigned int line__)
1298 {
1299         unsigned short magic = 33;
1300         translate(magic);
1301         if (iomode_ == sd_deserialize)
1302         {
1303                 if (magic != 33)
1304                 {
1305                         fprintf(stderr, "%s[%d]:  OUT OF SYNC HERE\n", file__, line__);
1306                         if (isEOF())
1307                                 fprintf(stderr, "%s[%d]:  GOT EOF\n", file__, line__);
1308                         abort();
1309                 }
1310         }
1311 }
1312
1313 void SerDesBin::annotation_list_start(Address &id, unsigned long &nelem, const char *)
1314 {
1315    if (iomode_ == sd_deserialize) 
1316    {
1317            nelem = 0UL;
1318    }
1319
1320         if (nelem)
1321         {
1322                 serialize_printf("%s[%d]: enter annotation_list_start id = %p, nelem = %ld\n", 
1323                                 FILE__, __LINE__, (void *)id, nelem);
1324         }
1325
1326         magic_check(FILE__, __LINE__);
1327         translate(id);
1328         translate(nelem);
1329
1330         if (nelem)
1331                 serialize_printf("%s[%d]: leave annotation_list_start id = %p, nelem = %ld\n", FILE__, __LINE__, (void *)id, nelem);
1332 }
1333
1334 void SerDesBin::annotation_list_end()
1335 {
1336    //  don't need to do anything
1337 }
1338
1339 void SerDesBin::translate(bool &param, const char *tag)
1340 {
1341    int rc;
1342    if (iomode_ == sd_serialize) 
1343    {
1344       rc = fwrite(&param, sizeof(bool), 1, f);
1345
1346       if (1 != rc) 
1347          SER_ERR("fwrite");
1348    }
1349    else 
1350    {
1351       rc = fread(&param, sizeof(bool), 1, f);
1352
1353       if (1 != rc) 
1354          SER_ERR("fread");
1355    }
1356
1357    if (noisy)
1358       serialize_printf("%s[%d]:  %sserialize %s=%s\n", FILE__, __LINE__,
1359             iomode_ == sd_serialize ? "" : "de", 
1360             tag ? tag : "no-tag",
1361             param ? "true": "false");
1362 }
1363
1364 void SerDesBin::translate(char &param, const char *tag)
1365 {
1366    int rc;
1367
1368    if (iomode_ == sd_serialize) 
1369    {
1370       rc = fwrite(&param, sizeof(char), 1, f);
1371
1372       if (1 != rc) 
1373          SER_ERR("fwrite");
1374    }
1375    else 
1376    {
1377       rc = fread(&param, sizeof(char), 1, f);
1378
1379       if (1 != rc) 
1380          SER_ERR("fread");
1381    }
1382
1383    if (noisy)
1384       serialize_printf("%s[%d]:  %sserialize %s=%c\n", FILE__, __LINE__,
1385             iomode_ == sd_serialize ? "" : "de", 
1386             tag ? tag : "no-tag", param);
1387 }
1388
1389 void SerDesBin::translate(int &param, const char *tag)
1390 {
1391    int rc;
1392    if (iomode_ == sd_serialize) 
1393    {
1394       rc = fwrite(&param, sizeof(int), 1, f);
1395
1396       if (1 != rc) 
1397          SER_ERR("fwrite");
1398    }
1399    else 
1400    {
1401            errno = 0;
1402            rc = fread(&param, sizeof(int), 1, f);
1403
1404       if (1 != rc) 
1405           {
1406                   //fprintf(stderr, "%s[%d]:  failed to deserialize int-'%s', rc = %d:%s, noisy = %d\n", 
1407                 //                FILE__, __LINE__, tag ? tag : "no_tag", rc, strerror(errno), noisy);
1408                  // fprintf(stderr, "isEOF = %s\n", isEOF() ? "true" : "false");
1409          SER_ERR("fread");
1410           }
1411    }
1412
1413    if (noisy)
1414       serialize_printf("%s[%d]:  %sserialize %s=%d\n", FILE__, __LINE__,
1415             iomode_ == sd_serialize ? "" : "de", 
1416             tag ? tag : "no-tag", param);
1417 }
1418
1419 void SerDesBin::translate(long &param, const char *tag)
1420 {
1421    int rc;
1422    if (iomode_ == sd_serialize) 
1423    {
1424       rc = fwrite(&param, sizeof(long), 1, f);
1425
1426       if (1 != rc) 
1427          SER_ERR("fwrite");
1428    }
1429    else 
1430    {
1431       rc = fread(&param, sizeof(long), 1, f);
1432
1433       if (1 != rc) 
1434          SER_ERR("fread");
1435    }
1436
1437    if (noisy)
1438       serialize_printf("%s[%d]:  %sserialize %s=%lu\n", FILE__, __LINE__,
1439             iomode_ == sd_serialize ? "" : "de", 
1440             tag ? tag : "no-tag", param);
1441 }
1442
1443 void SerDesBin::translate(unsigned short &param, const char *tag)
1444 {
1445         short lshort = static_cast<short>(param);
1446         translate (lshort, tag);
1447         param = static_cast<unsigned short>(lshort);
1448 }
1449
1450 void SerDesBin::translate(short &param, const char *tag)
1451 {
1452    int rc;
1453    if (iomode_ == sd_serialize) 
1454    {
1455       rc = fwrite(&param, sizeof(short), 1, f);
1456
1457       if (1 != rc) 
1458          SER_ERR("fwrite");
1459    }
1460    else 
1461    {
1462       rc = fread(&param, sizeof(short), 1, f);
1463
1464       if (1 != rc) 
1465          SER_ERR("fread");
1466    }
1467
1468    if (noisy)
1469       serialize_printf("%s[%d]:  %sserialize %s=%d\n", FILE__, __LINE__,
1470             iomode_ == sd_serialize ? "" : "de", 
1471             tag ? tag : "no-tag", param);
1472 }
1473
1474 void SerDesBin::translate(unsigned int &param, const char * tag)
1475 {
1476    //  overkill for a typecast??
1477    translate( (int &) param, tag);
1478 }
1479
1480 void SerDesBin::translate(float &param, const char *tag)
1481 {
1482    int rc;
1483    if (iomode_ == sd_serialize) 
1484    {
1485       rc = fwrite(&param, sizeof(float), 1, f);
1486
1487       if (1 != rc) 
1488          SER_ERR("fwrite");
1489    }
1490    else 
1491    {
1492       rc = fread(&param, sizeof(float), 1, f);
1493
1494       if (1 != rc) 
1495          SER_ERR("fread");
1496    }
1497
1498    if (noisy)
1499       serialize_printf("%s[%d]:  %sserialize %s=%e\n", FILE__, __LINE__,
1500             iomode_ == sd_serialize ? "" : "de", 
1501             tag ? tag : "no-tag", param);
1502 }
1503
1504 void SerDesBin::translate(double &param, const char *tag)
1505 {
1506    int rc;
1507    if (iomode_ == sd_serialize) 
1508    {
1509       rc = fwrite(&param, sizeof(double), 1, f);
1510
1511       if (1 != rc) 
1512          SER_ERR("fwrite");
1513    }
1514    else 
1515    {
1516       rc = fread(&param, sizeof(double), 1, f);
1517
1518       if (1 != rc) 
1519          SER_ERR("fread");
1520    }
1521
1522    if (noisy)
1523       serialize_printf("%s[%d]:  %sserialize %s=%g\n", FILE__, __LINE__,
1524             iomode_ == sd_serialize ? "" : "de", 
1525             tag ? tag : "no-tag", param);
1526 }
1527
1528 void SerDesBin::translate(Address &param, const char *tag)
1529 {
1530    int rc;
1531    if (iomode_ == sd_serialize) 
1532    {
1533       rc = fwrite(&param, sizeof(Address), 1, f);
1534
1535       if (1 != rc) 
1536          SER_ERR("fwrite");
1537    }
1538    else 
1539    {
1540            memset(&param, 0, sizeof(Address));
1541       rc = fread(&param, sizeof(Address), 1, f);
1542
1543       if (1 != rc) 
1544          SER_ERR("fread");
1545    }
1546
1547    if (noisy)
1548       serialize_printf("%s[%d]:  %sserialize %s=%lx\n", FILE__, __LINE__,
1549             iomode_ == sd_serialize ? "" : "de", 
1550             tag ? tag : "no-tag", param);
1551 }
1552
1553 void SerDesBin::translate(void * &param, const char *tag)
1554 {
1555    int rc;
1556    if (iomode_ == sd_serialize) 
1557    {
1558       rc = fwrite(&param, sizeof(void *), 1, f);
1559
1560       if (1 != rc) 
1561          SER_ERR("fwrite");
1562    }
1563    else 
1564    {
1565       rc = fread(&param, sizeof(void *), 1, f);
1566
1567       if (1 != rc) 
1568          SER_ERR("fread");
1569    }
1570
1571    if (noisy)
1572       serialize_printf("%s[%d]:  %sserialize %s=%p\n", FILE__, __LINE__,
1573             iomode_ == sd_serialize ? "" : "de", 
1574             tag ? tag : "no-tag", param);
1575 }
1576
1577 void SerDesBin::translate(const char * &param, int bufsize, const char *tag)
1578 {
1579    //  string output format is
1580    //  [1]  length of string
1581    //  [2]  string data
1582    int rc, len;
1583    if (iomode_ == sd_serialize) 
1584    {
1585       len = strlen(param);
1586
1587       rc = fwrite( &len, sizeof(int), 1, f);
1588
1589       if (1 != rc) 
1590          SER_ERR("fwrite");
1591
1592       rc = fwrite(param, sizeof(char), len, f);
1593
1594       if (len != rc) 
1595          SER_ERR("fwrite");
1596    }
1597    else 
1598    {
1599       rc = fread(&len, sizeof(int), 1, f);
1600
1601       if (1 != rc)  
1602       {
1603          fprintf(stderr, "%s[%d]:  fread, got %d not 1: %s\n", FILE__, __LINE__, rc,  strerror(errno));
1604          SER_ERR("fread");
1605       }
1606
1607       if (len > bufsize) 
1608       {
1609          fprintf(stderr, "%s[%d]:  insufficient buffer: %d, need %d...  truncation....\n", FILE__, __LINE__, bufsize, len);
1610                  len = bufsize;
1611
1612          //char msg[128];
1613          //sprintf(msg, "not enough space in string buffer, %d needed", len);
1614          //SER_ERR("msg");
1615       }
1616
1617       if (len < 0) 
1618       {
1619          fprintf(stderr, "%s[%d]:  bad bufsize %d for %s\n", FILE__, __LINE__, len, tag ? tag : "no_tag");
1620          char msg[128];
1621          sprintf(msg, "bad bufsize, %d ", len);
1622          SER_ERR("msg");
1623       }
1624
1625           char *l_ptr = const_cast<char *> (param);
1626           if (len != 0)
1627           {
1628                   rc = fread(l_ptr, sizeof(char), len, f);
1629
1630                   if (len != rc) 
1631                   {
1632                           fprintf(stderr, "%s[%d]:  fread, got %d not %d: %s\n", 
1633                                           FILE__, __LINE__, rc, len, strerror(errno));
1634                           SER_ERR("fread");
1635                   }
1636           }
1637           else 
1638           {
1639                   //  Zero length strings are allowed
1640                   //fprintf(stderr, "%s[%d]:  WARN:  zero length string for %s\n", FILE__, __LINE__, tag ? tag : "no_tag_provided");
1641           }
1642
1643           l_ptr[len] = '\0';
1644
1645    }
1646
1647    if (noisy)
1648       serialize_printf("%s[%d]:  %sserialize %s=%s\n", FILE__, __LINE__,
1649             iomode_ == sd_serialize ? "" : "de", 
1650             tag ? tag : "no-tag", param);
1651 }
1652
1653 void SerDesBin::translate(char * &param, int bufsize, const char *tag)
1654 {
1655    const char * p = const_cast<const char *>(param);
1656    translate(p, bufsize, tag);
1657    param = const_cast<char *>(p);
1658 }
1659
1660 void SerDesBin::translate(std::string &param, const char *tag)
1661 {
1662    if (iomode_ == sd_serialize) 
1663    {
1664       const char *cstr = param.c_str();
1665       translate(cstr, 0, tag);
1666    }
1667    else 
1668    {
1669       char buf[4096];
1670       const char *buf2 = buf;
1671       translate(buf2, 4096, tag);
1672       param = std::string(buf2);
1673    }
1674    if ((iomode_ == sd_deserialize) ||strstr(param.c_str(), "file")) 
1675    {
1676       serialize_printf("%s[%d]:  %sserializing string %s--%s, len = %lu\n", 
1677             FILE__, __LINE__, (iomode_ == sd_serialize) ? "" : "de", tag ? tag : "unnamed",
1678               param.c_str(), (unsigned long) param.length());
1679    }
1680 }
1681
1682 void SerDesBin::translate(std::vector<std::string> &param, const char *tag, const char * elem_tag)
1683 {
1684    //  string list output format is
1685    //  [1]  length of list, n
1686    //  [2]  <n> strings
1687
1688    unsigned long nelem = param.size();
1689    translate(nelem, tag);
1690
1691    if (iomode_ == sd_serialize) 
1692    {
1693       for (unsigned long i = 0; i < nelem; ++i) 
1694       {
1695          translate(param[i], elem_tag);
1696       }
1697    }
1698    else 
1699    {
1700       param.resize(nelem);
1701       for (unsigned long i = 0; i < nelem; ++i) 
1702       {
1703          param[i] = "";
1704          translate(param[i], elem_tag);
1705       }
1706    }
1707 }
1708
1709 SerializerBase *Serializable::lookupExistingSerializer()
1710 {
1711         //fprintf(stderr, "%s[%d]:  lookupExistingSerializer: index = %d, serializers.size() = %lu\n", FILE__, __LINE__, active_serializer_index, SerializerBase::active_serializers.size());
1712
1713         if (active_serializer_index == (unsigned short) -1)
1714                 return NULL;
1715
1716         if (SerializerBase::active_serializers.size() <= active_serializer_index)
1717                 return NULL;
1718
1719         return SerializerBase::active_serializers[active_serializer_index];
1720 }
1721
1722 namespace Dyninst {
1723
1724 bool ser_operation(SerializerBase *sb, ser_post_op_t &op, const char *tag)
1725 {
1726         try 
1727         {
1728                 gtranslate(sb, op, serPostOp2Str, tag);
1729         }
1730         catch (const Dyninst::SerializerError &err_)
1731         {   
1732                 if (isEOF(sb))
1733                 {   
1734                         serialize_printf("%s[%d]:  got EOF\n", FILE__, __LINE__);
1735                 }   
1736                 else
1737                 {
1738                         fprintf(stderr, "%s[%d]:  SerializerError thrown\n", FILE__, __LINE__);
1739                 }
1740                 return false;
1741         }
1742         catch (...)
1743         {
1744                 fprintf(stderr, "%s[%d]:  Unknown error thrown\n", FILE__, __LINE__);
1745                 return false;
1746         }
1747
1748         return true;
1749
1750 }
1751
1752 void throw_ser_err(const char *file__, unsigned int line, const char *msg)
1753 {
1754         throw SerializerError(file__, line, std::string(msg));
1755 }
1756 void serialize_annotatable_id(SerializerBase *sb, void *&id, const char *tag)
1757 {
1758         Address l_id = (Address &)id;
1759         gtranslate(sb, l_id, tag);
1760         id = (void *)l_id;
1761 }
1762
1763 bool set_sb_annotatable_sparse_map(SerializerBase *sb, AnnotatableSparse *as, void *id)
1764 {
1765         sb->set_annotatable_sparse_map(as, id);
1766         return true;
1767 }
1768
1769 bool set_sb_annotatable_dense_map(SerializerBase *sb, AnnotatableDense *ad, void *id)
1770 {
1771         sb->set_annotatable_dense_map(ad, id);
1772         return true;
1773 }
1774
1775 void SerializerBase::set_annotatable_sparse_map(AnnotatableSparse *as, void *id)
1776 {
1777         (*sparse_annotatable_map)[id] = as;
1778 }
1779
1780 void SerializerBase::set_annotatable_dense_map(AnnotatableDense *ad, void *id)
1781 {
1782         (*dense_annotatable_map)[id] = ad;
1783 }
1784
1785 unsigned short get_serializer_index(SerializerBase *sb)
1786 {
1787         if (!sb) return (unsigned short) -1;
1788         return sb->getIndex();
1789 }
1790 } // namespace dyninst
1791
1792 SerializerBase::SerializerBase(SerContextBase *scb, std::string name_, 
1793                 std::string filename, 
1794                 iomode_t dir, 
1795                 bool verbose):
1796         sparse_annotatable_map(NULL),
1797         dense_annotatable_map(NULL)
1798 {
1799         if (!scb)
1800         {
1801                 serializer_printf("%s[%d]:  ERROR:  no context for serializer\n", FILE__, __LINE__);
1802                 return;
1803         }
1804
1805         sparse_annotatable_map = new dyn_hash_map<void *, AnnotatableSparse *>();
1806         dense_annotatable_map = new dyn_hash_map<void *, AnnotatableDense *>();
1807         scon = scb;
1808         serializer_name = std::string(name_);
1809
1810         serialize_printf("%s[%d]:  before new SerFile, scb = %p, name = %s/%s\n", 
1811                         FILE__, __LINE__, scb, serializer_name.c_str(), filename.c_str());
1812
1813         sf = new SerFile(std::string(filename), dir, verbose);
1814         assert(sf);
1815
1816         sd = sf->getSD();
1817         if (!sd) 
1818         {
1819                 fprintf(stderr, "%s[%d]:  failed to get sd here\n", FILE__, __LINE__);
1820         }
1821         assert(scb);
1822
1823         scb->serfilename = sf->getCacheFileName();
1824         if (dir == sd_serialize)
1825         {
1826                 ser_index = (unsigned short) active_serializers.size();
1827                 active_serializers.push_back(this);
1828         }
1829 }
1830
1831 SerializerBase::SerializerBase() : 
1832         ser_index((unsigned short) -1),
1833         sparse_annotatable_map(NULL),
1834         dense_annotatable_map(NULL)
1835 {
1836         fprintf(stderr, "%s[%d]:  WARN:  inside default ctor\n", FILE__, __LINE__);
1837         sparse_annotatable_map = new dyn_hash_map<void *, AnnotatableSparse *>();
1838         dense_annotatable_map = new dyn_hash_map<void *, AnnotatableDense *>();
1839 }
1840
1841 SerializerBase::~SerializerBase()
1842 {
1843         serialize_printf("%s[%d]:  serializer %p-%sdtor\n", FILE__, __LINE__,
1844                         this, serializer_name.c_str());
1845 }
1846
1847 unsigned short get_serializer_index(SerializerBase *sb)
1848 {
1849         assert(sb);
1850         return sb->getIndex();
1851 }
1852
1853 unsigned short SerializerBase::getIndex()
1854 {
1855         return ser_index;
1856 }
1857
1858 void SerializerBase::globalDisable()
1859 {
1860         global_disable = true;
1861 }
1862 bool SerializerBase::serializationDisabled()
1863 {
1864         return global_disable;
1865 }
1866
1867 void SerializerBase::globalEnable()
1868 {
1869         global_disable = false;
1870 }
1871
1872 SerContextBase *SerializerBase::getContext() 
1873 {
1874         return scon;
1875 }
1876
1877 bool SerializerBase::isInput () 
1878 {
1879         return iomode() == sd_deserialize;
1880 }
1881
1882 bool SerializerBase::isOutput () 
1883 {
1884         return iomode() == sd_serialize;
1885 }
1886
1887 SerializerBase *SerializerBase::getSerializer(std::string subsystem, std::string fname)
1888 {
1889         dyn_hash_map<std::string, subsystem_serializers_t>::iterator ssiter; 
1890         ssiter = all_serializers.find(subsystem);
1891
1892         if (ssiter == all_serializers.end()) 
1893         {
1894                 fprintf(stderr, "%s[%d]:  no serializer for subsystem %s\n", 
1895                                 FILE__, __LINE__, subsystem.c_str());
1896                 return NULL;
1897         }
1898
1899         subsystem_serializers_t &subsys_map = ssiter->second;
1900
1901         dyn_hash_map<std::string, SerializerBase *>::iterator sbiter;
1902         sbiter = subsys_map.find(fname);
1903         if (sbiter == subsys_map.end()) 
1904         {
1905                 fprintf(stderr, "%s[%d]:  no serializer for filename %s\n", 
1906                                 FILE__, __LINE__, fname.c_str());
1907                 return NULL;
1908         }
1909
1910         SerializerBase *sb =  sbiter->second;
1911         if (!sb) 
1912         {
1913                 fprintf(stderr, "%s[%d]:  ERROR:  NULL serializer\n", FILE__, __LINE__);
1914                 return NULL;
1915         }
1916
1917         return sb;
1918 }
1919
1920 bool SerializerBase::addSerializer(std::string subsystem, 
1921                 std::string fname, SerializerBase *sb)
1922 {
1923    subsystem_serializers_t ss_serializers;
1924    dyn_hash_map<std::string, subsystem_serializers_t>::iterator ssiter; 
1925    ssiter =  all_serializers.find(subsystem);
1926
1927    if (ssiter == all_serializers.end()) 
1928    {
1929       //  make an entry 
1930       all_serializers[subsystem] = ss_serializers;
1931    }
1932
1933    ss_serializers = all_serializers[subsystem];
1934
1935    dyn_hash_map<std::string, SerializerBase *>::iterator sbiter;
1936    sbiter = ss_serializers.find(fname);
1937    if (sbiter != ss_serializers.end()) 
1938    {
1939       serializer_printf("%s[%d]:  already have serializer for filename %s\n", 
1940             FILE__, __LINE__, fname.c_str());
1941       return false;
1942    }
1943
1944    //  add serializer to map since it does not exist there already
1945
1946    ss_serializers[fname] = sb;
1947    return true;
1948 }
1949
1950 iomode_t SerializerBase::iomode()
1951 {
1952    if (sd) 
1953    {
1954       return sd->iomode();
1955    }
1956
1957    fprintf(stderr, "%s[%d]:  no sd for iomode query\n", FILE__, __LINE__);
1958    return sd_serialize;
1959 }
1960
1961 void SerializerBase::serialize_annotations(void *id, 
1962                 std::vector<ser_rec_t> &sers, const char *tag)
1963 {
1964         Address id_add = (Address) id;
1965
1966         unsigned long nelem = 0UL;
1967         if (isOutput())
1968                 nelem = sers.size();
1969
1970         getSD().annotation_list_start(id_add, nelem);
1971
1972         if (nelem)
1973                 serialize_printf("%s[%d]:  need to %s %lu annos\n", 
1974                                 FILE__, __LINE__, isInput() ? "deserialize" : "serialize", nelem);
1975
1976         if (sers.size())
1977                 serialize_printf( "%s[%d]: serialize_annotations:  %s, id = %p, nelem = %lu\n", 
1978                                 FILE__, __LINE__, isInput() ? "deserialize" : "serialize", 
1979                                 (void *)id_add, nelem);
1980
1981         for (unsigned long i = 0; i < nelem; ++i)
1982         {
1983                 AnnotationClassBase *acb = NULL;
1984                 void *my_anno = NULL;
1985                 AnnotationClassID a_id = (AnnotationClassID) -1;
1986                 void *lparent_id = NULL;
1987                 sparse_or_dense_anno_t lsod = sparse;
1988
1989                 if (isOutput())
1990                 {
1991                         acb = sers[i].acb;
1992                         assert(acb);
1993                         a_id = acb->getID();
1994                         my_anno = sers[i].data;
1995                         lparent_id = sers[i].parent_id;
1996                         lsod = sers[i].sod;
1997                 }
1998
1999                 getSD().annotation_start(a_id, lparent_id, lsod, acb ? acb->getName().c_str() : NULL);
2000
2001                 if (isInput())
2002                 {
2003                         acb = AnnotationClassBase::findAnnotationClass(a_id);
2004
2005                         if (!acb)
2006                         {
2007                                 AnnotationClassBase::dumpAnnotationClasses();
2008                                 fprintf(stderr, "%s[%d]:  FIXME:  cannot find annotation class for id %d\n", 
2009                                                 FILE__, __LINE__, a_id);
2010                                 return;
2011                         }
2012                         else
2013                         {
2014                                 serialize_printf("%s[%d]:  got annotation type id=%d\n", 
2015                                                 FILE__, __LINE__, acb->getID());
2016                         }
2017
2018                         //  when deserializing, we need to allocate an object
2019                         //  of the type of the annotation before deserializing into it.
2020                         serialize_printf("%s[%d]:  before allocation\n", FILE__, __LINE__);
2021                         my_anno = acb->allocate();
2022                         assert(my_anno);
2023
2024                         ser_rec_t sr;
2025                         sr.data = my_anno;
2026                         sr.acb = acb;
2027                         sers.push_back(sr);
2028                         serialize_printf("%s[%d]:  created deserialize rec: %p/%p\n", 
2029                                         FILE__, __LINE__, my_anno, acb);
2030                 }
2031
2032                 ser_func_t sf = acb->getSerializeFunc();
2033
2034                 assert(sf);
2035                 assert(my_anno);
2036
2037                 //  execute the serialization function for this annotation
2038                 serialize_printf("%s[%d]:  calling serialize func for type %s\n", 
2039                                 FILE__, __LINE__, acb->getTypeName());
2040                 (*sf)(my_anno, this, tag);
2041
2042                 getSD().annotation_end();
2043         }
2044         getSD().annotation_list_end();
2045 }
2046
2047 namespace Dyninst {
2048
2049 void annotation_start(SerializerBase *sb, AnnotationClassID &a_id, 
2050                 void *&lparent_id, sparse_or_dense_anno_t &lsod, const char *)
2051 {
2052         sb->annotation_start(a_id, lparent_id, lsod, NULL);
2053         serialize_printf("%s[%d]:  leaving to annotation_start:  id = %d\n", 
2054                         FILE__, __LINE__, a_id);
2055 }
2056
2057 void annotation_end(SerializerBase *sb)
2058 {
2059         sb->annotation_end();
2060 }
2061
2062 void annotation_container_start(SerializerBase *sb, void *&id)
2063 {
2064         sb->annotation_container_start(id);
2065 }
2066
2067 void annotation_container_end(SerializerBase *sb)
2068 {
2069         sb->annotation_container_end();
2070 }
2071
2072 void annotation_container_item_start(SerializerBase *sb, void *&id)
2073 {
2074         sb->annotation_container_item_start(id);
2075 }
2076
2077 void annotation_container_item_end(SerializerBase *sb)
2078 {
2079         sb->annotation_container_item_end();
2080 }
2081
2082 void vector_start(SerializerBase *sb, unsigned long &nelem, const char *tag)
2083 {       
2084         sb->vector_start(nelem, tag);
2085 }
2086
2087 void vector_end(SerializerBase *sb)
2088 {
2089         sb->vector_end();
2090 }
2091
2092 AnnotationContainerBase * get_container(void *parent_id)
2093 {
2094         AnnotationContainerBase *cont =  AnnotationContainerBase::getContainer(parent_id);
2095         if (!cont)
2096         {
2097                 fprintf(stderr, "%s[%d]:  failed to find container with id %p\n", 
2098                                 FILE__, __LINE__, parent_id);
2099         }
2100         return cont;
2101 }
2102
2103 bool deserialize_container_item(AnnotationContainerBase *acb, SerializerBase *sb)
2104 {
2105         if (!acb->deserialize_item(sb))
2106         {
2107                 fprintf(stderr, "%s[%d]:  failed to deserialize container item\n", FILE__, __LINE__);
2108                 return false;
2109         }
2110         return true;
2111 }
2112
2113 bool deserialize_container_item(SerializerBase *sb, void *parent_id)
2114 {
2115         AnnotationContainerBase *cont =  AnnotationContainerBase::getContainer(parent_id);
2116         if (!cont)
2117         {
2118                 fprintf(stderr, "%s[%d]:  failed to find container with id %p\n", 
2119                                 FILE__, __LINE__, parent_id);
2120                 return false;
2121         }
2122
2123         if (!cont->deserialize_item(sb))
2124         {
2125                 fprintf(stderr, "%s[%d]:  failed to deserialize container item\n", 
2126                                 FILE__, __LINE__);
2127                 return false;
2128         }
2129         return true;
2130
2131 }
2132
2133 }
2134
2135 void SerializerBase::annotation_start(AnnotationClassID &a_id, 
2136                 void *&lparent_id, sparse_or_dense_anno_t &lsod, const char *)
2137 {
2138         getSD().annotation_start(a_id, lparent_id, lsod, NULL);
2139
2140         serialize_printf("%s[%d]:  leaving to annotation_start:  id = %d, ser_id = %d\n",
2141                         FILE__, __LINE__, a_id, ser_index);
2142 }
2143
2144 void SerializerBase::annotation_end()
2145 {
2146         getSD().annotation_end();
2147 }
2148
2149 void SerializerBase::annotation_container_start(void *&id)
2150 {
2151         getSD().annotation_container_start(id);
2152 }
2153
2154 void SerializerBase::annotation_container_end()
2155 {
2156         getSD().annotation_container_end();
2157 }
2158
2159 void SerializerBase::annotation_container_item_start(void *&id)
2160 {
2161         getSD().annotation_container_item_start(id);
2162 }
2163
2164 void SerializerBase::annotation_container_item_end()
2165 {
2166         getSD().annotation_container_item_end();
2167 }
2168
2169 void SerializerBase::magic_check(const char *file__, unsigned int line__)
2170 {
2171         getSD().magic_check(file__, line__);
2172 }
2173
2174 bool SerializerBase::serialize_post_annotation(void *parent_id, void *anno, 
2175                 AnnotationClassBase *acb, sparse_or_dense_anno_t sod, const char *tag)
2176 {
2177         serialize_printf("%s[%d]: serialize_post_annotation:  ser_id = %d, parent_id = %p\n", 
2178                         FILE__, __LINE__, ser_index, parent_id);
2179
2180         void *my_anno = NULL;
2181         AnnotationClassID a_id;
2182         sparse_or_dense_anno_t lsod = sod;
2183         void *lparent_id = parent_id;
2184
2185         if (isOutput())
2186         {
2187                 assert(acb);
2188                 a_id = acb->getID();
2189                 assert(anno);
2190                 my_anno = anno;
2191         }
2192
2193         getSD().annotation_start(a_id, lparent_id, lsod, acb ? acb->getName().c_str() : NULL);
2194
2195         if (isInput())
2196         {
2197                 acb = AnnotationClassBase::findAnnotationClass(a_id);
2198
2199                 if (!acb)
2200                 {
2201                         AnnotationClassBase::dumpAnnotationClasses();
2202                         fprintf(stderr, "%s[%d]:  FIXME:  cannot find annotation class for id %d\n", 
2203                                         FILE__, __LINE__, a_id);
2204                         return false;
2205                 }
2206                 else
2207                 {
2208                         fprintf(stderr, "%s[%d]:  got annotation type id=%d\n", 
2209                                         FILE__, __LINE__, acb->getID());
2210                 }
2211
2212                 //  when deserializing, we need to allocate an object
2213                 //  of the type of the annotation before deserializing into it.
2214                 my_anno = acb->allocate();
2215                 assert(my_anno);
2216                 //parent_id = lparent_id;
2217                 //sod = lsod;
2218         }
2219
2220         ser_func_t sf = acb->getSerializeFunc();
2221
2222         assert(sf);
2223         assert(my_anno);
2224
2225         //  execute the serialization function for this annotation
2226         serialize_printf("%s[%d]:  calling serialize func for type %s\n", 
2227                         FILE__, __LINE__, acb->getTypeName());
2228
2229         (*sf)(my_anno, this, tag);
2230
2231                 getSD().annotation_end();
2232
2233                 if (isInput())
2234                 {
2235                         //  we have the (void *) annotation and the annotation type
2236                         //  now lookup the object to which it belonged in the map of annotatable objects
2237                         //  and add it as an annotation.
2238
2239                         if (lsod == sparse)
2240                         {
2241                                 dyn_hash_map<void *, AnnotatableSparse *>::iterator iter;
2242                                 iter = sparse_annotatable_map->find(lparent_id);
2243                                 if (iter == sparse_annotatable_map->end())
2244                                 {
2245                                         fprintf(stderr, "%s[%d]:  ERROR:  cant find parent to assign anno to\n", 
2246                                                         FILE__, __LINE__);
2247                                 }
2248                                 else
2249                                 {
2250                                         AnnotatableSparse *as = iter->second;
2251                                         assert(as);
2252                                         assert(acb);
2253                                         fprintf(stderr, "%s[%d]:  readding post annotation\n", FILE__, __LINE__);
2254                                         if (!as->addAnnotation(my_anno, acb->getID()))
2255                                         {
2256                                                 fprintf(stderr, "%s[%d]:  ERROR:  failed to add annotation here\n", 
2257                                                                 FILE__, __LINE__);
2258                                         }
2259                                 }
2260                         }
2261                         else if (lsod == dense)
2262                         {
2263                                 dyn_hash_map<void *, AnnotatableDense *>::iterator iter;
2264                                 iter = dense_annotatable_map->find(lparent_id);
2265                                 if (iter == dense_annotatable_map->end())
2266                                 {
2267                                         fprintf(stderr, "%s[%d]:  ERROR:  cant find parent to assign anno to\n", 
2268                                                         FILE__, __LINE__);
2269                                 }
2270                                 else
2271                                 {
2272                                         AnnotatableDense *ad = iter->second;
2273                                         assert(ad);
2274                                         assert(acb);
2275                                         fprintf(stderr, "%s[%d]:  readding post annotation\n", FILE__, __LINE__);
2276                                         if (!ad->addAnnotation(my_anno, acb->getID()))
2277                                         {
2278                                                 fprintf(stderr, "%s[%d]:  ERROR:  failed to add annotation here\n", 
2279                                                                 FILE__, __LINE__);
2280                                         }
2281                                 }
2282                         }
2283                         else
2284                         {
2285                                 fprintf(stderr, "%s[%d]:  ERROR:  sparse/dense not set properly\n", 
2286                                                 FILE__, __LINE__);
2287                                 return false;
2288                         }
2289                 }
2290
2291                 return true;
2292 }
2293
2294 void SerializerBase::vector_start(unsigned long &size, const char *tag) 
2295 {
2296    getSD().vector_start(size, tag);
2297 }
2298
2299
2300 void SerializerBase::vector_end() 
2301 {
2302    getSD().vector_end();
2303 }
2304
2305 void SerializerBase::hash_map_start(unsigned long &size, const char *tag) 
2306 {
2307    getSD().hash_map_start(size, tag);
2308 }
2309
2310 void SerializerBase::hash_map_end() 
2311 {
2312    getSD().hash_map_end();
2313 }
2314
2315 void SerializerBase::multimap_start(unsigned long &size, const char *tag) 
2316 {
2317    getSD().multimap_start(size, tag);
2318 }
2319
2320 void SerializerBase::multimap_end() 
2321 {
2322    getSD().multimap_end();
2323 }
2324
2325 void SerializerBase::pair_start(const char *tag) 
2326 {
2327    getSD().pair_start(tag);
2328 }
2329
2330 SerDes &SerializerBase::getSD()
2331 {
2332         assert(sd);
2333         return *sd;
2334 }
2335
2336 SerFile &SerializerBase::getSF()
2337 {
2338         assert(sf);
2339         return *sf;
2340 }
2341
2342 void SerializerBase::pair_end() 
2343 {
2344    getSD().pair_end();
2345 }
2346
2347 void SerializerBase::translate_base(short &v, const char *&t)
2348 {
2349    getSD().translate(v, t);
2350 }
2351
2352 void SerializerBase::translate_base(unsigned short &v, const char *&t)
2353 {
2354    getSD().translate(v, t);
2355 }
2356
2357 void SerializerBase::translate_base(bool &v, const char *&t)
2358 {
2359    getSD().translate(v, t);
2360 }
2361
2362 void SerializerBase::translate_base(char &v, const char *&t)
2363 {
2364    getSD().translate(v, t);
2365 }
2366
2367 void SerializerBase::translate_base(int &v, const char *&t)
2368 {
2369    getSD().translate(v, t);
2370 }
2371
2372 void SerializerBase::translate_base(unsigned int &v, const char *&t)
2373 {
2374    getSD().translate(v, t);
2375 }
2376
2377 void SerializerBase::translate_base(long &v, const char *&t)
2378 {
2379    getSD().translate(v, t);
2380 }
2381
2382 void SerializerBase::translate_base(unsigned long &v, const char *&t)
2383 {
2384    getSD().translate(v, t);
2385 }
2386
2387 void SerializerBase::translate_base(float &v, const char *&t)
2388 {
2389    getSD().translate(v, t);
2390 }
2391
2392 void SerializerBase::translate_base(double &v, const char *&t)
2393 {
2394    getSD().translate(v, t);
2395 }
2396
2397 void SerializerBase::translate_base(const char *&v, int bufsize, const char *&t)
2398 {
2399    getSD().translate(v, bufsize, t);
2400 }
2401
2402 void SerializerBase::translate_base(char *&v, int bufsize, const char *&t)
2403 {
2404    getSD().translate(v, bufsize, t);
2405 }
2406
2407 void SerializerBase::translate_base(void *&v, const char *&t)
2408 {
2409    getSD().translate(v, t);
2410 }
2411
2412 void SerializerBase::translate_base(std::string &v, const char *t)
2413 {
2414    getSD().translate(v, t);
2415 }
2416