@@ -68,12 +68,12 @@ void elf_generate_header(void)
6868 }
6969
7070 elf32_hdr_t hdr ;
71- int phnum = 1 , shnum = 8 , shstrndx = 7 ;
71+ int phnum = 2 , shnum = 8 , shstrndx = 7 ;
7272 int shoff = elf_header_len + elf_code -> size + elf_data -> size +
7373 elf_rodata -> size + elf_symtab -> size + elf_strtab -> size +
7474 elf_shstr -> size ;
7575 if (dynlink ) {
76- phnum += 3 ;
76+ phnum += 2 ;
7777 shnum += 7 ;
7878 shstrndx += 7 ;
7979 shoff += elf_interp -> size + elf_relplt -> size + elf_plt -> size +
@@ -198,60 +198,74 @@ void elf_generate_program_headers(void)
198198 * ---+----------------+-------------------------------------------------+
199199 * 54 | | |
200200 */
201- /* program header - code and data combined */
201+ /* program header - read only segment */
202202 elf32_phdr_t phdr ;
203- phdr .p_type = 1 ; /* PT_LOAD */
204- phdr .p_offset = elf_header_len ; /* offset of segment */
205- phdr .p_vaddr = ELF_START + phdr . p_offset ; /* virtual address */
206- phdr .p_paddr = ELF_START + phdr . p_offset ; /* physical address */
203+ phdr .p_type = 1 ; /* PT_LOAD */
204+ phdr .p_offset = 0 ; /* offset of segment */
205+ phdr .p_vaddr = ELF_START ; /* virtual address */
206+ phdr .p_paddr = ELF_START ; /* physical address */
207207 phdr .p_filesz =
208- elf_code -> size + elf_data -> size + elf_rodata -> size ; /* size in file */
209- phdr .p_memsz = elf_code -> size + elf_data -> size + elf_rodata -> size +
210- elf_bss_size ; /* size in memory */
211- phdr .p_flags = 7 ; /* flags */
212- phdr .p_align = 4 ; /* alignment */
208+ elf_header_len + elf_code -> size + elf_rodata -> size ; /* size in file */
209+ phdr .p_memsz =
210+ elf_header_len + elf_code -> size + elf_rodata -> size ; /* size in memory */
211+ phdr .p_flags = 5 ; /* flags */
212+ phdr .p_align = 0x1000 ; /* alignment */
213+ if (dynlink ) {
214+ phdr .p_filesz += elf_relplt -> size + elf_plt -> size ;
215+ phdr .p_memsz += elf_relplt -> size + elf_plt -> size ;
216+ }
213217 elf_write_blk (elf_program_header , & phdr , sizeof (elf32_phdr_t ));
218+
219+ /* program header - readable and writable segment */
220+ phdr .p_type = 1 ; /* PT_LOAD */
221+ phdr .p_offset = elf_header_len + elf_code -> size +
222+ elf_rodata -> size ; /* offset of segment */
223+ phdr .p_vaddr = elf_data_start ; /* virtual address */
224+ phdr .p_paddr = elf_data_start ; /* physical address */
225+ phdr .p_filesz = elf_data -> size ; /* size in file */
226+ phdr .p_memsz = elf_data -> size + elf_bss_size ; /* size in memory */
227+ phdr .p_flags = 6 ; /* flags */
228+ phdr .p_align = 0x1000 ; /* alignment */
214229 if (dynlink ) {
215- /* program header - all dynamic sections combined */
216- phdr .p_type = 1 ; /* PT_LOAD */
217- phdr .p_offset = elf_header_len + elf_code -> size + elf_data -> size +
218- elf_rodata -> size ; /* offset of segment */
219- phdr .p_vaddr = ELF_START + phdr .p_offset ; /* virtual address */
220- phdr .p_paddr = ELF_START + phdr .p_offset ; /* physical address */
221- phdr .p_filesz = elf_interp -> size + elf_relplt -> size + elf_plt -> size +
222- elf_got -> size + elf_dynstr -> size + elf_dynsym -> size +
223- elf_dynamic -> size ; /* size in file */
224- phdr .p_memsz = elf_interp -> size + elf_relplt -> size + elf_plt -> size +
225- elf_got -> size + elf_dynstr -> size + elf_dynsym -> size +
226- elf_dynamic -> size ; /* size in memory */
227- phdr .p_flags = 7 ; /* flags */
228- phdr .p_align = 4 ; /* alignment */
229- elf_write_blk (elf_program_header , & phdr , sizeof (elf32_phdr_t ));
230+ phdr .p_offset += elf_relplt -> size + elf_plt -> size ;
231+ phdr .p_vaddr = elf_interp_start ;
232+ phdr .p_paddr = elf_interp_start ;
233+ phdr .p_filesz += elf_interp -> size + elf_got -> size + elf_dynstr -> size +
234+ elf_dynsym -> size + elf_dynamic -> size ;
235+ phdr .p_memsz += elf_interp -> size + elf_got -> size + elf_dynstr -> size +
236+ elf_dynsym -> size + elf_dynamic -> size ;
237+ }
238+ elf_write_blk (elf_program_header , & phdr , sizeof (elf32_phdr_t ));
230239
240+
241+ if (dynlink ) {
231242 /* program header - program interpreter (.interp section) */
232243 phdr .p_type = 3 ; /* PT_INTERP */
233- phdr .p_offset = elf_header_len + elf_code -> size + elf_data -> size +
234- elf_rodata -> size ; /* offset of segment */
235- phdr .p_vaddr = ELF_START + phdr .p_offset ; /* virtual address */
236- phdr .p_paddr = ELF_START + phdr .p_offset ; /* physical address */
237- phdr .p_filesz = strlen (DYN_LINKER ) + 1 ; /* size in file */
238- phdr .p_memsz = strlen (DYN_LINKER ) + 1 ; /* size in memory */
239- phdr .p_flags = 4 ; /* flags */
240- phdr .p_align = 1 ; /* alignment */
244+ phdr .p_offset = elf_header_len + elf_code -> size + elf_rodata -> size +
245+ elf_relplt -> size +
246+ elf_plt -> size ; /* offset of segment */
247+ phdr .p_vaddr = elf_interp_start ; /* virtual address */
248+ phdr .p_paddr = elf_interp_start ; /* physical address */
249+ phdr .p_filesz = strlen (DYN_LINKER ) + 1 ; /* size in file */
250+ phdr .p_memsz = strlen (DYN_LINKER ) + 1 ; /* size in memory */
251+ phdr .p_flags = 4 ; /* flags */
252+ phdr .p_align = 1 ; /* alignment */
241253 elf_write_blk (elf_program_header , & phdr , sizeof (elf32_phdr_t ));
242254
243255 /* program header - .dynamic section */
244256 phdr .p_type = 2 ; /* PT_DYNAMIC */
245- phdr .p_offset = elf_header_len + elf_code -> size + elf_data -> size +
246- elf_rodata -> size + elf_interp -> size + elf_relplt -> size +
247- elf_plt -> size + elf_got -> size + elf_dynstr -> size +
248- elf_dynsym -> size ; /* offset of segment */
249- phdr .p_vaddr = ELF_START + phdr .p_offset ; /* virtual address */
250- phdr .p_paddr = ELF_START + phdr .p_offset ; /* physical address */
251- phdr .p_filesz = elf_dynamic -> size ; /* size in file */
252- phdr .p_memsz = elf_dynamic -> size ; /* size in memory */
253- phdr .p_flags = 6 ; /* flags */
254- phdr .p_align = 4 ; /* alignment */
257+ phdr .p_offset = elf_header_len + elf_code -> size + elf_rodata -> size +
258+ elf_relplt -> size + elf_plt -> size + elf_interp -> size +
259+ elf_got -> size + elf_dynstr -> size +
260+ elf_dynsym -> size ; /* offset of segment */
261+ phdr .p_vaddr = elf_got_start + elf_got -> size + elf_dynstr -> size +
262+ elf_dynsym -> size ; /* virtual address */
263+ phdr .p_paddr = elf_got_start + elf_got -> size + elf_dynstr -> size +
264+ elf_dynsym -> size ; /* physical address */
265+ phdr .p_filesz = elf_dynamic -> size ; /* size in file */
266+ phdr .p_memsz = elf_dynamic -> size ; /* size in memory */
267+ phdr .p_flags = 6 ; /* flags */
268+ phdr .p_align = 4 ; /* alignment */
255269 elf_write_blk (elf_program_header , & phdr , sizeof (elf32_phdr_t ));
256270 }
257271}
@@ -327,21 +341,6 @@ void elf_generate_section_headers(void)
327341 ofs += elf_code -> size ;
328342 sh_name += strlen (".text" ) + 1 ;
329343
330- /* .data */
331- shdr .sh_name = sh_name ;
332- shdr .sh_type = 1 ;
333- shdr .sh_flags = 3 ;
334- shdr .sh_addr = elf_data_start ;
335- shdr .sh_offset = ofs ;
336- shdr .sh_size = elf_data -> size ;
337- shdr .sh_link = 0 ;
338- shdr .sh_info = 0 ;
339- shdr .sh_addralign = 4 ;
340- shdr .sh_entsize = 0 ;
341- elf_write_blk (elf_section_header , & shdr , sizeof (elf32_shdr_t ));
342- ofs += elf_data -> size ;
343- sh_name += strlen (".data" ) + 1 ;
344-
345344 /* .rodata */
346345 shdr .sh_name = sh_name ; /* Offset in shstrtab for ".rodata" */
347346 shdr .sh_type = 1 ; /* SHT_PROGBITS */
@@ -357,46 +356,16 @@ void elf_generate_section_headers(void)
357356 ofs += elf_rodata -> size ;
358357 sh_name += strlen (".rodata" ) + 1 ;
359358
360- /* .bss */
361- shdr .sh_name = sh_name ; /* Offset in shstrtab for ".bss" */
362- shdr .sh_type = 8 ; /* SHT_NOBITS */
363- shdr .sh_flags = 3 ; /* SHF_ALLOC | SHF_WRITE */
364- shdr .sh_addr = elf_bss_start ;
365- shdr .sh_offset = ofs ; /* File offset (not actually used for NOBITS) */
366- shdr .sh_size = elf_bss_size ;
367- shdr .sh_link = 0 ;
368- shdr .sh_info = 0 ;
369- shdr .sh_addralign = 4 ;
370- shdr .sh_entsize = 0 ;
371- elf_write_blk (elf_section_header , & shdr , sizeof (elf32_shdr_t ));
372- sh_name += strlen (".bss" ) + 1 ;
373- /* Note: .bss is not written to file (SHT_NOBITS) */
374-
375359 if (dynlink ) {
376- /* .interp */
377- shdr .sh_name = sh_name ;
378- shdr .sh_type = 1 ;
379- shdr .sh_flags = 0x2 ;
380- shdr .sh_addr = elf_interp_start ;
381- shdr .sh_offset = ofs ;
382- shdr .sh_size = strlen (DYN_LINKER ) + 1 ;
383- shdr .sh_link = 0 ;
384- shdr .sh_info = 0 ;
385- shdr .sh_addralign = 1 ;
386- shdr .sh_entsize = 0 ;
387- elf_write_blk (elf_section_header , & shdr , sizeof (elf32_shdr_t ));
388- ofs += elf_interp -> size ;
389- sh_name += strlen (".interp" ) + 1 ;
390-
391360 /* .rel.plt */
392361 shdr .sh_name = sh_name ;
393362 shdr .sh_type = 9 ; /* SHT_REL */
394363 shdr .sh_flags = 0x42 ; /* 0x40 | SHF_ALLOC */
395364 shdr .sh_addr = elf_relplt_start ;
396365 shdr .sh_offset = ofs ;
397366 shdr .sh_size = elf_relplt -> size ;
398- shdr .sh_link = 10 ; /* The section header index of .dynsym. */
399- shdr .sh_info = 8 ; /* The section header index of .got. */
367+ shdr .sh_link = 8 ; /* The section header index of .dynsym. */
368+ shdr .sh_info = 6 ; /* The section header index of .got. */
400369 shdr .sh_addralign = 4 ;
401370 shdr .sh_entsize = sizeof (elf32_rel_t );
402371 elf_write_blk (elf_section_header , & shdr , sizeof (elf32_shdr_t ));
@@ -418,6 +387,21 @@ void elf_generate_section_headers(void)
418387 ofs += elf_plt -> size ;
419388 sh_name += strlen (".plt" ) + 1 ;
420389
390+ /* .interp */
391+ shdr .sh_name = sh_name ;
392+ shdr .sh_type = 1 ;
393+ shdr .sh_flags = 0x2 ;
394+ shdr .sh_addr = elf_interp_start ;
395+ shdr .sh_offset = ofs ;
396+ shdr .sh_size = strlen (DYN_LINKER ) + 1 ;
397+ shdr .sh_link = 0 ;
398+ shdr .sh_info = 0 ;
399+ shdr .sh_addralign = 1 ;
400+ shdr .sh_entsize = 0 ;
401+ elf_write_blk (elf_section_header , & shdr , sizeof (elf32_shdr_t ));
402+ ofs += elf_interp -> size ;
403+ sh_name += strlen (".interp" ) + 1 ;
404+
421405 /* .got */
422406 shdr .sh_name = sh_name ;
423407 shdr .sh_type = 1 ;
@@ -455,7 +439,7 @@ void elf_generate_section_headers(void)
455439 shdr .sh_addr = elf_got_start + elf_got -> size + elf_dynstr -> size ;
456440 shdr .sh_offset = ofs ;
457441 shdr .sh_size = elf_dynsym -> size ;
458- shdr .sh_link = 9 ;
442+ shdr .sh_link = 7 ;
459443 shdr .sh_info = 1 ;
460444 shdr .sh_addralign = 4 ;
461445 shdr .sh_entsize = sizeof (elf32_sym_t );
@@ -471,7 +455,7 @@ void elf_generate_section_headers(void)
471455 elf_got_start + elf_got -> size + elf_dynstr -> size + elf_dynsym -> size ;
472456 shdr .sh_offset = ofs ;
473457 shdr .sh_size = elf_dynamic -> size ;
474- shdr .sh_link = 9 ; /* The section header index of .dynstr. */
458+ shdr .sh_link = 7 ; /* The section header index of .dynstr. */
475459 shdr .sh_info = 0 ;
476460 shdr .sh_addralign = 4 ;
477461 shdr .sh_entsize = 0 ;
@@ -480,6 +464,36 @@ void elf_generate_section_headers(void)
480464 sh_name += strlen (".dynamic" ) + 1 ;
481465 }
482466
467+ /* .data */
468+ shdr .sh_name = sh_name ;
469+ shdr .sh_type = 1 ;
470+ shdr .sh_flags = 3 ;
471+ shdr .sh_addr = elf_data_start ;
472+ shdr .sh_offset = ofs ;
473+ shdr .sh_size = elf_data -> size ;
474+ shdr .sh_link = 0 ;
475+ shdr .sh_info = 0 ;
476+ shdr .sh_addralign = 4 ;
477+ shdr .sh_entsize = 0 ;
478+ elf_write_blk (elf_section_header , & shdr , sizeof (elf32_shdr_t ));
479+ ofs += elf_data -> size ;
480+ sh_name += strlen (".data" ) + 1 ;
481+
482+ /* .bss */
483+ shdr .sh_name = sh_name ; /* Offset in shstrtab for ".bss" */
484+ shdr .sh_type = 8 ; /* SHT_NOBITS */
485+ shdr .sh_flags = 3 ; /* SHF_ALLOC | SHF_WRITE */
486+ shdr .sh_addr = elf_bss_start ;
487+ shdr .sh_offset = ofs ; /* File offset (not actually used for NOBITS) */
488+ shdr .sh_size = elf_bss_size ;
489+ shdr .sh_link = 0 ;
490+ shdr .sh_info = 0 ;
491+ shdr .sh_addralign = 4 ;
492+ shdr .sh_entsize = 0 ;
493+ elf_write_blk (elf_section_header , & shdr , sizeof (elf32_shdr_t ));
494+ sh_name += strlen (".bss" ) + 1 ;
495+ /* Note: .bss is not written to file (SHT_NOBITS) */
496+
483497 /* .symtab */
484498 shdr .sh_name = sh_name ;
485499 shdr .sh_type = 2 ;
@@ -587,10 +601,10 @@ void elf_generate_sections(void)
587601 got_size += PTR_SIZE ;
588602
589603 /* Get the starting points of the sections. */
590- elf_interp_start = elf_bss_start + elf_bss_size ;
591- elf_relplt_start = elf_interp_start + elf_interp -> size ;
604+ elf_relplt_start = elf_rodata_start + elf_rodata -> size ;
592605 elf_plt_start = elf_relplt_start + relplt_size ;
593- elf_got_start = elf_plt_start + plt_size ;
606+ elf_interp_start = elf_plt_start + plt_size + 0x1000 ;
607+ elf_got_start = elf_interp_start + elf_interp -> size ;
594608
595609 /* dynstr, dynsym and relplt sections */
596610 elf_write_byte (elf_dynstr , 0 );
@@ -708,19 +722,15 @@ void elf_generate_sections(void)
708722 elf_write_byte (elf_shstr , 0 );
709723 elf_write_str (elf_shstr , ".text" );
710724 elf_write_byte (elf_shstr , 0 );
711- elf_write_str (elf_shstr , ".data" );
712- elf_write_byte (elf_shstr , 0 );
713725 elf_write_str (elf_shstr , ".rodata" );
714726 elf_write_byte (elf_shstr , 0 );
715- elf_write_str (elf_shstr , ".bss" );
716- elf_write_byte (elf_shstr , 0 );
717727 if (dynlink ) {
718- elf_write_str (elf_shstr , ".interp" );
719- elf_write_byte (elf_shstr , 0 );
720728 elf_write_str (elf_shstr , ".rel.plt" );
721729 elf_write_byte (elf_shstr , 0 );
722730 elf_write_str (elf_shstr , ".plt" );
723731 elf_write_byte (elf_shstr , 0 );
732+ elf_write_str (elf_shstr , ".interp" );
733+ elf_write_byte (elf_shstr , 0 );
724734 elf_write_str (elf_shstr , ".got" );
725735 elf_write_byte (elf_shstr , 0 );
726736 elf_write_str (elf_shstr , ".dynstr" );
@@ -730,6 +740,10 @@ void elf_generate_sections(void)
730740 elf_write_str (elf_shstr , ".dynamic" );
731741 elf_write_byte (elf_shstr , 0 );
732742 }
743+ elf_write_str (elf_shstr , ".data" );
744+ elf_write_byte (elf_shstr , 0 );
745+ elf_write_str (elf_shstr , ".bss" );
746+ elf_write_byte (elf_shstr , 0 );
733747 elf_write_str (elf_shstr , ".symtab" );
734748 elf_write_byte (elf_shstr , 0 );
735749 elf_write_str (elf_shstr , ".strtab" );
@@ -758,16 +772,21 @@ void elf_add_symbol(const char *symbol, int pc)
758772
759773void elf_preprocess (void )
760774{
761- elf_header_len = sizeof (elf32_hdr_t ) + sizeof (elf32_phdr_t );
775+ elf_header_len = sizeof (elf32_hdr_t ) + ( sizeof (elf32_phdr_t ) << 1 );
762776 if (dynlink )
763- elf_header_len += (sizeof (elf32_phdr_t ) * 3 );
777+ elf_header_len += (sizeof (elf32_phdr_t ) << 1 );
764778 elf_align (elf_data );
765779 elf_align (elf_rodata );
766780 elf_code_start = ELF_START + elf_header_len ;
767- elf_data_start = elf_code_start + elf_offset ;
768- elf_rodata_start = elf_data_start + elf_data -> size ;
769- elf_bss_start = elf_rodata_start + elf_rodata -> size ;
781+ elf_rodata_start = elf_code_start + elf_offset ;
770782 elf_generate_sections ();
783+ if (dynlink ) {
784+ elf_data_start = elf_got_start + elf_got -> size + elf_dynstr -> size +
785+ elf_dynsym -> size + elf_dynamic -> size ;
786+ } else {
787+ elf_data_start = elf_rodata_start + elf_rodata -> size + 0x1000 ;
788+ }
789+ elf_bss_start = elf_data_start + elf_data -> size ;
771790 elf_align (elf_symtab );
772791 elf_align (elf_strtab );
773792}
@@ -794,20 +813,20 @@ void elf_generate(const char *outfile)
794813 fputc (elf_header -> elements [i ], fp );
795814 for (int i = 0 ; i < elf_program_header -> size ; i ++ )
796815 fputc (elf_program_header -> elements [i ], fp );
816+ /* Read only sections */
797817 for (int i = 0 ; i < elf_code -> size ; i ++ )
798818 fputc (elf_code -> elements [i ], fp );
799- for (int i = 0 ; i < elf_data -> size ; i ++ )
800- fputc (elf_data -> elements [i ], fp );
801819 for (int i = 0 ; i < elf_rodata -> size ; i ++ )
802820 fputc (elf_rodata -> elements [i ], fp );
803- /* Note: .bss is not written to file (SHT_NOBITS) */
821+
822+ /* Readable and writable sections */
804823 if (dynlink ) {
805- for (int i = 0 ; i < elf_interp -> size ; i ++ )
806- fputc (elf_interp -> elements [i ], fp );
807824 for (int i = 0 ; i < elf_relplt -> size ; i ++ )
808825 fputc (elf_relplt -> elements [i ], fp );
809826 for (int i = 0 ; i < elf_plt -> size ; i ++ )
810827 fputc (elf_plt -> elements [i ], fp );
828+ for (int i = 0 ; i < elf_interp -> size ; i ++ )
829+ fputc (elf_interp -> elements [i ], fp );
811830 for (int i = 0 ; i < elf_got -> size ; i ++ )
812831 fputc (elf_got -> elements [i ], fp );
813832 for (int i = 0 ; i < elf_dynstr -> size ; i ++ )
@@ -817,6 +836,11 @@ void elf_generate(const char *outfile)
817836 for (int i = 0 ; i < elf_dynamic -> size ; i ++ )
818837 fputc (elf_dynamic -> elements [i ], fp );
819838 }
839+ for (int i = 0 ; i < elf_data -> size ; i ++ )
840+ fputc (elf_data -> elements [i ], fp );
841+ /* Note: .bss is not written to file (SHT_NOBITS) */
842+
843+ /* Other sections and section headers */
820844 for (int i = 0 ; i < elf_symtab -> size ; i ++ )
821845 fputc (elf_symtab -> elements [i ], fp );
822846 for (int i = 0 ; i < elf_strtab -> size ; i ++ )
0 commit comments