1 
2 /*--------------------------------------------------------------------*/
3 /*--- Representation of source level types.         priv_tytypes.h ---*/
4 /*--------------------------------------------------------------------*/
5 
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9 
10    Copyright (C) 2008-2013 OpenWorks LLP
11       info@open-works.co.uk
12 
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17 
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22 
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26    02111-1307, USA.
27 
28    The GNU General Public License is contained in the file COPYING.
29 
30    Neither the names of the U.S. Department of Energy nor the
31    University of California nor the names of its contributors may be
32    used to endorse or promote products derived from this software
33    without prior written permission.
34 */
35 
36 #ifndef __PRIV_TYTYPES_H
37 #define __PRIV_TYTYPES_H
38 
39 #include "pub_core_basics.h"   // UWord
40 #include "pub_core_xarray.h"   // XArray
41 #include "priv_misc.h"         // MaybeULong
42 
43 typedef
44    enum {
45       Te_EMPTY=10, /* empty (contains no info) */
46       Te_INDIR,    /* indirection to some other TyEnt */
47       Te_UNKNOWN,  /* denotes a unknown type/field/whatever */
48       Te_Atom,     /* name & 64-bit const, iow, enumeration member */
49       Te_Field,    /* struct/class field defn */
50       Te_Bound,    /* array bounds indication, for one dimension */
51       Te_TyBase,   /* base type */
52       Te_TyPtr,    /* pointer type */
53       Te_TyRef,    /* reference type */
54       Te_TyPtrMbr, /* pointer to member type */
55       Te_TyRvalRef,/* rvalue reference type */
56       Te_TyTyDef,  /* a renaming of some other type */
57       Te_TyStOrUn, /* structure or union type */
58       Te_TyEnum,   /* an enum type */
59       Te_TyArray,  /* an array type */
60       Te_TyFn,     /* function type */
61       Te_TyQual,   /* qualified type */
62       Te_TyVoid    /* void type */
63    }
64    TyEntTag;
65 
66 /* Fields ending in "R" are references to other TyEnts.  Fields ending
67    in "Rs" are XArray*s of references to other TyEnts. */
68 typedef
69    struct {
70       UWord    cuOff;
71       TyEntTag tag;
72       union {
73          struct {
74          } EMPTY;
75          struct {
76             UWord indR;
77          } INDIR;
78          struct {
79          } UNKNOWN;
80          struct {
81             HChar* name; /* in mallocville */
82             Bool   valueKnown; /* atoms w/ unknown value are possible */
83             Long   value;
84          } Atom;
85          struct {
86             HChar* name;  /* in mallocville */
87             UWord  typeR; /* should be Te_TyXXXX */
88             union {
89                UChar* loc;   /* location expr, in mallocville */
90                Word offset;  /* or offset from the beginning of containing
91                                 entity */
92             } pos;
93             Word  nLoc;  /* number of bytes in .pos.loc if >= 0, or -1
94                             if .pos.offset should be used instead */
95             Bool   isStruct;
96          } Field;
97          struct {
98             Bool knownL;
99             Bool knownU;
100             Long boundL;
101             Long boundU;
102          } Bound;
103          struct {
104             HChar* name; /* in mallocville */
105             Int    szB;
106             UChar  enc; /* S:signed U:unsigned F:floating C:complex float */
107          } TyBase;
108          struct {
109             Int   szB;
110             UWord typeR;
111          } TyPorR;
112          struct {
113             HChar* name;  /* in mallocville */
114             UWord  typeR; /* MAY BE D3_INVALID_CUOFF, denoting unknown */
115          } TyTyDef;
116          struct {
117             HChar*  name; /* in mallocville */
118             UWord   szB;
119             UWord   typeR;
120             XArray* /* of UWord */ fieldRs;
121             Bool    complete;
122             Bool    isStruct;
123          } TyStOrUn;
124          struct {
125             HChar*  name; /* in mallocville */
126             Int     szB;
127             XArray* /* of UWord */ atomRs;
128          } TyEnum;
129          struct {
130             UWord   typeR;
131             XArray* /* of UWord */ boundRs;
132          } TyArray;
133          struct {
134          } TyFn;
135          struct {
136             UChar qual; /* C:const V:volatile R:restrict */
137             UWord typeR;
138          } TyQual;
139          struct {
140             Bool isFake; /* True == introduced by the reader */
141          } TyVoid;
142       } Te;
143    }
144    TyEnt;
145 
146 /* Does this TyEnt denote a type, as opposed to some other kind of
147    thing? */
148 Bool ML_(TyEnt__is_type)( const TyEnt* );
149 
150 /* Print a TyEnt, debug-style. */
151 void ML_(pp_TyEnt)( const TyEnt* );
152 
153 /* Print a whole XArray of TyEnts, debug-style */
154 void ML_(pp_TyEnts)( const XArray* tyents, const HChar* who );
155 
156 /* Print a TyEnt, C style, chasing stuff as necessary. */
157 void ML_(pp_TyEnt_C_ishly)( const XArray* /* of TyEnt */ tyents,
158                             UWord cuOff );
159 
160 /* Generates a total ordering on TyEnts based only on their .cuOff
161    fields. */
162 Word ML_(TyEnt__cmp_by_cuOff_only) ( const TyEnt* te1, const TyEnt* te2 );
163 
164 /* Generates a total ordering on TyEnts based on everything except
165    their .cuOff fields. */
166 Word ML_(TyEnt__cmp_by_all_except_cuOff) ( const TyEnt* te1, const TyEnt* te2 );
167 
168 /* Free up all directly or indirectly heap-allocated stuff attached to
169    this TyEnt, and set its tag to Te_EMPTY.  The .cuOff field is
170    unchanged. */
171 void ML_(TyEnt__make_EMPTY) ( TyEnt* te );
172 
173 /* How big is this type?  If .b in the returned struct is False, the
174    size is unknown. */
175 
176 MaybeULong ML_(sizeOfType)( const XArray* /* of TyEnt */ tyents,
177                             UWord cuOff );
178 
179 /* Describe where in the type 'offset' falls.  Caller must
180    deallocate the resulting XArray. */
181 XArray* /*UChar*/ ML_(describe_type)( /*OUT*/PtrdiffT* residual_offset,
182                                       const XArray* /* of TyEnt */ tyents,
183                                       UWord ty_cuOff,
184                                       PtrdiffT offset );
185 
186 
187 /* A fast-lookup cache for ML_(TyEnts__index_by_cuOff).  Nothing
188    particularly surprising here; it's 2 way set associative, with some
189    number of ways, doesn't particularly have to be a power of 2.  In
190    order to have a way to indicate an invalid entry, we set the second
191    value of the pair to NULL, and keep checking for it, since
192    unfortunately there's no obvious cuOff number that we could put in
193    the first word of the pair that could indicate an invalid entry.
194 
195    4096 arrived at as the best value for an E6600 loading Qt-4.4.1
196    Designer and all associated libraries, compiled by gcc-4.3.1,
197    -g -O, 64-bit, which is at least a moderately good stress test,
198    with the largest library being about 150MB.*/
199 
200 #define N_TYENT_INDEX_CACHE 4096
201 
202 typedef
203    struct {
204       struct { UWord cuOff0; TyEnt* ent0;
205                UWord cuOff1; TyEnt* ent1; }
206          ce[N_TYENT_INDEX_CACHE];
207    }
208    TyEntIndexCache;
209 
210 void ML_(TyEntIndexCache__invalidate) ( TyEntIndexCache* cache );
211 
212 /* 'ents' is an XArray of TyEnts, sorted by their .cuOff fields.  Find
213    the entry which has .cuOff field as specified.  Returns NULL if not
214    found.  Asserts if more than one entry has the specified .cuOff
215    value. */
216 TyEnt* ML_(TyEnts__index_by_cuOff) ( const XArray* /* of TyEnt */ ents,
217                                      TyEntIndexCache* cache,
218                                      UWord cuOff_to_find );
219 
220 #endif /* ndef __PRIV_TYTYPES_H */
221 
222 /*--------------------------------------------------------------------*/
223 /*--- end                                           priv_tytypes.h ---*/
224 /*--------------------------------------------------------------------*/
225