boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

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         }