1 /**
2 * @file op_abi.c
3 * This file contains a simple C interface to the ABI-describing functionality,
4 * the majority of which is implemented in C++. This is the file which is
5 * intended for use in files outside the /libabi directory.
6 *
7 * @remark Copyright 2002, 2005 OProfile authors
8 * @remark Read the file COPYING
9 *
10 * @author Graydon Hoare
11 * @author Philippe Elie
12 */
13
14 #include "op_abi.h"
15 #include "odb.h"
16 #include "op_sample_file.h"
17
18 #include <stdio.h>
19 #include <stddef.h>
20 #include <assert.h>
21
22 static struct op_abi_entry const abi_entries[] = {
23 { "sizeof_double", sizeof(double) },
24 { "sizeof_time_t", sizeof(time_t) },
25 { "sizeof_u8", sizeof(u8) },
26 { "sizeof_u32", sizeof(u32) },
27 { "sizeof_int", sizeof(int) },
28 { "sizeof_unsigned_int", sizeof(unsigned int) },
29 { "sizeof_odb_key_t", sizeof(odb_key_t) },
30 { "sizeof_odb_index_t", sizeof(odb_index_t) },
31 { "sizeof_odb_value_t", sizeof(odb_value_t) },
32 { "sizeof_odb_node_nr_t", sizeof(odb_node_nr_t) },
33 { "sizeof_odb_descr_t", sizeof(odb_descr_t) },
34 { "sizeof_odb_node_t", sizeof(odb_node_t) },
35 { "sizeof_struct_opd_header", sizeof(struct opd_header) },
36
37 { "offsetof_node_key", offsetof(odb_node_t, key) },
38 { "offsetof_node_value", offsetof(odb_node_t, value) },
39 { "offsetof_node_next", offsetof(odb_node_t, next) },
40
41 { "offsetof_descr_size", offsetof(odb_descr_t, size) },
42 { "offsetof_descr_current_size", offsetof(odb_descr_t, current_size) },
43
44 { "offsetof_header_magic", offsetof(struct opd_header, magic) },
45 { "offsetof_header_version", offsetof(struct opd_header, version) },
46 { "offsetof_header_cpu_type", offsetof(struct opd_header, cpu_type) },
47 { "offsetof_header_ctr_event", offsetof(struct opd_header, ctr_event) },
48 { "offsetof_header_ctr_um", offsetof(struct opd_header, ctr_um) },
49 { "offsetof_header_ctr_count", offsetof(struct opd_header, ctr_count) },
50 { "offsetof_header_is_kernel", offsetof(struct opd_header, is_kernel) },
51 { "offsetof_header_cpu_speed", offsetof(struct opd_header, cpu_speed) },
52 { "offsetof_header_mtime", offsetof(struct opd_header, mtime) },
53 { "offsetof_header_cg_to_is_kernel", offsetof(struct opd_header, cg_to_is_kernel), },
54 { "offsetof_header_anon_start", offsetof(struct opd_header, anon_start) },
55 { "offsetof_header_cg_to_anon_start", offsetof(struct opd_header, cg_to_anon_start) },
56
57 { NULL, 0 },
58 };
59
60
get_abi(void)61 struct op_abi_entry const * get_abi(void)
62 {
63 return abi_entries;
64 }
65
66
op_little_endian(void)67 int op_little_endian(void)
68 {
69 unsigned int probe = 0xff;
70 size_t sz = sizeof(unsigned int);
71 unsigned char * probe_byte = (unsigned char *)&probe;
72
73 assert(probe_byte[0] == 0xff || probe_byte[sz - 1] == 0xff);
74
75 return probe_byte[0] == 0xff;
76 }
77
78
op_write_abi_to_file(char const * abi_file)79 int op_write_abi_to_file(char const * abi_file)
80 {
81 FILE * fp;
82 struct op_abi_entry const * abi_entry;
83
84 if ((fp = fopen(abi_file, "w")) == NULL)
85 return 0;
86
87 for (abi_entry = get_abi() ; abi_entry->name != NULL; ++abi_entry)
88 fprintf(fp, "%s %u\n", abi_entry->name, abi_entry->offset);
89 fprintf(fp, "little_endian %d\n", op_little_endian());
90
91 fclose(fp);
92
93 return 1;
94 }
95