@@ -193,28 +193,29 @@ void elf_generate_program_headers(void)
193193 * 54 | | |
194194 */
195195 /* program header - code and data combined */
196- phdr .p_type = 1 ; /* PT_LOAD */
197- phdr .p_offset = elf_header_len ; /* offset of segment */
198- phdr .p_vaddr = elf_code_start ; /* virtual address */
199- phdr .p_paddr = elf_code_start ; /* physical address */
196+ phdr .p_type = 1 ; /* PT_LOAD */
197+ phdr .p_offset = elf_header_len ; /* offset of segment */
198+ phdr .p_vaddr = elf_code_start ; /* virtual address */
199+ phdr .p_paddr = elf_code_start ; /* physical address */
200+ /* Don't include interp in the first LOAD segment for dynlink */
200201 phdr .p_filesz = elf_code -> size + elf_data -> size ; /* size in file */
201202 phdr .p_memsz = elf_code -> size + elf_data -> size ; /* size in memory */
202203 phdr .p_flags = 7 ; /* flags */
203204 phdr .p_align = 4 ; /* alignment */
204205 elf_write_blk (elf_program_header , & phdr , sizeof (elf32_phdr_t ));
205206 if (dynlink ) {
206- /* program header - .rel.plt .plt .got .dynstr .dynsym and .dynamic
207- * sections combined */
207+ /* program header - interp + dynamic sections combined in second LOAD */
208208 phdr .p_type = 1 ; /* PT_LOAD */
209- phdr .p_offset = elf_header_len + elf_code -> size + elf_data -> size +
210- elf_interp -> size ; /* offset of segment */
211- phdr .p_vaddr = elf_relplt_start ; /* virtual address */
212- phdr .p_paddr = elf_relplt_start ; /* physical address */
213- phdr .p_filesz = elf_relplt -> size + elf_plt -> size + elf_got -> size +
214- elf_dynstr -> size + elf_dynsym -> size +
209+ phdr .p_offset = elf_header_len + elf_code -> size +
210+ elf_data -> size ; /* offset of segment */
211+ /* Virtual address must map correctly: VA = ELF_START + file_offset */
212+ phdr .p_vaddr = ELF_START + phdr .p_offset ; /* virtual address */
213+ phdr .p_paddr = ELF_START + phdr .p_offset ; /* physical address */
214+ phdr .p_filesz = elf_interp -> size + elf_relplt -> size + elf_plt -> size +
215+ elf_got -> size + elf_dynstr -> size + elf_dynsym -> size +
215216 elf_dynamic -> size ; /* size in file */
216- phdr .p_memsz = elf_relplt -> size + elf_plt -> size + elf_got -> size +
217- elf_dynstr -> size + elf_dynsym -> size +
217+ phdr .p_memsz = elf_interp -> size + elf_relplt -> size + elf_plt -> size +
218+ elf_got -> size + elf_dynstr -> size + elf_dynsym -> size +
218219 elf_dynamic -> size ; /* size in memory */
219220 phdr .p_flags = 7 ; /* flags */
220221 phdr .p_align = 4 ; /* alignment */
@@ -223,29 +224,28 @@ void elf_generate_program_headers(void)
223224 /* program header - program interpreter (.interp section) */
224225 phdr .p_type = 3 ; /* PT_INTERP */
225226 phdr .p_offset = elf_header_len + elf_code -> size +
226- elf_data -> size ; /* offset of segment */
227- phdr .p_vaddr = elf_data_start + elf_data -> size ; /* virtual address */
228- phdr .p_paddr = elf_data_start + elf_data -> size ; /* physical address */
229- phdr .p_filesz = strlen (DYN_LINKER ) + 1 ; /* size in file */
230- phdr .p_memsz = strlen (DYN_LINKER ) + 1 ; /* size in memory */
231- phdr .p_flags = 4 ; /* flags */
232- phdr .p_align = 1 ; /* alignment */
227+ elf_data -> size ; /* offset of segment */
228+ /* Virtual address must map correctly: VA = ELF_START + file_offset */
229+ phdr .p_vaddr = ELF_START + phdr .p_offset ; /* virtual address */
230+ phdr .p_paddr = ELF_START + phdr .p_offset ; /* physical address */
231+ phdr .p_filesz = elf_interp -> size ; /* size in file */
232+ phdr .p_memsz = elf_interp -> size ; /* size in memory */
233+ phdr .p_flags = 4 ; /* flags */
234+ phdr .p_align = 1 ; /* alignment */
233235 elf_write_blk (elf_program_header , & phdr , sizeof (elf32_phdr_t ));
234236
235237 /* program header - .dynamic section */
236238 phdr .p_type = 2 ; /* PT_DYNAMIC */
237239 phdr .p_offset = elf_header_len + elf_code -> size + elf_data -> size +
238240 elf_interp -> size + elf_relplt -> size + elf_plt -> size +
239241 elf_got -> size + elf_dynstr -> size +
240- elf_dynsym -> size ; /* offset of segment */
241- phdr .p_vaddr = elf_got_start + elf_got -> size + elf_dynstr -> size +
242- elf_dynsym -> size ; /* virtual address */
243- phdr .p_paddr = elf_got_start + elf_got -> size + elf_dynstr -> size +
244- elf_dynsym -> size ; /* physical address */
245- phdr .p_filesz = elf_dynamic -> size ; /* size in file */
246- phdr .p_memsz = elf_dynamic -> size ; /* size in memory */
247- phdr .p_flags = 6 ; /* flags */
248- phdr .p_align = 4 ; /* alignment */
242+ elf_dynsym -> size ; /* offset of segment */
243+ phdr .p_vaddr = ELF_START + phdr .p_offset ; /* virtual address */
244+ phdr .p_paddr = ELF_START + phdr .p_offset ; /* physical address */
245+ phdr .p_filesz = elf_dynamic -> size ; /* size in file */
246+ phdr .p_memsz = elf_dynamic -> size ; /* size in memory */
247+ phdr .p_flags = 6 ; /* flags */
248+ phdr .p_align = 4 ; /* alignment */
249249 elf_write_blk (elf_program_header , & phdr , sizeof (elf32_phdr_t ));
250250 }
251251}
@@ -332,7 +332,7 @@ void elf_generate_section_headers(void)
332332 shdr .sh_name = sh_name ;
333333 shdr .sh_type = 1 ;
334334 shdr .sh_flags = 0x2 ;
335- shdr .sh_addr = elf_data_start + elf_data -> size ;
335+ shdr .sh_addr = ELF_START + ofs ; /* Use consistent VA calculation */
336336 shdr .sh_offset = ofs ;
337337 shdr .sh_size = strlen (DYN_LINKER ) + 1 ;
338338 shdr .sh_link = 0 ;
@@ -345,9 +345,9 @@ void elf_generate_section_headers(void)
345345
346346 /* .rel.plt */
347347 shdr .sh_name = sh_name ;
348- shdr .sh_type = 9 ; /* SHT_REL */
349- shdr .sh_flags = 0x42 ; /* 0x40 | SHF_ALLOC */
350- shdr .sh_addr = elf_relplt_start ;
348+ shdr .sh_type = 9 ; /* SHT_REL */
349+ shdr .sh_flags = 0x42 ; /* 0x40 | SHF_ALLOC */
350+ shdr .sh_addr = ELF_START + ofs ; /* Use consistent VA calculation */
351351 shdr .sh_offset = ofs ;
352352 shdr .sh_size = elf_relplt -> size ;
353353 shdr .sh_link = 8 ; /* The section header index of .dynsym. */
@@ -362,7 +362,7 @@ void elf_generate_section_headers(void)
362362 shdr .sh_name = sh_name ;
363363 shdr .sh_type = 1 ;
364364 shdr .sh_flags = 0x6 ;
365- shdr .sh_addr = elf_plt_start ;
365+ shdr .sh_addr = ELF_START + ofs ; /* Use consistent VA calculation */
366366 shdr .sh_offset = ofs ;
367367 shdr .sh_size = elf_plt -> size ;
368368 shdr .sh_link = 0 ;
@@ -377,7 +377,7 @@ void elf_generate_section_headers(void)
377377 shdr .sh_name = sh_name ;
378378 shdr .sh_type = 1 ;
379379 shdr .sh_flags = 0x3 ;
380- shdr .sh_addr = elf_got_start ;
380+ shdr .sh_addr = ELF_START + ofs ; /* Use consistent VA calculation */
381381 shdr .sh_offset = ofs ;
382382 shdr .sh_size = elf_got -> size ;
383383 shdr .sh_link = 0 ;
@@ -392,7 +392,7 @@ void elf_generate_section_headers(void)
392392 shdr .sh_name = sh_name ;
393393 shdr .sh_type = 3 ;
394394 shdr .sh_flags = 0x2 ;
395- shdr .sh_addr = elf_got_start + elf_got -> size ;
395+ shdr .sh_addr = ELF_START + ofs ; /* Use consistent VA calculation */
396396 shdr .sh_offset = ofs ;
397397 shdr .sh_size = elf_dynstr -> size ;
398398 shdr .sh_link = 0 ;
@@ -407,7 +407,7 @@ void elf_generate_section_headers(void)
407407 shdr .sh_name = sh_name ;
408408 shdr .sh_type = 11 ;
409409 shdr .sh_flags = 0x2 ;
410- shdr .sh_addr = elf_got_start + elf_got -> size + elf_dynstr -> size ;
410+ shdr .sh_addr = ELF_START + ofs ; /* Use consistent VA calculation */
411411 shdr .sh_offset = ofs ;
412412 shdr .sh_size = elf_dynsym -> size ;
413413 shdr .sh_link = 7 ;
@@ -422,8 +422,7 @@ void elf_generate_section_headers(void)
422422 shdr .sh_name = sh_name ;
423423 shdr .sh_type = 6 ;
424424 shdr .sh_flags = 0x3 ;
425- shdr .sh_addr =
426- elf_got_start + elf_got -> size + elf_dynstr -> size + elf_dynsym -> size ;
425+ shdr .sh_addr = ELF_START + ofs ; /* Use consistent VA calculation */
427426 shdr .sh_offset = ofs ;
428427 shdr .sh_size = elf_dynamic -> size ;
429428 shdr .sh_link = 7 ; /* The section header index of .dynstr. */
@@ -531,7 +530,14 @@ void elf_generate_sections(void)
531530 got_sz += PTR_SIZE ;
532531
533532 /* Get the starting points of the sections. */
534- elf_relplt_start = elf_data_start + elf_data -> size + elf_interp -> size ;
533+ int code_size_estimate = elf_offset ;
534+ int data_size_adjusted = elf_data -> size ;
535+
536+ /* Now calculate the virtual addresses */
537+ int file_offset_after_data =
538+ elf_header_len + code_size_estimate + data_size_adjusted ;
539+ elf_interp_start = ELF_START + file_offset_after_data ;
540+ elf_relplt_start = elf_interp_start + elf_interp -> size ;
535541 elf_plt_start = elf_relplt_start + relplt_sz ;
536542 elf_got_start = elf_plt_start + plt_sz ;
537543
@@ -701,8 +707,12 @@ void elf_preprocess(void)
701707 elf_header_len += (sizeof (elf32_phdr_t ) * 3 );
702708 elf_code_start = ELF_START + elf_header_len ;
703709 elf_data_start = elf_code_start + elf_offset ;
710+ /* Align elf_data BEFORE generate_sections so the size is correct */
704711 elf_align (elf_data );
712+
713+ /* Now generate sections with the correct aligned sizes */
705714 elf_generate_sections ();
715+
706716 elf_align (elf_symtab );
707717 elf_align (elf_strtab );
708718}
0 commit comments