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
22static 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
61struct op_abi_entry const * get_abi(void)
62{
63	return abi_entries;
64}
65
66
67int 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
79int 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