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