Merge branch 'vendor/OPENSSL'
[dragonfly.git] / contrib / gcc-5.0 / gcc / cp / vtable-class-hierarchy.c
1 /* Copyright (C) 2012-2015 Free Software Foundation, Inc.
2
3    This file is part of GCC.
4
5    GCC is free software; you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3, or (at your option)
8    any later version.
9
10    GCC is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GCC; see the file COPYING3.  If not see
17 <http://www.gnu.org/licenses/>.  */
18
19 /* Virtual Table Pointer Security Pass - Detect corruption of vtable pointers
20    before using them for virtual method dispatches.  */
21
22 /* This file is part of the vtable security feature implementation.
23    The vtable security feature is designed to detect when a virtual
24    call is about to be made through an invalid vtable pointer
25    (possibly due to data corruption or malicious attacks). The
26    compiler finds every virtual call, and inserts a verification call
27    before the virtual call.  The verification call takes the actual
28    vtable pointer value in the object through which the virtual call
29    is being made, and compares the vtable pointer against a set of all
30    valid vtable pointers that the object could contain (this set is
31    based on the declared type of the object).  If the pointer is in
32    the valid set, execution is allowed to continue; otherwise the
33    program is halted.
34
35   There are several pieces needed in order to make this work: 1. For
36   every virtual class in the program (i.e. a class that contains
37   virtual methods), we need to build the set of all possible valid
38   vtables that an object of that class could point to.  This includes
39   vtables for any class(es) that inherit from the class under
40   consideration.  2. For every such data set we build up, we need a
41   way to find and reference the data set.  This is complicated by the
42   fact that the real vtable addresses are not known until runtime,
43   when the program is loaded into memory, but we need to reference the
44   sets at compile time when we are inserting verification calls into
45   the program.  3.  We need to find every virtual call in the program,
46   and insert the verification call (with the appropriate arguments)
47   before the virtual call.  4. We need some runtime library pieces:
48   the code to build up the data sets at runtime; the code to actually
49   perform the verification using the data sets; and some code to set
50   protections on the data sets, so they themselves do not become
51   hacker targets.
52
53   To find and reference the set of valid vtable pointers for any given
54   virtual class, we create a special global varible for each virtual
55   class.  We refer to this as the "vtable map variable" for that
56   class.  The vtable map variable has the type "void *", and is
57   initialized by the compiler to NULL.  At runtime when the set of
58   valid vtable pointers for a virtual class, e.g. class Foo, is built,
59   the vtable map variable for class Foo is made to point to the set.
60   During compile time, when the compiler is inserting verification
61   calls into the program, it passes the vtable map variable for the
62   appropriate class to the verification call, so that at runtime the
63   verification call can find the appropriate data set.
64
65   The actual set of valid vtable pointers for a virtual class,
66   e.g. class Foo, cannot be built until runtime, when the vtables get
67   loaded into memory and their addresses are known.  But the knowledge
68   about which vtables belong in which class' hierarchy is only known
69   at compile time.  Therefore at compile time we collect class
70   hierarchy and vtable information about every virtual class, and we
71   generate calls to build up the data sets at runtime.  To build the
72   data sets, we call one of the functions we add to the runtime
73   library, __VLTRegisterPair.  __VLTRegisterPair takes two arguments,
74   a vtable map variable and the address of a vtable.  If the vtable
75   map variable is currently NULL, it creates a new data set (hash
76   table), makes the vtable map variable point to the new data set, and
77   inserts the vtable address into the data set.  If the vtable map
78   variable is not NULL, it just inserts the vtable address into the
79   data set.  In order to make sure that our data sets are built before
80   any verification calls happen, we create a special constructor
81   initialization function for each compilation unit, give it a very
82   high initialization priority, and insert all of our calls to
83   __VLTRegisterPair into our special constructor initialization
84   function.
85
86   The vtable verification feature is controlled by the flag
87   '-fvtable-verify='.  There are three flavors of this:
88   '-fvtable-verify=std', '-fvtable-verify=preinit', and
89   '-fvtable-verify=none'.  If the option '-fvtable-verfy=preinit' is
90   used, then our constructor initialization function gets put into the
91   preinit array.  This is necessary if there are data sets that need
92   to be built very early in execution.  If the constructor
93   initialization function gets put into the preinit array, the we also
94   add calls to __VLTChangePermission at the beginning and end of the
95   function.  The call at the beginning sets the permissions on the
96   data sets and vtable map variables to read/write, and the one at the
97   end makes them read-only.  If the '-fvtable-verify=std' option is
98   used, the constructor initialization functions are executed at their
99   normal time, and the __VLTChangePermission calls are handled
100   differently (see the comments in libstdc++-v3/libsupc++/vtv_rts.cc).
101   The option '-fvtable-verify=none' turns off vtable verification.
102
103   This file contains code to find and record the class hierarchies for
104   the virtual classes in a program, and all the vtables associated
105   with each such class; to generate the vtable map variables; and to
106   generate the constructor initialization function (with the calls to
107   __VLTRegisterPair, and __VLTChangePermission).  The main data
108   structures used for collecting the class hierarchy data and
109   building/maintaining the vtable map variable data are defined in
110   gcc/vtable-verify.h, because they are used both here and in
111   gcc/vtable-verify.c.  */
112
113 #include "config.h"
114 #include "system.h"
115 #include "coretypes.h"
116 #include "cp-tree.h"
117 #include "output.h"
118 #include "hash-map.h"
119 #include "is-a.h"
120 #include "plugin-api.h"
121 #include "vec.h"
122 #include "hashtab.h"
123 #include "hash-set.h"
124 #include "machmode.h"
125 #include "tm.h"
126 #include "hard-reg-set.h"
127 #include "input.h"
128 #include "function.h"
129 #include "ipa-ref.h"
130 #include "cgraph.h"
131 #include "tree-iterator.h"
132 #include "vtable-verify.h"
133 #include "gimplify.h"
134 #include "stringpool.h"
135 #include "stor-layout.h"
136
137 static int num_calls_to_regset = 0;
138 static int num_calls_to_regpair = 0;
139 static int current_set_size;
140
141 /* Mark these specially since they need to be stored in precompiled
142    header IR.  */
143 static GTY (()) vec<tree, va_gc> *vlt_saved_class_info;
144 static GTY (()) tree vlt_register_pairs_fndecl = NULL_TREE;
145 static GTY (()) tree vlt_register_set_fndecl = NULL_TREE;
146
147 struct work_node {
148   struct vtv_graph_node *node;
149   struct work_node *next;
150 };
151
152 struct vtbl_map_node *vtable_find_or_create_map_decl (tree);
153
154 /* As part of vtable verification the compiler generates and inserts
155    calls to __VLTVerifyVtablePointer, which is in libstdc++.  This
156    function builds and initializes the function decl that is used
157    in generating those function calls.
158
159    In addition to __VLTVerifyVtablePointer there is also
160    __VLTVerifyVtablePointerDebug which can be used in place of
161    __VLTVerifyVtablePointer, and which takes extra parameters and
162    outputs extra information, to help debug problems.  The debug
163    version of this function is generated and used if flag_vtv_debug is
164    true.
165
166    The signatures for these functions are:
167
168    void * __VLTVerifyVtablePointer (void **, void*);
169    void * __VLTVerifyVtablePointerDebug (void**, void *, char *, char *);
170 */
171
172 void
173 vtv_build_vtable_verify_fndecl (void)
174 {
175   tree func_type = NULL_TREE;
176
177   if (verify_vtbl_ptr_fndecl != NULL_TREE
178       && TREE_CODE (verify_vtbl_ptr_fndecl) != ERROR_MARK)
179     return;
180
181   if (flag_vtv_debug)
182     {
183       func_type = build_function_type_list (const_ptr_type_node,
184                                             build_pointer_type (ptr_type_node),
185                                             const_ptr_type_node,
186                                             const_string_type_node,
187                                             const_string_type_node,
188                                             NULL_TREE);
189       verify_vtbl_ptr_fndecl =
190         build_lang_decl (FUNCTION_DECL,
191                          get_identifier ("__VLTVerifyVtablePointerDebug"),
192                          func_type);
193     }
194   else
195     {
196       func_type = build_function_type_list (const_ptr_type_node,
197                                             build_pointer_type (ptr_type_node),
198                                             const_ptr_type_node,
199                                             NULL_TREE);
200       verify_vtbl_ptr_fndecl =
201         build_lang_decl (FUNCTION_DECL,
202                          get_identifier ("__VLTVerifyVtablePointer"),
203                          func_type);
204     }
205
206   TREE_NOTHROW (verify_vtbl_ptr_fndecl) = 1;
207   DECL_ATTRIBUTES (verify_vtbl_ptr_fndecl)
208       = tree_cons (get_identifier ("leaf"), NULL,
209                    DECL_ATTRIBUTES (verify_vtbl_ptr_fndecl));
210   DECL_PURE_P (verify_vtbl_ptr_fndecl) = 1;
211   TREE_PUBLIC (verify_vtbl_ptr_fndecl) = 1;
212   DECL_PRESERVE_P (verify_vtbl_ptr_fndecl) = 1;
213 }
214
215 /* As part of vtable verification the compiler generates and inserts
216    calls to __VLTRegisterSet and __VLTRegisterPair, which are in
217    libsupc++.  This function builds and initializes the function decls
218    that are used in generating those function calls.
219
220    The signatures for these functions are:
221
222    void __VLTRegisterSetDebug (void **, const void *, std::size_t,
223                                size_t, void **);
224
225    void __VLTRegisterSet (void **, const void *, std::size_t,
226                           size_t, void **);
227
228    void __VLTRegisterPairDebug (void **, const void *, size_t,
229                                 const void *, const char *, const char *);
230
231    void __VLTRegisterPair (void **, const void *, size_t, const void *);
232 */
233
234 static void
235 init_functions (void)
236 {
237   tree register_set_type;
238   tree register_pairs_type;
239
240   if (vlt_register_set_fndecl != NULL_TREE)
241     return;
242
243   gcc_assert (vlt_register_pairs_fndecl == NULL_TREE);
244   gcc_assert (vlt_register_set_fndecl == NULL_TREE);
245
246   /* Build function decl for __VLTRegisterSet*.  */
247
248   register_set_type = build_function_type_list
249                                              (void_type_node,
250                                               build_pointer_type (ptr_type_node),
251                                               const_ptr_type_node,
252                                               size_type_node,
253                                               size_type_node,
254                                               build_pointer_type (ptr_type_node),
255                                               NULL_TREE);
256
257   if (flag_vtv_debug)
258     vlt_register_set_fndecl = build_lang_decl
259                                        (FUNCTION_DECL,
260                                         get_identifier ("__VLTRegisterSetDebug"),
261                                         register_set_type);
262   else
263     vlt_register_set_fndecl = build_lang_decl
264                                        (FUNCTION_DECL,
265                                         get_identifier ("__VLTRegisterSet"),
266                                         register_set_type);
267
268
269   TREE_NOTHROW (vlt_register_set_fndecl) = 1;
270   DECL_ATTRIBUTES (vlt_register_set_fndecl) =
271                     tree_cons (get_identifier ("leaf"), NULL,
272                                DECL_ATTRIBUTES (vlt_register_set_fndecl));
273   DECL_EXTERNAL(vlt_register_set_fndecl) = 1;
274   TREE_PUBLIC (vlt_register_set_fndecl) = 1;
275   DECL_PRESERVE_P (vlt_register_set_fndecl) = 1;
276   SET_DECL_LANGUAGE (vlt_register_set_fndecl, lang_cplusplus);
277
278   /* Build function decl for __VLTRegisterPair*.  */
279
280   if (flag_vtv_debug)
281     {
282       register_pairs_type = build_function_type_list (void_type_node,
283                                                       build_pointer_type
284                                                               (ptr_type_node),
285                                                       const_ptr_type_node,
286                                                       size_type_node,
287                                                       const_ptr_type_node,
288                                                       const_string_type_node,
289                                                       const_string_type_node,
290                                                       NULL_TREE);
291
292       vlt_register_pairs_fndecl = build_lang_decl
293                                       (FUNCTION_DECL,
294                                        get_identifier ("__VLTRegisterPairDebug"),
295                                        register_pairs_type);
296     }
297   else
298     {
299       register_pairs_type = build_function_type_list (void_type_node,
300                                                       build_pointer_type
301                                                               (ptr_type_node),
302                                                       const_ptr_type_node,
303                                                       size_type_node,
304                                                       const_ptr_type_node,
305                                                       NULL_TREE);
306
307       vlt_register_pairs_fndecl = build_lang_decl
308                                       (FUNCTION_DECL,
309                                        get_identifier ("__VLTRegisterPair"),
310                                        register_pairs_type);
311     }
312
313   TREE_NOTHROW (vlt_register_pairs_fndecl) = 1;
314   DECL_ATTRIBUTES (vlt_register_pairs_fndecl) =
315                     tree_cons (get_identifier ("leaf"), NULL,
316                                DECL_ATTRIBUTES (vlt_register_pairs_fndecl));
317   DECL_EXTERNAL(vlt_register_pairs_fndecl) = 1;
318   TREE_PUBLIC (vlt_register_pairs_fndecl) = 1;
319   DECL_PRESERVE_P (vlt_register_pairs_fndecl) = 1;
320   SET_DECL_LANGUAGE (vlt_register_pairs_fndecl, lang_cplusplus);
321
322 }
323
324 /* This is a helper function for
325    vtv_compute_class_hierarchy_transitive_closure.  It adds a
326    vtv_graph_node to the WORKLIST, which is a linked list of
327    seen-but-not-yet-processed nodes.  INSERTED is a bitmap, one bit
328    per node, to help make sure that we don't insert a node into the
329    worklist more than once.  Each node represents a class somewhere in
330    our class hierarchy information. Every node in the graph gets added
331    to the worklist exactly once and removed from the worklist exactly
332    once (when all of its children have been processed).  */
333
334 static void
335 add_to_worklist (struct work_node **worklist, struct vtv_graph_node *node,
336                  sbitmap inserted)
337 {
338   struct work_node *new_work_node;
339
340   if (bitmap_bit_p (inserted, node->class_uid))
341     return;
342
343   new_work_node = XNEW (struct work_node);
344   new_work_node->next = *worklist;
345   new_work_node->node = node;
346   *worklist = new_work_node;
347
348   bitmap_set_bit (inserted, node->class_uid);
349 }
350
351 /* This is a helper function for
352    vtv_compute_class_hierarchy_transitive_closure.  It goes through
353    the WORKLIST of class hierarchy nodes looking for a "leaf" node,
354    i.e. a node whose children in the hierarchy have all been
355    processed.  When it finds the next leaf node, it removes it from
356    the linked list (WORKLIST) and returns the node.  */
357
358 static struct vtv_graph_node *
359 find_and_remove_next_leaf_node (struct work_node **worklist)
360 {
361   struct work_node *prev, *cur;
362   struct vtv_graph_node *ret_val = NULL;
363
364   for (prev = NULL, cur = *worklist; cur; prev = cur, cur = cur->next)
365     {
366       if ((cur->node->children).length() == cur->node->num_processed_children)
367         {
368           if (prev == NULL)
369             (*worklist) = cur->next;
370           else
371             prev->next = cur->next;
372
373           cur->next = NULL;
374           ret_val = cur->node;
375           free (cur);
376           return ret_val;
377         }
378     }
379
380   return NULL;
381 }
382
383 /* In our class hierarchy graph, each class node contains a bitmap,
384    with one bit for each class in the hierarchy.  The bits are set for
385    classes that are descendants in the graph of the current node.
386    Initially the descendants bitmap is only set for immediate
387    descendants.  This function traverses the class hierarchy graph,
388    bottom up, filling in the transitive closures for the descendants
389    as we rise up the graph.  */
390
391 void
392 vtv_compute_class_hierarchy_transitive_closure (void)
393 {
394   struct work_node *worklist = NULL;
395   sbitmap inserted = sbitmap_alloc (num_vtable_map_nodes);
396   unsigned i;
397   unsigned j;
398
399   /* Note: Every node in the graph gets added to the worklist exactly
400    once and removed from the worklist exactly once (when all of its
401    children have been processed).  Each node's children edges are
402    followed exactly once, and each node's parent edges are followed
403    exactly once.  So this algorithm is roughly O(V + 2E), i.e.
404    O(E + V).  */
405
406   /* Set-up:                                                                */
407   /* Find all the "leaf" nodes in the graph, and add them to the worklist.  */
408   bitmap_clear (inserted);
409   for (j = 0; j < num_vtable_map_nodes; ++j)
410     {
411       struct vtbl_map_node *cur = vtbl_map_nodes_vec[j];
412       if (cur->class_info
413           && ((cur->class_info->children).length() == 0)
414           && ! (bitmap_bit_p (inserted, cur->class_info->class_uid)))
415         add_to_worklist (&worklist, cur->class_info, inserted);
416     }
417
418   /* Main work: pull next leaf node off work list, process it, add its
419      parents to the worklist, where a 'leaf' node is one that has no
420      children, or all of its children have been processed.  */
421   while (worklist)
422     {
423       struct vtv_graph_node *temp_node =
424                                   find_and_remove_next_leaf_node (&worklist);
425
426       gcc_assert (temp_node != NULL);
427       temp_node->descendants = sbitmap_alloc (num_vtable_map_nodes);
428       bitmap_clear (temp_node->descendants);
429       bitmap_set_bit (temp_node->descendants, temp_node->class_uid);
430       for (i = 0; i < (temp_node->children).length(); ++i)
431         bitmap_ior (temp_node->descendants, temp_node->descendants,
432                         temp_node->children[i]->descendants);
433       for (i = 0; i < (temp_node->parents).length(); ++i)
434         {
435           temp_node->parents[i]->num_processed_children =
436                     temp_node->parents[i]->num_processed_children + 1;
437           if (!bitmap_bit_p (inserted, temp_node->parents[i]->class_uid))
438             add_to_worklist (&worklist, temp_node->parents[i], inserted);
439         }
440     }
441 }
442
443 /* Keep track of which pairs we have already created __VLTRegisterPair
444    calls for, to prevent creating duplicate calls within the same
445    compilation unit.  VTABLE_DECL is the var decl for the vtable of
446    the (descendant) class that we are adding to our class hierarchy
447    data.  VPTR_ADDRESS is an expression for calculating the correct
448    offset into the vtable (VTABLE_DECL).  It is the actual vtable
449    pointer address that will be stored in our list of valid vtable
450    pointers for BASE_CLASS.  BASE_CLASS is the record_type node for
451    the base class to whose hiearchy we want to add
452    VPTR_ADDRESS. (VTABLE_DECL should be the vtable for BASE_CLASS or
453    one of BASE_CLASS' descendents.  */
454
455 static bool
456 check_and_record_registered_pairs (tree vtable_decl, tree vptr_address,
457                                    tree base_class)
458 {
459   unsigned offset;
460   struct vtbl_map_node *base_vtable_map_node;
461   bool inserted_something = false;
462
463
464   if (TREE_CODE (vptr_address) == ADDR_EXPR
465       && TREE_CODE (TREE_OPERAND (vptr_address, 0)) == MEM_REF)
466     vptr_address = TREE_OPERAND (vptr_address, 0);
467
468   if (TREE_OPERAND_LENGTH (vptr_address) > 1)
469     offset = TREE_INT_CST_LOW (TREE_OPERAND (vptr_address, 1));
470   else
471     offset = 0;
472
473   base_vtable_map_node = vtbl_map_get_node (TYPE_MAIN_VARIANT (base_class));
474
475   inserted_something = vtbl_map_node_registration_insert
476                                                         (base_vtable_map_node,
477                                                          vtable_decl,
478                                                          offset);
479   return !inserted_something;
480 }
481
482 /* Given an IDENTIFIER_NODE, build and return a string literal based on it.  */
483
484 static tree
485 build_string_from_id (tree identifier)
486 {
487   int len;
488
489   gcc_assert (TREE_CODE (identifier) == IDENTIFIER_NODE);
490
491   len = IDENTIFIER_LENGTH (identifier);
492   return build_string_literal (len + 1, IDENTIFIER_POINTER (identifier));
493 }
494
495 /* A class may contain secondary vtables in it, for various reasons.
496    This function goes through the decl chain of a class record looking
497    for any fields that point to secondary vtables, and adding calls to
498    __VLTRegisterPair for the secondary vtable pointers.
499
500    BASE_CLASS_DECL_ARG is an expression for the address of the vtable
501    map variable for the BASE_CLASS (whose hierarchy we are currently
502    updating).  BASE_CLASS is the record_type node for the base class.
503    RECORD_TYPE is the record_type node for the descendant class that
504    we are possibly adding to BASE_CLASS's hierarchy.  BODY is the
505    function body for the constructor init function to which we are
506    adding our calls to __VLTRegisterPair.  */
507
508 static void
509 register_construction_vtables (tree base_class, tree record_type,
510                                vec<tree> *vtable_ptr_array)
511 {
512   tree vtbl_var_decl;
513
514   if (TREE_CODE (record_type) != RECORD_TYPE)
515     return;
516
517   vtbl_var_decl = CLASSTYPE_VTABLES (record_type);
518
519   if (CLASSTYPE_VBASECLASSES (record_type))
520     {
521       tree vtt_decl;
522       bool already_registered = false;
523       tree val_vtbl_decl = NULL_TREE;
524
525       vtt_decl = DECL_CHAIN (vtbl_var_decl);
526
527       /* Check to see if we have found a VTT.  Add its data if appropriate.  */
528       if (vtt_decl)
529         {
530           tree values = DECL_INITIAL (vtt_decl);
531           if (TREE_ASM_WRITTEN (vtt_decl)
532               && values != NULL_TREE
533               && TREE_CODE (values) == CONSTRUCTOR
534               && TREE_CODE (TREE_TYPE (values)) == ARRAY_TYPE)
535             {
536               unsigned HOST_WIDE_INT cnt;
537               constructor_elt *ce;
538
539               /* Loop through the initialization values for this
540                  vtable to get all the correct vtable pointer
541                  addresses that we need to add to our set of valid
542                  vtable pointers for the current base class.  This may
543                  result in adding more than just the element assigned
544                  to the primary vptr of the class, so we may end up
545                  with more vtable pointers than are strictly
546                  necessary.  */
547
548               for (cnt = 0;
549                    vec_safe_iterate (CONSTRUCTOR_ELTS (values),
550                                      cnt, &ce);
551                    cnt++)
552                 {
553                   tree value = ce->value;
554
555                   /* Search for the ADDR_EXPR operand within the value.  */
556
557                   while (value
558                          && TREE_OPERAND (value, 0)
559                          && TREE_CODE (TREE_OPERAND (value, 0)) == ADDR_EXPR)
560                     value = TREE_OPERAND (value, 0);
561
562                   /* The VAR_DECL for the vtable should be the first
563                      argument of the ADDR_EXPR, which is the first
564                      argument of value.*/
565
566                   if (TREE_OPERAND (value, 0))
567                     val_vtbl_decl = TREE_OPERAND (value, 0);
568
569                   while (TREE_CODE (val_vtbl_decl) != VAR_DECL
570                          && TREE_OPERAND (val_vtbl_decl, 0))
571                     val_vtbl_decl = TREE_OPERAND (val_vtbl_decl, 0);
572
573                   gcc_assert (TREE_CODE (val_vtbl_decl) == VAR_DECL);
574
575                   /* Check to see if we already have this vtable pointer in
576                      our valid set for this base class.  */
577
578                   already_registered = check_and_record_registered_pairs
579                                                                (val_vtbl_decl,
580                                                                 value,
581                                                                 base_class);
582
583                   if (already_registered)
584                     continue;
585
586                   /* Add this vtable pointer to our set of valid
587                      pointers for the base class.  */
588
589                   vtable_ptr_array->safe_push (value);
590                   current_set_size++;
591                 }
592             }
593         }
594     }
595 }
596
597 /* This function iterates through all the vtables it can find from the
598    BINFO of a class, to make sure we have found ALL of the vtables
599    that an object of that class could point to.  Generate calls to
600    __VLTRegisterPair for those vtable pointers that we find.
601
602    BINFO is the tree_binfo node for the BASE_CLASS.  BODY is the
603    function body for the constructor init function to which we are
604    adding calls to __VLTRegisterPair.  ARG1 is an expression for the
605    address of the vtable map variable (for the BASE_CLASS), that will
606    point to the updated data set.  BASE_CLASS is the record_type node
607    for the base class whose set of valid vtable pointers we are
608    updating. STR1 and STR2 are all debugging information, to be passed
609    as parameters to __VLTRegisterPairDebug.  STR1 represents the name
610    of the vtable map variable to be updated by the call.  Similarly,
611    STR2 represents the name of the class whose vtable pointer is being
612    added to the hierarchy.  */
613
614 static void
615 register_other_binfo_vtables (tree binfo, tree base_class,
616                               vec<tree> *vtable_ptr_array)
617 {
618   unsigned ix;
619   tree base_binfo;
620   tree vtable_decl;
621   bool already_registered;
622
623   if (binfo == NULL_TREE)
624     return;
625
626   for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
627     {
628       if ((!BINFO_PRIMARY_P (base_binfo)
629            || BINFO_VIRTUAL_P (base_binfo))
630           && (vtable_decl = get_vtbl_decl_for_binfo (base_binfo)))
631         {
632           tree vtable_address = build_vtbl_address (base_binfo);
633
634           already_registered = check_and_record_registered_pairs
635                                                               (vtable_decl,
636                                                                vtable_address,
637                                                                base_class);
638           if (!already_registered)
639             {
640               vtable_ptr_array->safe_push (vtable_address);
641               current_set_size++;
642             }
643         }
644
645       register_other_binfo_vtables (base_binfo, base_class, vtable_ptr_array);
646     }
647 }
648
649 /* The set of valid vtable pointers for any given class are stored in
650    a hash table.  For reasons of efficiency, that hash table size is
651    always a power of two.  In order to try to prevent re-sizing the
652    hash tables very often, we pass __VLTRegisterPair an initial guess
653    as to the number of entries the hashtable will eventually need
654    (rounded up to the nearest power of two).  This function takes the
655    class information we have collected for a particular class,
656    CLASS_NODE, and calculates the hash table size guess.  */
657
658 static int
659 guess_num_vtable_pointers (struct vtv_graph_node *class_node)
660 {
661   tree vtbl;
662   int total_num_vtbls = 0;
663   int num_vtbls_power_of_two = 1;
664   unsigned i;
665
666   for (i = 0; i < num_vtable_map_nodes; ++i)
667     if (bitmap_bit_p (class_node->descendants, i))
668       {
669         tree class_type = vtbl_map_nodes_vec[i]->class_info->class_type;
670         for (vtbl = CLASSTYPE_VTABLES (class_type); vtbl;
671              vtbl = DECL_CHAIN (vtbl))
672           {
673             total_num_vtbls++;
674             if (total_num_vtbls > num_vtbls_power_of_two)
675               num_vtbls_power_of_two <<= 1;
676           }
677       }
678   return num_vtbls_power_of_two;
679 }
680
681 /* A simple hash function on strings */
682 /* Be careful about changing this routine. The values generated will
683    be stored in the calls to InitSet. So, changing this routine may
684    cause a binary incompatibility.  */
685
686 static uint32_t
687 vtv_string_hash (const char *in)
688 {
689   const char *s = in;
690   uint32_t h = 0;
691
692   gcc_assert (in != NULL);
693   for ( ; *s; ++s)
694     h = 5 * h + *s;
695   return h;
696 }
697
698 static char *
699 get_log_file_name (const char *fname)
700 {
701   const char *tmp_dir = concat (dump_dir_name, NULL);
702   char *full_name;
703   int dir_len;
704   int fname_len;
705
706   dir_len = strlen (tmp_dir);
707   fname_len = strlen (fname);
708
709   full_name = XNEWVEC (char, dir_len + fname_len + 1);
710   strcpy (full_name, tmp_dir);
711   strcpy (full_name + dir_len, fname);
712
713   return full_name;
714 }
715
716 static void
717 write_out_current_set_data (tree base_class, int set_size)
718 {
719   static int class_data_log_fd = -1;
720   char buffer[1024];
721   int bytes_written __attribute__ ((unused));
722   char *file_name = get_log_file_name ("vtv_class_set_sizes.log");
723
724   if (class_data_log_fd == -1)
725     class_data_log_fd = open (file_name,
726                               O_WRONLY | O_APPEND | O_CREAT, S_IRWXU);
727
728   if (class_data_log_fd == -1)
729     {
730       warning_at (UNKNOWN_LOCATION, 0,
731                   "unable to open log file %<vtv_class_set_sizes.log%>: %m");
732       return;
733     }
734
735   snprintf (buffer, sizeof (buffer), "%s %d\n",
736             IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (base_class))),
737             set_size);
738   bytes_written = write (class_data_log_fd, buffer, strlen (buffer));
739 }
740
741 static tree
742 build_key_buffer_arg (tree base_ptr_var_decl)
743 {
744   const int key_type_fixed_size = 8;
745   uint32_t len1 = IDENTIFIER_LENGTH (DECL_NAME (base_ptr_var_decl));
746   uint32_t hash_value = vtv_string_hash (IDENTIFIER_POINTER
747                                               (DECL_NAME (base_ptr_var_decl)));
748   void *key_buffer = xmalloc (len1 + key_type_fixed_size);
749   uint32_t *value_ptr = (uint32_t *) key_buffer;
750   tree ret_value;
751
752   /* Set the len and hash for the string.  */
753   *value_ptr = len1;
754   value_ptr++;
755   *value_ptr = hash_value;
756
757   /* Now copy the string representation of the vtbl map name...  */
758   memcpy ((char *) key_buffer + key_type_fixed_size,
759           IDENTIFIER_POINTER (DECL_NAME (base_ptr_var_decl)),
760           len1);
761
762   /* ... and build a string literal from it. This will make a copy
763      so the key_bufffer is not needed anymore after this.  */
764   ret_value = build_string_literal (len1 + key_type_fixed_size,
765                                     (char *) key_buffer);
766   free (key_buffer);
767   return ret_value;
768 }
769
770 static void
771 insert_call_to_register_set (tree class_name,
772                              vec<tree> *vtbl_ptr_array, tree body, tree arg1,
773                              tree arg2, tree size_hint_arg)
774 {
775   tree call_expr;
776   int num_args = vtbl_ptr_array->length();
777   char *array_arg_name = ACONCAT (("__vptr_array_",
778                                    IDENTIFIER_POINTER (class_name), NULL));
779   tree array_arg_type = build_array_type_nelts (build_pointer_type
780                                                   (build_pointer_type
781                                                      (void_type_node)),
782                                                 num_args);
783   tree array_arg = build_decl (UNKNOWN_LOCATION, VAR_DECL,
784                                get_identifier (array_arg_name),
785                                array_arg_type);
786   int k;
787
788   vec<constructor_elt, va_gc> *array_elements;
789   vec_alloc (array_elements, num_args);
790                                                         
791   tree initial = NULL_TREE;
792   tree arg3 = NULL_TREE;
793
794   TREE_PUBLIC (array_arg) = 0;
795   DECL_EXTERNAL (array_arg) = 0;
796   TREE_STATIC (array_arg) = 1;
797   DECL_ARTIFICIAL (array_arg) = 0;
798   TREE_READONLY (array_arg) = 1;
799   DECL_IGNORED_P (array_arg) = 0;
800   DECL_PRESERVE_P (array_arg) = 0;
801   DECL_VISIBILITY (array_arg) = VISIBILITY_HIDDEN;
802
803   for (k = 0; k < num_args; ++k)
804     {
805       CONSTRUCTOR_APPEND_ELT (array_elements, NULL_TREE, (*vtbl_ptr_array)[k]);
806     }
807
808   initial = build_constructor (TREE_TYPE (array_arg), array_elements);
809
810   TREE_CONSTANT (initial) = 1;
811   TREE_STATIC (initial) = 1;
812   DECL_INITIAL (array_arg) = initial;
813   relayout_decl (array_arg);
814   varpool_node::finalize_decl (array_arg);
815
816   arg3 = build1 (ADDR_EXPR, TYPE_POINTER_TO (TREE_TYPE (array_arg)), array_arg);
817
818   TREE_TYPE (arg3) = build_pointer_type (TREE_TYPE (array_arg));
819
820   call_expr = build_call_expr (vlt_register_set_fndecl, 5, arg1,
821                                arg2, /* set_symbol_key */
822                                size_hint_arg, build_int_cst (size_type_node,
823                                                              num_args),
824                                arg3);
825   append_to_statement_list (call_expr, &body);
826   num_calls_to_regset++;
827 }
828
829 static void
830 insert_call_to_register_pair (vec<tree> *vtbl_ptr_array, tree arg1,
831                               tree arg2, tree size_hint_arg, tree str1,
832                               tree str2, tree body)
833 {
834   tree call_expr;
835   int num_args = vtbl_ptr_array->length();
836   tree vtable_address = NULL_TREE;
837
838   if (num_args == 0)
839     vtable_address = build_int_cst (build_pointer_type (void_type_node), 0);
840   else
841     vtable_address = (*vtbl_ptr_array)[0];
842
843   if (flag_vtv_debug)
844     call_expr = build_call_expr (vlt_register_pairs_fndecl, 6, arg1, arg2,
845                                  size_hint_arg, vtable_address, str1, str2);
846   else
847     call_expr = build_call_expr (vlt_register_pairs_fndecl, 4, arg1, arg2,
848                                  size_hint_arg, vtable_address);
849     
850   append_to_statement_list (call_expr, &body);
851   num_calls_to_regpair++;
852 }
853
854 static void
855 output_set_info (tree record_type, vec<tree> vtbl_ptr_array)
856 {
857   static int vtv_debug_log_fd = -1;
858   char buffer[1024];
859   int bytes_written __attribute__ ((unused));
860   int array_len = vtbl_ptr_array.length();
861   const char *class_name =
862               IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (record_type)));
863   char *file_name = get_log_file_name ("vtv_set_ptr_data.log");
864
865   if (vtv_debug_log_fd == -1)
866     vtv_debug_log_fd = open (file_name,
867                              O_WRONLY | O_APPEND | O_CREAT, S_IRWXU);
868   if (vtv_debug_log_fd == -1)
869     {
870       warning_at (UNKNOWN_LOCATION, 0,
871                   "unable to open log file %<vtv_set_ptr_data.log%>: %m");
872       return;
873     }
874
875   for (int i = 0; i < array_len; ++i)
876     {
877       const char *vptr_name = "unknown";
878       int vptr_offset = 0;
879       
880       if (TREE_CODE (vtbl_ptr_array[i]) == POINTER_PLUS_EXPR)
881         {
882           tree arg0 = TREE_OPERAND (vtbl_ptr_array[i], 0);
883           tree arg1 = TREE_OPERAND (vtbl_ptr_array[i], 1);
884
885           if (TREE_CODE (arg0) == ADDR_EXPR)
886             arg0 = TREE_OPERAND (arg0, 0);
887
888           if (TREE_CODE (arg0) == VAR_DECL)
889             vptr_name = IDENTIFIER_POINTER (DECL_NAME (arg0));
890
891           if (TREE_CODE (arg1) == INTEGER_CST)
892             vptr_offset = TREE_INT_CST_LOW (arg1);
893         }
894
895       snprintf (buffer, sizeof (buffer), "%s %s %s + %d\n",
896                 main_input_filename, class_name, vptr_name, vptr_offset);
897       bytes_written = write (vtv_debug_log_fd, buffer, strlen(buffer));
898     }
899
900 }
901
902 /* This function goes through our internal class hierarchy & vtable
903    pointer data structure and outputs calls to __VLTRegisterPair for
904    every class-vptr pair (for those classes whose vtable would be
905    output in the current compilation unit).  These calls get put into
906    our constructor initialization function.  BODY is the function
907    body, so far, of our constructor initialization function, to which we
908    add the calls.  */
909
910 static bool
911 register_all_pairs (tree body)
912 {
913   bool registered_at_least_one = false;
914   vec<tree> *vtbl_ptr_array = NULL;
915   unsigned j;
916
917   for (j = 0; j < num_vtable_map_nodes; ++j)
918     {
919       struct vtbl_map_node *current = vtbl_map_nodes_vec[j];
920       unsigned i = 0;
921       tree base_class = current->class_info->class_type;
922       tree base_ptr_var_decl = current->vtbl_map_decl;
923       tree arg1;
924       tree arg2;
925       tree new_type;
926       tree str1 = NULL_TREE;
927       tree str2 = NULL_TREE;
928       size_t size_hint;
929       tree size_hint_arg;
930
931       gcc_assert (current->class_info != NULL);
932
933
934       if (flag_vtv_debug)
935         str1 = build_string_from_id (DECL_NAME (base_ptr_var_decl));
936
937       new_type = build_pointer_type (TREE_TYPE (base_ptr_var_decl));
938       arg1 = build1 (ADDR_EXPR, new_type, base_ptr_var_decl);
939
940       /* We need a fresh vector for each iteration.  */
941       if (vtbl_ptr_array)
942         vec_free (vtbl_ptr_array);
943
944       vec_alloc (vtbl_ptr_array, 10);
945
946       for (i = 0; i < num_vtable_map_nodes; ++i)
947         if (bitmap_bit_p (current->class_info->descendants, i))
948           {
949             struct vtbl_map_node *vtbl_class_node = vtbl_map_nodes_vec[i];
950             tree class_type = vtbl_class_node->class_info->class_type;
951
952             if (class_type
953                 && (TREE_CODE (class_type) == RECORD_TYPE))
954               {
955                 bool already_registered;
956
957                 tree binfo = TYPE_BINFO (class_type);
958                 tree vtable_decl;
959                 bool vtable_should_be_output = false;
960
961                 vtable_decl = CLASSTYPE_VTABLES (class_type);
962
963                 /* Handle main vtable for this class.  */
964
965                 if (vtable_decl)
966                   {
967                     vtable_should_be_output = TREE_ASM_WRITTEN (vtable_decl);
968                     str2 = build_string_from_id (DECL_NAME (vtable_decl));
969                   }
970
971                 if (vtable_decl && vtable_should_be_output)
972                   {
973                     tree vtable_address = build_vtbl_address (binfo);
974
975                     already_registered = check_and_record_registered_pairs
976                                                               (vtable_decl,
977                                                                vtable_address,
978                                                                base_class);
979
980
981                     if (!already_registered)
982                       {
983                         vtbl_ptr_array->safe_push (vtable_address);
984
985                         /* Find and handle any 'extra' vtables associated
986                            with this class, via virtual inheritance.   */
987                         register_construction_vtables (base_class, class_type,
988                                                        vtbl_ptr_array);
989
990                         /* Find and handle any 'extra' vtables associated
991                            with this class, via multiple inheritance.   */
992                         register_other_binfo_vtables (binfo, base_class,
993                                                       vtbl_ptr_array);
994                       }
995                   }
996               }
997           }
998       current_set_size = vtbl_ptr_array->length();
999
1000       /* Sometimes we need to initialize the set symbol even if we are
1001          not adding any vtable pointers to the set in the current
1002          compilation unit.  In that case, we need to initialize the
1003          set to our best guess as to what the eventual size of the set
1004          hash table will be (to prevent having to re-size the hash
1005          table later).  */
1006
1007       size_hint = guess_num_vtable_pointers (current->class_info);
1008
1009       /* If we have added vtable pointers to the set in this
1010          compilation unit, adjust the size hint for the set's hash
1011          table appropriately.  */
1012       if (vtbl_ptr_array->length() > 0)
1013         {
1014           unsigned len = vtbl_ptr_array->length();
1015           while ((size_t) len > size_hint)
1016             size_hint <<= 1;
1017         }
1018       size_hint_arg = build_int_cst (size_type_node, size_hint);
1019
1020       /* Get the key-buffer argument.  */
1021       arg2 = build_key_buffer_arg (base_ptr_var_decl);
1022
1023       if (str2 == NULL_TREE)
1024         str2 = build_string_literal (strlen ("unknown") + 1,
1025                                      "unknown");
1026
1027       if (flag_vtv_debug)
1028         output_set_info (current->class_info->class_type,
1029                          *vtbl_ptr_array);
1030
1031       if (vtbl_ptr_array->length() > 1)
1032         {
1033           insert_call_to_register_set (current->class_name,
1034                                        vtbl_ptr_array, body, arg1, arg2,
1035                                        size_hint_arg);
1036           registered_at_least_one = true;
1037         }
1038       else
1039         {
1040
1041           if (vtbl_ptr_array->length() > 0
1042               || (current->is_used
1043                   || (current->registered->size() > 0)))
1044             {
1045               insert_call_to_register_pair (vtbl_ptr_array,
1046                                             arg1, arg2, size_hint_arg, str1,
1047                                             str2, body);
1048               registered_at_least_one = true;
1049             }
1050         }
1051
1052       if (flag_vtv_counts && current_set_size > 0)
1053         write_out_current_set_data (base_class, current_set_size);
1054
1055     }
1056
1057   return registered_at_least_one;
1058 }
1059
1060 /* Given a tree containing a class type (CLASS_TYPE), this function
1061    finds and returns the class hierarchy node for that class in our
1062    data structure.  */
1063
1064 static struct vtv_graph_node *
1065 find_graph_node (tree class_type)
1066 {
1067   struct vtbl_map_node *vtbl_node;
1068
1069   vtbl_node = vtbl_map_get_node (TYPE_MAIN_VARIANT (class_type));
1070   if (vtbl_node)
1071     return vtbl_node->class_info;
1072
1073   return NULL;
1074 }
1075
1076 /* Add base class/derived class pair to our internal class hierarchy
1077    data structure.  BASE_NODE is our vtv_graph_node that corresponds
1078    to a base class.  DERIVED_NODE is our vtv_graph_node that
1079    corresponds to a class that is a descendant of the base class
1080    (possibly the base class itself).  */
1081
1082 static void
1083 add_hierarchy_pair (struct vtv_graph_node *base_node,
1084                     struct vtv_graph_node *derived_node)
1085 {
1086   (base_node->children).safe_push (derived_node);
1087   (derived_node->parents).safe_push (base_node);
1088 }
1089
1090 /* This functions adds a new base class/derived class relationship to
1091    our class hierarchy data structure.  Both parameters are trees
1092    representing the class types, i.e. RECORD_TYPE trees.
1093    DERIVED_CLASS can be the same as BASE_CLASS.  */
1094
1095 static void
1096 update_class_hierarchy_information (tree base_class,
1097                                     tree derived_class)
1098 {
1099   struct vtv_graph_node *base_node = find_graph_node (base_class);
1100   struct vtv_graph_node *derived_node = find_graph_node (derived_class);
1101
1102   add_hierarchy_pair (base_node, derived_node);
1103 }
1104
1105
1106 static void
1107 write_out_vtv_count_data (void)
1108 {
1109   static int vtv_count_log_fd = -1;
1110   char buffer[1024];
1111   int unused_vtbl_map_vars = 0;
1112   int bytes_written __attribute__ ((unused));
1113   char *file_name = get_log_file_name ("vtv_count_data.log");
1114
1115   if (vtv_count_log_fd == -1)
1116     vtv_count_log_fd = open (file_name,
1117                              O_WRONLY | O_APPEND | O_CREAT, S_IRWXU);
1118   if (vtv_count_log_fd == -1)
1119     {
1120       warning_at (UNKNOWN_LOCATION, 0,
1121                   "unable to open log file %<vtv_count_data.log%>: %m");
1122       return;
1123     }
1124
1125   for (unsigned i = 0; i < num_vtable_map_nodes; ++i)
1126     {
1127       struct vtbl_map_node *current = vtbl_map_nodes_vec[i];
1128       if (!current->is_used
1129           && current->registered->size() == 0)
1130         unused_vtbl_map_vars++;
1131     }
1132
1133   snprintf (buffer, sizeof (buffer), "%s %d %d %d %d %d\n",
1134             main_input_filename, total_num_virtual_calls,
1135             total_num_verified_vcalls, num_calls_to_regset,
1136             num_calls_to_regpair, unused_vtbl_map_vars);
1137
1138   bytes_written = write (vtv_count_log_fd, buffer, strlen (buffer));
1139 }
1140
1141 /* This function calls register_all_pairs, which actually generates
1142    all the calls to __VLTRegisterPair (in the verification constructor
1143    init function).  It also generates the calls to
1144    __VLTChangePermission, if the verification constructor init
1145    function is going into the preinit array.  INIT_ROUTINE_BODY is
1146    the body of our constructior initialization function, to which we
1147    add our function calls.*/
1148
1149 bool
1150 vtv_register_class_hierarchy_information (tree init_routine_body)
1151 {
1152   bool registered_something = false;
1153  
1154   init_functions ();
1155
1156   if (num_vtable_map_nodes == 0)
1157     return false;
1158
1159   /* Add class hierarchy pairs to the vtable map data structure.  */
1160   registered_something = register_all_pairs (init_routine_body);
1161
1162   if (flag_vtv_counts)
1163     write_out_vtv_count_data ();
1164
1165   return registered_something;
1166 }
1167
1168
1169 /* Generate the special constructor function that calls
1170    __VLTChangePermission and __VLTRegisterPairs, and give it a very
1171    high initialization priority.  */
1172
1173 void
1174 vtv_generate_init_routine (void)
1175 {
1176   tree init_routine_body;
1177   bool vtable_classes_found = false;
1178
1179   push_lang_context (lang_name_c);
1180
1181   /* The priority for this init function (constructor) is carefully
1182      chosen so that it will happen after the calls to unprotect the
1183      memory used for vtable verification and before the memory is
1184      protected again.  */
1185   init_routine_body = vtv_start_verification_constructor_init_function ();
1186
1187   vtable_classes_found =
1188                  vtv_register_class_hierarchy_information (init_routine_body);
1189
1190   if (vtable_classes_found)
1191     {
1192       tree vtv_fndecl =
1193         vtv_finish_verification_constructor_init_function (init_routine_body);
1194       TREE_STATIC (vtv_fndecl) = 1;
1195       TREE_USED (vtv_fndecl) = 1;
1196       DECL_PRESERVE_P (vtv_fndecl) = 1;
1197 #if defined (TARGET_PECOFF)
1198       if (flag_vtable_verify == VTV_PREINIT_PRIORITY && !TARGET_PECOFF)
1199 #else
1200       if (flag_vtable_verify == VTV_PREINIT_PRIORITY)
1201 #endif
1202         DECL_STATIC_CONSTRUCTOR (vtv_fndecl) = 0;
1203
1204       gimplify_function_tree (vtv_fndecl);
1205       cgraph_node::add_new_function (vtv_fndecl, false);
1206
1207       symtab->process_new_functions ();
1208
1209 #if defined (TARGET_PECOFF)
1210       if (flag_vtable_verify == VTV_PREINIT_PRIORITY && !TARGET_PECOFF)
1211 #else
1212       if (flag_vtable_verify == VTV_PREINIT_PRIORITY)
1213 #endif
1214         assemble_vtv_preinit_initializer (vtv_fndecl);
1215
1216     }
1217   pop_lang_context ();
1218 }
1219
1220 /* This funtion takes a tree containing a class type (BASE_TYPE), and
1221    it either finds the existing vtbl_map_node for that class in our
1222    data structure, or it creates a new node and adds it to the data
1223    structure if there is not one for the class already.  As part of
1224    this process it also creates the global vtable map variable for the
1225    class.  */
1226
1227 struct vtbl_map_node *
1228 vtable_find_or_create_map_decl (tree base_type)
1229 {
1230   char *var_name = NULL;
1231   struct vtbl_map_node *vtable_map_node = NULL;
1232
1233   /* Verify the type has an associated vtable.  */
1234   if (!TYPE_BINFO (base_type) || !BINFO_VTABLE (TYPE_BINFO (base_type)))
1235     return NULL;
1236
1237   /* Create map lookup symbol for base class */
1238   var_name = get_mangled_vtable_map_var_name (base_type);
1239
1240   /* We've already created the variable; just look it.  */
1241   vtable_map_node = vtbl_map_get_node (TYPE_MAIN_VARIANT (base_type));
1242
1243   if (!vtable_map_node || (vtable_map_node->vtbl_map_decl == NULL_TREE))
1244     {
1245       /* If we haven't already created the *__vtable_map global
1246          variable for this class, do so now, and add it to the
1247          varpool, to make sure it gets saved and written out.  */
1248
1249       tree var_decl = NULL;
1250       tree var_type = build_pointer_type (void_type_node);
1251       tree initial_value = integer_zero_node;
1252
1253       var_decl  = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1254                               get_identifier (var_name), var_type);
1255
1256       DECL_EXTERNAL (var_decl) = 0;
1257       TREE_STATIC (var_decl) = 1;
1258       DECL_VISIBILITY (var_decl) = VISIBILITY_HIDDEN;
1259       SET_DECL_ASSEMBLER_NAME (var_decl, get_identifier (var_name));
1260       DECL_ARTIFICIAL (var_decl) = 1;
1261       /* We cannot mark this variable as read-only because we want to be
1262          able to write to it at runtime.  */
1263       TREE_READONLY (var_decl) = 0;
1264       DECL_IGNORED_P (var_decl) = 1;
1265       DECL_PRESERVE_P (var_decl) = 1;
1266
1267       /* Put these mmap variables in thr .vtable_map_vars section, so
1268          we can find and protect them.  */
1269
1270       set_decl_section_name (var_decl, ".vtable_map_vars");
1271       symtab_node::get (var_decl)->implicit_section = true;
1272       DECL_INITIAL (var_decl) = initial_value;
1273
1274       comdat_linkage (var_decl);
1275
1276       varpool_node::finalize_decl (var_decl);
1277       if (!vtable_map_node)
1278         vtable_map_node =
1279                    find_or_create_vtbl_map_node (TYPE_MAIN_VARIANT (base_type));
1280       if (vtable_map_node->vtbl_map_decl == NULL_TREE)
1281         vtable_map_node->vtbl_map_decl = var_decl;
1282     }
1283
1284   gcc_assert (vtable_map_node);
1285   return vtable_map_node;
1286 }
1287
1288 /* This function is used to build up our class hierarchy data for a
1289    particular class.  TYPE is the record_type tree node for the
1290    class.  */
1291
1292 static void
1293 vtv_insert_single_class_info (tree type)
1294 {
1295   if (flag_vtable_verify)
1296     {
1297       tree binfo =  TYPE_BINFO (type);
1298       tree base_binfo;
1299       struct vtbl_map_node *own_map;
1300       int i;
1301
1302       /* First make sure to create the map for this record type.  */
1303       own_map = vtable_find_or_create_map_decl (type);
1304       if (own_map == NULL)
1305         return;
1306
1307       /* Go through the list of all base classes for the current
1308          (derived) type, make sure the *__vtable_map global variable
1309          for the base class exists, and add the base class/derived
1310          class pair to the class hierarchy information we are
1311          accumulating (for vtable pointer verification).  */
1312       for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
1313         {
1314           tree tree_val = BINFO_TYPE (base_binfo);
1315           struct vtbl_map_node *vtable_map_node = NULL;
1316
1317           vtable_map_node = vtable_find_or_create_map_decl (tree_val);
1318
1319           if (vtable_map_node != NULL)
1320             update_class_hierarchy_information (tree_val, type);
1321         }
1322     }
1323 }
1324
1325 /* This function adds classes we are interested in to a list of
1326    classes.  RECORD is the record_type node for the class we are
1327    adding to the list.  */
1328
1329 void
1330 vtv_save_class_info (tree record)
1331 {
1332   if (!flag_vtable_verify || TREE_CODE (record) == UNION_TYPE)
1333     return;
1334
1335   if (!vlt_saved_class_info)
1336     vec_alloc (vlt_saved_class_info, 10);
1337
1338   gcc_assert (TREE_CODE (record) == RECORD_TYPE);
1339
1340   vec_safe_push (vlt_saved_class_info, record);
1341 }
1342
1343
1344 /* This function goes through the list of classes we saved and calls
1345    vtv_insert_single_class_info on each one, to build up our class
1346    hierarchy data structure.  */
1347
1348 void
1349 vtv_recover_class_info (void)
1350 {
1351   tree current_class;
1352   unsigned i;
1353
1354   if (vlt_saved_class_info)
1355     {
1356       for (i = 0; i < vlt_saved_class_info->length(); ++i)
1357         {
1358           current_class = (*vlt_saved_class_info)[i];
1359           gcc_assert (TREE_CODE (current_class) == RECORD_TYPE);
1360           vtv_insert_single_class_info (current_class);
1361         }
1362     }
1363 }
1364
1365 #include "gt-cp-vtable-class-hierarchy.h"