+ /* Version ident */
+ fields = build_decl (FIELD_DECL, NULL_TREE, long_unsigned_type_node);
+ value = tree_cons (fields, convert (long_unsigned_type_node, build_int_2
+ (GCOV_VERSION, 0)), value);
+
+ /* NULL */
+ field = build_decl (FIELD_DECL, NULL_TREE, build_pointer_type
+ (build_qualified_type
+ (ginfo_type, TYPE_QUAL_CONST)));
+ TREE_CHAIN (field) = fields;
+ fields = field;
+ value = tree_cons (fields, null_pointer_node, value);
+
+ /* Filename */
+ {
+ tree filename_string;
+ char *filename;
+ int filename_len;
+
+ filename = getpwd ();
+ filename = (filename && da_file_name[0] != '/'
+ ? concat (filename, "/", da_file_name, NULL)
+ : da_file_name);
+ filename_len = strlen (filename);
+ filename_string = build_string (filename_len + 1, filename);
+ if (filename != da_file_name)
+ free (filename);
+ TREE_TYPE (filename_string) = build_array_type
+ (char_type_node, build_index_type
+ (build_int_2 (filename_len, 0)));
+
+ field = build_decl (FIELD_DECL, NULL_TREE, string_type);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+ value = tree_cons (fields, build1 (ADDR_EXPR, string_type,
+ filename_string), value);
+ }
+
+ /* Workspace */
+ field = build_decl (FIELD_DECL, NULL_TREE, long_integer_type_node);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+ value = tree_cons (fields,
+ convert (long_integer_type_node, integer_zero_node),
+ value);
+
+ /* function_info table */
+ {
+ struct function_list *item;
+ int num_nodes = 0;
+ tree array_value = NULL_TREE;
+ tree finfo_type, finfo_ptr_type;
+ tree name, checksum, arcs;
+
+ finfo_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
+ name = build_decl (FIELD_DECL, NULL_TREE, string_type);
+ checksum = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
+ TREE_CHAIN (checksum) = name;
+ arcs = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
+ TREE_CHAIN (arcs) = checksum;
+ finish_builtin_struct (finfo_type, "__function_info",
+ arcs, NULL_TREE);
+ finfo_ptr_type = build_pointer_type
+ (build_qualified_type (finfo_type, TYPE_QUAL_CONST));
+
+ for (item = functions_head; item != 0; item = item->next, num_nodes++)
+ {
+ size_t name_len = strlen (item->name);
+ tree finfo_value = NULL_TREE;
+ tree fname = build_string (name_len + 1, item->name);
+
+ TREE_TYPE (fname) = build_array_type
+ (char_type_node, build_index_type (build_int_2 (name_len, 0)));
+ finfo_value = tree_cons (name, build1
+ (ADDR_EXPR, string_type,
+ fname), finfo_value);
+ finfo_value = tree_cons (checksum, convert
+ (unsigned_type_node,
+ build_int_2 (item->cfg_checksum, 0)),
+ finfo_value);
+ finfo_value = tree_cons (arcs, convert
+ (unsigned_type_node,
+ build_int_2 (item->count_edges, 0)),
+ finfo_value);
+ array_value = tree_cons (NULL_TREE, build
+ (CONSTRUCTOR, finfo_type, NULL_TREE,
+ nreverse (finfo_value)), array_value);
+ }
+
+ /* Create constructor for array. */
+ if (num_nodes)
+ {
+ tree array_type;
+
+ array_type = build_array_type (finfo_type, build_index_type
+ (build_int_2 (num_nodes - 1, 0)));
+ array_value = build (CONSTRUCTOR, array_type,
+ NULL_TREE, nreverse (array_value));
+ array_value = build1
+ (ADDR_EXPR, finfo_ptr_type, array_value);
+ }
+ else
+ array_value = null_pointer_node;
+
+ field = build_decl (FIELD_DECL, NULL_TREE, finfo_ptr_type);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+ value = tree_cons (fields, array_value, value);
+
+ /* number of functions */
+ field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+ value = tree_cons (fields, convert (unsigned_type_node, build_int_2
+ (num_nodes, 0)), value);
+ }
+
+ /* arc count table */
+ {
+ tree counts_table = null_pointer_node;
+
+ if (profile_info.count_instrumented_edges)
+ {
+ tree gcov_type_array_type
+ = build_array_type (gcov_type, build_index_type
+ (build_int_2 (profile_info.
+ count_instrumented_edges - 1, 0)));
+ /* No values. */
+ counts_table
+ = build (VAR_DECL, gcov_type_array_type, NULL_TREE, NULL_TREE);
+ TREE_STATIC (counts_table) = 1;
+ DECL_NAME (counts_table) = get_identifier (XSTR (profiler_label, 0));
+ assemble_variable (counts_table, 0, 0, 0);
+ counts_table = build1 (ADDR_EXPR, gcov_ptr_type, counts_table);
+ }
+
+ field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+ value = tree_cons (fields, counts_table, value);
+ }
+
+ /* number of arc counts */
+ field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+ value = tree_cons (fields, convert
+ (unsigned_type_node,
+ build_int_2 (profile_info
+ .count_instrumented_edges, 0)),
+ value);
+
+ finish_builtin_struct (ginfo_type, "__gcov_info", fields, NULL_TREE);
+ structure = build (VAR_DECL, ginfo_type, NULL_TREE, NULL_TREE);
+ DECL_INITIAL (structure)
+ = build (CONSTRUCTOR, ginfo_type, NULL_TREE, nreverse (value));
+ TREE_STATIC (structure) = 1;
+ ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
+ DECL_NAME (structure) = get_identifier (name);
+
+ /* Build structure. */
+ assemble_variable (structure, 0, 0, 0);