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 | |
46322b33 | 52 | ctf_align_pos(pos, integer_declaration->p.alignment); |
6dc2ca62 | 53 | |
c5e74408 MD |
54 | if (!ctf_pos_access_ok(pos, integer_declaration->len)) |
55 | return -EFAULT; | |
56 | ||
670977d3 | 57 | assert(!(pos->offset % CHAR_BIT)); |
d11e9c49 MD |
58 | if (!integer_declaration->signedness) { |
59 | switch (integer_declaration->len) { | |
60 | case 8: | |
61 | { | |
62 | uint8_t v; | |
63 | ||
5385cf15 | 64 | v = *(const uint8_t *) ctf_get_pos_addr(pos); |
d11e9c49 MD |
65 | integer_definition->value._unsigned = v; |
66 | break; | |
67 | } | |
68 | case 16: | |
69 | { | |
70 | uint16_t v; | |
71 | ||
5385cf15 | 72 | v = *(const uint16_t *) ctf_get_pos_addr(pos); |
d11e9c49 MD |
73 | integer_definition->value._unsigned = |
74 | rbo ? GUINT16_SWAP_LE_BE(v) : v; | |
75 | break; | |
76 | } | |
77 | case 32: | |
78 | { | |
79 | uint32_t v; | |
80 | ||
5385cf15 | 81 | v = *(const uint32_t *) ctf_get_pos_addr(pos); |
d11e9c49 MD |
82 | integer_definition->value._unsigned = |
83 | rbo ? GUINT32_SWAP_LE_BE(v) : v; | |
84 | break; | |
85 | } | |
86 | case 64: | |
87 | { | |
88 | uint64_t v; | |
89 | ||
5385cf15 | 90 | v = *(const uint64_t *) ctf_get_pos_addr(pos); |
d11e9c49 MD |
91 | integer_definition->value._unsigned = |
92 | rbo ? GUINT64_SWAP_LE_BE(v) : v; | |
93 | break; | |
94 | } | |
95 | default: | |
96 | assert(0); | |
97 | } | |
98 | } else { | |
99 | switch (integer_declaration->len) { | |
100 | case 8: | |
101 | { | |
102 | int8_t v; | |
103 | ||
5385cf15 | 104 | v = *(const int8_t *) ctf_get_pos_addr(pos); |
d11e9c49 MD |
105 | integer_definition->value._signed = v; |
106 | break; | |
107 | } | |
108 | case 16: | |
109 | { | |
110 | int16_t v; | |
111 | ||
5385cf15 | 112 | v = *(const int16_t *) ctf_get_pos_addr(pos); |
d11e9c49 | 113 | integer_definition->value._signed = |
27265cb3 | 114 | rbo ? (int16_t) GUINT16_SWAP_LE_BE(v) : v; |
d11e9c49 MD |
115 | break; |
116 | } | |
117 | case 32: | |
118 | { | |
119 | int32_t v; | |
120 | ||
5385cf15 | 121 | v = *(const int32_t *) ctf_get_pos_addr(pos); |
d11e9c49 | 122 | integer_definition->value._signed = |
27265cb3 | 123 | rbo ? (int32_t) GUINT32_SWAP_LE_BE(v) : v; |
d11e9c49 MD |
124 | break; |
125 | } | |
126 | case 64: | |
127 | { | |
128 | int64_t v; | |
129 | ||
5385cf15 | 130 | v = *(const int64_t *) ctf_get_pos_addr(pos); |
d11e9c49 | 131 | integer_definition->value._signed = |
27265cb3 | 132 | rbo ? (int64_t) GUINT64_SWAP_LE_BE(v) : v; |
d11e9c49 MD |
133 | break; |
134 | } | |
135 | default: | |
136 | assert(0); | |
137 | } | |
6dc2ca62 | 138 | } |
d11e9c49 | 139 | ctf_move_pos(pos, integer_declaration->len); |
c5e74408 | 140 | return 0; |
6dc2ca62 MD |
141 | } |
142 | ||
7fe00194 | 143 | static |
1cf393f6 | 144 | int _aligned_integer_write(struct bt_stream_pos *ppos, |
0d69b916 | 145 | struct bt_definition *definition) |
6dc2ca62 | 146 | { |
d11e9c49 MD |
147 | struct definition_integer *integer_definition = |
148 | container_of(definition, struct definition_integer, p); | |
149 | const struct declaration_integer *integer_declaration = | |
150 | integer_definition->declaration; | |
46322b33 | 151 | struct ctf_stream_pos *pos = ctf_pos(ppos); |
f6625916 | 152 | int rbo = (integer_declaration->byte_order != BYTE_ORDER); /* reverse byte order */ |
6dc2ca62 | 153 | |
46322b33 | 154 | ctf_align_pos(pos, integer_declaration->p.alignment); |
6dc2ca62 | 155 | |
c5e74408 MD |
156 | if (!ctf_pos_access_ok(pos, integer_declaration->len)) |
157 | return -EFAULT; | |
158 | ||
670977d3 | 159 | assert(!(pos->offset % CHAR_BIT)); |
bed864a7 | 160 | if (pos->dummy) |
6dc2ca62 | 161 | goto end; |
d11e9c49 MD |
162 | if (!integer_declaration->signedness) { |
163 | uint64_t v = integer_definition->value._unsigned; | |
164 | ||
165 | switch (integer_declaration->len) { | |
166 | case 8: *(uint8_t *) ctf_get_pos_addr(pos) = (uint8_t) v; | |
167 | break; | |
168 | case 16: | |
169 | *(uint16_t *) ctf_get_pos_addr(pos) = rbo ? | |
170 | GUINT16_SWAP_LE_BE((uint16_t) v) : | |
171 | (uint16_t) v; | |
172 | break; | |
173 | case 32: | |
174 | *(uint32_t *) ctf_get_pos_addr(pos) = rbo ? | |
175 | GUINT32_SWAP_LE_BE((uint32_t) v) : | |
176 | (uint32_t) v; | |
177 | break; | |
178 | case 64: | |
179 | *(uint64_t *) ctf_get_pos_addr(pos) = rbo ? | |
180 | GUINT64_SWAP_LE_BE(v) : v; | |
181 | break; | |
182 | default: | |
183 | assert(0); | |
184 | } | |
185 | } else { | |
186 | int64_t v = integer_definition->value._signed; | |
187 | ||
188 | switch (integer_declaration->len) { | |
189 | case 8: *(int8_t *) ctf_get_pos_addr(pos) = (int8_t) v; | |
190 | break; | |
191 | case 16: | |
192 | *(int16_t *) ctf_get_pos_addr(pos) = rbo ? | |
27265cb3 | 193 | (int16_t) GUINT16_SWAP_LE_BE((int16_t) v) : |
d11e9c49 MD |
194 | (int16_t) v; |
195 | break; | |
196 | case 32: | |
197 | *(int32_t *) ctf_get_pos_addr(pos) = rbo ? | |
27265cb3 | 198 | (int32_t) GUINT32_SWAP_LE_BE((int32_t) v) : |
d11e9c49 MD |
199 | (int32_t) v; |
200 | break; | |
201 | case 64: | |
202 | *(int64_t *) ctf_get_pos_addr(pos) = rbo ? | |
203 | GUINT64_SWAP_LE_BE(v) : v; | |
204 | break; | |
205 | default: | |
206 | assert(0); | |
207 | } | |
6dc2ca62 MD |
208 | } |
209 | end: | |
46322b33 | 210 | ctf_move_pos(pos, integer_declaration->len); |
c5e74408 | 211 | return 0; |
6dc2ca62 MD |
212 | } |
213 | ||
0d69b916 | 214 | int ctf_integer_read(struct bt_stream_pos *ppos, struct bt_definition *definition) |
6dc2ca62 | 215 | { |
d11e9c49 MD |
216 | struct definition_integer *integer_definition = |
217 | container_of(definition, struct definition_integer, p); | |
218 | const struct declaration_integer *integer_declaration = | |
219 | integer_definition->declaration; | |
46322b33 | 220 | struct ctf_stream_pos *pos = ctf_pos(ppos); |
6dc2ca62 | 221 | |
5385cf15 MD |
222 | if (!(integer_declaration->p.alignment % CHAR_BIT) |
223 | && !(integer_declaration->len % CHAR_BIT)) { | |
c5e74408 | 224 | return _aligned_integer_read(ppos, definition); |
5385cf15 MD |
225 | } |
226 | ||
46322b33 | 227 | ctf_align_pos(pos, integer_declaration->p.alignment); |
c5e74408 MD |
228 | |
229 | if (!ctf_pos_access_ok(pos, integer_declaration->len)) | |
230 | return -EFAULT; | |
231 | ||
d11e9c49 MD |
232 | if (!integer_declaration->signedness) { |
233 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
47415068 JD |
234 | bt_bitfield_read_le(mmap_align_addr(pos->base_mma) + |
235 | pos->mmap_base_offset, unsigned long, | |
d11e9c49 MD |
236 | pos->offset, integer_declaration->len, |
237 | &integer_definition->value._unsigned); | |
238 | else | |
47415068 JD |
239 | bt_bitfield_read_be(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 { | |
244 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
47415068 JD |
245 | bt_bitfield_read_le(mmap_align_addr(pos->base_mma) + |
246 | pos->mmap_base_offset, unsigned long, | |
d11e9c49 MD |
247 | pos->offset, integer_declaration->len, |
248 | &integer_definition->value._signed); | |
249 | else | |
47415068 JD |
250 | bt_bitfield_read_be(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); | |
6dc2ca62 | 254 | } |
46322b33 | 255 | ctf_move_pos(pos, integer_declaration->len); |
c5e74408 | 256 | return 0; |
6dc2ca62 | 257 | } |
7fe00194 | 258 | |
0d69b916 | 259 | int ctf_integer_write(struct bt_stream_pos *ppos, struct bt_definition *definition) |
7fe00194 | 260 | { |
d11e9c49 MD |
261 | struct definition_integer *integer_definition = |
262 | container_of(definition, struct definition_integer, p); | |
263 | const struct declaration_integer *integer_declaration = | |
264 | integer_definition->declaration; | |
46322b33 MD |
265 | struct ctf_stream_pos *pos = ctf_pos(ppos); |
266 | ||
5385cf15 MD |
267 | if (!(integer_declaration->p.alignment % CHAR_BIT) |
268 | && !(integer_declaration->len % CHAR_BIT)) { | |
c5e74408 | 269 | return _aligned_integer_write(ppos, definition); |
5385cf15 MD |
270 | } |
271 | ||
46322b33 | 272 | ctf_align_pos(pos, integer_declaration->p.alignment); |
c5e74408 MD |
273 | |
274 | if (!ctf_pos_access_ok(pos, integer_declaration->len)) | |
275 | return -EFAULT; | |
276 | ||
7fe00194 MD |
277 | if (pos->dummy) |
278 | goto end; | |
d11e9c49 MD |
279 | if (!integer_declaration->signedness) { |
280 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
47415068 JD |
281 | bt_bitfield_write_le(mmap_align_addr(pos->base_mma) + |
282 | pos->mmap_base_offset, unsigned long, | |
d11e9c49 MD |
283 | pos->offset, integer_declaration->len, |
284 | integer_definition->value._unsigned); | |
285 | else | |
47415068 JD |
286 | bt_bitfield_write_be(mmap_align_addr(pos->base_mma) + |
287 | pos->mmap_base_offset, unsigned long, | |
d11e9c49 MD |
288 | pos->offset, integer_declaration->len, |
289 | integer_definition->value._unsigned); | |
290 | } else { | |
291 | if (integer_declaration->byte_order == LITTLE_ENDIAN) | |
47415068 JD |
292 | bt_bitfield_write_le(mmap_align_addr(pos->base_mma) + |
293 | pos->mmap_base_offset, unsigned long, | |
d11e9c49 MD |
294 | pos->offset, integer_declaration->len, |
295 | integer_definition->value._signed); | |
296 | else | |
47415068 JD |
297 | bt_bitfield_write_be(mmap_align_addr(pos->base_mma) + |
298 | pos->mmap_base_offset, unsigned long, | |
d11e9c49 MD |
299 | pos->offset, integer_declaration->len, |
300 | integer_definition->value._signed); | |
301 | } | |
7fe00194 | 302 | end: |
46322b33 | 303 | ctf_move_pos(pos, integer_declaration->len); |
c5e74408 | 304 | return 0; |
7fe00194 | 305 | } |