Rev 43 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 43 | Rev 44 | ||
---|---|---|---|
Line 2148... | Line 2148... | ||
2148 | size_t first_segment_offset; |
2148 | size_t first_segment_offset; |
2149 | size_t compressor_outlen; |
2149 | size_t compressor_outlen; |
2150 | size_t compressor_inlen; |
2150 | size_t compressor_inlen; |
2151 | size_t reallocated_size; |
2151 | size_t reallocated_size; |
2152 | size_t available_space; |
2152 | size_t available_space; |
- | 2153 | size_t segment_offset; |
|
2153 | size_t fsentry_index; |
2154 | size_t fsentry_index; |
2154 | size_t largest_index; |
2155 | size_t largest_index; |
2155 | size_t largest_size; |
2156 | size_t largest_size; |
- | 2157 | size_t segment_size; |
|
2156 | size_t imgdir_size; |
2158 | size_t imgdir_size; |
2157 | size_t curr_offset; |
2159 | size_t curr_offset; |
2158 | size_t table_index; |
2160 | size_t table_index; |
2159 | size_t remaining_len; |
2161 | size_t remaining_len; |
2160 | ifs_t ifs = { 0 }; |
2162 | ifs_t ifs = { 0 }; |
Line 2522... | Line 2524... | ||
2522 | &startup_bootargs_offset); // where to save the offset of the boot arguments |
2524 | &startup_bootargs_offset); // where to save the offset of the boot arguments |
2523 | 2525 | ||
2524 | // fix shdr_addr in procnto's arguments structure, same value as startup_header.image_paddr (which is not set yet) (TODO: support 64-bit shdr_addr offsets -- see comment in bootargs_entry_t struct) |
2526 | // fix shdr_addr in procnto's arguments structure, same value as startup_header.image_paddr (which is not set yet) (TODO: support 64-bit shdr_addr offsets -- see comment in bootargs_entry_t struct) |
2525 | ((bootargs_entry_t *) &startup_code.bytes[startup_bootargs_offset])->shdr_addr = (uint32_t) (image_base + boot_code.size); |
2527 | ((bootargs_entry_t *) &startup_code.bytes[startup_bootargs_offset])->shdr_addr = (uint32_t) (image_base + boot_code.size); |
2526 | 2528 | ||
2527 | // backup two interesting values and chop off the ELF header until the start of the first segment |
2529 | // backup two interesting values and chop off the ELF header until the start of the first loadable segment |
2528 | #define ELFHDR ((elf_header_t *) startup_code.bytes) // this convenient definition will make sure the ELF header points at the right location |
2530 | #define ELFHDR ((elf_header_t *) startup_code.bytes) // this convenient definition will make sure the ELF header points at the right location |
2529 | startup_header.startup_vaddr = (uint32_t) ELF_GET_NUMERIC (ELFHDR, ELFHDR, entrypoint_offset); // read ELF entrypoint and store it in the startup header (it will be rewritten at the end of the process) |
2531 | startup_header.startup_vaddr = (uint32_t) ELF_GET_NUMERIC (ELFHDR, ELFHDR, entrypoint_offset); // read ELF entrypoint and store it in the startup header (it will be rewritten at the end of the process) |
2530 | if (boot_type == BOOTTYPE_UEFI) |
2532 | if (boot_type == BOOTTYPE_UEFI) |
2531 | { |
2533 | { |
2532 | uefi_header = (uefi64_header_t *) ifs.data.bytes; // restore UEFI header pointer |
2534 | uefi_header = (uefi64_header_t *) ifs.data.bytes; // restore UEFI header pointer |
Line 2537... | Line 2539... | ||
2537 | cumulated_segment_length = 0; |
2539 | cumulated_segment_length = 0; |
2538 | program_header_table_count = ELF_GET_NUMERIC (ELFHDR, ELFHDR, program_header_table_len); // get the number of program headers |
2540 | program_header_table_count = ELF_GET_NUMERIC (ELFHDR, ELFHDR, program_header_table_len); // get the number of program headers |
2539 | for (table_index = 0; table_index < program_header_table_count; table_index++) |
2541 | for (table_index = 0; table_index < program_header_table_count; table_index++) |
2540 | { |
2542 | { |
2541 | phdr = (elf_program_header_t *) &startup_code.bytes[ELF_GET_NUMERIC (ELFHDR, ELFHDR, program_header_table_offset) + (size_t) ELF_GET_NUMERIC (ELFHDR, ELFHDR, program_header_item_size) * table_index]; // quick access to program header |
2543 | phdr = (elf_program_header_t *) &startup_code.bytes[ELF_GET_NUMERIC (ELFHDR, ELFHDR, program_header_table_offset) + (size_t) ELF_GET_NUMERIC (ELFHDR, ELFHDR, program_header_item_size) * table_index]; // quick access to program header |
2542 | if ( |
2544 | if (phdr->u.elf.segment_type == ELF_SEGMENTTYPE_LOADABLE) |
- | 2545 | { |
|
2543 |
|
2546 | segment_offset = ELF_GET_NUMERIC (ELFHDR, phdr, file_offset); // get this segment's start offset in the ELF file |
2544 |
|
2547 | segment_size = ELF_GET_NUMERIC (ELFHDR, phdr, size_in_file); // get this ELF segment's length in the ELF file |
- | 2548 | if (first_segment_offset == 0) |
|
- | 2549 | first_segment_offset = segment_offset; // save the first segment's start offset |
|
- | 2550 | if (segment_size != 0) |
|
- | 2551 | { |
|
- | 2552 | cumulated_segment_length = (segment_offset - first_segment_offset) + segment_size; |
|
2545 |
|
2553 | minimal_padded_length = (segment_offset - first_segment_offset) + ELF_GET_NUMERIC (ELFHDR, phdr, size_in_memory); // get this ELF segment's required memory in the ELF file |
- | 2554 | } |
|
- | 2555 | } |
|
2546 | } |
2556 | } |
- | 2557 | ASSERT_WITH_ERRNO (Buffer_Subset (&startup_code, first_segment_offset)); // chop off the ELF header |
|
- | 2558 | ASSERT_WITH_ERRNO (Buffer_SubsetWithLength (&startup_code, 0, cumulated_segment_length)); // and chop off what's beyond the interesting parts |
|
2547 | #undef ELFHDR |
2559 | #undef ELFHDR |
2548 | - | ||
2549 | // FIXME: more bytes are read from the file past the last segment. Either a mkifs bug, or I'm wrong somewhere? |
- | |
2550 | ASSERT_WITH_ERRNO (Buffer_SubsetWithLength (&startup_code, first_segment_offset, cumulated_segment_length + (boot_type == BOOTTYPE_UEFI ? 0x400 : 0x820))); |
- | |
2551 | 2560 | ||
2552 | // pad with zeroes up to the required memory length and align with page size plus 4 (FIXME: understand why +4) |
2561 | // pad with zeroes up to the required memory length and align with page size plus 4 (FIXME: understand why +4) |
2553 | ASSERT_WITH_ERRNO (Buffer_PadWithZeroesTo (&startup_code, ROUND_TO_UPPER_MULTIPLE (minimal_padded_length, image_pagesize) + 4)); // pad as necessary |
2562 | ASSERT_WITH_ERRNO (Buffer_PadWithZeroesTo (&startup_code, ROUND_TO_UPPER_MULTIPLE (minimal_padded_length, image_pagesize) + 4)); // pad as necessary |
2554 | 2563 | ||
2555 | // write the startup blob and pad as necessary |
2564 | // write the startup blob and pad as necessary |