(linenum→info "unix/slp.c:2238")

qemu/0.9.1/elf_ops.h

    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: static int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend,
  142:                               int must_swab, uint64_t *pentry,
  143:                               uint64_t *lowaddr, uint64_t *highaddr)
  144: {
  145:     struct elfhdr ehdr;
  146:     struct elf_phdr *phdr = NULL, *ph;
  147:     int size, i, total_size;
  148:     elf_word mem_size;
  149:     uint64_t addr, low = 0, high = 0;
  150:     uint8_t *data = NULL;
  151: 
  152:     if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
  153:         goto fail;
  154:     if (must_swab) {
  155:         glue(bswap_ehdr, SZ)(&ehdr);
  156:     }
  157: 
  158:     if (ELF_MACHINE != ehdr.e_machine)
  159:         goto fail;
  160: 
  161:     if (pentry)
  162:         *pentry = (uint64_t)(elf_sword)ehdr.e_entry;
  163: 
  164:     glue(load_symbols, SZ)(&ehdr, fd, must_swab);
  165: 
  166:     size = ehdr.e_phnum * sizeof(phdr[0]);
  167:     lseek(fd, ehdr.e_phoff, SEEK_SET);
  168:     phdr = qemu_mallocz(size);
  169:     if (!phdr)
  170:         goto fail;
  171:     if (read(fd, phdr, size) != size)
  172:         goto fail;
  173:     if (must_swab) {
  174:         for(i = 0; i < ehdr.e_phnum; i++) {
  175:             ph = &phdr[i];
  176:             glue(bswap_phdr, SZ)(ph);
  177:         }
  178:     }
  179: 
  180:     total_size = 0;
  181:     for(i = 0; i < ehdr.e_phnum; i++) {
  182:         ph = &phdr[i];
  183:         if (ph->p_type == PT_LOAD) {
  184:             mem_size = ph->p_memsz;
  185:             /* XXX: avoid allocating */
  186:             data = qemu_mallocz(mem_size);
  187:             if (ph->p_filesz > 0) {
  188:                 if (lseek(fd, ph->p_offset, SEEK_SET) < 0)
  189:                     goto fail;
  190:                 if (read(fd, data, ph->p_filesz) != ph->p_filesz)
  191:                     goto fail;
  192:             }
  193:             addr = ph->p_vaddr + virt_to_phys_addend;
  194: 
  195:             cpu_physical_memory_write_rom(addr, data, mem_size);
  196: 
  197:             total_size += mem_size;
  198:             if (!low || addr < low)
  199:                 low = addr;
  200:             if (!high || (addr + mem_size) > high)
  201:                 high = addr + mem_size;
  202: 
  203:             qemu_free(data);
  204:             data = NULL;
  205:         }
  206:     }
  207:     qemu_free(phdr);
  208:     if (lowaddr)
  209:         *lowaddr = (uint64_t)(elf_sword)low;
  210:     if (highaddr)
  211:         *highaddr = (uint64_t)(elf_sword)high;
  212:     return total_size;
  213:  fail:
  214:     qemu_free(data);
  215:     qemu_free(phdr);
  216:     return -1;
  217: }
Syntax (Markdown)