Upstream | cc2ee17 | 1970-01-12 13:46:40 +0000 | [diff] [blame^] | 1 | /** |
| 2 | * @file abi.cpp |
| 3 | * |
| 4 | * @remark Copyright 2002 OProfile authors |
| 5 | * @remark Read the file COPYING |
| 6 | * |
| 7 | * @author Graydon Hoare |
| 8 | * @author John Levon |
| 9 | */ |
| 10 | |
| 11 | #include "abi.h" |
| 12 | #include "odb.h" |
| 13 | #include "op_sample_file.h" |
| 14 | |
| 15 | #include <iostream> |
| 16 | #include <cassert> |
| 17 | |
| 18 | using namespace std; |
| 19 | |
| 20 | typedef map<string, int> abi_map; |
| 21 | typedef map<string, int>::const_iterator abi_iter; |
| 22 | |
| 23 | #define byte_addr(x) (reinterpret_cast<unsigned char *>(&(x))) |
| 24 | #define field_offset(s, f) (byte_addr(s.f) - byte_addr(s)) |
| 25 | |
| 26 | abi_exception::abi_exception(string const d) : desc(d) {} |
| 27 | |
| 28 | |
| 29 | abi::abi() |
| 30 | { |
| 31 | odb_node_t node; |
| 32 | odb_descr_t descr; |
| 33 | struct opd_header header; |
| 34 | |
| 35 | slots["sizeof_double"] = sizeof(double); |
| 36 | slots["sizeof_time_t"] = sizeof(time_t); |
| 37 | slots["sizeof_u8"] = sizeof(u8); |
| 38 | slots["sizeof_u32"] = sizeof(u32); |
| 39 | slots["sizeof_int"] = sizeof(int); |
| 40 | slots["sizeof_unsigned_int"] = sizeof(unsigned int); |
| 41 | slots["sizeof_odb_key_t"] = sizeof(odb_key_t); |
| 42 | slots["sizeof_odb_index_t"] = sizeof(odb_index_t); |
| 43 | slots["sizeof_odb_value_t"] = sizeof(odb_value_t); |
| 44 | slots["sizeof_odb_node_nr_t"] = sizeof(odb_node_nr_t); |
| 45 | slots["sizeof_odb_descr_t"] = sizeof(odb_descr_t); |
| 46 | slots["sizeof_odb_node_t"] = sizeof(odb_node_t); |
| 47 | slots["sizeof_struct_opd_header"] = sizeof(struct opd_header); |
| 48 | |
| 49 | slots["offsetof_node_key"] = field_offset(node, key); |
| 50 | slots["offsetof_node_value"] = field_offset(node, value); |
| 51 | slots["offsetof_node_next"] = field_offset(node, next); |
| 52 | |
| 53 | slots["offsetof_descr_size"] = field_offset(descr, size); |
| 54 | slots["offsetof_descr_current_size"] = field_offset(descr, current_size); |
| 55 | |
| 56 | slots["offsetof_header_magic"] = field_offset(header, magic); |
| 57 | slots["offsetof_header_version"] = field_offset(header, version); |
| 58 | slots["offsetof_header_cpu_type"] = field_offset(header, cpu_type); |
| 59 | slots["offsetof_header_ctr_event"] = field_offset(header, ctr_event); |
| 60 | slots["offsetof_header_ctr_um"] = field_offset(header, ctr_um); |
| 61 | slots["offsetof_header_ctr_count"] = field_offset(header, ctr_count); |
| 62 | slots["offsetof_header_is_kernel"] = field_offset(header, is_kernel); |
| 63 | slots["offsetof_header_cpu_speed"] = field_offset(header, cpu_speed); |
| 64 | slots["offsetof_header_mtime"] = field_offset(header, mtime); |
| 65 | slots["offsetof_header_cg_to_is_kernel"] = field_offset(header, |
| 66 | cg_to_is_kernel); |
| 67 | slots["offsetof_header_anon_start"] = field_offset(header, anon_start); |
| 68 | slots["offsetof_header_cg_to_anon_start"] = field_offset(header, |
| 69 | cg_to_anon_start); |
| 70 | |
| 71 | // determine endianness |
| 72 | |
| 73 | unsigned int probe = 0xff; |
| 74 | size_t sz = sizeof(unsigned int); |
| 75 | unsigned char * probe_byte = reinterpret_cast<unsigned char *>(&probe); |
| 76 | |
| 77 | assert(probe_byte[0] == 0xff || probe_byte[sz - 1] == 0xff); |
| 78 | |
| 79 | if (probe_byte[0] == 0xff) |
| 80 | slots["little_endian"] = 1; |
| 81 | else |
| 82 | slots["little_endian"] = 0; |
| 83 | } |
| 84 | |
| 85 | |
| 86 | abi::abi(abi const & other) |
| 87 | { |
| 88 | slots.clear(); |
| 89 | slots.insert(other.slots.begin(), other.slots.end()); |
| 90 | } |
| 91 | |
| 92 | |
| 93 | int abi::need(string const key) const throw (abi_exception) |
| 94 | { |
| 95 | if (slots.find(key) != slots.end()) |
| 96 | return slots.find(key)->second; |
| 97 | else |
| 98 | throw abi_exception(string("missing ABI key: ") + key); |
| 99 | } |
| 100 | |
| 101 | |
| 102 | bool abi::operator==(abi const & other) const |
| 103 | { |
| 104 | abi_iter i = slots.begin(); |
| 105 | abi_iter e = slots.end(); |
| 106 | abi_map const & theirs = other.slots; |
| 107 | |
| 108 | for (; i != e; ++i) { |
| 109 | if (theirs.find(i->first) == theirs.end() || |
| 110 | theirs.find(i->first)->second != i->second) |
| 111 | return false; |
| 112 | } |
| 113 | |
| 114 | return true; |
| 115 | } |
| 116 | |
| 117 | |
| 118 | ostream & operator<<(ostream & o, abi const & abi) |
| 119 | { |
| 120 | abi_iter i = abi.slots.begin(); |
| 121 | abi_iter e = abi.slots.end(); |
| 122 | |
| 123 | for (; i != e; ++i) { |
| 124 | o << i->first << " " << i->second << endl; |
| 125 | } |
| 126 | |
| 127 | return o; |
| 128 | } |
| 129 | |
| 130 | |
| 131 | istream & operator>>(istream & i, abi & abi) |
| 132 | { |
| 133 | string key; |
| 134 | int val; |
| 135 | abi.slots.clear(); |
| 136 | |
| 137 | while(i >> key >> val) { |
| 138 | abi.slots[key] = val; |
| 139 | } |
| 140 | |
| 141 | return i; |
| 142 | } |