/[qemu]/qemu/dyngen.c
ViewVC logotype

Diff of /qemu/dyngen.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.13 by bellard, Tue May 13 18:59:59 2003 UTC revision 1.14 by bellard, Sun May 25 16:43:08 2003 UTC
# Line 170  void elf_swap_phdr(struct elf_phdr *h) Line 170  void elf_swap_phdr(struct elf_phdr *h)
170      swabls(&h->p_align);                /* Segment alignment */      swabls(&h->p_align);                /* Segment alignment */
171  }  }
172    
173    /* ELF file info */
174  int do_swap;  int do_swap;
175    struct elf_shdr *shdr;
176    struct elfhdr ehdr;
177    ElfW(Sym) *symtab;
178    int nb_syms;
179    char *strtab;
180    /* data section */
181    uint8_t *data_data;
182    int data_shndx;
183    
184  uint16_t get16(uint16_t *p)  uint16_t get16(uint16_t *p)
185  {  {
# Line 270  int strstart(const char *str, const char Line 279  int strstart(const char *str, const char
279  /* generate op code */  /* generate op code */
280  void gen_code(const char *name, host_ulong offset, host_ulong size,  void gen_code(const char *name, host_ulong offset, host_ulong size,
281                FILE *outfile, uint8_t *text, ELF_RELOC *relocs, int nb_relocs, int reloc_sh_type,                FILE *outfile, uint8_t *text, ELF_RELOC *relocs, int nb_relocs, int reloc_sh_type,
282                ElfW(Sym) *symtab, char *strtab, int gen_switch)                int gen_switch)
283  {  {
284      int copy_size = 0;      int copy_size = 0;
285      uint8_t *p_start, *p_end;      uint8_t *p_start, *p_end;
# Line 291  void gen_code(const char *name, host_ulo Line 300  void gen_code(const char *name, host_ulo
300      switch(ELF_ARCH) {      switch(ELF_ARCH) {
301      case EM_386:      case EM_386:
302          {          {
303              uint8_t *p;              int len;
304              p = p_end - 1;              len = p_end - p_start;
305              if (p == p_start)              if (len == 0)
306                  error("empty code for %s", name);                  error("empty code for %s", name);
307              if (p[0] != 0xc3)              if (p_end[-1] == 0xc3) {
308                  error("ret expected at the end of %s", name);                  len--;
309              copy_size = p - p_start;              } else {
310                    error("ret or jmp expected at the end of %s", name);
311                }
312                copy_size = len;
313          }          }
314          break;          break;
315      case EM_PPC:      case EM_PPC:
# Line 423  void gen_code(const char *name, host_ulo Line 435  void gen_code(const char *name, host_ulo
435              sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;              sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
436              if (strstart(sym_name, "__op_param", &p)) {              if (strstart(sym_name, "__op_param", &p)) {
437                  n = strtoul(p, NULL, 10);                  n = strtoul(p, NULL, 10);
438                  if (n >= MAX_ARGS)                  if (n > MAX_ARGS)
439                      error("too many arguments in %s", name);                      error("too many arguments in %s", name);
440                  args_present[n - 1] = 1;                  args_present[n - 1] = 1;
441              }              }
# Line 459  void gen_code(const char *name, host_ulo Line 471  void gen_code(const char *name, host_ulo
471              if (rel->r_offset >= start_offset &&              if (rel->r_offset >= start_offset &&
472                  rel->r_offset < start_offset + copy_size) {                  rel->r_offset < start_offset + copy_size) {
473                  sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;                  sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
474                  if (*sym_name && !strstart(sym_name, "__op_param", &p)) {                  if (*sym_name &&
475                        !strstart(sym_name, "__op_param", NULL) &&
476                        !strstart(sym_name, "__op_jmp", NULL)) {
477  #if defined(HOST_SPARC)  #if defined(HOST_SPARC)
478                      if (sym_name[0] == '.') {                      if (sym_name[0] == '.') {
479                          fprintf(outfile,                          fprintf(outfile,
# Line 474  void gen_code(const char *name, host_ulo Line 488  void gen_code(const char *name, host_ulo
488          }          }
489    
490          fprintf(outfile, "    memcpy(gen_code_ptr, (void *)((char *)&%s+%d), %d);\n", name, start_offset - offset, copy_size);          fprintf(outfile, "    memcpy(gen_code_ptr, (void *)((char *)&%s+%d), %d);\n", name, start_offset - offset, copy_size);
491    
492            /* emit code offset information */
493            {
494                ElfW(Sym) *sym;
495                const char *sym_name, *p;
496                target_ulong val;
497                int n;
498    
499                for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
500                    sym_name = strtab + sym->st_name;
501                    if (strstart(sym_name, "__op_label", &p)) {
502                        /* test if the variable refers to a label inside
503                           the code we are generating */
504                        if (sym->st_shndx != data_shndx)
505                            error("__op_labelN symbols must be in .data or .sdata section");
506                        val = *(target_ulong *)(data_data + sym->st_value);
507                        if (val >= start_offset && val < start_offset + copy_size) {
508                            n = strtol(p, NULL, 10);
509                            fprintf(outfile, "    label_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n", n, val - start_offset);
510                        }
511                    }
512                }
513            }
514    
515            /* load parameres in variables */
516          for(i = 0; i < nb_args; i++) {          for(i = 0; i < nb_args; i++) {
517              fprintf(outfile, "    param%d = *opparam_ptr++;\n", i + 1);              fprintf(outfile, "    param%d = *opparam_ptr++;\n", i + 1);
518          }          }
# Line 519  void gen_code(const char *name, host_ulo Line 558  void gen_code(const char *name, host_ulo
558                      if (rel->r_offset >= start_offset &&                      if (rel->r_offset >= start_offset &&
559                          rel->r_offset < start_offset + copy_size) {                          rel->r_offset < start_offset + copy_size) {
560                          sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;                          sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
561                            if (strstart(sym_name, "__op_jmp", &p)) {
562                                int n;
563                                n = strtol(p, NULL, 10);
564                                /* __op_jmp relocations are done at
565                                   runtime to do translated block
566                                   chaining: the offset of the instruction
567                                   needs to be stored */
568                                fprintf(outfile, "    jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",
569                                        n, rel->r_offset - start_offset);
570                                continue;
571                            }
572                            
573                          if (strstart(sym_name, "__op_param", &p)) {                          if (strstart(sym_name, "__op_param", &p)) {
574                              snprintf(name, sizeof(name), "param%s", p);                              snprintf(name, sizeof(name), "param%s", p);
575                          } else {                          } else {
# Line 824  void gen_code(const char *name, host_ulo Line 875  void gen_code(const char *name, host_ulo
875  int load_elf(const char *filename, FILE *outfile, int do_print_enum)  int load_elf(const char *filename, FILE *outfile, int do_print_enum)
876  {  {
877      int fd;      int fd;
878      struct elfhdr ehdr;      struct elf_shdr *sec, *symtab_sec, *strtab_sec, *text_sec;
879      struct elf_shdr *sec, *shdr, *symtab_sec, *strtab_sec, *text_sec;      int i, j;
880      int i, j, nb_syms;      ElfW(Sym) *sym;
881      ElfW(Sym) *symtab, *sym;      char *shstr, *data_name;
     char *shstr, *strtab;  
882      uint8_t *text;      uint8_t *text;
883      void *relocs;      void *relocs;
884      int nb_relocs, reloc_sh_type;      int nb_relocs, reloc_sh_type;
# Line 880  int load_elf(const char *filename, FILE Line 930  int load_elf(const char *filename, FILE
930          error("could not find .text section");          error("could not find .text section");
931      text = load_data(fd, text_sec->sh_offset, text_sec->sh_size);      text = load_data(fd, text_sec->sh_offset, text_sec->sh_size);
932    
933    #if defined(HOST_PPC)
934        data_name = ".sdata";
935    #else
936        data_name = ".data";
937    #endif
938        sec = find_elf_section(shdr, ehdr.e_shnum, shstr, data_name);
939        if (!sec)
940            error("could not find %s section", data_name);
941        data_shndx = sec - shdr;
942        data_data = load_data(fd, sec->sh_offset, sec->sh_size);
943        
944      /* find text relocations, if any */      /* find text relocations, if any */
945      nb_relocs = 0;      nb_relocs = 0;
946      relocs = NULL;      relocs = NULL;
# Line 936  int load_elf(const char *filename, FILE Line 997  int load_elf(const char *filename, FILE
997              name = strtab + sym->st_name;              name = strtab + sym->st_name;
998              if (strstart(name, OP_PREFIX, &p)) {              if (strstart(name, OP_PREFIX, &p)) {
999                  gen_code(name, sym->st_value, sym->st_size, outfile,                  gen_code(name, sym->st_value, sym->st_size, outfile,
1000                           text, relocs, nb_relocs, reloc_sh_type, symtab, strtab, 2);                           text, relocs, nb_relocs, reloc_sh_type, 2);
1001              }              }
1002          }          }
1003      } else {      } else {
# Line 963  fprintf(outfile, Line 1024  fprintf(outfile,
1024  #endif  #endif
1025  fprintf(outfile,  fprintf(outfile,
1026  "int dyngen_code(uint8_t *gen_code_buf,\n"  "int dyngen_code(uint8_t *gen_code_buf,\n"
1027    "                uint16_t *label_offsets, uint16_t *jmp_offsets,\n"
1028  "                const uint16_t *opc_buf, const uint32_t *opparam_buf)\n"  "                const uint16_t *opc_buf, const uint32_t *opparam_buf)\n"
1029  "{\n"  "{\n"
1030  "    uint8_t *gen_code_ptr;\n"  "    uint8_t *gen_code_ptr;\n"
# Line 1001  fprintf(outfile, Line 1063  fprintf(outfile,
1063                  if (sym->st_shndx != (text_sec - shdr))                  if (sym->st_shndx != (text_sec - shdr))
1064                      error("invalid section for opcode (0x%x)", sym->st_shndx);                      error("invalid section for opcode (0x%x)", sym->st_shndx);
1065                  gen_code(name, sym->st_value, sym->st_size, outfile,                  gen_code(name, sym->st_value, sym->st_size, outfile,
1066                           text, relocs, nb_relocs, reloc_sh_type, symtab, strtab, 1);                           text, relocs, nb_relocs, reloc_sh_type, 1);
1067              }              }
1068          }          }
1069    
# Line 1056  fprintf(outfile, Line 1118  fprintf(outfile,
1118                  if (sym->st_shndx != (text_sec - shdr))                  if (sym->st_shndx != (text_sec - shdr))
1119                      error("invalid section for opcode (0x%x)", sym->st_shndx);                      error("invalid section for opcode (0x%x)", sym->st_shndx);
1120                  gen_code(name, sym->st_value, sym->st_size, outfile,                  gen_code(name, sym->st_value, sym->st_size, outfile,
1121                           text, relocs, nb_relocs, reloc_sh_type, symtab, strtab, 0);                           text, relocs, nb_relocs, reloc_sh_type, 0);
1122              }              }
1123          }          }
1124      }      }

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26