make variable and parameter lists annotations to class Symbol instead of class members
[dyninst.git] / symtabAPI / src / serialize.h
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 #ifndef __SERIALIZE__H__
33 #define __SERIALIZE__H__
34
35 #include <libxml/xmlwriter.h>
36 #include "common/h/headers.h"
37 #include "common/h/serialize.h"
38 #include "symtabAPI/h/Symtab.h"
39 #include "symtabAPI/h/LineInformation.h"
40 #include "symtabAPI/h/RangeLookup.h"
41
42 namespace Dyninst {
43 namespace SymtabAPI {
44 class SymtabTranslatorBase;
45
46 bool deserialize(Symtab &, SymtabTranslatorBase &);
47 bool serialize(Symtab &, SymtabTranslatorBase &);
48
49 class ExceptionBlock;
50 class relocationEntry;
51
52 class SymtabTranslatorBase {
53    public:
54       virtual void vector_start(unsigned int &size, const char *tag = NULL) {
55          getSD().vector_start(size, tag);
56       }
57
58       virtual void vector_end() {
59          getSD().vector_end();
60       }
61
62       iomode_t iomode() {return getSD().iomode();}
63
64       virtual void annotation_start(const char *string_id, const char *tag = NULL) {}
65       virtual void annotation_end() {}
66    protected:
67       Symtab *parent_symtab;
68
69       virtual SerDes &getSD() = 0;
70    private:
71
72       virtual void symbol_start(Symbol &, const char * = NULL) {}
73       virtual void symbol_end(Symbol &, const char * = NULL) {}
74       virtual void symtab_start(Symtab &, const char * = NULL) {}
75       virtual void symtab_end(Symtab &, const char * = NULL) {}
76       //virtual void region_end(Section &, const char * = NULL) {}
77       //virtual void region_start(Section &, const char * = NULL) {}
78       virtual void module_start(Module &, const char * = NULL) {}
79       virtual void module_end(Module &, const char * = NULL) {}
80       virtual void exception_start(ExceptionBlock &, const char * = NULL) {}
81       virtual void exception_end(ExceptionBlock &, const char * = NULL){}
82       virtual void relocation_start(relocationEntry &, const char * = NULL) {}
83       virtual void relocation_end(relocationEntry &, const char * = NULL) {}
84       virtual void line_information_start(LineInformation &, const char * = NULL) {}
85       virtual void line_information_end(LineInformation &, const char * = NULL) {}
86       virtual void type_collection_start(typeCollection &, const char * = NULL) {}
87       virtual void type_collection_end(typeCollection &, const char * = NULL) {}
88
89    public:
90       SymtabTranslatorBase(Symtab *parent_symtab_) :
91          parent_symtab(parent_symtab_)
92       {}
93       SymtabTranslatorBase(Symtab *parent_symtab_, bool doingInputFlag) :
94          parent_symtab(parent_symtab_)
95       {}
96       virtual ~SymtabTranslatorBase() {}
97
98       virtual bool translate_annotation(void *anno, const char *name) 
99       {
100 #if 0
101          annotation_start(name);
102          annotation_end();
103 #endif
104          return true;
105       }
106
107       virtual void translate(Symbol::SymbolType &param, const char *tag = NULL) = 0;
108       virtual void translate(Symbol::SymbolLinkage &param, const char *tag = NULL) = 0;
109       virtual void translate(Symbol::SymbolTag &param, const char *tag = NULL) = 0;
110       virtual void translate(supportedLanguages & param, const char *tag = NULL) = 0;
111
112       virtual void translate_base(LineInformation &param, const char * = NULL) {
113          try {
114             line_information_start(param);
115 #if 0
116             translate_hash_set<SymtabTranslatorBase, std::string>(this, param.sourceLineNames, "sourceLineNames");
117 #endif
118             line_information_end(param);
119          } SER_CATCH("LineInformation")
120       }
121
122       virtual void translate_base(typeCollection &param, const char * = NULL) {
123          try {
124             type_collection_start(param);
125             type_collection_end(param);
126          } SER_CATCH("typeCollection")
127       }
128
129       virtual void translate_base(Symbol &param, const char * = NULL) {
130          try {
131             symbol_start(param);
132             translate(param.type_, "type");
133             translate(param.linkage_, "linkage");
134             getSD().translate(param.addr_, "addr");
135             getSD().translate(param.size_, "size");
136             getSD().translate(param.isInDynsymtab_, "isInDynsymtab");
137             getSD().translate(param.isInSymtab_, "isInSymtab");
138             getSD().translate(param.prettyNames, "prettyNames", "prettyName");
139             getSD().translate(param.mangledNames, "mangledNames", "mangledName");
140             getSD().translate(param.typedNames, "typedNames", "typedName");
141 #if 0 // FIXME
142             translate(param.tag_, "tag");
143 #endif
144             getSD().translate(param.framePtrRegNum_, "framePtrRegNum");
145             //  Note:  have to deal with retType_ here?? Probably use type id.
146             getSD().translate(param.moduleName_, "moduleName");
147             symbol_end(param);
148          } SER_CATCH("Symbol")
149       }
150
151       virtual void translate_base(Symtab &param, const char * = NULL) {
152          try {
153             symtab_start(param);
154 #if 0
155             getSD().translate(param.filename_, "file");
156
157             fprintf(stderr, "%s[%d]:  %sserialize: file = %s\n", FILE__, __LINE__, 
158                   getSD().iomode() == sd_serialize ? "" : "de", 
159                   param.filename_.c_str());
160 #endif
161
162 #if 0
163             getSD().translate(param.codeOffset_, "codeOff");
164             getSD().translate(param.codePtrOffset_, "codePtrOff");
165             getSD().translate(param.codeLen_, "codeLen");
166             fprintf(stderr, "%s[%d]:  %sserialize: codeLen = %d\n", FILE__, __LINE__, 
167                   getSD().iomode() == sd_serialize ? "" : "de", 
168                   param.codeLen_);
169 #endif
170             //getSD().translate(param.codePtrOffset_, "codePtrOff");
171             getSD().translate(param.imageOffset_, "imageOffset");
172             getSD().translate(param.imageLen_, "imageLen");
173             getSD().translate(param.dataOffset_, "dataOff");
174             //getSD().translate(param.dataPtrOffset_, "dataPtrOff");
175             getSD().translate(param.dataLen_, "dataLen");
176             getSD().translate(param.is_a_out, "isExec");
177
178             translate_vector<SymtabTranslatorBase, Module>(this, param._mods, 
179                   "Modules");
180             //translate_vector<SymtabTranslatorBase, Section>(this, param.sections_, 
181              //     "Sections");
182             translate_vector<SymtabTranslatorBase, Symbol>(this, param.everyUniqueFunction, 
183                   "EveryUniqueFunction");
184             translate_vector<SymtabTranslatorBase, Symbol>(this, param.everyUniqueVariable, 
185                   "EveryUniqueVariable");
186             translate_vector<SymtabTranslatorBase, Symbol>(this, param.modSyms, 
187                   "ModuleSymbols");
188             translate_vector<SymtabTranslatorBase, ExceptionBlock>(this, param.excpBlocks, 
189                   "ExceptionBlocks");
190             //translate_vector<SymtabTranslatorBase, relocationEntry>(this, param.relocation_table, 
191             //      "RelocationEntries");
192
193             symtab_end(param);
194          } SER_CATCH("Symtab")
195       }
196
197       //  Migrate Section to "Region", I think
198 #if 0
199       virtual void translate_base(Section &param, const char * = NULL) {
200          try {
201             section_start(param);
202             getSD().translate(param.sidnumber_, "id");
203             getSD().translate(param.sname_, "name");
204             getSD().translate(param.saddr_, "addr");
205             getSD().translate(param.ssize_, "size");
206 #if 0
207             //  I think this was obsoleted??
208             getSD().translate(param.rawDataOffset_, "offset");
209 #endif
210             getSD().translate(param.sflags_, "flags");
211             section_end(param);
212          } SER_CATCH("Section")
213       }
214 #endif
215
216       virtual void translate_base(Module &param, const char * = NULL) {
217          try {
218             module_start(param);
219             getSD().translate(param.fileName_, "fileName");
220             getSD().translate(param.fullName_, "fullName");
221             getSD().translate(param.addr_, "Address");
222             translate(param.language_, "Language");
223             if (getSD().iomode() == sd_deserialize)
224                param.exec_ = parent_symtab;
225             module_end(param);
226          } SER_CATCH("Module")
227       }
228
229       virtual void translate_base(ExceptionBlock &param, const char * = NULL) {
230          try {
231             exception_start(param);
232             getSD().translate(param.tryStart_, "tryAddr");
233             getSD().translate(param.trySize_, "trySize");
234             getSD().translate(param.catchStart_, "catchAddr");
235             getSD().translate(param.hasTry_, "hasTry");
236             exception_end(param);
237          }SER_CATCH("ExceptionBlock")
238       }
239
240       virtual void translate_base(relocationEntry &param, const char * = NULL) {
241          try {
242             relocation_start(param);
243             getSD().translate(param.target_addr_, "targetAddr");
244             getSD().translate(param.rel_addr_, "relocationAddr");
245             getSD().translate(param.name_, "name");
246             relocation_end(param);
247          } SER_CATCH("relocationEntry")
248       }
249 };
250
251 class SymtabTranslatorXML : public SymtabTranslatorBase {
252    SerDesXML sd;
253    xmlTextWriterPtr writer;
254    public:
255    SerDes &getSD() {return sd;}
256    SymtabTranslatorXML(Symtab *st, string file);
257    virtual ~SymtabTranslatorXML() {}
258
259    private:
260    virtual void symtab_start(Symtab &, const char * = NULL);
261    virtual void symtab_end(Symtab &, const char * = NULL); 
262    virtual void symbol_start(Symbol &, const char * = NULL);
263    virtual void symbol_end(Symbol &, const char * = NULL);
264    virtual void exception_start(ExceptionBlock &, const char * = NULL);
265    virtual void exception_end(ExceptionBlock &, const char * = NULL);
266    virtual void relocation_start(relocationEntry &, const char * = NULL);
267    virtual void relocation_end(relocationEntry &, const char * = NULL);
268    virtual void module_start(Module &, const char * = NULL);
269    virtual void module_end(Module &, const char * = NULL);
270 #if 0
271    virtual void section_start(Section &, const char * = NULL);
272    virtual void section_end(Section &, const char * = NULL);
273 #endif
274    virtual void line_information_start(LineInformation &, const char * = NULL);
275    virtual void line_information_end(LineInformation &, const char * = NULL);
276    virtual void type_collection_start(typeCollection &, const char * = NULL);
277    virtual void type_collection_end(typeCollection &, const char * = NULL);
278
279    virtual void translate(Symbol::SymbolType &param, const char *tag = NULL);
280    virtual void translate(Symbol::SymbolLinkage &param, const char *tag = NULL);
281    virtual void translate(Symbol::SymbolTag &param, const char *tag = NULL);
282    virtual void translate(supportedLanguages &param, const char *tag = NULL);
283 };
284
285 class SymtabTranslatorBin : public SymtabTranslatorBase {
286    SerDesBin sd;
287
288    //  catch-all for modules without a home
289    //  (they should all have offset=NULL
290    Module *default_module;
291
292    public:
293    SerDes &getSD() {return sd;}
294    SymtabTranslatorBin(Symtab *st, string file, bool verbose = false); 
295    SymtabTranslatorBin(Symtab *st, string file, iomode_t iomode, bool verbose = false); 
296    virtual ~SymtabTranslatorBin();
297
298    private:
299    virtual void translate(Symbol::SymbolType &param, const char *tag = NULL); 
300    virtual void translate(Symbol::SymbolLinkage &param, const char *tag = NULL); 
301    virtual void translate(Symbol::SymbolTag &param, const char *tag = NULL); 
302    virtual void translate(supportedLanguages &param, const char *tag = NULL); 
303
304    virtual void symtab_start(Symtab &param, const char * = NULL);
305    virtual void symtab_end(Symtab &param, const char * = NULL);
306    virtual void symbol_end(Symbol &param, const char * = NULL); 
307
308 #if 0
309    virtual void line_information_start(LineInformation &, const char * = NULL);
310    virtual void line_information_end(LineInformation &, const char * = NULL);
311    virtual void type_collection_start(typeCollection &, const char * = NULL);
312    virtual void type_collection_end(typeCollection &, const char * = NULL);
313 #endif
314
315    //  Convenience functions called by symtab_end()...
316    //  For deserialization, once we have created all the basic arrays
317    //  of objects, we then need to do some extra work to re-create
318    //  hashes, indexes, auxilliary data, etc.  That's what these do.
319
320    void rebuild_section_hash(Symtab &param);
321    void rebuild_symbol_indexes(Symtab &param);
322    void translate_notype_syms(Symtab &param);
323
324 };
325
326 template<class S, class Value, class ValueLess>
327 void translate_range_lookup(S *ser, RangeLookup<Value, ValueLess> &rl, 
328       const char *tag, const char *key_tag, const char *value_tag)
329 {
330    ser->range_lookup_start(tag);
331    translate_multimap(rl.valuesByAddressRangeMap, "ValuesByAddress", "Address", "Value");
332    translate_multimap(rl.addressRangesByValueMap, "AddressRangesByValue", "Value", "AddressRange");
333    ser->range_lookup_end();
334 }
335
336 } // namespace symtabAPI
337 } // namespace Dyninst
338 #endif