Annotation of qemu/elf_ops.h, revision 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