@@ -193,28 +193,29 @@ void elf_generate_program_headers(void)
193
193
* 54 | | |
194
194
*/
195
195
/* 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 */
200
201
phdr .p_filesz = elf_code -> size + elf_data -> size ; /* size in file */
201
202
phdr .p_memsz = elf_code -> size + elf_data -> size ; /* size in memory */
202
203
phdr .p_flags = 7 ; /* flags */
203
204
phdr .p_align = 4 ; /* alignment */
204
205
elf_write_blk (elf_program_header , & phdr , sizeof (elf32_phdr_t ));
205
206
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 */
208
208
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 +
215
216
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 +
218
219
elf_dynamic -> size ; /* size in memory */
219
220
phdr .p_flags = 7 ; /* flags */
220
221
phdr .p_align = 4 ; /* alignment */
@@ -223,29 +224,28 @@ void elf_generate_program_headers(void)
223
224
/* program header - program interpreter (.interp section) */
224
225
phdr .p_type = 3 ; /* PT_INTERP */
225
226
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 */
233
235
elf_write_blk (elf_program_header , & phdr , sizeof (elf32_phdr_t ));
234
236
235
237
/* program header - .dynamic section */
236
238
phdr .p_type = 2 ; /* PT_DYNAMIC */
237
239
phdr .p_offset = elf_header_len + elf_code -> size + elf_data -> size +
238
240
elf_interp -> size + elf_relplt -> size + elf_plt -> size +
239
241
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 */
249
249
elf_write_blk (elf_program_header , & phdr , sizeof (elf32_phdr_t ));
250
250
}
251
251
}
@@ -332,7 +332,7 @@ void elf_generate_section_headers(void)
332
332
shdr .sh_name = sh_name ;
333
333
shdr .sh_type = 1 ;
334
334
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 */
336
336
shdr .sh_offset = ofs ;
337
337
shdr .sh_size = strlen (DYN_LINKER ) + 1 ;
338
338
shdr .sh_link = 0 ;
@@ -345,9 +345,9 @@ void elf_generate_section_headers(void)
345
345
346
346
/* .rel.plt */
347
347
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 */
351
351
shdr .sh_offset = ofs ;
352
352
shdr .sh_size = elf_relplt -> size ;
353
353
shdr .sh_link = 8 ; /* The section header index of .dynsym. */
@@ -362,7 +362,7 @@ void elf_generate_section_headers(void)
362
362
shdr .sh_name = sh_name ;
363
363
shdr .sh_type = 1 ;
364
364
shdr .sh_flags = 0x6 ;
365
- shdr .sh_addr = elf_plt_start ;
365
+ shdr .sh_addr = ELF_START + ofs ; /* Use consistent VA calculation */
366
366
shdr .sh_offset = ofs ;
367
367
shdr .sh_size = elf_plt -> size ;
368
368
shdr .sh_link = 0 ;
@@ -377,7 +377,7 @@ void elf_generate_section_headers(void)
377
377
shdr .sh_name = sh_name ;
378
378
shdr .sh_type = 1 ;
379
379
shdr .sh_flags = 0x3 ;
380
- shdr .sh_addr = elf_got_start ;
380
+ shdr .sh_addr = ELF_START + ofs ; /* Use consistent VA calculation */
381
381
shdr .sh_offset = ofs ;
382
382
shdr .sh_size = elf_got -> size ;
383
383
shdr .sh_link = 0 ;
@@ -392,7 +392,7 @@ void elf_generate_section_headers(void)
392
392
shdr .sh_name = sh_name ;
393
393
shdr .sh_type = 3 ;
394
394
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 */
396
396
shdr .sh_offset = ofs ;
397
397
shdr .sh_size = elf_dynstr -> size ;
398
398
shdr .sh_link = 0 ;
@@ -407,7 +407,7 @@ void elf_generate_section_headers(void)
407
407
shdr .sh_name = sh_name ;
408
408
shdr .sh_type = 11 ;
409
409
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 */
411
411
shdr .sh_offset = ofs ;
412
412
shdr .sh_size = elf_dynsym -> size ;
413
413
shdr .sh_link = 7 ;
@@ -422,8 +422,7 @@ void elf_generate_section_headers(void)
422
422
shdr .sh_name = sh_name ;
423
423
shdr .sh_type = 6 ;
424
424
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 */
427
426
shdr .sh_offset = ofs ;
428
427
shdr .sh_size = elf_dynamic -> size ;
429
428
shdr .sh_link = 7 ; /* The section header index of .dynstr. */
@@ -531,7 +530,14 @@ void elf_generate_sections(void)
531
530
got_sz += PTR_SIZE ;
532
531
533
532
/* 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 ;
535
541
elf_plt_start = elf_relplt_start + relplt_sz ;
536
542
elf_got_start = elf_plt_start + plt_sz ;
537
543
@@ -701,8 +707,12 @@ void elf_preprocess(void)
701
707
elf_header_len += (sizeof (elf32_phdr_t ) * 3 );
702
708
elf_code_start = ELF_START + elf_header_len ;
703
709
elf_data_start = elf_code_start + elf_offset ;
710
+ /* Align elf_data BEFORE generate_sections so the size is correct */
704
711
elf_align (elf_data );
712
+
713
+ /* Now generate sections with the correct aligned sizes */
705
714
elf_generate_sections ();
715
+
706
716
elf_align (elf_symtab );
707
717
elf_align (elf_strtab );
708
718
}
0 commit comments