1 /*
2   Copyright (C) 2010-2013 David Anderson.  All rights reserved.
3 
4   Redistribution and use in source and binary forms, with or without
5   modification, are permitted provided that the following conditions are met:
6   * Redistributions of source code must retain the above copyright
7     notice, this list of conditions and the following disclaimer.
8   * Redistributions in binary form must reproduce the above copyright
9     notice, this list of conditions and the following disclaimer in the
10     documentation and/or other materials provided with the distribution.
11   * Neither the name of the example nor the
12     names of its contributors may be used to endorse or promote products
13     derived from this software without specific prior written permission.
14 
15   THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY
16   EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18   DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY
19   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 */
27 
28 
29 //
30 // irepform.h
31 //
32 //
33 class IRCUdata;
34 class IRDie;
35 class IRAttr;
36 class IRFormInterface;
37 
38 // An Abstract class.
39 class IRForm {
40 public:
41     //virtual void emitvalue() = 0;
42     //IRForm & operator=(const IRForm &r);
43     virtual IRForm * clone() const  =0;
~IRForm()44     virtual ~IRForm() {};
IRForm()45     IRForm() {};
46     virtual enum Dwarf_Form_Class getFormClass() const = 0;
47 private:
48 };
49 
50 class IRFormUnknown : public IRForm {
51 public:
IRFormUnknown()52     IRFormUnknown():
53         finalform_(0), initialform_(0),
54         formclass_(DW_FORM_CLASS_UNKNOWN)
55         {}
~IRFormUnknown()56     ~IRFormUnknown() {};
57     IRFormUnknown(IRFormInterface *);
IRFormUnknown(const IRFormUnknown & r)58     IRFormUnknown(const IRFormUnknown &r) {
59         finalform_ = r.finalform_;
60         initialform_ = r.initialform_;
61         formclass_ = r.formclass_;
62     }
clone()63     virtual IRFormUnknown * clone() const {
64         return new IRFormUnknown(*this);
65     }
66     IRFormUnknown & operator=(const IRFormUnknown &r) {
67         if(this == &r) return *this;
68         finalform_ = r.finalform_;
69         initialform_ = r.initialform_;
70         formclass_ = r.formclass_;
71         return *this;
72     };
getFormClass()73     enum Dwarf_Form_Class getFormClass() const { return formclass_; };
74 private:
75     Dwarf_Half finalform_;
76     // In most cases directform == indirect form.
77     // Otherwise, directform == DW_FORM_indirect.
78     Dwarf_Half initialform_;
79     enum Dwarf_Form_Class formclass_;
80 };
81 // An address class entry refers to some part
82 // (normally a loadable) section of the object file.
83 // Not to DWARF info. Typically into .text or .data for example.
84 // We therefore want a section number and offset (generally useless for us)
85 // or preferably  an elf symbol as that has a value
86 // and an elf section number.
87 // We often/usually know neither here so we do not even try.
88 // Later we will make one up if we have to.
89 class IRFormAddress : public IRForm {
90 public:
IRFormAddress()91     IRFormAddress():
92         finalform_(0), initialform_(0),
93         formclass_(DW_FORM_CLASS_ADDRESS),
94         address_(0)
95         {};
96     IRFormAddress(IRFormInterface *);
~IRFormAddress()97     ~IRFormAddress() {};
98     IRFormAddress & operator=(const IRFormAddress &r) {
99         if(this == &r) return *this;
100         finalform_ = r.finalform_;
101         initialform_ = r.initialform_;
102         formclass_ = r.formclass_;
103         address_ = r.address_;
104         return *this;
105     };
IRFormAddress(const IRFormAddress & r)106     IRFormAddress(const IRFormAddress &r) {
107         finalform_ = r.finalform_;
108         initialform_ = r.initialform_;
109         formclass_ = r.formclass_;
110         address_ = r.address_;
111     }
clone()112     virtual IRFormAddress * clone() const {
113         return new IRFormAddress(*this);
114     };
setInitialForm(Dwarf_Half v)115     void setInitialForm(Dwarf_Half v) { initialform_ = v;}
setFinalForm(Dwarf_Half v)116     void setFinalForm(Dwarf_Half v) { finalform_ = v;}
getInitialForm()117     Dwarf_Half getInitialForm() { return initialform_;}
getFinalForm()118     Dwarf_Half getFinalForm() {return finalform_;}
getAddress()119     Dwarf_Addr  getAddress() { return address_;};
getFormClass()120     enum Dwarf_Form_Class getFormClass() const { return formclass_; };
121 private:
setAddress(Dwarf_Addr addr)122     void setAddress(Dwarf_Addr addr) { address_ = addr; };
123     Dwarf_Half finalform_;
124     // In most cases directform == indirect form.
125     // Otherwise, directform == DW_FORM_indirect.
126     Dwarf_Half initialform_;
127     enum Dwarf_Form_Class formclass_;
128     Dwarf_Addr address_;
129 };
130 class IRFormBlock : public IRForm {
131 public:
IRFormBlock()132     IRFormBlock():
133         finalform_(0), initialform_(0),
134         formclass_(DW_FORM_CLASS_BLOCK),
135         fromloclist_(0),sectionoffset_(0)
136         {}
137     IRFormBlock(IRFormInterface *);
~IRFormBlock()138     ~IRFormBlock() {};
139     IRFormBlock & operator=(const IRFormBlock &r) {
140         if(this == &r) return *this;
141         finalform_ = r.finalform_;
142         initialform_ = r.initialform_;
143         formclass_ = r.formclass_;
144         blockdata_ = r.blockdata_;
145         fromloclist_ = r.fromloclist_;
146         sectionoffset_ = r.sectionoffset_;
147         return *this;
148     };
IRFormBlock(const IRFormBlock & r)149     IRFormBlock(const IRFormBlock &r) {
150         finalform_ = r.finalform_;
151         initialform_ = r.initialform_;
152         formclass_ = r.formclass_;
153         blockdata_ = r.blockdata_;
154         fromloclist_ = r.fromloclist_;
155         sectionoffset_ = r.sectionoffset_;
156     }
clone()157     virtual IRFormBlock * clone() const {
158         return new IRFormBlock(*this);
159     }
setInitialForm(Dwarf_Half v)160     void setInitialForm(Dwarf_Half v) { initialform_ = v;}
setFinalForm(Dwarf_Half v)161     void setFinalForm(Dwarf_Half v) { finalform_ = v;}
getInitialForm()162     Dwarf_Half getInitialForm() { return initialform_;}
getFinalForm()163     Dwarf_Half getFinalForm() {return finalform_;}
164 
getFormClass()165     enum Dwarf_Form_Class getFormClass() const { return formclass_; };
166 private:
167     Dwarf_Half finalform_;
168     // In most cases directform == indirect form.
169     // Otherwise, directform == DW_FORM_indirect.
170     Dwarf_Half initialform_;
171     enum Dwarf_Form_Class formclass_;
172     std::vector<char> blockdata_;
173     Dwarf_Small fromloclist_;
174     Dwarf_Unsigned sectionoffset_;
175 
insertBlock(Dwarf_Block * bl)176     void insertBlock(Dwarf_Block *bl) {
177         char *d = static_cast<char *>(bl->bl_data);
178         Dwarf_Unsigned len = bl->bl_len;
179         blockdata_.clear();
180         blockdata_.insert(blockdata_.end(),d+0,d+len);
181         fromloclist_ = bl->bl_from_loclist;
182         sectionoffset_ = bl->bl_section_offset;
183     };
184 };
185 class IRFormConstant : public IRForm {
186 public:
187     enum Signedness {SIGN_NOT_SET,SIGN_UNKNOWN,UNSIGNED, SIGNED };
IRFormConstant()188     IRFormConstant():
189         finalform_(0), initialform_(0),
190         formclass_(DW_FORM_CLASS_CONSTANT),
191         signedness_(SIGN_NOT_SET),
192         uval_(0), sval_(0)
193         {}
194     IRFormConstant(IRFormInterface *);
~IRFormConstant()195     ~IRFormConstant() {};
IRFormConstant(Dwarf_Half finalform,Dwarf_Half initialform,enum Dwarf_Form_Class formclass,IRFormConstant::Signedness signedness,Dwarf_Unsigned uval,Dwarf_Signed sval)196     IRFormConstant(Dwarf_Half finalform,
197         Dwarf_Half initialform,
198         enum Dwarf_Form_Class formclass,
199         IRFormConstant::Signedness signedness,
200         Dwarf_Unsigned uval,
201         Dwarf_Signed sval) {
202         finalform_ = finalform;
203         initialform_ = initialform;
204         formclass_ = formclass;
205         signedness_ = signedness;
206         uval_ = uval;
207         sval_ = sval;
208     };
209     IRFormConstant & operator=(const IRFormConstant &r) {
210         if(this == &r) return *this;
211         finalform_ = r.finalform_;
212         initialform_ = r.initialform_;
213         formclass_ = r.formclass_;
214         signedness_ = r.signedness_;
215         uval_ = r.uval_;
216         sval_ = r.sval_;
217         return *this;
218     };
IRFormConstant(const IRFormConstant & r)219     IRFormConstant(const IRFormConstant &r) {
220         finalform_ = r.finalform_;
221         initialform_ = r.initialform_;
222         formclass_ = r.formclass_;
223         signedness_ = r.signedness_;
224         uval_ = r.uval_;
225         sval_ = r.sval_;
226     }
clone()227     virtual IRFormConstant * clone() const {
228         return new IRFormConstant(*this);
229     }
setInitialForm(Dwarf_Half v)230     void setInitialForm(Dwarf_Half v) { initialform_ = v;}
setFinalForm(Dwarf_Half v)231     void setFinalForm(Dwarf_Half v) { finalform_ = v;}
getInitialForm()232     Dwarf_Half getInitialForm() { return initialform_;}
getFinalForm()233     Dwarf_Half getFinalForm() {return finalform_;}
getFormClass()234     Dwarf_Form_Class getFormClass() const { return formclass_; };
getSignedness()235     Signedness getSignedness() const {return signedness_; };
getSignedVal()236     Dwarf_Signed getSignedVal() const {return sval_;};
getUnsignedVal()237     Dwarf_Unsigned getUnsignedVal() const {return uval_;};
238 private:
239     Dwarf_Half finalform_;
240     // In most cases directform == indirect form.
241     // Otherwise, directform == DW_FORM_indirect.
242     Dwarf_Half initialform_;
243     enum Dwarf_Form_Class formclass_;
244     // Starts at SIGN_NOT_SET.
245     // SIGN_UNKNOWN means it was a DW_FORM_data* of some
246     // kind so we do not really know.
247     Signedness signedness_;
248     // Both uval_ and sval_ are always set to the same bits.
249     Dwarf_Unsigned uval_;
250     Dwarf_Signed sval_;
251 
setValues(Dwarf_Signed sval,Dwarf_Unsigned uval,enum Signedness s)252     void setValues(Dwarf_Signed sval, Dwarf_Unsigned uval,
253         enum Signedness s) {
254         signedness_ = s;
255         uval_ = uval;
256         sval_ = sval;
257     }
258 };
259 
260 class IRFormExprloc : public IRForm {
261 public:
IRFormExprloc()262     IRFormExprloc():
263         finalform_(0), initialform_(0),
264         formclass_(DW_FORM_CLASS_EXPRLOC)
265         {};
266     IRFormExprloc(IRFormInterface *);
~IRFormExprloc()267     ~IRFormExprloc() {};
268     IRFormExprloc & operator=(const IRFormExprloc &r) {
269         if(this == &r) return *this;
270         finalform_ = r.finalform_;
271         initialform_ = r.initialform_;
272         formclass_ = r.formclass_;
273         exprlocdata_ = r.exprlocdata_;
274         return *this;
275     };
IRFormExprloc(const IRFormExprloc & r)276     IRFormExprloc(const IRFormExprloc &r) {
277         finalform_ = r.finalform_;
278         initialform_ = r.initialform_;
279         formclass_ = r.formclass_;
280         exprlocdata_ = r.exprlocdata_;
281 
282     }
clone()283     virtual IRFormExprloc * clone() const {
284         return new IRFormExprloc(*this);
285     }
setInitialForm(Dwarf_Half v)286     void setInitialForm(Dwarf_Half v) { initialform_ = v;}
setFinalForm(Dwarf_Half v)287     void setFinalForm(Dwarf_Half v) { finalform_ = v;}
getInitialForm()288     Dwarf_Half getInitialForm() { return initialform_;}
getFinalForm()289     Dwarf_Half getFinalForm() {return finalform_;}
getFormClass()290     enum Dwarf_Form_Class getFormClass() const { return formclass_; };
291 private:
292     Dwarf_Half finalform_;
293     // In most cases directform == indirect form.
294     // Otherwise, directform == DW_FORM_indirect.
295     Dwarf_Half initialform_;
296     enum Dwarf_Form_Class formclass_;
297     std::vector<char> exprlocdata_;
insertBlock(Dwarf_Unsigned len,Dwarf_Ptr data)298     void insertBlock(Dwarf_Unsigned len, Dwarf_Ptr data) {
299         char *d = static_cast<char *>(data);
300         exprlocdata_.clear();
301         exprlocdata_.insert(exprlocdata_.end(),d+0,d+len);
302     };
303 };
304 
305 
306 class IRFormFlag : public IRForm {
307 public:
IRFormFlag()308     IRFormFlag():
309         initialform_(0),
310         finalform_(0),
311         formclass_(DW_FORM_CLASS_FLAG),
312         flagval_(0)
313         {};
314     IRFormFlag(IRFormInterface*);
~IRFormFlag()315     ~IRFormFlag() {};
316     IRFormFlag & operator=(const IRFormFlag &r) {
317         if(this == &r) return *this;
318         initialform_ = r.initialform_;
319         finalform_ = r.finalform_;
320         formclass_ = r.formclass_;
321         flagval_ = r.flagval_;
322         return *this;
323     };
IRFormFlag(const IRFormFlag & r)324     IRFormFlag(const IRFormFlag &r) {
325         initialform_ = r.initialform_;
326         finalform_ = r.finalform_;
327         formclass_ = r.formclass_;
328         flagval_ = r.flagval_;
329     }
clone()330     virtual IRFormFlag * clone() const {
331         return new IRFormFlag(*this);
332     }
getFormClass()333     enum Dwarf_Form_Class getFormClass() const { return formclass_; };
setInitialForm(Dwarf_Half v)334     void setInitialForm(Dwarf_Half v) { initialform_ = v;}
setFinalForm(Dwarf_Half v)335     void setFinalForm(Dwarf_Half v) { finalform_ = v;}
getInitialForm()336     Dwarf_Half getInitialForm() { return initialform_;}
getFinalForm()337     Dwarf_Half getFinalForm() {return finalform_;}
setFlagVal(Dwarf_Bool v)338     void setFlagVal(Dwarf_Bool v) { flagval_ = v;}
getFlagVal()339     Dwarf_Bool getFlagVal() { return flagval_; }
340 private:
341     Dwarf_Half initialform_;
342     // In most cases initialform_ == finalform_.
343     // Otherwise, initialform == DW_FORM_indirect.
344     Dwarf_Half finalform_;
345     enum Dwarf_Form_Class formclass_;
346     Dwarf_Bool flagval_;
347 };
348 
349 
350 class IRFormLinePtr : public IRForm {
351 public:
IRFormLinePtr()352     IRFormLinePtr():
353         finalform_(0), initialform_(0),
354         formclass_(DW_FORM_CLASS_LINEPTR),
355         debug_line_offset_(0)
356         {};
357     IRFormLinePtr(IRFormInterface *);
~IRFormLinePtr()358     ~IRFormLinePtr() {};
359     IRFormLinePtr & operator=(const IRFormLinePtr &r) {
360         if(this == &r) return *this;
361         finalform_ = r.finalform_;
362         initialform_ = r.initialform_;
363         formclass_ = r.formclass_;
364         debug_line_offset_ = r.debug_line_offset_;
365         return *this;
366     };
IRFormLinePtr(const IRFormLinePtr & r)367     IRFormLinePtr(const IRFormLinePtr &r) {
368         finalform_ = r.finalform_;
369         initialform_ = r.initialform_;
370         formclass_ = r.formclass_;
371         debug_line_offset_ = r.debug_line_offset_;
372     }
setInitialForm(Dwarf_Half v)373     void setInitialForm(Dwarf_Half v) { initialform_ = v;}
setFinalForm(Dwarf_Half v)374     void setFinalForm(Dwarf_Half v) { finalform_ = v;}
getInitialForm()375     Dwarf_Half getInitialForm() { return initialform_;}
getFinalForm(void)376     Dwarf_Half getFinalForm(void) {return finalform_; }
clone()377     virtual IRFormLinePtr * clone() const {
378         return new IRFormLinePtr(*this);
379     }
getFormClass()380     enum Dwarf_Form_Class getFormClass() const { return formclass_; };
381 private:
382     Dwarf_Half finalform_;
383     // In most cases directform == indirect form.
384     // Otherwise, directform == DW_FORM_indirect.
385     Dwarf_Half initialform_;
386     enum Dwarf_Form_Class formclass_;
387     Dwarf_Off debug_line_offset_;
388 
setOffset(Dwarf_Unsigned uval)389     void setOffset(Dwarf_Unsigned uval) {
390         debug_line_offset_ = uval;
391     };
392 };
393 
394 
395 class IRFormLoclistPtr : public IRForm {
396 public:
IRFormLoclistPtr()397     IRFormLoclistPtr():
398         finalform_(0), initialform_(0),
399         formclass_(DW_FORM_CLASS_LOCLISTPTR),
400         loclist_offset_(0)
401         {};
402     IRFormLoclistPtr(IRFormInterface *);
~IRFormLoclistPtr()403     ~IRFormLoclistPtr() {};
404     IRFormLoclistPtr & operator=(const IRFormLoclistPtr &r) {
405         if(this == &r) return *this;
406         finalform_ = r.finalform_;
407         initialform_ = r.initialform_;
408         formclass_ = r.formclass_;
409         loclist_offset_ = r.loclist_offset_;
410         return *this;
411     };
IRFormLoclistPtr(const IRFormLoclistPtr & r)412     IRFormLoclistPtr(const IRFormLoclistPtr &r) {
413         finalform_ = r.finalform_;
414         initialform_ = r.initialform_;
415         formclass_ = r.formclass_;
416         loclist_offset_ = r.loclist_offset_;
417     }
clone()418     virtual IRFormLoclistPtr * clone() const {
419         return new IRFormLoclistPtr(*this);
420     }
setInitialForm(Dwarf_Half v)421     void setInitialForm(Dwarf_Half v) { initialform_ = v;}
setFinalForm(Dwarf_Half v)422     void setFinalForm(Dwarf_Half v) { finalform_ = v;}
getInitialForm()423     Dwarf_Half getInitialForm() { return initialform_;}
getFinalForm()424     Dwarf_Half getFinalForm() {return finalform_;}
getFormClass()425     enum Dwarf_Form_Class getFormClass() const { return formclass_; };
426 private:
427     Dwarf_Half finalform_;
428     // In most cases directform == indirect form.
429     // Otherwise, directform == DW_FORM_indirect.
430     Dwarf_Half initialform_;
431     enum Dwarf_Form_Class formclass_;
432     Dwarf_Off loclist_offset_;
433 
setOffset(Dwarf_Unsigned uval)434     void setOffset(Dwarf_Unsigned uval) {
435         loclist_offset_ = uval;
436     };
437 };
438 
439 
440 class IRFormMacPtr : public IRForm {
441 public:
IRFormMacPtr()442     IRFormMacPtr():
443         finalform_(0), initialform_(0),
444         formclass_(DW_FORM_CLASS_MACPTR),
445         macro_offset_(0)
446         {};
447     IRFormMacPtr(IRFormInterface *);
~IRFormMacPtr()448     ~IRFormMacPtr() {};
449     IRFormMacPtr & operator=(const IRFormMacPtr &r) {
450         if(this == &r) return *this;
451         finalform_ = r.finalform_;
452         initialform_ = r.initialform_;
453         formclass_ = r.formclass_;
454         macro_offset_ = r.macro_offset_;
455         return *this;
456     };
IRFormMacPtr(const IRFormMacPtr & r)457     IRFormMacPtr(const IRFormMacPtr &r) {
458         finalform_ = r.finalform_;
459         initialform_ = r.initialform_;
460         formclass_ = r.formclass_;
461         macro_offset_ = r.macro_offset_;
462     }
clone()463     virtual IRFormMacPtr * clone() const {
464         return new IRFormMacPtr(*this);
465     }
setInitialForm(Dwarf_Half v)466     void setInitialForm(Dwarf_Half v) { initialform_ = v;}
setFinalForm(Dwarf_Half v)467     void setFinalForm(Dwarf_Half v) { finalform_ = v;}
getInitialForm()468     Dwarf_Half getInitialForm() { return initialform_;}
getFinalForm()469     Dwarf_Half getFinalForm() {return finalform_;}
getFormClass()470     enum Dwarf_Form_Class getFormClass() const { return formclass_; };
471 private:
472     Dwarf_Half finalform_;
473     // In most cases directform == indirect form.
474     // Otherwise, directform == DW_FORM_indirect.
475     Dwarf_Half initialform_;
476     enum Dwarf_Form_Class formclass_;
477     Dwarf_Off macro_offset_;
478 
setOffset(Dwarf_Unsigned uval)479     void setOffset(Dwarf_Unsigned uval) {
480         macro_offset_ = uval;
481     };
482 };
483 
484 
485 class IRFormRangelistPtr : public IRForm {
486 public:
IRFormRangelistPtr()487     IRFormRangelistPtr():
488         finalform_(0), initialform_(0),
489         formclass_(DW_FORM_CLASS_RANGELISTPTR),
490         rangelist_offset_(0)
491         {};
492     IRFormRangelistPtr(IRFormInterface *);
~IRFormRangelistPtr()493     ~IRFormRangelistPtr() {};
494     IRFormRangelistPtr & operator=(const IRFormRangelistPtr &r) {
495         if(this == &r) return *this;
496         finalform_ = r.finalform_;
497         initialform_ = r.initialform_;
498         formclass_ = r.formclass_;
499         rangelist_offset_ = r.rangelist_offset_;
500         return *this;
501     };
IRFormRangelistPtr(const IRFormRangelistPtr & r)502     IRFormRangelistPtr(const IRFormRangelistPtr &r) {
503         finalform_ = r.finalform_;
504         initialform_ = r.initialform_;
505         formclass_ = r.formclass_;
506         rangelist_offset_ = r.rangelist_offset_;
507     }
setInitialForm(Dwarf_Half v)508     void setInitialForm(Dwarf_Half v) { initialform_ = v;}
setFinalForm(Dwarf_Half v)509     void setFinalForm(Dwarf_Half v) { finalform_ = v;}
getInitialForm()510     Dwarf_Half getInitialForm() { return initialform_;}
getFinalForm()511     Dwarf_Half getFinalForm() {return finalform_;}
clone()512     virtual IRFormRangelistPtr * clone() const {
513         return new IRFormRangelistPtr(*this);
514     }
getFormClass()515     enum Dwarf_Form_Class getFormClass() const { return formclass_; };
516 private:
517     Dwarf_Half finalform_;
518     // In most cases directform == indirect form.
519     // Otherwise, directform == DW_FORM_indirect.
520     Dwarf_Half initialform_;
521     enum Dwarf_Form_Class formclass_;
522     Dwarf_Off rangelist_offset_;
523 
setOffset(Dwarf_Unsigned uval)524     void setOffset(Dwarf_Unsigned uval) {
525         rangelist_offset_ = uval;
526     };
527 };
528 
529 class IRFormFramePtr : public IRForm {
530 public:
IRFormFramePtr()531     IRFormFramePtr():
532         finalform_(0), initialform_(0),
533         formclass_(DW_FORM_CLASS_FRAMEPTR),
534         frame_offset_(0)
535         {};
536     IRFormFramePtr(IRFormInterface *);
~IRFormFramePtr()537     ~IRFormFramePtr() {};
538     IRFormFramePtr & operator=(const IRFormFramePtr &r) {
539         if(this == &r) return *this;
540         finalform_ = r.finalform_;
541         initialform_ = r.initialform_;
542         formclass_ = r.formclass_;
543         frame_offset_ = r.frame_offset_;
544         return *this;
545     };
IRFormFramePtr(const IRFormFramePtr & r)546     IRFormFramePtr(const IRFormFramePtr &r) {
547         finalform_ = r.finalform_;
548         initialform_ = r.initialform_;
549         formclass_ = r.formclass_;
550         frame_offset_ = r.frame_offset_;
551     }
clone()552     virtual IRFormFramePtr * clone() const {
553         return new IRFormFramePtr(*this);
554     }
setInitialForm(Dwarf_Half v)555     void setInitialForm(Dwarf_Half v) { initialform_ = v;}
setFinalForm(Dwarf_Half v)556     void setFinalForm(Dwarf_Half v) { finalform_ = v;}
getInitialForm()557     Dwarf_Half getInitialForm() { return initialform_;}
getFinalForm()558     Dwarf_Half getFinalForm() {return finalform_;}
getFormClass()559     enum Dwarf_Form_Class getFormClass() const { return formclass_; };
560 private:
561     Dwarf_Half finalform_;
562     // In most cases directform == indirect form.
563     // Otherwise, directform == DW_FORM_indirect.
564     Dwarf_Half initialform_;
565     enum Dwarf_Form_Class formclass_;
566     Dwarf_Off frame_offset_;
567 
setOffset(Dwarf_Unsigned uval)568     void setOffset(Dwarf_Unsigned uval) {
569         frame_offset_ = uval;
570     };
571 };
572 
573 
574 
575 class IRFormReference : public IRForm {
576 public:
IRFormReference()577     IRFormReference():
578         finalform_(0), initialform_(0),
579         formclass_(DW_FORM_CLASS_REFERENCE),
580         reftype_(RT_NONE),
581         globalOffset_(0),cuRelativeOffset_(0),
582         targetInputDie_(0),
583         target_die_(0)
584         {initSig8();};
585     IRFormReference(IRFormInterface *);
~IRFormReference()586     ~IRFormReference() {};
587     IRFormReference & operator=(const IRFormReference &r) {
588         if(this == &r) return *this;
589         finalform_ = r.finalform_;
590         initialform_ = r.initialform_;
591         formclass_ = r.formclass_;
592         reftype_ = r.reftype_;
593         globalOffset_ = r.globalOffset_;
594         cuRelativeOffset_ = r.cuRelativeOffset_;
595         typeSig8_ = r.typeSig8_;
596         targetInputDie_ = r.targetInputDie_;
597         target_die_ = r.target_die_;
598         return *this;
599     };
IRFormReference(const IRFormReference & r)600     IRFormReference(const IRFormReference &r) {
601         finalform_ = r.finalform_;
602         initialform_ = r.initialform_;
603         formclass_ = r.formclass_;
604         reftype_ = r.reftype_;
605         globalOffset_ = r.globalOffset_;
606         cuRelativeOffset_ = r.cuRelativeOffset_;
607         typeSig8_ = r.typeSig8_;
608         targetInputDie_ = r.targetInputDie_;
609         target_die_ = r.target_die_;
610     }
clone()611     virtual IRFormReference * clone() const {
612         return new IRFormReference(*this);
613     }
setInitialForm(Dwarf_Half v)614     void setInitialForm(Dwarf_Half v) { initialform_ = v;}
setFinalForm(Dwarf_Half v)615     void setFinalForm(Dwarf_Half v) { finalform_ = v;}
getInitialForm()616     Dwarf_Half getInitialForm() { return initialform_;}
getFinalForm()617     Dwarf_Half getFinalForm() {return finalform_;}
setOffset(Dwarf_Off off)618     void setOffset(Dwarf_Off off) { globalOffset_ = off;
619         reftype_ = RT_GLOBAL;};
setCUOffset(Dwarf_Off off)620     void setCUOffset(Dwarf_Off off) { cuRelativeOffset_= off;
621         reftype_ = RT_CUREL;};
setSignature(Dwarf_Sig8 * sig)622     void setSignature(Dwarf_Sig8 * sig) { typeSig8_ = *sig;
623         reftype_ = RT_SIG;};
getSignature()624     const Dwarf_Sig8 *getSignature() { return &typeSig8_;};
getFormClass()625     enum Dwarf_Form_Class getFormClass() const { return formclass_; };
626     enum RefType { RT_NONE,RT_GLOBAL, RT_CUREL,RT_SIG };
getReferenceType()627     enum RefType getReferenceType() { return reftype_;};
getTargetGenDie()628     Dwarf_P_Die getTargetGenDie() { return target_die_;};
getTargetInDie()629     IRDie * getTargetInDie() { return targetInputDie_;};
setTargetGenDie(Dwarf_P_Die targ)630     void setTargetGenDie(Dwarf_P_Die targ) { target_die_ = targ; };
setTargetInDie(IRDie * targ)631     void setTargetInDie(IRDie* targ) { targetInputDie_ = targ; };
632 
633 private:
634     void initSig8();
635 
636     Dwarf_Half finalform_;
637     // In most cases directform == indirect form.
638     // Otherwise, directform == DW_FORM_indirect.
639     Dwarf_Half initialform_;
640     enum Dwarf_Form_Class formclass_;
641     enum RefType reftype_;
642 
643     // gobalOffset_ on input target set if and only if RT_GLOBAL
644     Dwarf_Off globalOffset_;
645     // cuRelativeOffset_  on input targetset if and only if RT_CUREL
646     Dwarf_Off cuRelativeOffset_;
647     // typeSig8_ on input target set if and only if RT_SIG
648     Dwarf_Sig8 typeSig8_;
649 
650     // For RT_SIG we do not need extra data.
651     // For RT_CUREL and RT_GLOBAL we do.
652 
653     // For RT_CUREL.  Points at the target input DIE
654     // after all input DIEs set up for a CU .
655     IRDie * targetInputDie_;
656     // FIXME
657     Dwarf_P_Die target_die_; //for RT_CUREL, this is known
658         // for sure only after all target DIEs generated!
659 
660     // RT_GLOBAL. FIXME
661 };
662 
663 
664 class IRFormString: public IRForm {
665 public:
IRFormString()666     IRFormString():
667         finalform_(0), initialform_(0),
668         formclass_(DW_FORM_CLASS_STRING),
669         strpoffset_(0) {};
~IRFormString()670     ~IRFormString() {};
671     IRFormString(IRFormInterface *);
IRFormString(const IRFormString & r)672     IRFormString(const IRFormString &r) {
673         finalform_ = r.finalform_;
674         initialform_ = r.initialform_;
675         formclass_ = r.formclass_;
676         formdata_= r.formdata_;
677         strpoffset_= r.strpoffset_;
678     }
clone()679     virtual IRFormString * clone() const {
680         return new IRFormString(*this);
681     }
682     IRFormString & operator=(const IRFormString &r) {
683         if(this == &r) return *this;
684         finalform_ = r.finalform_;
685         initialform_ = r.initialform_;
686         formclass_ = r.formclass_;
687         formdata_ = r.formdata_;
688         strpoffset_ = r.strpoffset_;
689         return *this;
690     };
setInitialForm(Dwarf_Half v)691     void setInitialForm(Dwarf_Half v) { initialform_ = v;}
setFinalForm(Dwarf_Half v)692     void setFinalForm(Dwarf_Half v) { finalform_ = v;}
getInitialForm()693     Dwarf_Half getInitialForm() { return initialform_;}
getFinalForm()694     Dwarf_Half getFinalForm() {return finalform_;}
setString(const char * s)695     void setString(const char *s) {formdata_ = s; };
getString()696     const std::string & getString() const {return formdata_; };
getFormClass()697     enum Dwarf_Form_Class getFormClass() const { return formclass_; };
698 private:
699     Dwarf_Half finalform_;
700     // In most cases directform == indirect form.
701     // Otherwise, directform == DW_FORM_indirect.
702     Dwarf_Half initialform_;
703     enum Dwarf_Form_Class formclass_;
704     std::string formdata_;
705     Dwarf_Unsigned strpoffset_;
706 };
707 
708 
709 // Factory Method.
710 IRForm *formFactory(Dwarf_Debug dbg, Dwarf_Attribute attr,
711     IRCUdata &cudata,IRAttr & irattr);
712 
713