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
43typedef
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. */
68typedef
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 */
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? */
148Bool ML_(TyEnt__is_type)( TyEnt* );
149
150/* Print a TyEnt, debug-style. */
151void ML_(pp_TyEnt)( TyEnt* );
152
153/* Print a whole XArray of TyEnts, debug-style */
154void ML_(pp_TyEnts)( XArray* tyents, const HChar* who );
155
156/* Print a TyEnt, C style, chasing stuff as necessary. */
157void ML_(pp_TyEnt_C_ishly)( XArray* /* of TyEnt */ tyents,
158                            UWord cuOff );
159
160/* Generates a total ordering on TyEnts based only on their .cuOff
161   fields. */
162Word 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. */
166Word 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. */
171void 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
176MaybeULong ML_(sizeOfType)( XArray* /* of TyEnt */ tyents,
177                            UWord cuOff );
178
179/* Describe where in the type 'offset' falls.  Caller must
180   deallocate the resulting XArray. */
181XArray* /*UChar*/ ML_(describe_type)( /*OUT*/PtrdiffT* residual_offset,
182                                      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
202typedef
203   struct {
204      struct { UWord cuOff0; TyEnt* ent0;
205               UWord cuOff1; TyEnt* ent1; }
206         ce[N_TYENT_INDEX_CACHE];
207   }
208   TyEntIndexCache;
209
210void 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. */
216TyEnt* ML_(TyEnts__index_by_cuOff) ( 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