elf64getsec.c (1603B)
1 #include <stdio.h> 2 3 #include <scc/mach.h> 4 #include <scc/elf64.h> 5 6 #include "../libmach.h" 7 8 Section * 9 elf64getsec(Obj *obj, int *idx, Section *sec) 10 { 11 int stype, n = *idx; 12 unsigned long flags, type; 13 unsigned sflags; 14 Elf64 *elf = obj->data; 15 Elf_Ehdr *hdr = &elf->hdr; 16 Elf_Shdr *shdr; 17 18 if (n >= elf->nsec) 19 return NULL; 20 21 shdr = &elf->shdr[n]; 22 flags = shdr->sh_flags; 23 type = shdr->sh_type; 24 25 if (flags & SHF_ALLOC) { 26 if (type == SHT_NOBITS) 27 stype = 'B'; 28 else if (flags & SHF_WRITE) 29 stype = 'D'; 30 else 31 stype = 'T'; 32 } else { 33 stype = 'N'; 34 } 35 36 sflags = 0; 37 if (flags & SHF_WRITE) 38 sflags |= SWRITE; 39 if (flags & SHF_EXECINSTR) 40 sflags |= SEXEC; 41 if (flags & SHF_ALLOC) 42 sflags |= SLOAD|SREAD; 43 if (type != SHT_NOBITS) 44 sflags |= SALLOC; 45 if (stype == 'T' || stype == 'D') 46 sflags |= SRELOC; 47 48 /* 49 * We cannot differentiate between load and base address 50 * in a section, while we can use the physical address 51 * for that when dealing with segments. 52 * Also, we don't have an easy way to know the number of 53 * relocations affecting one section. To know that, we 54 * have to run over the relocation sections and find one 55 * with the sh_link pointing to this section. Maybe, 56 * we should just remove the nrelloc field. 57 */ 58 if (n == SHN_UNDEF) 59 sec->name = "*UND*"; 60 else 61 sec->name = elf64str(obj, SEC_STRTBL, shdr->sh_name); 62 63 sec->index = n; 64 sec->size = shdr->sh_size; 65 sec->base = shdr->sh_addr; 66 sec->load = shdr->sh_addr; 67 sec->offset = shdr->sh_offset; 68 sec->nreloc = 0; 69 sec->type = stype; 70 sec->flags = sflags; 71 sec->align = shdr->sh_addralign; 72 73 return sec; 74 }