pt-note-phdr.after (3534B)
1 /* compute number of program headers */ 2 switch(file_type) { 3 default: 4 case TCC_OUTPUT_OBJ: 5 phnum = 0; 6 break; 7 case TCC_OUTPUT_EXE: 8 if (!s1->static_link) 9 phnum = 4 + HAVE_PHDR; 10 else 11 phnum = 2; 12 break; 13 case TCC_OUTPUT_DLL: 14 phnum = 3; 15 break; 16 } 17 18 /* AT.2: bump phnum by 1 when an SHT_NOTE+SHF_ALLOC section is 19 * present, so the layout has room for one PT_NOTE phdr covering 20 * the .note* group. Gating on actual presence keeps the phnum 21 * unchanged for builds with no note sections (aarch64/riscv64 22 * stay byte-identical). */ 23 if (phnum > 0) { 24 for (i = 1; i < s1->nb_sections; i++) { 25 Section *ns = s1->sections[i]; 26 if (ns->sh_type == SHT_NOTE && (ns->sh_flags & SHF_ALLOC)) { 27 phnum++; 28 break; 29 } 30 } 31 } 32 33 /* Allocate strings for section names */ 34 alloc_sec_names(s1, file_type, strsec); 35 36 /* allocate program segment headers */ 37 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr))); 38 39 /* compute section to program header mapping */ 40 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf, 41 sec_order); 42 43 /* Fill remaining program header and finalize relocation related to dynamic 44 linking. */ 45 if (phnum > 0) { 46 fill_unloadable_phdr(phdr, phnum, interp, dynamic); 47 /* AT.2: fill the PT_NOTE phdr in the leftover PT_NULL slot. 48 * layout_sections fills the PT_LOAD slots; fill_unloadable_phdr 49 * fills PT_PHDR/PT_INTERP/PT_DYNAMIC. The extra slot reserved by 50 * the bump above is left as PT_NULL by tcc_mallocz, so the first 51 * PT_NULL we find is ours. Range = [min sh_offset, max 52 * sh_offset+sh_size) over SHT_NOTE+SHF_ALLOC sections. */ 53 { 54 addr_t note_off = 0, note_end = 0, note_addr = 0; 55 int note_found = 0; 56 for (i = 1; i < s1->nb_sections; i++) { 57 Section *ns = s1->sections[i]; 58 if (ns->sh_type != SHT_NOTE || !(ns->sh_flags & SHF_ALLOC)) 59 continue; 60 if (!note_found) { 61 note_off = ns->sh_offset; 62 note_end = ns->sh_offset + ns->sh_size; 63 note_addr = ns->sh_addr; 64 note_found = 1; 65 } else { 66 if (ns->sh_offset < note_off) 67 note_off = ns->sh_offset; 68 if (ns->sh_offset + ns->sh_size > note_end) 69 note_end = ns->sh_offset + ns->sh_size; 70 if (ns->sh_addr < note_addr) 71 note_addr = ns->sh_addr; 72 } 73 } 74 if (note_found) { 75 ElfW(Phdr) *nph = NULL; 76 int j; 77 for (j = 0; j < phnum; j++) { 78 if (phdr[j].p_type == PT_NULL) { 79 nph = &phdr[j]; 80 break; 81 } 82 } 83 if (nph) { 84 nph->p_type = PT_NOTE; 85 nph->p_flags = PF_R; 86 nph->p_offset = note_off; 87 nph->p_vaddr = note_addr; 88 nph->p_paddr = note_addr; 89 nph->p_filesz = note_end - note_off; 90 nph->p_memsz = note_end - note_off; 91 nph->p_align = 4; 92 } 93 } 94 }