/**
* @file op_abi.c
* This file contains a simple C interface to the ABI-describing functionality,
* the majority of which is implemented in C++. This is the file which is
* intended for use in files outside the /libabi directory.
*
* @remark Copyright 2002, 2005 OProfile authors
* @remark Read the file COPYING
*
* @author Graydon Hoare
* @author Philippe Elie
*/
#include "op_abi.h"
#include "odb.h"
#include "op_sample_file.h"
#include <stdio.h>
#include <stddef.h>
#include <assert.h>
static struct op_abi_entry const abi_entries[] = {
{ "sizeof_double", sizeof(double) },
{ "sizeof_time_t", sizeof(time_t) },
{ "sizeof_u8", sizeof(u8) },
{ "sizeof_u32", sizeof(u32) },
{ "sizeof_int", sizeof(int) },
{ "sizeof_unsigned_int", sizeof(unsigned int) },
{ "sizeof_odb_key_t", sizeof(odb_key_t) },
{ "sizeof_odb_index_t", sizeof(odb_index_t) },
{ "sizeof_odb_value_t", sizeof(odb_value_t) },
{ "sizeof_odb_node_nr_t", sizeof(odb_node_nr_t) },
{ "sizeof_odb_descr_t", sizeof(odb_descr_t) },
{ "sizeof_odb_node_t", sizeof(odb_node_t) },
{ "sizeof_struct_opd_header", sizeof(struct opd_header) },
{ "offsetof_node_key", offsetof(odb_node_t, key) },
{ "offsetof_node_value", offsetof(odb_node_t, value) },
{ "offsetof_node_next", offsetof(odb_node_t, next) },
{ "offsetof_descr_size", offsetof(odb_descr_t, size) },
{ "offsetof_descr_current_size", offsetof(odb_descr_t, current_size) },
{ "offsetof_header_magic", offsetof(struct opd_header, magic) },
{ "offsetof_header_version", offsetof(struct opd_header, version) },
{ "offsetof_header_cpu_type", offsetof(struct opd_header, cpu_type) },
{ "offsetof_header_ctr_event", offsetof(struct opd_header, ctr_event) },
{ "offsetof_header_ctr_um", offsetof(struct opd_header, ctr_um) },
{ "offsetof_header_ctr_count", offsetof(struct opd_header, ctr_count) },
{ "offsetof_header_is_kernel", offsetof(struct opd_header, is_kernel) },
{ "offsetof_header_cpu_speed", offsetof(struct opd_header, cpu_speed) },
{ "offsetof_header_mtime", offsetof(struct opd_header, mtime) },
{ "offsetof_header_cg_to_is_kernel", offsetof(struct opd_header, cg_to_is_kernel), },
{ "offsetof_header_anon_start", offsetof(struct opd_header, anon_start) },
{ "offsetof_header_cg_to_anon_start", offsetof(struct opd_header, cg_to_anon_start) },
{ NULL, 0 },
};
struct op_abi_entry const * get_abi(void)
{
return abi_entries;
}
int op_little_endian(void)
{
unsigned int probe = 0xff;
size_t sz = sizeof(unsigned int);
unsigned char * probe_byte = (unsigned char *)&probe;
assert(probe_byte[0] == 0xff || probe_byte[sz - 1] == 0xff);
return probe_byte[0] == 0xff;
}
int op_write_abi_to_file(char const * abi_file)
{
FILE * fp;
struct op_abi_entry const * abi_entry;
if ((fp = fopen(abi_file, "w")) == NULL)
return 0;
for (abi_entry = get_abi() ; abi_entry->name != NULL; ++abi_entry)
fprintf(fp, "%s %u\n", abi_entry->name, abi_entry->offset);
fprintf(fp, "little_endian %d\n", op_little_endian());
fclose(fp);
return 1;
}