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