@@ -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