* Parse an instruction message. */
| 254 | * Parse an instruction message. |
| 255 | */ |
| 256 | static void parseInstruction(Binary *B, const Message &msg) |
| 257 | { |
| 258 | intptr_t address = 0; |
| 259 | size_t length = 0; |
| 260 | off_t offset = 0; |
| 261 | bool have_address = false, have_length = false, have_offset = false, |
| 262 | dup = false; |
| 263 | for (unsigned i = 0; i < msg.num_params; i++) |
| 264 | { |
| 265 | switch (msg.params[i].name) |
| 266 | { |
| 267 | case PARAM_ADDRESS: |
| 268 | dup = dup || have_address; |
| 269 | address = (intptr_t)msg.params[i].value.integer; |
| 270 | have_address = true; |
| 271 | break; |
| 272 | case PARAM_LENGTH: |
| 273 | dup = dup || have_length; |
| 274 | length = (size_t)msg.params[i].value.integer; |
| 275 | have_length = true; |
| 276 | break; |
| 277 | case PARAM_OFFSET: |
| 278 | dup = dup || have_offset; |
| 279 | offset = (off_t)msg.params[i].value.integer; |
| 280 | have_offset = true; |
| 281 | break; |
| 282 | default: |
| 283 | break; |
| 284 | } |
| 285 | } |
| 286 | if (!have_address) |
| 287 | error("failed to parse \"instruction\" message (id=%u); missing " |
| 288 | "\"address\" parameter", msg.id); |
| 289 | if (!have_length) |
| 290 | error("failed to parse \"instruction\" message (id=%u); missing " |
| 291 | "\"length\" parameter", msg.id); |
| 292 | if (length == 0 || length > 15) |
| 293 | error("failed to parse \"instruction\" message (id=%u); \"length\" " |
| 294 | "parameter must be within the range 1..15", msg.id); |
| 295 | if (!have_offset) |
| 296 | error("failed to parse \"instruction\" message (id=%u); missing " |
| 297 | "\"offset\" parameter", msg.id); |
| 298 | if (offset < 0) |
| 299 | error("failed to parse \"instruction\" message (id=%u); the " |
| 300 | "instruction offset (%zd) is negative", msg.id, offset); |
| 301 | if (offset + length > B->size) |
| 302 | error("failed to parse \"instruction\" message (id=%u); the " |
| 303 | "instruction offset+length (%zd+%zu) overflows " |
| 304 | "the end-of-file \"%s\" (with size %zu)", msg.id, offset, length, |
| 305 | B->filename, B->size); |
| 306 | if (dup) |
| 307 | error("failed to parse \"instruction\" message (id=%u); duplicate " |
| 308 | "parameters detected", msg.id); |
| 309 | |
| 310 | size_t pcrel32_idx = 0, pcrel8_idx = 0; |
| 311 | unsigned pcrel_idx = getInstrPCRelativeIndex(B->original.bytes + offset, |
| 312 | length); |
| 313 | if (pcrel_idx != 0) |
no test coverage detected