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 | ||
5385cf15 | 65 | v = *(const uint8_t *) ctf_get_pos_addr(pos); |
d11e9c49 MD |
66 | integer_definition->value._unsigned = v; |
67 | break; | |
68 | } | |
69 | case 16: | |
70 | { | |
71 | uint16_t v; | |
72 | ||
5385cf15 | 73 | v = *(const uint16_t *) ctf_get_pos_addr(pos); |
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 | ||
5385cf15 | 82 | v = *(const uint32_t *) ctf_get_pos_addr(pos); |
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 | ||
5385cf15 | 91 | v = *(const uint64_t *) ctf_get_pos_addr(pos); |
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 | ||
5385cf15 | 105 | v = *(const int8_t *) ctf_get_pos_addr(pos); |
d11e9c49 MD |
106 | integer_definition->value._signed = v; |
107 | break; | |
108 | } | |
109 | case 16: | |
110 | { | |
111 | int16_t v; | |
112 | ||
5385cf15 | 113 | v = *(const int16_t *) ctf_get_pos_addr(pos); |
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 | ||
5385cf15 | 122 | v = *(const int32_t *) ctf_get_pos_addr(pos); |
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 | ||
5385cf15 | 131 | v = *(const int64_t *) ctf_get_pos_addr(pos); |
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 MD |
165 | if (!integer_declaration->signedness) { |
166 | uint64_t v = integer_definition->value._unsigned; | |
167 | ||
168 | switch (integer_declaration->len) { | |
169 | case 8: *(uint8_t *) ctf_get_pos_addr(pos) = (uint8_t) v; | |
170 | break; | |
171 | case 16: | |
172 | *(uint16_t *) ctf_get_pos_addr(pos) = rbo ? | |
173 | GUINT16_SWAP_LE_BE((uint16_t) v) : | |
174 | (uint16_t) v; | |
175 | break; | |
176 | case 32: | |
177 | *(uint32_t *) ctf_get_pos_addr(pos) = rbo ? | |
178 | GUINT32_SWAP_LE_BE((uint32_t) v) : | |
179 | (uint32_t) v; | |
180 | break; | |
181 | case 64: | |
182 | *(uint64_t *) ctf_get_pos_addr(pos) = rbo ? | |
183 | GUINT64_SWAP_LE_BE(v) : v; | |
184 | break; | |
185 | default: | |
186 | assert(0); | |
187 | } | |
188 | } else { | |
189 | int64_t v = integer_definition->value._signed; | |
190 | ||
191 | switch (integer_declaration->len) { | |
192 | case 8: *(int8_t *) ctf_get_pos_addr(pos) = (int8_t) v; | |
193 | break; | |
194 | case 16: | |
195 | *(int16_t *) ctf_get_pos_addr(pos) = rbo ? | |
27265cb3 | 196 | (int16_t) GUINT16_SWAP_LE_BE((int16_t) v) : |
d11e9c49 MD |
197 | (int16_t) v; |
198 | break; | |
199 | case 32: | |
200 | *(int32_t *) ctf_get_pos_addr(pos) = rbo ? | |
27265cb3 | 201 | (int32_t) GUINT32_SWAP_LE_BE((int32_t) v) : |
d11e9c49 MD |
202 | (int32_t) v; |
203 | break; | |
204 | case 64: | |
205 | *(int64_t *) ctf_get_pos_addr(pos) = rbo ? | |
206 | GUINT64_SWAP_LE_BE(v) : v; | |
207 | break; | |
208 | default: | |
209 | assert(0); | |
210 | } | |
6dc2ca62 MD |
211 | } |
212 | end: | |
70fd5a51 MD |
213 | if (!ctf_move_pos(pos, integer_declaration->len)) |
214 | return -EFAULT; | |
c5e74408 | 215 | return 0; |
6dc2ca62 MD |
216 | } |
217 | ||
0d69b916 | 218 | int ctf_integer_read(struct bt_stream_pos *ppos, struct bt_definition *definition) |
6dc2ca62 | 219 | { |
d11e9c49 MD |
220 | struct definition_integer *integer_definition = |
221 | container_of(definition, struct definition_integer, p); | |
222 | const struct declaration_integer *integer_declaration = | |
223 | integer_definition->declaration; | |
46322b33 | 224 | struct ctf_stream_pos *pos = ctf_pos(ppos); |
6dc2ca62 | 225 | |
5385cf15 MD |
226 | if (!(integer_declaration->p.alignment % CHAR_BIT) |
227 | && !(integer_declaration->len % CHAR_BIT)) { | |
c5e74408 | 228 | return _aligned_integer_read(ppos, definition); |
5385cf15 MD |
229 | } |
230 | ||
70fd5a51 MD |
231 | if (!ctf_align_pos(pos, integer_declaration->p.alignment)) |
232 | return -EFAULT; | |
c5e74408 MD |
233 | |
234 | if (!ctf_pos_access_ok(pos, integer_declaration->len)) | |
235 | return -EFAULT; | |
236 | ||
d11e9c49 MD |
237 | if (!integer_declaration->signedness) { |
238 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
47415068 JD |
239 | bt_bitfield_read_le(mmap_align_addr(pos->base_mma) + |
240 | pos->mmap_base_offset, unsigned long, | |
d11e9c49 MD |
241 | pos->offset, integer_declaration->len, |
242 | &integer_definition->value._unsigned); | |
243 | else | |
47415068 JD |
244 | bt_bitfield_read_be(mmap_align_addr(pos->base_mma) + |
245 | pos->mmap_base_offset, unsigned long, | |
d11e9c49 MD |
246 | pos->offset, integer_declaration->len, |
247 | &integer_definition->value._unsigned); | |
248 | } else { | |
249 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
47415068 JD |
250 | bt_bitfield_read_le(mmap_align_addr(pos->base_mma) + |
251 | pos->mmap_base_offset, unsigned long, | |
d11e9c49 MD |
252 | pos->offset, integer_declaration->len, |
253 | &integer_definition->value._signed); | |
254 | else | |
47415068 JD |
255 | bt_bitfield_read_be(mmap_align_addr(pos->base_mma) + |
256 | pos->mmap_base_offset, unsigned long, | |
d11e9c49 MD |
257 | pos->offset, integer_declaration->len, |
258 | &integer_definition->value._signed); | |
6dc2ca62 | 259 | } |
70fd5a51 MD |
260 | if (!ctf_move_pos(pos, integer_declaration->len)) |
261 | return -EFAULT; | |
c5e74408 | 262 | return 0; |
6dc2ca62 | 263 | } |
7fe00194 | 264 | |
0d69b916 | 265 | int ctf_integer_write(struct bt_stream_pos *ppos, struct bt_definition *definition) |
7fe00194 | 266 | { |
d11e9c49 MD |
267 | struct definition_integer *integer_definition = |
268 | container_of(definition, struct definition_integer, p); | |
269 | const struct declaration_integer *integer_declaration = | |
270 | integer_definition->declaration; | |
46322b33 MD |
271 | struct ctf_stream_pos *pos = ctf_pos(ppos); |
272 | ||
5385cf15 MD |
273 | if (!(integer_declaration->p.alignment % CHAR_BIT) |
274 | && !(integer_declaration->len % CHAR_BIT)) { | |
c5e74408 | 275 | return _aligned_integer_write(ppos, definition); |
5385cf15 MD |
276 | } |
277 | ||
70fd5a51 MD |
278 | if (!ctf_align_pos(pos, integer_declaration->p.alignment)) |
279 | return -EFAULT; | |
c5e74408 MD |
280 | |
281 | if (!ctf_pos_access_ok(pos, integer_declaration->len)) | |
282 | return -EFAULT; | |
283 | ||
7fe00194 MD |
284 | if (pos->dummy) |
285 | goto end; | |
d11e9c49 MD |
286 | if (!integer_declaration->signedness) { |
287 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
47415068 JD |
288 | bt_bitfield_write_le(mmap_align_addr(pos->base_mma) + |
289 | pos->mmap_base_offset, unsigned long, | |
d11e9c49 MD |
290 | pos->offset, integer_declaration->len, |
291 | integer_definition->value._unsigned); | |
292 | else | |
47415068 JD |
293 | bt_bitfield_write_be(mmap_align_addr(pos->base_mma) + |
294 | pos->mmap_base_offset, unsigned long, | |
d11e9c49 MD |
295 | pos->offset, integer_declaration->len, |
296 | integer_definition->value._unsigned); | |
297 | } else { | |
298 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
47415068 JD |
299 | bt_bitfield_write_le(mmap_align_addr(pos->base_mma) + |
300 | pos->mmap_base_offset, unsigned long, | |
d11e9c49 MD |
301 | pos->offset, integer_declaration->len, |
302 | integer_definition->value._signed); | |
303 | else | |
47415068 JD |
304 | bt_bitfield_write_be(mmap_align_addr(pos->base_mma) + |
305 | pos->mmap_base_offset, unsigned long, | |
d11e9c49 MD |
306 | pos->offset, integer_declaration->len, |
307 | integer_definition->value._signed); | |
308 | } | |
7fe00194 | 309 | end: |
70fd5a51 MD |
310 | if (!ctf_move_pos(pos, integer_declaration->len)) |
311 | return -EFAULT; | |
c5e74408 | 312 | return 0; |
7fe00194 | 313 | } |