Annotation of qemu/elf_ops.h, revision 1.1.1.1

1.1       root        1: static void glue(bswap_ehdr, SZ)(struct elfhdr *ehdr)
                      2: {
                      3:     bswap16s(&ehdr->e_type);                   /* Object file type */
                      4:     bswap16s(&ehdr->e_machine);                /* Architecture */
                      5:     bswap32s(&ehdr->e_version);                /* Object file version */
                      6:     bswapSZs(&ehdr->e_entry);          /* Entry point virtual address */
                      7:     bswapSZs(&ehdr->e_phoff);          /* Program header table file offset */
                      8:     bswapSZs(&ehdr->e_shoff);          /* Section header table file offset */
                      9:     bswap32s(&ehdr->e_flags);          /* Processor-specific flags */
                     10:     bswap16s(&ehdr->e_ehsize);         /* ELF header size in bytes */
                     11:     bswap16s(&ehdr->e_phentsize);              /* Program header table entry size */
                     12:     bswap16s(&ehdr->e_phnum);          /* Program header table entry count */
                     13:     bswap16s(&ehdr->e_shentsize);              /* Section header table entry size */
                     14:     bswap16s(&ehdr->e_shnum);          /* Section header table entry count */
                     15:     bswap16s(&ehdr->e_shstrndx);               /* Section header string table index */
                     16: }
                     17: 
                     18: static void glue(bswap_phdr, SZ)(struct elf_phdr *phdr)
                     19: {
                     20:     bswap32s(&phdr->p_type);                   /* Segment type */
                     21:     bswapSZs(&phdr->p_offset);         /* Segment file offset */
                     22:     bswapSZs(&phdr->p_vaddr);          /* Segment virtual address */
                     23:     bswapSZs(&phdr->p_paddr);          /* Segment physical address */
                     24:     bswapSZs(&phdr->p_filesz);         /* Segment size in file */
                     25:     bswapSZs(&phdr->p_memsz);          /* Segment size in memory */
                     26:     bswap32s(&phdr->p_flags);          /* Segment flags */
                     27:     bswapSZs(&phdr->p_align);          /* Segment alignment */
                     28: }
                     29: 
                     30: static void glue(bswap_shdr, SZ)(struct elf_shdr *shdr)
                     31: {
                     32:     bswap32s(&shdr->sh_name);
                     33:     bswap32s(&shdr->sh_type);
                     34:     bswapSZs(&shdr->sh_flags);
                     35:     bswapSZs(&shdr->sh_addr);
                     36:     bswapSZs(&shdr->sh_offset);
                     37:     bswapSZs(&shdr->sh_size);
                     38:     bswap32s(&shdr->sh_link);
                     39:     bswap32s(&shdr->sh_info);
                     40:     bswapSZs(&shdr->sh_addralign);
                     41:     bswapSZs(&shdr->sh_entsize);
                     42: }
                     43: 
                     44: static void glue(bswap_sym, SZ)(struct elf_sym *sym)
                     45: {
                     46:     bswap32s(&sym->st_name);
                     47:     bswapSZs(&sym->st_value);
                     48:     bswapSZs(&sym->st_size);
                     49:     bswap16s(&sym->st_shndx);
                     50: }
                     51: 
                     52: static struct elf_shdr *glue(find_section, SZ)(struct elf_shdr *shdr_table, 
                     53:                                                int n, int type)
                     54: {
                     55:     int i;
                     56:     for(i=0;i<n;i++) {
                     57:         if (shdr_table[i].sh_type == type)
                     58:             return shdr_table + i;
                     59:     }
                     60:     return NULL;
                     61: }
                     62: 
                     63: static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab)
                     64: {
                     65:     struct elf_shdr *symtab, *strtab, *shdr_table = NULL;
                     66:     struct elf_sym *syms = NULL;
                     67: #if (SZ == 64)
                     68:     struct elf32_sym *syms32 = NULL;
                     69: #endif
                     70:     struct syminfo *s;
                     71:     int nsyms, i;
                     72:     char *str = NULL;
                     73: 
                     74:     shdr_table = load_at(fd, ehdr->e_shoff, 
                     75:                          sizeof(struct elf_shdr) * ehdr->e_shnum);
                     76:     if (!shdr_table)
                     77:         return -1;
                     78:     
                     79:     if (must_swab) {
                     80:         for (i = 0; i < ehdr->e_shnum; i++) {
                     81:             glue(bswap_shdr, SZ)(shdr_table + i);
                     82:         }
                     83:     }
                     84:         
                     85:     symtab = glue(find_section, SZ)(shdr_table, ehdr->e_shnum, SHT_SYMTAB);
                     86:     if (!symtab)
                     87:         goto fail;
                     88:     syms = load_at(fd, symtab->sh_offset, symtab->sh_size);
                     89:     if (!syms)
                     90:         goto fail;
                     91: 
                     92:     nsyms = symtab->sh_size / sizeof(struct elf_sym);
                     93: #if (SZ == 64)
                     94:     syms32 = qemu_mallocz(nsyms * sizeof(struct elf32_sym));
                     95: #endif
                     96:     for (i = 0; i < nsyms; i++) {
                     97:         if (must_swab)
                     98:             glue(bswap_sym, SZ)(&syms[i]);
                     99: #if (SZ == 64)
                    100:        syms32[i].st_name = syms[i].st_name;
                    101:        syms32[i].st_info = syms[i].st_info;
                    102:        syms32[i].st_other = syms[i].st_other;
                    103:        syms32[i].st_shndx = syms[i].st_shndx;
                    104:        syms32[i].st_value = syms[i].st_value & 0xffffffff;
                    105:        syms32[i].st_size = syms[i].st_size & 0xffffffff;
                    106: #endif
                    107:     }
                    108:     /* String table */
                    109:     if (symtab->sh_link >= ehdr->e_shnum)
                    110:         goto fail;
                    111:     strtab = &shdr_table[symtab->sh_link];
                    112: 
                    113:     str = load_at(fd, strtab->sh_offset, strtab->sh_size);
                    114:     if (!str)
                    115:        goto fail;
                    116: 
                    117:     /* Commit */
                    118:     s = qemu_mallocz(sizeof(*s));
                    119: #if (SZ == 64)
                    120:     s->disas_symtab = syms32;
                    121:     qemu_free(syms);
                    122: #else
                    123:     s->disas_symtab = syms;
                    124: #endif
                    125:     s->disas_num_syms = nsyms;
                    126:     s->disas_strtab = str;
                    127:     s->next = syminfos;
                    128:     syminfos = s;
                    129:     qemu_free(shdr_table);
                    130:     return 0;
                    131:  fail:
                    132: #if (SZ == 64)
                    133:     qemu_free(syms32);
                    134: #endif
                    135:     qemu_free(syms);
                    136:     qemu_free(str);
                    137:     qemu_free(shdr_table);
                    138:     return -1;
                    139: }
                    140: 
                    141: int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend,
                    142:                        int must_swab, uint64_t *pentry)
                    143: {
                    144:     struct elfhdr ehdr;
                    145:     struct elf_phdr *phdr = NULL, *ph;
                    146:     int size, i, total_size;
                    147:     elf_word mem_size, addr;
                    148:     uint8_t *data = NULL;
                    149: 
                    150:     if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
                    151:         goto fail;
                    152:     if (must_swab) {
                    153:         glue(bswap_ehdr, SZ)(&ehdr);
                    154:     }
                    155: 
                    156:     if (pentry)
                    157:        *pentry = (uint64_t)ehdr.e_entry;
                    158: 
                    159:     glue(load_symbols, SZ)(&ehdr, fd, must_swab);
                    160: 
                    161:     size = ehdr.e_phnum * sizeof(phdr[0]);
                    162:     lseek(fd, ehdr.e_phoff, SEEK_SET);
                    163:     phdr = qemu_mallocz(size);
                    164:     if (!phdr)
                    165:         goto fail;
                    166:     if (read(fd, phdr, size) != size)
                    167:         goto fail;
                    168:     if (must_swab) {
                    169:         for(i = 0; i < ehdr.e_phnum; i++) {
                    170:             ph = &phdr[i];
                    171:             glue(bswap_phdr, SZ)(ph);
                    172:         }
                    173:     }
                    174:     
                    175:     total_size = 0;
                    176:     for(i = 0; i < ehdr.e_phnum; i++) {
                    177:         ph = &phdr[i];
                    178:         if (ph->p_type == PT_LOAD) {
                    179:             mem_size = ph->p_memsz;
                    180:             /* XXX: avoid allocating */
                    181:             data = qemu_mallocz(mem_size);
                    182:             if (ph->p_filesz > 0) {
                    183:                 if (lseek(fd, ph->p_offset, SEEK_SET) < 0)
                    184:                     goto fail;
                    185:                 if (read(fd, data, ph->p_filesz) != ph->p_filesz)
                    186:                     goto fail;
                    187:             }
                    188:             addr = ph->p_vaddr + virt_to_phys_addend;
                    189: 
                    190:             cpu_physical_memory_write_rom(addr, data, mem_size);
                    191: 
                    192:             total_size += mem_size;
                    193: 
                    194:             qemu_free(data);
                    195:             data = NULL;
                    196:         }
                    197:     }
                    198:     qemu_free(phdr);
                    199:     return total_size;
                    200:  fail:
                    201:     qemu_free(data);
                    202:     qemu_free(phdr);
                    203:     return -1;
                    204: }
                    205: 

unix.superglobalmegacorp.com