Commit | Line | Data |
---|---|---|
6dc2ca62 MD |
1 | /* |
2 | * Common Trace Format | |
3 | * | |
4 | * Integers read/write functions. | |
5 | * | |
64fa3fec MD |
6 | * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation |
7 | * | |
8 | * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
6dc2ca62 | 9 | * |
ccd7e1c8 MD |
10 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
11 | * of this software and associated documentation files (the "Software"), to deal | |
12 | * in the Software without restriction, including without limitation the rights | |
13 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
14 | * copies of the Software, and to permit persons to whom the Software is | |
15 | * furnished to do so, subject to the following conditions: | |
de0ba614 | 16 | * |
ccd7e1c8 MD |
17 | * The above copyright notice and this permission notice shall be included in |
18 | * all copies or substantial portions of the Software. | |
6dc2ca62 MD |
19 | */ |
20 | ||
4c8bfb7e MD |
21 | #include <babeltrace/ctf/types.h> |
22 | #include <babeltrace/bitfield.h> | |
6dc2ca62 MD |
23 | #include <stdint.h> |
24 | #include <glib.h> | |
9b0422a0 | 25 | #include <babeltrace/endian.h> |
6dc2ca62 | 26 | |
5385cf15 MD |
27 | /* |
28 | * The aligned read/write functions are expected to be faster than the | |
29 | * bitfield variants. They will be enabled eventually as an | |
30 | * optimisation. | |
31 | */ | |
32 | ||
7fe00194 | 33 | static |
c5e74408 MD |
34 | int _aligned_integer_read(struct stream_pos *ppos, |
35 | struct definition *definition) | |
6dc2ca62 | 36 | { |
d11e9c49 MD |
37 | struct definition_integer *integer_definition = |
38 | container_of(definition, struct definition_integer, p); | |
39 | const struct declaration_integer *integer_declaration = | |
40 | integer_definition->declaration; | |
46322b33 | 41 | struct ctf_stream_pos *pos = ctf_pos(ppos); |
f6625916 | 42 | int rbo = (integer_declaration->byte_order != BYTE_ORDER); /* reverse byte order */ |
6dc2ca62 | 43 | |
46322b33 | 44 | ctf_align_pos(pos, integer_declaration->p.alignment); |
6dc2ca62 | 45 | |
c5e74408 MD |
46 | if (!ctf_pos_access_ok(pos, integer_declaration->len)) |
47 | return -EFAULT; | |
48 | ||
670977d3 | 49 | assert(!(pos->offset % CHAR_BIT)); |
d11e9c49 MD |
50 | if (!integer_declaration->signedness) { |
51 | switch (integer_declaration->len) { | |
52 | case 8: | |
53 | { | |
54 | uint8_t v; | |
55 | ||
5385cf15 | 56 | v = *(const uint8_t *) ctf_get_pos_addr(pos); |
d11e9c49 MD |
57 | integer_definition->value._unsigned = v; |
58 | break; | |
59 | } | |
60 | case 16: | |
61 | { | |
62 | uint16_t v; | |
63 | ||
5385cf15 | 64 | v = *(const uint16_t *) ctf_get_pos_addr(pos); |
d11e9c49 MD |
65 | integer_definition->value._unsigned = |
66 | rbo ? GUINT16_SWAP_LE_BE(v) : v; | |
67 | break; | |
68 | } | |
69 | case 32: | |
70 | { | |
71 | uint32_t v; | |
72 | ||
5385cf15 | 73 | v = *(const uint32_t *) ctf_get_pos_addr(pos); |
d11e9c49 MD |
74 | integer_definition->value._unsigned = |
75 | rbo ? GUINT32_SWAP_LE_BE(v) : v; | |
76 | break; | |
77 | } | |
78 | case 64: | |
79 | { | |
80 | uint64_t v; | |
81 | ||
5385cf15 | 82 | v = *(const uint64_t *) ctf_get_pos_addr(pos); |
d11e9c49 MD |
83 | integer_definition->value._unsigned = |
84 | rbo ? GUINT64_SWAP_LE_BE(v) : v; | |
85 | break; | |
86 | } | |
87 | default: | |
88 | assert(0); | |
89 | } | |
90 | } else { | |
91 | switch (integer_declaration->len) { | |
92 | case 8: | |
93 | { | |
94 | int8_t v; | |
95 | ||
5385cf15 | 96 | v = *(const int8_t *) ctf_get_pos_addr(pos); |
d11e9c49 MD |
97 | integer_definition->value._signed = v; |
98 | break; | |
99 | } | |
100 | case 16: | |
101 | { | |
102 | int16_t v; | |
103 | ||
5385cf15 | 104 | v = *(const int16_t *) ctf_get_pos_addr(pos); |
d11e9c49 | 105 | integer_definition->value._signed = |
27265cb3 | 106 | rbo ? (int16_t) GUINT16_SWAP_LE_BE(v) : v; |
d11e9c49 MD |
107 | break; |
108 | } | |
109 | case 32: | |
110 | { | |
111 | int32_t v; | |
112 | ||
5385cf15 | 113 | v = *(const int32_t *) ctf_get_pos_addr(pos); |
d11e9c49 | 114 | integer_definition->value._signed = |
27265cb3 | 115 | rbo ? (int32_t) GUINT32_SWAP_LE_BE(v) : v; |
d11e9c49 MD |
116 | break; |
117 | } | |
118 | case 64: | |
119 | { | |
120 | int64_t v; | |
121 | ||
5385cf15 | 122 | v = *(const int64_t *) ctf_get_pos_addr(pos); |
d11e9c49 | 123 | integer_definition->value._signed = |
27265cb3 | 124 | rbo ? (int64_t) GUINT64_SWAP_LE_BE(v) : v; |
d11e9c49 MD |
125 | break; |
126 | } | |
127 | default: | |
128 | assert(0); | |
129 | } | |
6dc2ca62 | 130 | } |
d11e9c49 | 131 | ctf_move_pos(pos, integer_declaration->len); |
c5e74408 | 132 | return 0; |
6dc2ca62 MD |
133 | } |
134 | ||
7fe00194 | 135 | static |
c5e74408 | 136 | int _aligned_integer_write(struct stream_pos *ppos, |
d11e9c49 | 137 | struct definition *definition) |
6dc2ca62 | 138 | { |
d11e9c49 MD |
139 | struct definition_integer *integer_definition = |
140 | container_of(definition, struct definition_integer, p); | |
141 | const struct declaration_integer *integer_declaration = | |
142 | integer_definition->declaration; | |
46322b33 | 143 | struct ctf_stream_pos *pos = ctf_pos(ppos); |
f6625916 | 144 | int rbo = (integer_declaration->byte_order != BYTE_ORDER); /* reverse byte order */ |
6dc2ca62 | 145 | |
46322b33 | 146 | ctf_align_pos(pos, integer_declaration->p.alignment); |
6dc2ca62 | 147 | |
c5e74408 MD |
148 | if (!ctf_pos_access_ok(pos, integer_declaration->len)) |
149 | return -EFAULT; | |
150 | ||
670977d3 | 151 | assert(!(pos->offset % CHAR_BIT)); |
bed864a7 | 152 | if (pos->dummy) |
6dc2ca62 | 153 | goto end; |
d11e9c49 MD |
154 | if (!integer_declaration->signedness) { |
155 | uint64_t v = integer_definition->value._unsigned; | |
156 | ||
157 | switch (integer_declaration->len) { | |
158 | case 8: *(uint8_t *) ctf_get_pos_addr(pos) = (uint8_t) v; | |
159 | break; | |
160 | case 16: | |
161 | *(uint16_t *) ctf_get_pos_addr(pos) = rbo ? | |
162 | GUINT16_SWAP_LE_BE((uint16_t) v) : | |
163 | (uint16_t) v; | |
164 | break; | |
165 | case 32: | |
166 | *(uint32_t *) ctf_get_pos_addr(pos) = rbo ? | |
167 | GUINT32_SWAP_LE_BE((uint32_t) v) : | |
168 | (uint32_t) v; | |
169 | break; | |
170 | case 64: | |
171 | *(uint64_t *) ctf_get_pos_addr(pos) = rbo ? | |
172 | GUINT64_SWAP_LE_BE(v) : v; | |
173 | break; | |
174 | default: | |
175 | assert(0); | |
176 | } | |
177 | } else { | |
178 | int64_t v = integer_definition->value._signed; | |
179 | ||
180 | switch (integer_declaration->len) { | |
181 | case 8: *(int8_t *) ctf_get_pos_addr(pos) = (int8_t) v; | |
182 | break; | |
183 | case 16: | |
184 | *(int16_t *) ctf_get_pos_addr(pos) = rbo ? | |
27265cb3 | 185 | (int16_t) GUINT16_SWAP_LE_BE((int16_t) v) : |
d11e9c49 MD |
186 | (int16_t) v; |
187 | break; | |
188 | case 32: | |
189 | *(int32_t *) ctf_get_pos_addr(pos) = rbo ? | |
27265cb3 | 190 | (int32_t) GUINT32_SWAP_LE_BE((int32_t) v) : |
d11e9c49 MD |
191 | (int32_t) v; |
192 | break; | |
193 | case 64: | |
194 | *(int64_t *) ctf_get_pos_addr(pos) = rbo ? | |
195 | GUINT64_SWAP_LE_BE(v) : v; | |
196 | break; | |
197 | default: | |
198 | assert(0); | |
199 | } | |
6dc2ca62 MD |
200 | } |
201 | end: | |
46322b33 | 202 | ctf_move_pos(pos, integer_declaration->len); |
c5e74408 | 203 | return 0; |
6dc2ca62 MD |
204 | } |
205 | ||
c5e74408 | 206 | int ctf_integer_read(struct stream_pos *ppos, struct definition *definition) |
6dc2ca62 | 207 | { |
d11e9c49 MD |
208 | struct definition_integer *integer_definition = |
209 | container_of(definition, struct definition_integer, p); | |
210 | const struct declaration_integer *integer_declaration = | |
211 | integer_definition->declaration; | |
46322b33 | 212 | struct ctf_stream_pos *pos = ctf_pos(ppos); |
6dc2ca62 | 213 | |
5385cf15 MD |
214 | if (!(integer_declaration->p.alignment % CHAR_BIT) |
215 | && !(integer_declaration->len % CHAR_BIT)) { | |
c5e74408 | 216 | return _aligned_integer_read(ppos, definition); |
5385cf15 MD |
217 | } |
218 | ||
46322b33 | 219 | ctf_align_pos(pos, integer_declaration->p.alignment); |
c5e74408 MD |
220 | |
221 | if (!ctf_pos_access_ok(pos, integer_declaration->len)) | |
222 | return -EFAULT; | |
223 | ||
d11e9c49 MD |
224 | if (!integer_declaration->signedness) { |
225 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
226 | bt_bitfield_read_le(pos->base, unsigned long, | |
227 | pos->offset, integer_declaration->len, | |
228 | &integer_definition->value._unsigned); | |
229 | else | |
230 | bt_bitfield_read_be(pos->base, unsigned long, | |
231 | pos->offset, integer_declaration->len, | |
232 | &integer_definition->value._unsigned); | |
233 | } else { | |
234 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
235 | bt_bitfield_read_le(pos->base, unsigned long, | |
236 | pos->offset, integer_declaration->len, | |
237 | &integer_definition->value._signed); | |
238 | else | |
239 | bt_bitfield_read_be(pos->base, unsigned long, | |
240 | pos->offset, integer_declaration->len, | |
241 | &integer_definition->value._signed); | |
6dc2ca62 | 242 | } |
46322b33 | 243 | ctf_move_pos(pos, integer_declaration->len); |
c5e74408 | 244 | return 0; |
6dc2ca62 | 245 | } |
7fe00194 | 246 | |
c5e74408 | 247 | int ctf_integer_write(struct stream_pos *ppos, struct definition *definition) |
7fe00194 | 248 | { |
d11e9c49 MD |
249 | struct definition_integer *integer_definition = |
250 | container_of(definition, struct definition_integer, p); | |
251 | const struct declaration_integer *integer_declaration = | |
252 | integer_definition->declaration; | |
46322b33 MD |
253 | struct ctf_stream_pos *pos = ctf_pos(ppos); |
254 | ||
5385cf15 MD |
255 | if (!(integer_declaration->p.alignment % CHAR_BIT) |
256 | && !(integer_declaration->len % CHAR_BIT)) { | |
c5e74408 | 257 | return _aligned_integer_write(ppos, definition); |
5385cf15 MD |
258 | } |
259 | ||
46322b33 | 260 | ctf_align_pos(pos, integer_declaration->p.alignment); |
c5e74408 MD |
261 | |
262 | if (!ctf_pos_access_ok(pos, integer_declaration->len)) | |
263 | return -EFAULT; | |
264 | ||
7fe00194 MD |
265 | if (pos->dummy) |
266 | goto end; | |
d11e9c49 MD |
267 | if (!integer_declaration->signedness) { |
268 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
269 | bt_bitfield_write_le(pos->base, unsigned long, | |
270 | pos->offset, integer_declaration->len, | |
271 | integer_definition->value._unsigned); | |
272 | else | |
273 | bt_bitfield_write_be(pos->base, unsigned long, | |
274 | pos->offset, integer_declaration->len, | |
275 | integer_definition->value._unsigned); | |
276 | } else { | |
277 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
278 | bt_bitfield_write_le(pos->base, unsigned long, | |
279 | pos->offset, integer_declaration->len, | |
280 | integer_definition->value._signed); | |
281 | else | |
282 | bt_bitfield_write_be(pos->base, unsigned long, | |
283 | pos->offset, integer_declaration->len, | |
284 | integer_definition->value._signed); | |
285 | } | |
7fe00194 | 286 | end: |
46322b33 | 287 | ctf_move_pos(pos, integer_declaration->len); |
c5e74408 | 288 | return 0; |
7fe00194 | 289 | } |