* Parse an emit message. */
| 414 | * Parse an emit message. |
| 415 | */ |
| 416 | static void parseEmit(Binary *B, const Message &msg) |
| 417 | { |
| 418 | const char *filename = nullptr; |
| 419 | Format format = FORMAT_BINARY; |
| 420 | bool have_format = false, dup = false; |
| 421 | for (unsigned i = 0; i < msg.num_params; i++) |
| 422 | { |
| 423 | switch (msg.params[i].name) |
| 424 | { |
| 425 | case PARAM_FILENAME: |
| 426 | dup = dup || (filename != nullptr); |
| 427 | filename = msg.params[i].value.string; |
| 428 | break; |
| 429 | case PARAM_FORMAT: |
| 430 | dup = dup || have_format; |
| 431 | format = (Format)msg.params[i].value.integer; |
| 432 | have_format = true; |
| 433 | break; |
| 434 | default: |
| 435 | break; |
| 436 | } |
| 437 | } |
| 438 | if (filename == nullptr) |
| 439 | error("failed to parse \"emit\" message (id=%u); missing " |
| 440 | "\"filename\" parameter", msg.id); |
| 441 | if (dup) |
| 442 | error("failed to parse \"emit\" message (id=%u); duplicate " |
| 443 | "parameters detected", msg.id); |
| 444 | B->output = filename; |
| 445 | |
| 446 | // Ensure B->filename != B->output |
| 447 | char *input = realpath(B->filename, NULL); |
| 448 | char *output = realpath(B->output, NULL); |
| 449 | if (input != NULL && output != NULL && strcmp(input, output) == 0) |
| 450 | error("failed to parse \"emit\" message (id=%u); output " |
| 451 | "binary path \"%s\" is the same as the input binary path " |
| 452 | "(hint: choose a different output filename)", msg.id, output); |
| 453 | free(input); |
| 454 | free(output); |
| 455 | |
| 456 | // Build trampoline entry set (b4 flush) |
| 457 | buildEntrySet(B); |
| 458 | |
| 459 | // Flush the queue: |
| 460 | queueFlush(B, INTPTR_MIN); |
| 461 | log(COLOR_NONE, '\n'); |
| 462 | |
| 463 | // Create and optimize the mappings: |
| 464 | MappingSet mappings; |
| 465 | size_t granularity = PAGE_SIZE; |
| 466 | granularity = (B->mode == MODE_PE_EXE || |
| 467 | B->mode == MODE_PE_DLL? WINDOWS_VIRTUAL_ALLOC_SIZE: |
| 468 | granularity); |
| 469 | size_t mapping_size = std::max(granularity, option_mem_mapping_size); |
| 470 | buildMappings(B->allocator, mapping_size, mappings); |
| 471 | switch (option_mem_granularity) |
| 472 | { |
| 473 | case 128: |
no test coverage detected