merge commit
[dyninst.git] / symtabAPI / src / Aggregate.C
1 /*
2  * Copyright (c) 1996-2007 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 "Annotatable.h"
33 #include "Serialization.h"
34 #include "common/h/serialize.h"
35
36 #include "Symtab.h"
37 #include "symutil.h"
38 #include "Module.h"
39 #include "Collections.h"
40
41 #include "Function.h"
42 #include "Variable.h"
43
44 #include "symtabAPI/src/Object.h"
45
46
47 #include "Aggregate.h"
48 #include "Symbol.h"
49
50 using namespace std;
51 using namespace Dyninst;
52 using namespace Dyninst::SymtabAPI;
53
54 Aggregate::Aggregate() :
55     module_(NULL)
56 {
57 }
58
59 Aggregate::Aggregate(Symbol *sym) :
60     module_(NULL)
61 {
62     assert(sym);
63     module_ = sym->getModule();
64     symbols_.push_back(sym);
65     mangledNames_.push_back(sym->getMangledName());
66     prettyNames_.push_back(sym->getPrettyName());
67     typedNames_.push_back(sym->getTypedName());
68 }
69
70
71 Offset Aggregate::getOffset() const 
72
73         return getFirstSymbol()->getOffset();
74 }
75
76 unsigned Aggregate::getSize() const 
77
78         return getFirstSymbol()->getSize(); 
79 }
80
81 Region * Aggregate::getRegion() const
82 {
83         return getFirstSymbol()->getRegion();
84 }
85
86 const vector<std::string> &Aggregate::getAllMangledNames() 
87 {
88     return mangledNames_;
89 }
90
91 const vector<std::string> &Aggregate::getAllPrettyNames() 
92 {
93     return prettyNames_;
94 }
95
96 const vector<std::string> &Aggregate::getAllTypedNames() 
97 {
98     return typedNames_;
99 }
100
101 bool Aggregate::addSymbol(Symbol *sym) {
102
103     // We keep a "primary" module, which is defined as "anything not DEFAULT_MODULE".
104     if (module_ == NULL) {
105         module_ = sym->getModule();
106     }
107     else if (module_->fileName() == "DEFAULT_MODULE") {
108         module_ = sym->getModule();
109     }
110     // else keep current module.
111
112     symbols_.push_back(sym);
113
114     // We need to add the symbol names (if they aren't there already)
115     // We can have multiple identical names - for example, there are
116     // often two symbols for main (static and dynamic symbol table)
117     
118     bool found = false;
119     for (unsigned j = 0; j < mangledNames_.size(); j++) {
120         if (sym->getMangledName() == mangledNames_[j]) {
121             found = true;
122             break;
123         }
124     }
125     if (!found) mangledNames_.push_back(sym->getMangledName());
126
127     found = false;
128
129     for (unsigned j = 0; j < prettyNames_.size(); j++) {
130         if (sym->getPrettyName() == prettyNames_[j]) {
131             found = true;
132             break;
133         }
134     }
135     if (!found) prettyNames_.push_back(sym->getPrettyName());
136
137     found = false;
138     for (unsigned j = 0; j < typedNames_.size(); j++) {
139         if (sym->getTypedName() == typedNames_[j]) {
140             found = true;
141             break;
142         }
143     }
144     if (!found) typedNames_.push_back(sym->getTypedName());;
145
146     return true;
147 }
148
149 bool Aggregate::removeSymbolInt(Symbol *sym) {
150     std::vector<Symbol *>::iterator iter;
151     for (iter = symbols_.begin(); iter != symbols_.end(); iter++) {
152         if ((*iter) == sym) {
153             symbols_.erase(iter);
154             break;
155         }
156     }
157     return true;
158 }
159
160 bool Aggregate::getSymbols(std::vector<Symbol *> &syms) const 
161 {
162     syms = symbols_;
163     return true;
164 }
165
166 Symbol * Aggregate::getFirstSymbol() const
167 {
168     assert( symbols_.size()>0 );
169     return symbols_[0];
170 }
171
172 SYMTAB_EXPORT bool Aggregate::addMangledName(string name, bool isPrimary) 
173  {
174     // Check to see if we're duplicating
175     for (unsigned i = 0; i < mangledNames_.size(); i++) {
176         if (mangledNames_[i] == name)
177             return false;
178     }
179
180     if (isPrimary) {
181         std::vector<std::string>::iterator iter = mangledNames_.begin();
182         mangledNames_.insert(iter, name);
183     }
184     else
185         mangledNames_.push_back(name);
186
187     if (addMangledNameInt(name, isPrimary) == false) return false;
188      return true;
189  }                                                                                                                                      
190  
191  SYMTAB_EXPORT bool Aggregate::addPrettyName(string name, bool isPrimary) 
192  {
193     // Check to see if we're duplicating
194     for (unsigned i = 0; i < prettyNames_.size(); i++) {
195         if (prettyNames_[i] == name)
196             return false;
197     }
198
199     if (isPrimary) {
200         std::vector<std::string>::iterator iter = prettyNames_.begin();
201         prettyNames_.insert(iter, name);
202     }
203     else
204         prettyNames_.push_back(name);
205     if (addPrettyNameInt(name, isPrimary) == false) return false;
206      return true;
207  }                                                                                                                                      
208  
209  SYMTAB_EXPORT bool Aggregate::addTypedName(string name, bool isPrimary) 
210  {
211     // Check to see if we're duplicating
212     for (unsigned i = 0; i < typedNames_.size(); i++) {
213         if (typedNames_[i] == name)
214             return false;
215     }
216     if (addTypedNameInt(name, isPrimary) == false) return false;
217
218     if (isPrimary) {
219         std::vector<std::string>::iterator iter = typedNames_.begin();
220         typedNames_.insert(iter, name);
221     }
222     else
223         typedNames_.push_back(name);
224         return true;
225  }
226
227 bool Aggregate::addMangledNameInt(string name, bool isPrimary) {
228     // Check to see if we're duplicating
229     for (unsigned i = 0; i < mangledNames_.size(); i++) {
230         if (mangledNames_[i] == name)
231             return false;
232     }
233
234     if (isPrimary) {
235         std::vector<std::string>::iterator iter = mangledNames_.begin();
236         mangledNames_.insert(iter, name);
237     }
238     else
239         mangledNames_.push_back(name);
240     return true;
241 }
242
243 bool Aggregate::addPrettyNameInt(string name, bool isPrimary) {
244     // Check to see if we're duplicating
245     for (unsigned i = 0; i < prettyNames_.size(); i++) {
246         if (prettyNames_[i] == name)
247             return false;
248     }
249
250     if (isPrimary) {
251         std::vector<std::string>::iterator iter = prettyNames_.begin();
252         prettyNames_.insert(iter, name);
253     }
254     else
255         prettyNames_.push_back(name);
256     return true;
257 }
258
259 bool Aggregate::addTypedNameInt(string name, bool isPrimary) {
260     // Check to see if we're duplicating
261     for (unsigned i = 0; i < typedNames_.size(); i++) {
262         if (typedNames_[i] == name)
263             return false;
264     }
265
266     if (isPrimary) {
267         std::vector<std::string>::iterator iter = typedNames_.begin();
268         typedNames_.insert(iter, name);
269     }
270     else
271         typedNames_.push_back(name);
272     return true;
273 }
274
275 bool Aggregate::changeSymbolOffset(Symbol *sym) 
276 {
277     Offset oldOffset = getOffset();
278
279     removeSymbolInt(sym);
280
281     if (symbols_.empty()) 
282         {
283         // This was the only one; so add it back in and update our address
284         // in the Symtab.
285         symbols_.push_back(sym);
286         module_->exec()->changeAggregateOffset(this, oldOffset, getOffset());
287     }
288     else 
289         {
290         module_->exec()->addSymbolToAggregates(sym);
291     }
292     return true;
293 }
294
295 void Aggregate::restore_type_by_id(SerializerBase *sb, Type *&t, 
296                 unsigned t_id) THROW_SPEC (SerializerError)
297 {
298         if (module_)
299         {
300                 typeCollection *tc = module_->getModuleTypesPrivate();
301                 if (tc)
302                 {
303                         t = tc->findType(t_id);
304                         if (!t)
305                         {
306                                 //fprintf(stderr, "%s[%d]: failed to find type in module(%s) collection\n", 
307                                 //              FILE__, __LINE__, module_->fileName().c_str());
308                         }
309                 }
310                 else
311                 {
312                         fprintf(stderr, "%s[%d]:  no types for module\n", FILE__, __LINE__);
313                 }
314         }
315         else
316         {
317                 fprintf(stderr, "%s[%d]:  bad deserialization order??\n", FILE__, __LINE__);
318                 //SER_ERR("FIXME");
319         }
320
321         if (!t)
322         {
323                 SerContextBase *scb = sb->getContext();
324                 if (!scb)
325                 {
326                         fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
327                         SER_ERR("FIXME");
328                 }
329
330                 SerContext<Symtab> *scs = dynamic_cast<SerContext<Symtab> *>(scb);
331
332                 if (!scs)
333                 {
334                         fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
335                         SER_ERR("FIXME");
336                 }
337
338                 Symtab *st = scs->getScope();
339 #if 0
340                 ScopedSerializerBase<Symtab> *ssb = dynamic_cast<ScopedSerializerBase<Symtab> *>(sb);
341
342                 if (!ssb)
343                 {
344                         fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
345                         SER_ERR("FIXME");
346                 }
347
348                 Symtab *st = ssb->getScope();
349 #endif
350
351                 if (!st)
352                 {
353                         fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
354                         SER_ERR("FIXME");
355                 }
356
357                 t = st->findType(t_id);
358
359                 if (!t)
360                 {
361                         //  This should probably throw, but let's play nice for now
362                         fprintf(stderr, "%s[%d]:  FIXME: cannot find type with id %d\n", FILE__, __LINE__, t_id);
363                         std::vector<Module *> mods;
364                         if (!st->getAllModules(mods))
365                         {
366                                 fprintf(stderr, "%s[%d]:  failed to get all modules\n", FILE__, __LINE__);
367                         }
368                         for (unsigned int i = 0; i < mods.size(); ++i)
369                         {
370                                 std::vector<Type *> *modtypes = mods[i]->getAllTypes();
371                                 fprintf(stderr, "%s[%d]:  module %s has %ld types\n", FILE__, __LINE__, mods[i]->fileName().c_str(), (unsigned long) modtypes ? modtypes->size() : -1);
372                                 if (mods[i]->getModuleTypesPrivate()->findType(t_id))
373                                         fprintf(stderr, "%s[%d]:  found type %d in mod %s\n", FILE__, __LINE__, t_id, mods[i]->fileName().c_str());
374                         }
375                 }
376         }
377 }
378
379 void Aggregate::restore_module_by_name(SerializerBase *sb,  
380                 std::string &mname) THROW_SPEC (SerializerError)
381 {
382
383         if (!sb)
384         {
385                 fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
386                 SER_ERR("FIXME");
387         }
388
389 #if 0
390         Dyninst::ScopedSerializerBase<Dyninst::SymtabAPI::Symtab> *ssb = dynamic_cast<Dyninst::ScopedSerializerBase<Dyninst::SymtabAPI::Symtab> *>(sb);
391
392         if (!ssb)
393         {
394                 fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME: %s\n", FILE__, __LINE__, typeid(sb).name());
395                 SER_ERR("FIXME");
396         }
397         Symtab *st = ssb->getScope();
398 #endif
399                 SerContextBase *scb = sb->getContext();
400                 if (!scb)
401                 {
402                         fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
403                         SER_ERR("FIXME");
404                 }
405
406                 SerContext<Symtab> *scs = dynamic_cast<SerContext<Symtab> *>(scb);
407
408                 if (!scs)
409                 {
410                         fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
411                         SER_ERR("FIXME");
412                 }
413
414                 Symtab *st = scs->getScope();
415
416
417         if (!st)
418         {
419                 fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
420                 SER_ERR("FIXME");
421         }
422
423         if (!st->findModuleByName(module_, mname) || !(module_))
424         {
425                 //  This should probably throw, but let's play nice for now
426                 fprintf(stderr, "%s[%d]:  FIXME: aggregate w/out module: %s\n", FILE__, __LINE__, mname.c_str());
427         }
428 }
429
430
431 extern Symbol * getSymForID(SerializerBase *sb, Address id);
432
433 void Aggregate::rebuild_symbol_vector(SerializerBase *sb, std::vector<Address> &symids) THROW_SPEC (SerializerError)
434 {
435         Offset off_accum = 0;
436         for (unsigned long i = 0; i < symids.size(); ++i)
437         {
438                 Symbol *sym = getSymForID(sb, symids[i]);
439                 if (!sym)
440                 {
441                         fprintf(stderr, "%s[%d]:  ERROR rebuilding aggregate: ", __FILE__, __LINE__);
442                         fprintf(stderr, "cannot find symbol for id %p\n", (void *) symids[i]);
443                         continue;
444                 }
445
446                 symbols_.push_back(sym);
447
448                 //  sanity check to make sure that all our symbols share the same offset
449                 if (serializer_debug_flag())
450                 {
451                         if (!off_accum) 
452                                 off_accum = sym->getOffset();
453                         else
454                         {
455                                 if (sym->getOffset() != off_accum)
456                                 {
457                                         fprintf(stderr, "%s[%d]:  INTERNAL ERROR:  mismatch offsets: %p--%p\n", FILE__, __LINE__, (void *)off_accum, (void *)sym->getOffset());
458                                 }
459                         }
460                 }
461
462                 //  This sucks, but apparently there are symbols that are somehow
463                 //  not getting their aggregate fields set properly (before serialize
464                 //  presumably), strangely only affects 64bit cases.  Here we try
465                 //  to correct for this by setting the aggregate values of all symbols
466                 //  at this Offset.  This lookup should be avoided by solving the problem
467                 //  somewhere else (at the source, wherever it is that the rogue symbols
468                 //  are being created and/or lost)
469                 //  
470                 //  Maybe it is also somehow possible that spurious symbols are being
471                 //  created and indexed during deserialize.
472                 SerContextBase *scb = sb->getContext();
473                 if (!scb)
474                 {
475                         fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
476                         SER_ERR("FIXME");
477                 }
478
479                 SerContext<Symtab> *scs = dynamic_cast<SerContext<Symtab> *>(scb);
480
481                 if (!scs)
482                 {
483                         fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
484                         SER_ERR("FIXME");
485                 }
486
487                 Symtab *st = scs->getScope();
488
489         if (!st)
490         {
491                 fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
492                 SER_ERR("FIXME");
493         }
494                 std::vector<Symbol *> *syms = st->findSymbolByOffset(sym->getOffset());
495                 for (unsigned long j = 0; j < syms->size(); ++j)
496                 {
497                         (*syms)[j]->aggregate_ = this;
498                 }
499 #if 0
500                 if (sym->aggregate_)
501                 {
502                         fprintf(stderr, "%s[%d]:  WARNING:  symbol %s already has aggregate!!\n", 
503                                         FILE__, __LINE__, sym->getName().c_str());
504                 }
505
506                 sym->aggregate_ = this;
507 #endif
508         }
509 }
510 #if 0
511 void Aggregate::rebuild_symbol_vector(SerializerBase *sb,  
512                 std::vector<Offset> *sym_offsets) THROW_SPEC (SerializerError)
513 {
514 #if 0
515         ScopedSerializerBase<Symtab> *ssb = dynamic_cast<ScopedSerializerBase<Symtab> *>(sb);
516
517         if (!ssb)
518         {
519                 //fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
520                 SER_ERR("FIXME");
521         }
522
523         Symtab *st = ssb->getScope();
524 #endif
525                 SerContextBase *scb = sb->getContext();
526                 if (!scb)
527                 {
528                         fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
529                         SER_ERR("FIXME");
530                 }
531
532                 SerContext<Symtab> *scs = dynamic_cast<SerContext<Symtab> *>(scb);
533
534                 if (!scs)
535                 {
536                         fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
537                         SER_ERR("FIXME");
538                 }
539
540                 Symtab *st = scs->getScope();
541
542         if (!st)
543         {
544                 fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
545                 SER_ERR("FIXME");
546         }
547
548         if (!sym_offsets)
549         {
550                 //  can't have any aggregates w/out symbols
551                 fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
552                 SER_ERR("FIXME");
553         }
554
555         if (!sym_offsets->size())
556         {
557                 //  can't have any aggregates w/out symbols
558                 fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
559                 SER_ERR("FIXME");
560         }
561
562         //symbols_.resize(sym_offsets->size());
563
564         for (unsigned int i = 0; i < sym_offsets->size(); ++i)
565         {
566                 std::vector<Symbol *> *syms = st->findSymbolByOffset((*sym_offsets)[i]);
567
568                 if (!syms)
569                 {
570                         //  Should throw here, but for now let's just scream
571                         fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
572                 }
573                 else
574                 {
575                         //  Not sure if we should interpret multiple symbols sharing that same offset
576                         //  as an error (probably not)
577 #if 0
578                         for (unsigned int i = 0; i < syms->size(); ++i)
579                         {
580                                 Symbol *s = (*syms)[i];
581                                 assert(s);
582                                 symbols_.push_back(s);
583                                 if (!s->aggregate_)
584                                 {
585                                         s->aggregate_ = this;
586                                 }
587                                 else
588                                 {
589                                         fprintf(stderr, "%s[%d]:  WARNING:  symbol %s already has aggregate!!\n", FILE__, __LINE__, s->getName().c_str());
590                                 }
591                         }
592 #endif
593                         //  This is annoying...  apparently we have several symbols for a given offset
594                         //  ...  while this might be theoretically OK, it's really probably a bug 
595                         //  somewhere else where we build up our indexes.
596                         if (syms->size())
597                         {
598                                 Symbol *s = (*syms)[0];
599                                 assert(s);
600                                 symbols_.push_back(s);
601                                 if (!s->aggregate_)
602                                 {
603                                         s->aggregate_ = this;
604                                 }
605                                 else
606                                 {
607                                         fprintf(stderr, "%s[%d]:  WARNING:  symbol %s already has aggregate!!\n", FILE__, __LINE__, s->getName().c_str());
608                                 }
609                         }
610                         if (syms->size() > 1)
611                         {
612                                 if (*(*syms)[0] == *(*syms)[1])
613                                 {
614                                         fprintf(stderr, "%s[%d]:  DESERIALIZE:  symbols are identical\n", FILE__, __LINE__);
615                                 }
616                                 else
617                                 {
618                                         fprintf(stderr, "%s[%d]:  DESERIALIZE:  symbols are not identical: sym0:\n", FILE__, __LINE__);
619                                         std::cerr << *((*syms)[0]) << std::endl;
620                                         std::cerr << "sym1:" << std::endl;
621                                         std::cerr << *((*syms)[1]) << std::endl;
622
623                                 }
624
625                         }
626                 }
627
628         }
629 }
630 #endif
631
632 std::ostream &operator<<(std::ostream &os, const Dyninst::SymtabAPI::Aggregate &a)
633 {
634         std::string modname = a.module_ ? a.module_->fullName() : std::string("no_mod");
635         os   << "Aggregate{"
636                 << " Module=" << modname
637                 << " MangledNames=["; 
638                 for (unsigned int i = 0; i < a.mangledNames_.size(); ++i)
639                 {
640                         os << a.mangledNames_[i];
641                         if ((i + 1) < a.mangledNames_.size())
642                                 os << ", ";
643                 }
644                 os << "]";
645
646                 os << " PrettyNames=["; 
647                 for (unsigned int i = 0; i < a.prettyNames_.size(); ++i)
648                 {
649                         os << a.prettyNames_[i];
650                         if ((i + 1) < a.prettyNames_.size())
651                                 os << ", ";
652                 }
653                 os << "]";
654
655                 os << " TypedNames=["; 
656                 for (unsigned int i = 0; i < a.typedNames_.size(); ++i)
657                 {
658                         os << a.typedNames_[i];
659                         if ((i + 1) < a.typedNames_.size())
660                                 os << ", ";
661                 }
662                 os << "]";
663                 os << " }";
664
665                 return os;
666 }
667
668 void Aggregate::serialize_aggregate(SerializerBase * sb, const char * tag) THROW_SPEC (SerializerError)
669 {
670         std::string modname = module_ ? module_->fullName() : std::string("");
671         std::vector<Address> symids;
672         for (unsigned long i = 0; i < symbols_.size(); ++i)
673         {
674                 assert(symbols_[i]);
675                 assert(sizeof(Address) == sizeof(void *));
676                 symids.push_back((Address) symbols_[i]);
677         }
678
679 #if 0
680         std::vector<Offset> sym_offsets;
681         sym_offsets.resize(symbols_.size());
682
683         //fprintf(stderr, "%s[%d]:  serialize_aggregate, module = %p\n", FILE__, __LINE__, module_);
684
685         for (unsigned int i = 0; i < symbols_.size(); ++i)
686         {
687                 assert(symbols_[i]);
688                 sym_offsets[i] = symbols_[i]->offset_;
689         }
690         fprintf(stderr, "%s[%d]:  serializing modname %s, with %ld symbols\n", FILE__, __LINE__, modname.c_str(), sym_offsets.size());
691 #endif
692
693         try
694         {
695                 ifxml_start_element(sb, tag);
696                 gtranslate(sb, modname, "moduleName");
697                 //  Arguably we should be able to reconstruct these name lists from the set of 
698                 //  symbols, right?  
699                 gtranslate(sb, mangledNames_, "mangledNameList");
700                 gtranslate(sb, prettyNames_, "prettyNameList");
701                 gtranslate(sb, typedNames_, "typedNameList");
702                 gtranslate(sb, symbols_, "aggregatedSymbols", "aggregateSymbol");
703 #if 0
704                 gtranslate(sb, sym_offsets, "symbolOffsetList");
705 #endif
706                 gtranslate(sb, symids, "symbolIDList");
707                 ifxml_end_element(sb, tag);
708
709                 if (sb->isBin() && sb->isInput())
710                 {
711                         restore_module_by_name(sb, modname);
712                         rebuild_symbol_vector(sb, symids);
713                 }
714
715 #if 0
716                 if (sb->isBin() && sb->isInput())
717                 {
718                         fprintf(stderr, "%s[%d]:  DESERIALIZE AGGREGATE %s, %lu offsets\n", FILE__, __LINE__, prettyNames_.size() ? prettyNames_[0].c_str() : "no_names", sym_offsets.size());
719                         rebuild_symbol_vector(sb, &sym_offsets);
720                 }
721 #endif
722         }
723         SER_CATCH(tag);
724
725         //fprintf(stderr, "%s[%d]:  serialize_aggregate, module = %p\n", FILE__, __LINE__, module_);
726 }
727
728 bool Aggregate::operator==(const Aggregate &a)
729 {
730         if (mangledNames_.size() != a.mangledNames_.size()) return false;
731         if (prettyNames_.size() != a.prettyNames_.size()) return false;
732         if (typedNames_.size() != a.typedNames_.size()) return false;
733         if (symbols_.size() != a.symbols_.size()) return false;
734         if (module_ && !a.module_) return false;
735         if (!module_ && a.module_) return false;
736         if (module_ && (module_->fullName() != a.module_->fullName())) return false;
737
738         for (unsigned int i = 0; i < mangledNames_.size(); ++i)
739         {
740                 if (mangledNames_[i] != a.mangledNames_[i]) return false;
741         }
742         for (unsigned int i = 0; i < prettyNames_.size(); ++i)
743         {
744                 if (prettyNames_[i] != a.prettyNames_[i]) return false;
745         }
746         for (unsigned int i = 0; i < typedNames_.size(); ++i)
747         {
748                 if (typedNames_[i] != a.typedNames_[i]) return false;
749         }
750         for (unsigned int i = 0; i < symbols_.size(); ++i)
751         {
752                 Symbol *s1 = symbols_[i];
753                 Symbol *s2 = a.symbols_[i];
754                 if (s1 && !s2) return false;
755                 if (!s1 && s2) return false;
756                 if (!s1)
757                         fprintf(stderr, "%s[%d]:  WARN:  NULL Symbol pointer here\n", FILE__, __LINE__);
758                 else
759                 {
760                         //  just compare offset and a couple other params
761                         if (s1->getOffset() != s2->getOffset()) return false;
762                         if (s1->getType() != s2->getType()) return false;
763                         if (s1->getSize() != s2->getSize()) return false;
764                 }
765         }
766
767         return true;
768 }