blob: 2a24b454e71fce8af35d915f14f686ff6adfa9ac [file] [log] [blame]
/**
* @file abi.cpp
*
* @remark Copyright 2002 OProfile authors
* @remark Read the file COPYING
*
* @author Graydon Hoare
* @author John Levon
*/
#include "abi.h"
#include "odb.h"
#include "op_sample_file.h"
#include <iostream>
#include <cassert>
using namespace std;
typedef map<string, int> abi_map;
typedef map<string, int>::const_iterator abi_iter;
#define byte_addr(x) (reinterpret_cast<unsigned char *>(&(x)))
#define field_offset(s, f) (byte_addr(s.f) - byte_addr(s))
abi_exception::abi_exception(string const d) : desc(d) {}
abi::abi()
{
odb_node_t node;
odb_descr_t descr;
struct opd_header header;
slots["sizeof_double"] = sizeof(double);
slots["sizeof_time_t"] = sizeof(time_t);
slots["sizeof_u8"] = sizeof(u8);
slots["sizeof_u32"] = sizeof(u32);
slots["sizeof_int"] = sizeof(int);
slots["sizeof_unsigned_int"] = sizeof(unsigned int);
slots["sizeof_odb_key_t"] = sizeof(odb_key_t);
slots["sizeof_odb_index_t"] = sizeof(odb_index_t);
slots["sizeof_odb_value_t"] = sizeof(odb_value_t);
slots["sizeof_odb_node_nr_t"] = sizeof(odb_node_nr_t);
slots["sizeof_odb_descr_t"] = sizeof(odb_descr_t);
slots["sizeof_odb_node_t"] = sizeof(odb_node_t);
slots["sizeof_struct_opd_header"] = sizeof(struct opd_header);
slots["offsetof_node_key"] = field_offset(node, key);
slots["offsetof_node_value"] = field_offset(node, value);
slots["offsetof_node_next"] = field_offset(node, next);
slots["offsetof_descr_size"] = field_offset(descr, size);
slots["offsetof_descr_current_size"] = field_offset(descr, current_size);
slots["offsetof_header_magic"] = field_offset(header, magic);
slots["offsetof_header_version"] = field_offset(header, version);
slots["offsetof_header_cpu_type"] = field_offset(header, cpu_type);
slots["offsetof_header_ctr_event"] = field_offset(header, ctr_event);
slots["offsetof_header_ctr_um"] = field_offset(header, ctr_um);
slots["offsetof_header_ctr_count"] = field_offset(header, ctr_count);
slots["offsetof_header_is_kernel"] = field_offset(header, is_kernel);
slots["offsetof_header_cpu_speed"] = field_offset(header, cpu_speed);
slots["offsetof_header_mtime"] = field_offset(header, mtime);
slots["offsetof_header_cg_to_is_kernel"] = field_offset(header,
cg_to_is_kernel);
slots["offsetof_header_anon_start"] = field_offset(header, anon_start);
slots["offsetof_header_cg_to_anon_start"] = field_offset(header,
cg_to_anon_start);
// determine endianness
unsigned int probe = 0xff;
size_t sz = sizeof(unsigned int);
unsigned char * probe_byte = reinterpret_cast<unsigned char *>(&probe);
assert(probe_byte[0] == 0xff || probe_byte[sz - 1] == 0xff);
if (probe_byte[0] == 0xff)
slots["little_endian"] = 1;
else
slots["little_endian"] = 0;
}
abi::abi(abi const & other)
{
slots.clear();
slots.insert(other.slots.begin(), other.slots.end());
}
int abi::need(string const key) const throw (abi_exception)
{
if (slots.find(key) != slots.end())
return slots.find(key)->second;
else
throw abi_exception(string("missing ABI key: ") + key);
}
bool abi::operator==(abi const & other) const
{
abi_iter i = slots.begin();
abi_iter e = slots.end();
abi_map const & theirs = other.slots;
for (; i != e; ++i) {
if (theirs.find(i->first) == theirs.end() ||
theirs.find(i->first)->second != i->second)
return false;
}
return true;
}
ostream & operator<<(ostream & o, abi const & abi)
{
abi_iter i = abi.slots.begin();
abi_iter e = abi.slots.end();
for (; i != e; ++i) {
o << i->first << " " << i->second << endl;
}
return o;
}
istream & operator>>(istream & i, abi & abi)
{
string key;
int val;
abi.slots.clear();
while(i >> key >> val) {
abi.slots[key] = val;
}
return i;
}