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. | |
c462e188 MD |
19 | * |
20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
23 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
25 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
26 | * SOFTWARE. | |
6dc2ca62 MD |
27 | */ |
28 | ||
4c8bfb7e MD |
29 | #include <babeltrace/ctf/types.h> |
30 | #include <babeltrace/bitfield.h> | |
6dc2ca62 MD |
31 | #include <stdint.h> |
32 | #include <glib.h> | |
9b0422a0 | 33 | #include <babeltrace/endian.h> |
6dc2ca62 | 34 | |
5385cf15 MD |
35 | /* |
36 | * The aligned read/write functions are expected to be faster than the | |
37 | * bitfield variants. They will be enabled eventually as an | |
38 | * optimisation. | |
39 | */ | |
40 | ||
7fe00194 | 41 | static |
1cf393f6 | 42 | int _aligned_integer_read(struct bt_stream_pos *ppos, |
0d69b916 | 43 | struct bt_definition *definition) |
6dc2ca62 | 44 | { |
d11e9c49 MD |
45 | struct definition_integer *integer_definition = |
46 | container_of(definition, struct definition_integer, p); | |
47 | const struct declaration_integer *integer_declaration = | |
48 | integer_definition->declaration; | |
46322b33 | 49 | struct ctf_stream_pos *pos = ctf_pos(ppos); |
f6625916 | 50 | int rbo = (integer_declaration->byte_order != BYTE_ORDER); /* reverse byte order */ |
6dc2ca62 | 51 | |
70fd5a51 MD |
52 | if (!ctf_align_pos(pos, integer_declaration->p.alignment)) |
53 | return -EFAULT; | |
6dc2ca62 | 54 | |
c5e74408 MD |
55 | if (!ctf_pos_access_ok(pos, integer_declaration->len)) |
56 | return -EFAULT; | |
57 | ||
670977d3 | 58 | assert(!(pos->offset % CHAR_BIT)); |
d11e9c49 MD |
59 | if (!integer_declaration->signedness) { |
60 | switch (integer_declaration->len) { | |
61 | case 8: | |
62 | { | |
63 | uint8_t v; | |
64 | ||
6a0b6cd5 | 65 | memcpy(&v, ctf_get_pos_addr(pos), sizeof(v)); |
d11e9c49 MD |
66 | integer_definition->value._unsigned = v; |
67 | break; | |
68 | } | |
69 | case 16: | |
70 | { | |
71 | uint16_t v; | |
72 | ||
6a0b6cd5 | 73 | memcpy(&v, ctf_get_pos_addr(pos), sizeof(v)); |
d11e9c49 MD |
74 | integer_definition->value._unsigned = |
75 | rbo ? GUINT16_SWAP_LE_BE(v) : v; | |
76 | break; | |
77 | } | |
78 | case 32: | |
79 | { | |
80 | uint32_t v; | |
81 | ||
6a0b6cd5 | 82 | memcpy(&v, ctf_get_pos_addr(pos), sizeof(v)); |
d11e9c49 MD |
83 | integer_definition->value._unsigned = |
84 | rbo ? GUINT32_SWAP_LE_BE(v) : v; | |
85 | break; | |
86 | } | |
87 | case 64: | |
88 | { | |
89 | uint64_t v; | |
90 | ||
6a0b6cd5 | 91 | memcpy(&v, ctf_get_pos_addr(pos), sizeof(v)); |
d11e9c49 MD |
92 | integer_definition->value._unsigned = |
93 | rbo ? GUINT64_SWAP_LE_BE(v) : v; | |
94 | break; | |
95 | } | |
96 | default: | |
97 | assert(0); | |
98 | } | |
99 | } else { | |
100 | switch (integer_declaration->len) { | |
101 | case 8: | |
102 | { | |
103 | int8_t v; | |
104 | ||
6a0b6cd5 | 105 | memcpy(&v, ctf_get_pos_addr(pos), sizeof(v)); |
d11e9c49 MD |
106 | integer_definition->value._signed = v; |
107 | break; | |
108 | } | |
109 | case 16: | |
110 | { | |
111 | int16_t v; | |
112 | ||
6a0b6cd5 | 113 | memcpy(&v, ctf_get_pos_addr(pos), sizeof(v)); |
d11e9c49 | 114 | integer_definition->value._signed = |
27265cb3 | 115 | rbo ? (int16_t) GUINT16_SWAP_LE_BE(v) : v; |
d11e9c49 MD |
116 | break; |
117 | } | |
118 | case 32: | |
119 | { | |
120 | int32_t v; | |
121 | ||
6a0b6cd5 | 122 | memcpy(&v, ctf_get_pos_addr(pos), sizeof(v)); |
d11e9c49 | 123 | integer_definition->value._signed = |
27265cb3 | 124 | rbo ? (int32_t) GUINT32_SWAP_LE_BE(v) : v; |
d11e9c49 MD |
125 | break; |
126 | } | |
127 | case 64: | |
128 | { | |
129 | int64_t v; | |
130 | ||
6a0b6cd5 | 131 | memcpy(&v, ctf_get_pos_addr(pos), sizeof(v)); |
d11e9c49 | 132 | integer_definition->value._signed = |
27265cb3 | 133 | rbo ? (int64_t) GUINT64_SWAP_LE_BE(v) : v; |
d11e9c49 MD |
134 | break; |
135 | } | |
136 | default: | |
137 | assert(0); | |
138 | } | |
6dc2ca62 | 139 | } |
70fd5a51 MD |
140 | if (!ctf_move_pos(pos, integer_declaration->len)) |
141 | return -EFAULT; | |
c5e74408 | 142 | return 0; |
6dc2ca62 MD |
143 | } |
144 | ||
7fe00194 | 145 | static |
1cf393f6 | 146 | int _aligned_integer_write(struct bt_stream_pos *ppos, |
0d69b916 | 147 | struct bt_definition *definition) |
6dc2ca62 | 148 | { |
d11e9c49 MD |
149 | struct definition_integer *integer_definition = |
150 | container_of(definition, struct definition_integer, p); | |
151 | const struct declaration_integer *integer_declaration = | |
152 | integer_definition->declaration; | |
46322b33 | 153 | struct ctf_stream_pos *pos = ctf_pos(ppos); |
f6625916 | 154 | int rbo = (integer_declaration->byte_order != BYTE_ORDER); /* reverse byte order */ |
6dc2ca62 | 155 | |
70fd5a51 MD |
156 | if (!ctf_align_pos(pos, integer_declaration->p.alignment)) |
157 | return -EFAULT; | |
6dc2ca62 | 158 | |
c5e74408 MD |
159 | if (!ctf_pos_access_ok(pos, integer_declaration->len)) |
160 | return -EFAULT; | |
161 | ||
670977d3 | 162 | assert(!(pos->offset % CHAR_BIT)); |
bed864a7 | 163 | if (pos->dummy) |
6dc2ca62 | 164 | goto end; |
d11e9c49 | 165 | if (!integer_declaration->signedness) { |
d11e9c49 | 166 | switch (integer_declaration->len) { |
6a0b6cd5 MD |
167 | case 8: |
168 | { | |
169 | uint8_t v = integer_definition->value._unsigned; | |
170 | ||
171 | memcpy(ctf_get_pos_addr(pos), &v, sizeof(v)); | |
d11e9c49 | 172 | break; |
6a0b6cd5 | 173 | } |
d11e9c49 | 174 | case 16: |
6a0b6cd5 MD |
175 | { |
176 | uint16_t v = integer_definition->value._unsigned; | |
177 | ||
178 | if (rbo) | |
179 | v = GUINT16_SWAP_LE_BE(v); | |
180 | memcpy(ctf_get_pos_addr(pos), &v, sizeof(v)); | |
d11e9c49 | 181 | break; |
6a0b6cd5 | 182 | } |
d11e9c49 | 183 | case 32: |
6a0b6cd5 MD |
184 | { |
185 | uint32_t v = integer_definition->value._unsigned; | |
186 | ||
187 | if (rbo) | |
188 | v = GUINT32_SWAP_LE_BE(v); | |
189 | memcpy(ctf_get_pos_addr(pos), &v, sizeof(v)); | |
d11e9c49 | 190 | break; |
6a0b6cd5 | 191 | } |
d11e9c49 | 192 | case 64: |
6a0b6cd5 MD |
193 | { |
194 | uint64_t v = integer_definition->value._unsigned; | |
195 | ||
196 | if (rbo) | |
197 | v = GUINT64_SWAP_LE_BE(v); | |
198 | memcpy(ctf_get_pos_addr(pos), &v, sizeof(v)); | |
d11e9c49 | 199 | break; |
6a0b6cd5 | 200 | } |
d11e9c49 MD |
201 | default: |
202 | assert(0); | |
203 | } | |
204 | } else { | |
d11e9c49 | 205 | switch (integer_declaration->len) { |
6a0b6cd5 MD |
206 | case 8: |
207 | { | |
208 | uint8_t v = integer_definition->value._signed; | |
209 | ||
210 | memcpy(ctf_get_pos_addr(pos), &v, sizeof(v)); | |
d11e9c49 | 211 | break; |
6a0b6cd5 | 212 | } |
d11e9c49 | 213 | case 16: |
6a0b6cd5 MD |
214 | { |
215 | int16_t v = integer_definition->value._signed; | |
216 | ||
217 | if (rbo) | |
218 | v = GUINT16_SWAP_LE_BE(v); | |
219 | memcpy(ctf_get_pos_addr(pos), &v, sizeof(v)); | |
d11e9c49 | 220 | break; |
6a0b6cd5 | 221 | } |
d11e9c49 | 222 | case 32: |
6a0b6cd5 MD |
223 | { |
224 | int32_t v = integer_definition->value._signed; | |
225 | ||
226 | if (rbo) | |
227 | v = GUINT32_SWAP_LE_BE(v); | |
228 | memcpy(ctf_get_pos_addr(pos), &v, sizeof(v)); | |
d11e9c49 | 229 | break; |
6a0b6cd5 | 230 | } |
d11e9c49 | 231 | case 64: |
6a0b6cd5 MD |
232 | { |
233 | int64_t v = integer_definition->value._signed; | |
234 | ||
235 | if (rbo) | |
236 | v = GUINT64_SWAP_LE_BE(v); | |
237 | memcpy(ctf_get_pos_addr(pos), &v, sizeof(v)); | |
d11e9c49 | 238 | break; |
6a0b6cd5 | 239 | } |
d11e9c49 MD |
240 | default: |
241 | assert(0); | |
242 | } | |
6dc2ca62 MD |
243 | } |
244 | end: | |
70fd5a51 MD |
245 | if (!ctf_move_pos(pos, integer_declaration->len)) |
246 | return -EFAULT; | |
c5e74408 | 247 | return 0; |
6dc2ca62 MD |
248 | } |
249 | ||
0d69b916 | 250 | int ctf_integer_read(struct bt_stream_pos *ppos, struct bt_definition *definition) |
6dc2ca62 | 251 | { |
d11e9c49 MD |
252 | struct definition_integer *integer_definition = |
253 | container_of(definition, struct definition_integer, p); | |
254 | const struct declaration_integer *integer_declaration = | |
255 | integer_definition->declaration; | |
46322b33 | 256 | struct ctf_stream_pos *pos = ctf_pos(ppos); |
6dc2ca62 | 257 | |
5385cf15 MD |
258 | if (!(integer_declaration->p.alignment % CHAR_BIT) |
259 | && !(integer_declaration->len % CHAR_BIT)) { | |
c5e74408 | 260 | return _aligned_integer_read(ppos, definition); |
5385cf15 MD |
261 | } |
262 | ||
70fd5a51 MD |
263 | if (!ctf_align_pos(pos, integer_declaration->p.alignment)) |
264 | return -EFAULT; | |
c5e74408 MD |
265 | |
266 | if (!ctf_pos_access_ok(pos, integer_declaration->len)) | |
267 | return -EFAULT; | |
268 | ||
d11e9c49 MD |
269 | if (!integer_declaration->signedness) { |
270 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
47415068 | 271 | bt_bitfield_read_le(mmap_align_addr(pos->base_mma) + |
6a0b6cd5 | 272 | pos->mmap_base_offset, unsigned char, |
d11e9c49 MD |
273 | pos->offset, integer_declaration->len, |
274 | &integer_definition->value._unsigned); | |
275 | else | |
47415068 | 276 | bt_bitfield_read_be(mmap_align_addr(pos->base_mma) + |
6a0b6cd5 | 277 | pos->mmap_base_offset, unsigned char, |
d11e9c49 MD |
278 | pos->offset, integer_declaration->len, |
279 | &integer_definition->value._unsigned); | |
280 | } else { | |
281 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
47415068 | 282 | bt_bitfield_read_le(mmap_align_addr(pos->base_mma) + |
6a0b6cd5 | 283 | pos->mmap_base_offset, unsigned char, |
d11e9c49 MD |
284 | pos->offset, integer_declaration->len, |
285 | &integer_definition->value._signed); | |
286 | else | |
47415068 | 287 | bt_bitfield_read_be(mmap_align_addr(pos->base_mma) + |
6a0b6cd5 | 288 | pos->mmap_base_offset, unsigned char, |
d11e9c49 MD |
289 | pos->offset, integer_declaration->len, |
290 | &integer_definition->value._signed); | |
6dc2ca62 | 291 | } |
70fd5a51 MD |
292 | if (!ctf_move_pos(pos, integer_declaration->len)) |
293 | return -EFAULT; | |
c5e74408 | 294 | return 0; |
6dc2ca62 | 295 | } |
7fe00194 | 296 | |
0d69b916 | 297 | int ctf_integer_write(struct bt_stream_pos *ppos, struct bt_definition *definition) |
7fe00194 | 298 | { |
d11e9c49 MD |
299 | struct definition_integer *integer_definition = |
300 | container_of(definition, struct definition_integer, p); | |
301 | const struct declaration_integer *integer_declaration = | |
302 | integer_definition->declaration; | |
46322b33 MD |
303 | struct ctf_stream_pos *pos = ctf_pos(ppos); |
304 | ||
5385cf15 MD |
305 | if (!(integer_declaration->p.alignment % CHAR_BIT) |
306 | && !(integer_declaration->len % CHAR_BIT)) { | |
c5e74408 | 307 | return _aligned_integer_write(ppos, definition); |
5385cf15 MD |
308 | } |
309 | ||
70fd5a51 MD |
310 | if (!ctf_align_pos(pos, integer_declaration->p.alignment)) |
311 | return -EFAULT; | |
c5e74408 MD |
312 | |
313 | if (!ctf_pos_access_ok(pos, integer_declaration->len)) | |
314 | return -EFAULT; | |
315 | ||
7fe00194 MD |
316 | if (pos->dummy) |
317 | goto end; | |
d11e9c49 MD |
318 | if (!integer_declaration->signedness) { |
319 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
47415068 | 320 | bt_bitfield_write_le(mmap_align_addr(pos->base_mma) + |
6a0b6cd5 | 321 | pos->mmap_base_offset, unsigned char, |
d11e9c49 MD |
322 | pos->offset, integer_declaration->len, |
323 | integer_definition->value._unsigned); | |
324 | else | |
47415068 | 325 | bt_bitfield_write_be(mmap_align_addr(pos->base_mma) + |
6a0b6cd5 | 326 | pos->mmap_base_offset, unsigned char, |
d11e9c49 MD |
327 | pos->offset, integer_declaration->len, |
328 | integer_definition->value._unsigned); | |
329 | } else { | |
330 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
47415068 | 331 | bt_bitfield_write_le(mmap_align_addr(pos->base_mma) + |
6a0b6cd5 | 332 | pos->mmap_base_offset, unsigned char, |
d11e9c49 MD |
333 | pos->offset, integer_declaration->len, |
334 | integer_definition->value._signed); | |
335 | else | |
47415068 | 336 | bt_bitfield_write_be(mmap_align_addr(pos->base_mma) + |
6a0b6cd5 | 337 | pos->mmap_base_offset, unsigned char, |
d11e9c49 MD |
338 | pos->offset, integer_declaration->len, |
339 | integer_definition->value._signed); | |
340 | } | |
7fe00194 | 341 | end: |
70fd5a51 MD |
342 | if (!ctf_move_pos(pos, integer_declaration->len)) |
343 | return -EFAULT; | |
c5e74408 | 344 | return 0; |
7fe00194 | 345 | } |