Diff for /qemu/dyngen.c between versions 1.1.1.4 and 1.1.1.5

version 1.1.1.4, 2018/04/24 16:45:12 version 1.1.1.5, 2018/04/24 16:47:40
Line 1 Line 1
 /*  /*
  *  Generic Dynamic compiler generator   *  Generic Dynamic compiler generator
  *    *
  *  Copyright (c) 2003 Fabrice Bellard   *  Copyright (c) 2003 Fabrice Bellard
  *   *
  *  The COFF object format support was extracted from Kazu's QEMU port   *  The COFF object format support was extracted from Kazu's QEMU port
Line 117 Line 117
 #define elf_check_arch(x) ((x) == EM_68K)  #define elf_check_arch(x) ((x) == EM_68K)
 #define ELF_USES_RELOCA  #define ELF_USES_RELOCA
   
   #elif defined(HOST_MIPS)
   
   #define ELF_CLASS       ELFCLASS32
   #define ELF_ARCH        EM_MIPS
   #define elf_check_arch(x) ((x) == EM_MIPS)
   #define ELF_USES_RELOC
   
   #elif defined(HOST_MIPS64)
   
   /* Assume n32 ABI here, which is ELF32. */
   #define ELF_CLASS       ELFCLASS32
   #define ELF_ARCH        EM_MIPS
   #define elf_check_arch(x) ((x) == EM_MIPS)
   #define ELF_USES_RELOCA
   
 #else  #else
 #error unsupported CPU - please update the code  #error unsupported CPU - please update the code
 #endif  #endif
Line 148  typedef uint64_t host_ulong; Line 163  typedef uint64_t host_ulong;
   
 #ifdef CONFIG_FORMAT_COFF  #ifdef CONFIG_FORMAT_COFF
   
 #include "a.out.h"  
   
 typedef int32_t host_long;  typedef int32_t host_long;
 typedef uint32_t host_ulong;  typedef uint32_t host_ulong;
   
   #include "a.out.h"
   
 #define FILENAMELEN 256  #define FILENAMELEN 256
   
 typedef struct coff_sym {  typedef struct coff_sym {
Line 189  typedef uint32_t host_ulong; Line 204  typedef uint32_t host_ulong;
 struct nlist_extended  struct nlist_extended
 {  {
    union {     union {
    char *n_name;      char *n_name;
    long  n_strx;      long  n_strx;
    } n_un;     } n_un;
    unsigned char n_type;      unsigned char n_type;
    unsigned char n_sect;      unsigned char n_sect;
    short st_desc;     short st_desc;
    unsigned long st_value;     unsigned long st_value;
    unsigned long st_size;     unsigned long st_size;
Line 217  enum { Line 232  enum {
   
 int do_swap;  int do_swap;
   
 void __attribute__((noreturn)) __attribute__((format (printf, 1, 2))) error(const char *fmt, ...)  static void __attribute__((noreturn)) __attribute__((format (printf, 1, 2))) error(const char *fmt, ...)
 {  {
     va_list ap;      va_list ap;
     va_start(ap, fmt);      va_start(ap, fmt);
Line 228  void __attribute__((noreturn)) __attribu Line 243  void __attribute__((noreturn)) __attribu
     exit(1);      exit(1);
 }  }
   
 void *load_data(int fd, long offset, unsigned int size)  static void *load_data(int fd, long offset, unsigned int size)
 {  {
     char *data;      char *data;
   
Line 357  int elf_must_swap(struct elfhdr *h) Line 372  int elf_must_swap(struct elfhdr *h)
   } swaptest;    } swaptest;
   
   swaptest.i = 1;    swaptest.i = 1;
   return (h->e_ident[EI_DATA] == ELFDATA2MSB) !=     return (h->e_ident[EI_DATA] == ELFDATA2MSB) !=
       (swaptest.b[0] == 0);        (swaptest.b[0] == 0);
 }  }
     
 void elf_swap_ehdr(struct elfhdr *h)  void elf_swap_ehdr(struct elfhdr *h)
 {  {
     swab16s(&h->e_type);                        /* Object file type */      swab16s(&h->e_type);                        /* Object file type */
Line 413  void elf_swap_rel(ELF_RELOC *rel) Line 428  void elf_swap_rel(ELF_RELOC *rel)
 #endif  #endif
 }  }
   
 struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum, const char *shstr,   struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum, const char *shstr,
                                   const char *name)                                    const char *name)
 {  {
     int i;      int i;
Line 438  int find_reloc(int sh_index) Line 453  int find_reloc(int sh_index)
   
     for(i = 0; i < ehdr.e_shnum; i++) {      for(i = 0; i < ehdr.e_shnum; i++) {
         sec = &shdr[i];          sec = &shdr[i];
         if (sec->sh_type == SHT_RELOC && sec->sh_info == sh_index)           if (sec->sh_type == SHT_RELOC && sec->sh_info == sh_index)
             return i;              return i;
     }      }
     return 0;      return 0;
Line 468  int load_object(const char *filename) Line 483  int load_object(const char *filename)
     ElfW(Sym) *sym;      ElfW(Sym) *sym;
     char *shstr;      char *shstr;
     ELF_RELOC *rel;      ELF_RELOC *rel;
       
     fd = open(filename, O_RDONLY);      fd = open(filename, O_RDONLY);
     if (fd < 0)       if (fd < 0)
         error("can't open file '%s'", filename);          error("can't open file '%s'", filename);
       
     /* Read ELF header.  */      /* Read ELF header.  */
     if (read(fd, &ehdr, sizeof (ehdr)) != sizeof (ehdr))      if (read(fd, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
         error("unable to read file header");          error("unable to read file header");
Line 509  int load_object(const char *filename) Line 524  int load_object(const char *filename)
     /* read all section data */      /* read all section data */
     sdata = malloc(sizeof(void *) * ehdr.e_shnum);      sdata = malloc(sizeof(void *) * ehdr.e_shnum);
     memset(sdata, 0, sizeof(void *) * ehdr.e_shnum);      memset(sdata, 0, sizeof(void *) * ehdr.e_shnum);
       
     for(i = 0;i < ehdr.e_shnum; i++) {      for(i = 0;i < ehdr.e_shnum; i++) {
         sec = &shdr[i];          sec = &shdr[i];
         if (sec->sh_type != SHT_NOBITS)          if (sec->sh_type != SHT_NOBITS)
Line 554  int load_object(const char *filename) Line 569  int load_object(const char *filename)
   
     symtab = (ElfW(Sym) *)sdata[symtab_sec - shdr];      symtab = (ElfW(Sym) *)sdata[symtab_sec - shdr];
     strtab = (char *)sdata[symtab_sec->sh_link];      strtab = (char *)sdata[symtab_sec->sh_link];
       
     nb_syms = symtab_sec->sh_size / sizeof(ElfW(Sym));      nb_syms = symtab_sec->sh_size / sizeof(ElfW(Sym));
     if (do_swap) {      if (do_swap) {
         for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {          for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
Line 594  void sym_ent_name(struct external_syment Line 609  void sym_ent_name(struct external_syment
 {  {
     char *q;      char *q;
     int c, i, len;      int c, i, len;
       
     if (ext_sym->e.e.e_zeroes != 0) {      if (ext_sym->e.e.e_zeroes != 0) {
         q = sym->st_name;          q = sym->st_name;
         for(i = 0; i < 8; i++) {          for(i = 0; i < 8; i++) {
Line 628  char *name_for_dotdata(struct coff_rel * Line 643  char *name_for_dotdata(struct coff_rel *
                 if (sym->st_syment->e_scnum == data_shndx &&                  if (sym->st_syment->e_scnum == data_shndx &&
                     text_data >= sym->st_value &&                      text_data >= sym->st_value &&
                     text_data < sym->st_value + sym->st_size) {                      text_data < sym->st_value + sym->st_size) {
                       
                     return sym->st_name;                      return sym->st_name;
   
                 }                  }
Line 686  int load_object(const char *filename) Line 701  int load_object(const char *filename)
     uint32_t *n_strtab;      uint32_t *n_strtab;
     EXE_SYM *sym;      EXE_SYM *sym;
     EXE_RELOC *rel;      EXE_RELOC *rel;
               const char *p;
     fd = open(filename, O_RDONLY       int aux_size, j;
   
       fd = open(filename, O_RDONLY
 #ifdef _WIN32  #ifdef _WIN32
               | O_BINARY                | O_BINARY
 #endif  #endif
               );                );
     if (fd < 0)       if (fd < 0)
         error("can't open file '%s'", filename);          error("can't open file '%s'", filename);
       
     /* Read COFF header.  */      /* Read COFF header.  */
     if (read(fd, &fhdr, sizeof (fhdr)) != sizeof (fhdr))      if (read(fd, &fhdr, sizeof (fhdr)) != sizeof (fhdr))
         error("unable to read file header");          error("unable to read file header");
Line 707  int load_object(const char *filename) Line 724  int load_object(const char *filename)
   
     /* read section headers */      /* read section headers */
     shdr = load_data(fd, sizeof(struct external_filehdr) + fhdr.f_opthdr, fhdr.f_nscns * sizeof(struct external_scnhdr));      shdr = load_data(fd, sizeof(struct external_filehdr) + fhdr.f_opthdr, fhdr.f_nscns * sizeof(struct external_scnhdr));
           
     /* read all section data */      /* read all section data */
     sdata = malloc(sizeof(void *) * fhdr.f_nscns);      sdata = malloc(sizeof(void *) * fhdr.f_nscns);
     memset(sdata, 0, sizeof(void *) * fhdr.f_nscns);      memset(sdata, 0, sizeof(void *) * fhdr.f_nscns);
       
     const char *p;  
     for(i = 0;i < fhdr.f_nscns; i++) {      for(i = 0;i < fhdr.f_nscns; i++) {
         sec = &shdr[i];          sec = &shdr[i];
         if (!strstart(sec->s_name,  ".bss", &p))          if (!strstart(sec->s_name,  ".bss", &p))
Line 732  int load_object(const char *filename) Line 748  int load_object(const char *filename)
     if (!data_sec)      if (!data_sec)
         error("could not find .data section");          error("could not find .data section");
     coff_data_shndx = data_sec - shdr;      coff_data_shndx = data_sec - shdr;
       
     coff_symtab = load_data(fd, fhdr.f_symptr, fhdr.f_nsyms*SYMESZ);      coff_symtab = load_data(fd, fhdr.f_symptr, fhdr.f_nsyms*SYMESZ);
     for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) {      for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) {
         for(i=0;i<8;i++)          for(i=0;i<8;i++)
Line 742  int load_object(const char *filename) Line 758  int load_object(const char *filename)
   
   
     n_strtab = load_data(fd, (fhdr.f_symptr + fhdr.f_nsyms*SYMESZ), STRTAB_SIZE);      n_strtab = load_data(fd, (fhdr.f_symptr + fhdr.f_nsyms*SYMESZ), STRTAB_SIZE);
     strtab = load_data(fd, (fhdr.f_symptr + fhdr.f_nsyms*SYMESZ), *n_strtab);       strtab = load_data(fd, (fhdr.f_symptr + fhdr.f_nsyms*SYMESZ), *n_strtab);
       
     nb_syms = fhdr.f_nsyms;      nb_syms = fhdr.f_nsyms;
   
     for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) {      for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) {
Line 756  int load_object(const char *filename) Line 772  int load_object(const char *filename)
         /* set coff symbol */          /* set coff symbol */
         symtab = malloc(sizeof(struct coff_sym) * nb_syms);          symtab = malloc(sizeof(struct coff_sym) * nb_syms);
   
         int aux_size, j;  
         for (i = 0, ext_sym = coff_symtab, sym = symtab; i < nb_syms; i++, ext_sym++, sym++) {          for (i = 0, ext_sym = coff_symtab, sym = symtab; i < nb_syms; i++, ext_sym++, sym++) {
                 memset(sym, 0, sizeof(*sym));                  memset(sym, 0, sizeof(*sym));
                 sym->st_syment = ext_sym;                  sym->st_syment = ext_sym;
Line 790  int load_object(const char *filename) Line 805  int load_object(const char *filename)
                 } else {                  } else {
                         sym->st_size = 0;                          sym->st_size = 0;
                 }                  }
                   
                 sym->st_type = ext_sym->e_type;                  sym->st_type = ext_sym->e_type;
                 sym->st_shndx = ext_sym->e_scnum;                  sym->st_shndx = ext_sym->e_scnum;
         }          }
   
                   
     /* find text relocations, if any */      /* find text relocations, if any */
     sec = &shdr[coff_text_shndx];      sec = &shdr[coff_text_shndx];
     coff_relocs = load_data(fd, sec->s_relptr, sec->s_nreloc*RELSZ);      coff_relocs = load_data(fd, sec->s_relptr, sec->s_nreloc*RELSZ);
Line 803  int load_object(const char *filename) Line 818  int load_object(const char *filename)
   
     /* set coff relocation */      /* set coff relocation */
     relocs = malloc(sizeof(struct coff_rel) * nb_relocs);      relocs = malloc(sizeof(struct coff_rel) * nb_relocs);
     for (i = 0, ext_rel = coff_relocs, rel = relocs; i < nb_relocs;       for (i = 0, ext_rel = coff_relocs, rel = relocs; i < nb_relocs;
          i++, ext_rel++, rel++) {           i++, ext_rel++, rel++) {
         memset(rel, 0, sizeof(*rel));          memset(rel, 0, sizeof(*rel));
         rel->r_reloc = ext_rel;          rel->r_reloc = ext_rel;
Line 832  uint8_t  **sdata; Line 847  uint8_t  **sdata;
   
 /* relocs */  /* relocs */
 struct relocation_info *relocs;  struct relocation_info *relocs;
           
 /* symbols */  /* symbols */
 EXE_SYM                 *symtab;  EXE_SYM                 *symtab;
 struct nlist    *symtab_std;  struct nlist    *symtab_std;
Line 852  static inline char *find_str_by_index(in Line 867  static inline char *find_str_by_index(in
 static char *get_sym_name(EXE_SYM *sym)  static char *get_sym_name(EXE_SYM *sym)
 {  {
         char *name = find_str_by_index(sym->n_un.n_strx);          char *name = find_str_by_index(sym->n_un.n_strx);
           
         if ( sym->n_type & N_STAB ) /* Debug symbols are ignored */          if ( sym->n_type & N_STAB ) /* Debug symbols are ignored */
                 return "debug";                  return "debug";
                           
         if(!name)          if(!name)
                 return name;                  return name;
         if(name[0]=='_')          if(name[0]=='_')
Line 865  static char *get_sym_name(EXE_SYM *sym) Line 880  static char *get_sym_name(EXE_SYM *sym)
 }  }
   
 /* find a section index given its segname, sectname */  /* find a section index given its segname, sectname */
 static int find_mach_sec_index(struct section *section_hdr, int shnum, const char *segname,   static int find_mach_sec_index(struct section *section_hdr, int shnum, const char *segname,
                                   const char *sectname)                                    const char *sectname)
 {  {
     int i;      int i;
Line 881  static int find_mach_sec_index(struct se Line 896  static int find_mach_sec_index(struct se
 }  }
   
 /* find a section header given its segname, sectname */  /* find a section header given its segname, sectname */
 struct section *find_mach_sec_hdr(struct section *section_hdr, int shnum, const char *segname,   struct section *find_mach_sec_hdr(struct section *section_hdr, int shnum, const char *segname,
                                   const char *sectname)                                    const char *sectname)
 {  {
     int index = find_mach_sec_index(section_hdr, shnum, segname, sectname);      int index = find_mach_sec_index(section_hdr, shnum, segname, sectname);
Line 894  struct section *find_mach_sec_hdr(struct Line 909  struct section *find_mach_sec_hdr(struct
 static inline void fetch_next_pair_value(struct relocation_info * rel, unsigned int *value)  static inline void fetch_next_pair_value(struct relocation_info * rel, unsigned int *value)
 {  {
     struct scattered_relocation_info * scarel;      struct scattered_relocation_info * scarel;
           
     if(R_SCATTERED & rel->r_address) {      if(R_SCATTERED & rel->r_address) {
         scarel = (struct scattered_relocation_info*)rel;          scarel = (struct scattered_relocation_info*)rel;
         if(scarel->r_type != PPC_RELOC_PAIR)          if(scarel->r_type != PPC_RELOC_PAIR)
Line 911  static inline void fetch_next_pair_value Line 926  static inline void fetch_next_pair_value
 static const char * find_sym_with_value_and_sec_number( int value, int sectnum, int * offset )  static const char * find_sym_with_value_and_sec_number( int value, int sectnum, int * offset )
 {  {
         int i, ret = -1;          int i, ret = -1;
           
         for( i = 0 ; i < nb_syms; i++ )          for( i = 0 ; i < nb_syms; i++ )
         {          {
             if( !(symtab[i].n_type & N_STAB) && (symtab[i].n_type & N_SECT) &&              if( !(symtab[i].n_type & N_STAB) && (symtab[i].n_type & N_SECT) &&
Line 930  static const char * find_sym_with_value_ Line 945  static const char * find_sym_with_value_
         }          }
 }  }
   
 /*   /*
  *  Find symbol name given a (virtual) address, and a section which is of type    *  Find symbol name given a (virtual) address, and a section which is of type
  *  S_NON_LAZY_SYMBOL_POINTERS or S_LAZY_SYMBOL_POINTERS or S_SYMBOL_STUBS   *  S_NON_LAZY_SYMBOL_POINTERS or S_LAZY_SYMBOL_POINTERS or S_SYMBOL_STUBS
  */   */
 static const char * find_reloc_name_in_sec_ptr(int address, struct section * sec_hdr)  static const char * find_reloc_name_in_sec_ptr(int address, struct section * sec_hdr)
 {  {
     unsigned int tocindex, symindex, size;      unsigned int tocindex, symindex, size;
     const char *name = 0;      const char *name = 0;
       
     /* Sanity check */      /* Sanity check */
     if(!( address >= sec_hdr->addr && address < (sec_hdr->addr + sec_hdr->size) ) )      if(!( address >= sec_hdr->addr && address < (sec_hdr->addr + sec_hdr->size) ) )
         return (char*)0;          return (char*)0;
                   
         if( sec_hdr->flags & S_SYMBOL_STUBS ){          if( sec_hdr->flags & S_SYMBOL_STUBS ){
                 size = sec_hdr->reserved2;                  size = sec_hdr->reserved2;
                 if(size == 0)                  if(size == 0)
                     error("size = 0");                      error("size = 0");
                   
         }          }
         else if( sec_hdr->flags & S_LAZY_SYMBOL_POINTERS ||          else if( sec_hdr->flags & S_LAZY_SYMBOL_POINTERS ||
                     sec_hdr->flags & S_NON_LAZY_SYMBOL_POINTERS)                      sec_hdr->flags & S_NON_LAZY_SYMBOL_POINTERS)
                 size = sizeof(unsigned long);                  size = sizeof(unsigned long);
         else          else
                 return 0;                  return 0;
                   
     /* Compute our index in toc */      /* Compute our index in toc */
         tocindex = (address - sec_hdr->addr)/size;          tocindex = (address - sec_hdr->addr)/size;
         symindex = tocdylib[sec_hdr->reserved1 + tocindex];          symindex = tocdylib[sec_hdr->reserved1 + tocindex];
           
         name = get_sym_name(&symtab[symindex]);          name = get_sym_name(&symtab[symindex]);
   
     return name;      return name;
Line 983  static const char * get_reloc_name(EXE_R Line 998  static const char * get_reloc_name(EXE_R
         int sectnum = rel->r_symbolnum;          int sectnum = rel->r_symbolnum;
         int sectoffset;          int sectoffset;
         int other_half=0;          int other_half=0;
           
         /* init the slide value */          /* init the slide value */
         *sslide = 0;          *sslide = 0;
           
         if(R_SCATTERED & rel->r_address)          if(R_SCATTERED & rel->r_address)
                 return (char *)find_reloc_name_given_its_address(sca_rel->r_value);                  return (char *)find_reloc_name_given_its_address(sca_rel->r_value);
   
         if(rel->r_extern)          if(rel->r_extern)
         {          {
                 /* ignore debug sym */                  /* ignore debug sym */
                 if ( symtab[rel->r_symbolnum].n_type & N_STAB )                   if ( symtab[rel->r_symbolnum].n_type & N_STAB )
                         return 0;                          return 0;
                 return get_sym_name(&symtab[rel->r_symbolnum]);                  return get_sym_name(&symtab[rel->r_symbolnum]);
         }          }
   
         /* Intruction contains an offset to the symbols pointed to, in the rel->r_symbolnum section */          /* Intruction contains an offset to the symbols pointed to, in the rel->r_symbolnum section */
         sectoffset = *(uint32_t *)(text + rel->r_address) & 0xffff;          sectoffset = *(uint32_t *)(text + rel->r_address) & 0xffff;
                           
         if(sectnum==0xffffff)          if(sectnum==0xffffff)
                 return 0;                  return 0;
   
Line 1026  static const char * get_reloc_name(EXE_R Line 1041  static const char * get_reloc_name(EXE_R
   
         if(rel->r_pcrel)          if(rel->r_pcrel)
                 sectoffset += rel->r_address;                  sectoffset += rel->r_address;
                           
         if (rel->r_type == PPC_RELOC_BR24)          if (rel->r_type == PPC_RELOC_BR24)
                 name = (char *)find_reloc_name_in_sec_ptr((int)sectoffset, &section_hdr[sectnum-1]);                  name = (char *)find_reloc_name_in_sec_ptr((int)sectoffset, &section_hdr[sectnum-1]);
   
         /* search it in the full symbol list, if not found */          /* search it in the full symbol list, if not found */
         if(!name)          if(!name)
                 name = (char *)find_sym_with_value_and_sec_number(sectoffset, sectnum, sslide);                  name = (char *)find_sym_with_value_and_sec_number(sectoffset, sectnum, sslide);
           
         return name;          return name;
 }  }
   
Line 1065  int load_object(const char *filename) Line 1080  int load_object(const char *filename)
     unsigned int i, j;      unsigned int i, j;
         EXE_SYM *sym;          EXE_SYM *sym;
         struct nlist *syment;          struct nlist *syment;
       
         fd = open(filename, O_RDONLY);          fd = open(filename, O_RDONLY);
     if (fd < 0)       if (fd < 0)
         error("can't open file '%s'", filename);          error("can't open file '%s'", filename);
                   
     /* Read Mach header.  */      /* Read Mach header.  */
     if (read(fd, &mach_hdr, sizeof (mach_hdr)) != sizeof (mach_hdr))      if (read(fd, &mach_hdr, sizeof (mach_hdr)) != sizeof (mach_hdr))
         error("unable to read file header");          error("unable to read file header");
Line 1078  int load_object(const char *filename) Line 1093  int load_object(const char *filename)
     if (!check_mach_header(mach_hdr)) {      if (!check_mach_header(mach_hdr)) {
         error("bad Mach header");          error("bad Mach header");
     }      }
       
     if (mach_hdr.cputype != CPU_TYPE_POWERPC)      if (mach_hdr.cputype != CPU_TYPE_POWERPC)
         error("Unsupported CPU");          error("Unsupported CPU");
           
     if (mach_hdr.filetype != MH_OBJECT)      if (mach_hdr.filetype != MH_OBJECT)
         error("Unsupported Mach Object");          error("Unsupported Mach Object");
       
     /* read segment headers */      /* read segment headers */
     for(i=0, j=sizeof(mach_hdr); i<mach_hdr.ncmds ; i++)      for(i=0, j=sizeof(mach_hdr); i<mach_hdr.ncmds ; i++)
     {      {
Line 1128  int load_object(const char *filename) Line 1143  int load_object(const char *filename)
     /* read all section data */      /* read all section data */
     sdata = (uint8_t **)malloc(sizeof(void *) * segment->nsects);      sdata = (uint8_t **)malloc(sizeof(void *) * segment->nsects);
     memset(sdata, 0, sizeof(void *) * segment->nsects);      memset(sdata, 0, sizeof(void *) * segment->nsects);
       
         /* Load the data in section data */          /* Load the data in section data */
         for(i = 0; i < segment->nsects; i++) {          for(i = 0; i < segment->nsects; i++) {
         sdata[i] = load_data(fd, section_hdr[i].offset, section_hdr[i].size);          sdata[i] = load_data(fd, section_hdr[i].offset, section_hdr[i].size);
     }      }
           
     /* text section */      /* text section */
         text_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);          text_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
         i = find_mach_sec_index(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);          i = find_mach_sec_index(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
         if (i == -1 || !text_sec_hdr)          if (i == -1 || !text_sec_hdr)
         error("could not find __TEXT,__text section");          error("could not find __TEXT,__text section");
     text = sdata[i];      text = sdata[i];
           
     /* Make sure dysym was loaded */      /* Make sure dysym was loaded */
     if(!(int)dysymtabcmd)      if(!(int)dysymtabcmd)
         error("could not find __DYSYMTAB segment");          error("could not find __DYSYMTAB segment");
       
     /* read the table of content of the indirect sym */      /* read the table of content of the indirect sym */
     tocdylib = load_data( fd, dysymtabcmd->indirectsymoff, dysymtabcmd->nindirectsyms * sizeof(uint32_t) );      tocdylib = load_data( fd, dysymtabcmd->indirectsymoff, dysymtabcmd->nindirectsyms * sizeof(uint32_t) );
       
     /* Make sure symtab was loaded  */      /* Make sure symtab was loaded  */
     if(!(int)symtabcmd)      if(!(int)symtabcmd)
         error("could not find __SYMTAB segment");          error("could not find __SYMTAB segment");
Line 1155  int load_object(const char *filename) Line 1170  int load_object(const char *filename)
   
     symtab_std = load_data(fd, symtabcmd->symoff, symtabcmd->nsyms * sizeof(struct nlist));      symtab_std = load_data(fd, symtabcmd->symoff, symtabcmd->nsyms * sizeof(struct nlist));
     strtab = load_data(fd, symtabcmd->stroff, symtabcmd->strsize);      strtab = load_data(fd, symtabcmd->stroff, symtabcmd->strsize);
           
         symtab = malloc(sizeof(EXE_SYM) * nb_syms);          symtab = malloc(sizeof(EXE_SYM) * nb_syms);
           
         /* Now transform the symtab, to an extended version, with the sym size, and the C name */          /* Now transform the symtab, to an extended version, with the sym size, and the C name */
         for(i = 0, sym = symtab, syment = symtab_std; i < nb_syms; i++, sym++, syment++) {          for(i = 0, sym = symtab, syment = symtab_std; i < nb_syms; i++, sym++, syment++) {
         struct nlist *sym_follow, *sym_next = 0;          struct nlist *sym_follow, *sym_next = 0;
         unsigned int j;          unsigned int j;
                 memset(sym, 0, sizeof(*sym));                  memset(sym, 0, sizeof(*sym));
                   
                 if ( syment->n_type & N_STAB ) /* Debug symbols are skipped */                  if ( syment->n_type & N_STAB ) /* Debug symbols are skipped */
             continue;              continue;
                           
                 memcpy(sym, syment, sizeof(*syment));                  memcpy(sym, syment, sizeof(*syment));
                           
                 /* Find the following symbol in order to get the current symbol size */                  /* Find the following symbol in order to get the current symbol size */
         for(j = 0, sym_follow = symtab_std; j < nb_syms; j++, sym_follow++) {          for(j = 0, sym_follow = symtab_std; j < nb_syms; j++, sym_follow++) {
             if ( sym_follow->n_sect != 1 || sym_follow->n_type & N_STAB || !(sym_follow->n_value > sym->st_value))              if ( sym_follow->n_sect != 1 || sym_follow->n_type & N_STAB || !(sym_follow->n_value > sym->st_value))
Line 1186  int load_object(const char *filename) Line 1201  int load_object(const char *filename)
                 else                  else
             sym->st_size = text_sec_hdr->size - sym->st_value;              sym->st_size = text_sec_hdr->size - sym->st_value;
         }          }
           
     /* Find Reloc */      /* Find Reloc */
     relocs = load_data(fd, text_sec_hdr->reloff, text_sec_hdr->nreloc * sizeof(struct relocation_info));      relocs = load_data(fd, text_sec_hdr->reloff, text_sec_hdr->nreloc * sizeof(struct relocation_info));
     nb_relocs = text_sec_hdr->nreloc;      nb_relocs = text_sec_hdr->nreloc;
Line 1271  int arm_emit_ldr_info(const char *name,  Line 1286  int arm_emit_ldr_info(const char *name, 
     uint8_t data_allocated[1024];      uint8_t data_allocated[1024];
     unsigned int data_index;      unsigned int data_index;
     int type;      int type;
       
     memset(data_allocated, 0, sizeof(data_allocated));      memset(data_allocated, 0, sizeof(data_allocated));
       
     p = p_start;      p = p_start;
     min_offset = p_end - p_start;      min_offset = p_end - p_start;
     spare = 0x7fffffff;      spare = 0x7fffffff;
Line 1316  int arm_emit_ldr_info(const char *name,  Line 1331  int arm_emit_ldr_info(const char *name, 
             if (spare > max_pool - offset)              if (spare > max_pool - offset)
                 spare = max_pool - offset;                  spare = max_pool - offset;
             if ((offset & 3) !=0)              if ((offset & 3) !=0)
                 error("%s:%04x: pc offset must be 32 bit aligned",                   error("%s:%04x: pc offset must be 32 bit aligned",
                       name, start_offset + p - p_start);                        name, start_offset + p - p_start);
             if (offset < 0)              if (offset < 0)
                 error("%s:%04x: Embedded literal value",                  error("%s:%04x: Embedded literal value",
                       name, start_offset + p - p_start);                        name, start_offset + p - p_start);
             pc_offset = p - p_start + offset + 8;              pc_offset = p - p_start + offset + 8;
             if (pc_offset <= (p - p_start) ||               if (pc_offset <= (p - p_start) ||
                 pc_offset >= (p_end - p_start))                  pc_offset >= (p_end - p_start))
                 error("%s:%04x: pc offset must point inside the function code",                   error("%s:%04x: pc offset must point inside the function code",
                       name, start_offset + p - p_start);                        name, start_offset + p - p_start);
             if (pc_offset < min_offset)              if (pc_offset < min_offset)
                 min_offset = pc_offset;                  min_offset = pc_offset;
             if (outfile) {              if (outfile) {
                 /* The intruction position */                  /* The intruction position */
                 fprintf(outfile, "    arm_ldr_ptr->ptr = gen_code_ptr + %d;\n",                   fprintf(outfile, "    arm_ldr_ptr->ptr = gen_code_ptr + %d;\n",
                         p - p_start);                          p - p_start);
                 /* The position of the constant pool data.  */                  /* The position of the constant pool data.  */
                 data_index = ((p_end - p_start) - pc_offset) >> 2;                  data_index = ((p_end - p_start) - pc_offset) >> 2;
                 fprintf(outfile, "    arm_ldr_ptr->data_ptr = arm_data_ptr - %d;\n",                   fprintf(outfile, "    arm_ldr_ptr->data_ptr = arm_data_ptr - %d;\n",
                         data_index);                          data_index);
                 fprintf(outfile, "    arm_ldr_ptr->type = %d;\n", type);                  fprintf(outfile, "    arm_ldr_ptr->type = %d;\n", type);
                 fprintf(outfile, "    arm_ldr_ptr++;\n");                  fprintf(outfile, "    arm_ldr_ptr++;\n");
Line 1417  int arm_emit_ldr_info(const char *name,  Line 1432  int arm_emit_ldr_info(const char *name, 
 #define MAX_ARGS 3  #define MAX_ARGS 3
   
 /* generate op code */  /* generate op code */
 void gen_code(const char *name, host_ulong offset, host_ulong size,   void gen_code(const char *name, host_ulong offset, host_ulong size,
               FILE *outfile, int gen_switch)                FILE *outfile, int gen_switch)
 {  {
     int copy_size = 0;      int copy_size = 0;
Line 1463  void gen_code(const char *name, host_ulo Line 1478  void gen_code(const char *name, host_ulo
         }          }
         copy_size = len;          copy_size = len;
     }      }
 #endif      #endif
 #elif defined(HOST_PPC)  #elif defined(HOST_PPC)
     {      {
         uint8_t *p;          uint8_t *p;
Line 1480  void gen_code(const char *name, host_ulo Line 1495  void gen_code(const char *name, host_ulo
         p = (void *)(p_end - 2);          p = (void *)(p_end - 2);
         if (p == p_start)          if (p == p_start)
             error("empty code for %s", name);              error("empty code for %s", name);
         if (get16((uint16_t *)p) != 0x07fe && get16((uint16_t *)p) != 0x07f4)          if ((get16((uint16_t *)p) & 0xfff0) != 0x07f0)
             error("br %%r14 expected at the end of %s", name);              error("br expected at the end of %s", name);
         copy_size = p - p_start;          copy_size = p - p_start;
     }      }
 #elif defined(HOST_ALPHA)  #elif defined(HOST_ALPHA)
Line 1495  void gen_code(const char *name, host_ulo Line 1510  void gen_code(const char *name, host_ulo
 #endif  #endif
         if (get32((uint32_t *)p) != 0x6bfa8001)          if (get32((uint32_t *)p) != 0x6bfa8001)
             error("ret expected at the end of %s", name);              error("ret expected at the end of %s", name);
         copy_size = p - p_start;                      copy_size = p - p_start;
     }      }
 #elif defined(HOST_IA64)  #elif defined(HOST_IA64)
     {      {
Line 1596  void gen_code(const char *name, host_ulo Line 1611  void gen_code(const char *name, host_ulo
         } else {          } else {
             error("No save at the beginning of %s", name);              error("No save at the beginning of %s", name);
         }          }
           
         /* Skip a preceeding nop, if present.  */          /* Skip a preceeding nop, if present.  */
         if (p > p_start) {          if (p > p_start) {
             skip_insn = get32((uint32_t *)(p - 0x4));              skip_insn = get32((uint32_t *)(p - 0x4));
             if (skip_insn == 0x01000000)              if (skip_insn == 0x01000000)
                 p -= 4;                  p -= 4;
         }          }
           
         copy_size = p - p_start;          copy_size = p - p_start;
     }      }
 #elif defined(HOST_ARM)  #elif defined(HOST_ARM)
Line 1624  void gen_code(const char *name, host_ulo Line 1639  void gen_code(const char *name, host_ulo
             p_start -= 4;              p_start -= 4;
             start_offset -= 4;              start_offset -= 4;
         }          }
         copy_size = arm_emit_ldr_info(name, start_offset, NULL, p_start, p_end,           copy_size = arm_emit_ldr_info(name, start_offset, NULL, p_start, p_end,
                                       relocs, nb_relocs);                                        relocs, nb_relocs);
     }      }
 #elif defined(HOST_M68K)  #elif defined(HOST_M68K)
Line 1635  void gen_code(const char *name, host_ulo Line 1650  void gen_code(const char *name, host_ulo
             error("empty code for %s", name);              error("empty code for %s", name);
         // remove NOP's, probably added for alignment          // remove NOP's, probably added for alignment
         while ((get16((uint16_t *)p) == 0x4e71) &&          while ((get16((uint16_t *)p) == 0x4e71) &&
                (p>p_start))                  (p>p_start))
             p -= 2;              p -= 2;
         if (get16((uint16_t *)p) != 0x4e75)          if (get16((uint16_t *)p) != 0x4e75)
             error("rts expected at the end of %s", name);              error("rts expected at the end of %s", name);
         copy_size = p - p_start;          copy_size = p - p_start;
     }      }
   #elif defined(HOST_MIPS) || defined(HOST_MIPS64)
       {
   #define INSN_RETURN     0x03e00008
   #define INSN_NOP        0x00000000
   
           uint8_t *p = p_end;
   
           if (p < (p_start + 0x8)) {
               error("empty code for %s", name);
           } else {
               uint32_t end_insn1, end_insn2;
   
               p -= 0x8;
               end_insn1 = get32((uint32_t *)(p + 0x0));
               end_insn2 = get32((uint32_t *)(p + 0x4));
               if (end_insn1 != INSN_RETURN && end_insn2 != INSN_NOP)
                   error("jr ra not found at end of %s", name);
           }
           copy_size = p - p_start;
       }
 #else  #else
 #error unsupported CPU  #error unsupported CPU
 #endif  #endif
Line 1665  void gen_code(const char *name, host_ulo Line 1700  void gen_code(const char *name, host_ulo
             }              }
         }          }
     }      }
       
     nb_args = 0;      nb_args = 0;
     while (nb_args < MAX_ARGS && args_present[nb_args])      while (nb_args < MAX_ARGS && args_present[nb_args])
         nb_args++;          nb_args++;
Line 1702  void gen_code(const char *name, host_ulo Line 1737  void gen_code(const char *name, host_ulo
                 sym_name = get_rel_sym_name(rel);                  sym_name = get_rel_sym_name(rel);
                 if(!sym_name)                  if(!sym_name)
                     continue;                      continue;
                 if (*sym_name &&                   if (*sym_name &&
                     !strstart(sym_name, "__op_param", NULL) &&                      !strstart(sym_name, "__op_param", NULL) &&
                     !strstart(sym_name, "__op_jmp", NULL) &&                      !strstart(sym_name, "__op_jmp", NULL) &&
                     !strstart(sym_name, "__op_gen_label", NULL)) {                      !strstart(sym_name, "__op_gen_label", NULL)) {
Line 1715  void gen_code(const char *name, host_ulo Line 1750  void gen_code(const char *name, host_ulo
                     }                      }
 #endif  #endif
 #if defined(__APPLE__)  #if defined(__APPLE__)
 /* set __attribute((unused)) on darwin because we wan't to avoid warning when we don't use the symbol */                      /* Set __attribute((unused)) on darwin because we
                     fprintf(outfile, "extern char %s __attribute__((unused));\n", sym_name);                         want to avoid warning when we don't use the symbol.  */
                       fprintf(outfile, "    extern char %s __attribute__((unused));\n", sym_name);
 #elif defined(HOST_IA64)  #elif defined(HOST_IA64)
                         if (ELF64_R_TYPE(rel->r_info) != R_IA64_PCREL21B)                          if (ELF64_R_TYPE(rel->r_info) != R_IA64_PCREL21B)
                                 /*                                  /*
Line 1740  void gen_code(const char *name, host_ulo Line 1776  void gen_code(const char *name, host_ulo
         {          {
             EXE_SYM *sym;              EXE_SYM *sym;
             const char *sym_name, *p;              const char *sym_name, *p;
             unsigned long val;              host_ulong val;
             int n;              int n;
   
             for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {              for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
Line 1748  void gen_code(const char *name, host_ulo Line 1784  void gen_code(const char *name, host_ulo
                 if (strstart(sym_name, "__op_label", &p)) {                  if (strstart(sym_name, "__op_label", &p)) {
                     uint8_t *ptr;                      uint8_t *ptr;
                     unsigned long offset;                      unsigned long offset;
                       
                     /* test if the variable refers to a label inside                      /* test if the variable refers to a label inside
                        the code we are generating */                         the code we are generating */
 #ifdef CONFIG_FORMAT_COFF  #ifdef CONFIG_FORMAT_COFF
Line 1772  void gen_code(const char *name, host_ulo Line 1808  void gen_code(const char *name, host_ulo
 #ifdef CONFIG_FORMAT_MACH  #ifdef CONFIG_FORMAT_MACH
                     offset -= section_hdr[sym->n_sect-1].addr;                      offset -= section_hdr[sym->n_sect-1].addr;
 #endif  #endif
                     val = *(unsigned long *)(ptr + offset);                      val = *(host_ulong *)(ptr + offset);
 #ifdef ELF_USES_RELOCA  #ifdef ELF_USES_RELOCA
                     {                      {
                         int reloc_shndx, nb_relocs1, j;                          int reloc_shndx, nb_relocs1, j;
Line 1780  void gen_code(const char *name, host_ulo Line 1816  void gen_code(const char *name, host_ulo
                         /* try to find a matching relocation */                          /* try to find a matching relocation */
                         reloc_shndx = find_reloc(sym->st_shndx);                          reloc_shndx = find_reloc(sym->st_shndx);
                         if (reloc_shndx) {                          if (reloc_shndx) {
                             nb_relocs1 = shdr[reloc_shndx].sh_size /                               nb_relocs1 = shdr[reloc_shndx].sh_size /
                                 shdr[reloc_shndx].sh_entsize;                                  shdr[reloc_shndx].sh_entsize;
                             rel = (ELF_RELOC *)sdata[reloc_shndx];                              rel = (ELF_RELOC *)sdata[reloc_shndx];
                             for(j = 0; j < nb_relocs1; j++) {                              for(j = 0; j < nb_relocs1; j++) {
Line 1792  void gen_code(const char *name, host_ulo Line 1828  void gen_code(const char *name, host_ulo
                             }                              }
                         }                          }
                     }                      }
 #endif                      #endif
                     if (val >= start_offset && val <= start_offset + copy_size) {                      if (val >= start_offset && val <= start_offset + copy_size) {
                         n = strtol(p, NULL, 10);                          n = strtol(p, NULL, 10);
                         fprintf(outfile, "    label_offsets[%d] = %ld + (gen_code_ptr - gen_code_buf);\n", n, (long)(val - start_offset));                          fprintf(outfile, "    label_offsets[%d] = %ld + (gen_code_ptr - gen_code_buf);\n", n, (long)(val - start_offset));
Line 1801  void gen_code(const char *name, host_ulo Line 1837  void gen_code(const char *name, host_ulo
             }              }
         }          }
   
         /* load parameres in variables */          /* load parameters in variables */
         for(i = 0; i < nb_args; i++) {          for(i = 0; i < nb_args; i++) {
             fprintf(outfile, "    param%d = *opparam_ptr++;\n", i + 1);              fprintf(outfile, "    param%d = *opparam_ptr++;\n", i + 1);
         }          }
Line 1809  void gen_code(const char *name, host_ulo Line 1845  void gen_code(const char *name, host_ulo
         /* patch relocations */          /* patch relocations */
 #if defined(HOST_I386)  #if defined(HOST_I386)
             {              {
                 char name[256];                  char relname[256];
                 int type;                  int type;
                 int addend;                  int addend;
                 int reloc_offset;                  int reloc_offset;
Line 1832  void gen_code(const char *name, host_ulo Line 1868  void gen_code(const char *name, host_ulo
                         continue;                          continue;
                     }                      }
   
                     get_reloc_expr(name, sizeof(name), sym_name);                      get_reloc_expr(relname, sizeof(relname), sym_name);
                     addend = get32((uint32_t *)(text + rel->r_offset));                      addend = get32((uint32_t *)(text + rel->r_offset));
 #ifdef CONFIG_FORMAT_ELF  #ifdef CONFIG_FORMAT_ELF
                     type = ELF32_R_TYPE(rel->r_info);                      type = ELF32_R_TYPE(rel->r_info);
                     switch(type) {                      switch(type) {
                     case R_386_32:                      case R_386_32:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                           fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
                                 reloc_offset, name, addend);                                  reloc_offset, relname, addend);
                         break;                          break;
                     case R_386_PC32:                      case R_386_PC32:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",                           fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
                                 reloc_offset, name, reloc_offset, addend);                                  reloc_offset, relname, reloc_offset, addend);
                         break;                          break;
                     default:                      default:
                         error("unsupported i386 relocation (%d)", type);                          error("unsupported i386 relocation (%d)", type);
Line 1865  void gen_code(const char *name, host_ulo Line 1901  void gen_code(const char *name, host_ulo
                     type = rel->r_type;                      type = rel->r_type;
                     switch(type) {                      switch(type) {
                     case DIR32:                      case DIR32:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                           fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
                                 reloc_offset, name, addend);                                  reloc_offset, relname, addend);
                         break;                          break;
                     case DISP32:                      case DISP32:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d -4;\n",                           fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d -4;\n",
                                 reloc_offset, name, reloc_offset, addend);                                  reloc_offset, relname, reloc_offset, addend);
                         break;                          break;
                     default:                      default:
                         error("unsupported i386 relocation (%d)", type);                          error("unsupported i386 relocation (%d)", type);
Line 1883  void gen_code(const char *name, host_ulo Line 1919  void gen_code(const char *name, host_ulo
             }              }
 #elif defined(HOST_X86_64)  #elif defined(HOST_X86_64)
             {              {
                 char name[256];                  char relname[256];
                 int type;                  int type;
                 int addend;                  int addend;
                 int reloc_offset;                  int reloc_offset;
Line 1891  void gen_code(const char *name, host_ulo Line 1927  void gen_code(const char *name, host_ulo
                 if (rel->r_offset >= start_offset &&                  if (rel->r_offset >= start_offset &&
                     rel->r_offset < start_offset + copy_size) {                      rel->r_offset < start_offset + copy_size) {
                     sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;                      sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
                     get_reloc_expr(name, sizeof(name), sym_name);                      get_reloc_expr(relname, sizeof(relname), sym_name);
                     type = ELF32_R_TYPE(rel->r_info);                      type = ELF32_R_TYPE(rel->r_info);
                     addend = rel->r_addend;                      addend = rel->r_addend;
                     reloc_offset = rel->r_offset - start_offset;                      reloc_offset = rel->r_offset - start_offset;
                     switch(type) {                      switch(type) {
                     case R_X86_64_32:                      case R_X86_64_32:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (uint32_t)%s + %d;\n",                           fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (uint32_t)%s + %d;\n",
                                 reloc_offset, name, addend);                                  reloc_offset, relname, addend);
                         break;                          break;
                     case R_X86_64_32S:                      case R_X86_64_32S:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (int32_t)%s + %d;\n",                           fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (int32_t)%s + %d;\n",
                                 reloc_offset, name, addend);                                  reloc_offset, relname, addend);
                         break;                          break;
                     case R_X86_64_PC32:                      case R_X86_64_PC32:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",                           fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
                                 reloc_offset, name, reloc_offset, addend);                                  reloc_offset, relname, reloc_offset, addend);
                         break;                          break;
                     default:                      default:
                         error("unsupported X86_64 relocation (%d)", type);                          error("unsupported X86_64 relocation (%d)", type);
Line 1917  void gen_code(const char *name, host_ulo Line 1953  void gen_code(const char *name, host_ulo
 #elif defined(HOST_PPC)  #elif defined(HOST_PPC)
             {              {
 #ifdef CONFIG_FORMAT_ELF  #ifdef CONFIG_FORMAT_ELF
                 char name[256];                  char relname[256];
                 int type;                  int type;
                 int addend;                  int addend;
                 int reloc_offset;                  int reloc_offset;
Line 1937  void gen_code(const char *name, host_ulo Line 1973  void gen_code(const char *name, host_ulo
                                     n, reloc_offset);                                      n, reloc_offset);
                             continue;                              continue;
                         }                          }
                           
                         get_reloc_expr(name, sizeof(name), sym_name);                          get_reloc_expr(relname, sizeof(relname), sym_name);
                         type = ELF32_R_TYPE(rel->r_info);                          type = ELF32_R_TYPE(rel->r_info);
                         addend = rel->r_addend;                          addend = rel->r_addend;
                         switch(type) {                          switch(type) {
                         case R_PPC_ADDR32:                          case R_PPC_ADDR32:
                             fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                               fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
                                     reloc_offset, name, addend);                                      reloc_offset, relname, addend);
                             break;                              break;
                         case R_PPC_ADDR16_LO:                          case R_PPC_ADDR16_LO:
                             fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",                               fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",
                                     reloc_offset, name, addend);                                      reloc_offset, relname, addend);
                             break;                              break;
                         case R_PPC_ADDR16_HI:                          case R_PPC_ADDR16_HI:
                             fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",                               fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",
                                     reloc_offset, name, addend);                                      reloc_offset, relname, addend);
                             break;                              break;
                         case R_PPC_ADDR16_HA:                          case R_PPC_ADDR16_HA:
                             fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",                               fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",
                                     reloc_offset, name, addend);                                      reloc_offset, relname, addend);
                             break;                              break;
                         case R_PPC_REL24:                          case R_PPC_REL24:
                             /* warning: must be at 32 MB distancy */                              /* warning: must be at 32 MB distancy */
                             fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",                               fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",
                                     reloc_offset, reloc_offset, name, reloc_offset, addend);                                      reloc_offset, reloc_offset, relname, reloc_offset, addend);
                             break;                              break;
                         default:                          default:
                             error("unsupported powerpc relocation (%d)", type);                              error("unsupported powerpc relocation (%d)", type);
Line 1969  void gen_code(const char *name, host_ulo Line 2005  void gen_code(const char *name, host_ulo
                     }                      }
                 }                  }
 #elif defined(CONFIG_FORMAT_MACH)  #elif defined(CONFIG_FORMAT_MACH)
                                 struct scattered_relocation_info *scarel;                  struct scattered_relocation_info *scarel;
                                 struct relocation_info * rel;                  struct relocation_info * rel;
                                 char final_sym_name[256];                  char final_sym_name[256];
                                 const char *sym_name;                  const char *sym_name;
                                 const char *p;                  const char *p;
                                 int slide, sslide;                  int slide, sslide;
                                 int i;                  int i;
           
                                 for(i = 0, rel = relocs; i < nb_relocs; i++, rel++) {                  for(i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
                                         unsigned int offset, length, value = 0;                      unsigned int offset, length, value = 0;
                                         unsigned int type, pcrel, isym = 0;                      unsigned int type, pcrel, isym = 0;
                                         unsigned int usesym = 0;                      unsigned int usesym = 0;
                                   
                                         if(R_SCATTERED & rel->r_address) {                      if(R_SCATTERED & rel->r_address) {
                                                 scarel = (struct scattered_relocation_info*)rel;                          scarel = (struct scattered_relocation_info*)rel;
                                                 offset = (unsigned int)scarel->r_address;                          offset = (unsigned int)scarel->r_address;
                                                 length = scarel->r_length;                          length = scarel->r_length;
                                                 pcrel = scarel->r_pcrel;                          pcrel = scarel->r_pcrel;
                                                 type = scarel->r_type;                          type = scarel->r_type;
                                                 value = scarel->r_value;                          value = scarel->r_value;
                                         } else {                      } else {
                                                 value = isym = rel->r_symbolnum;                          value = isym = rel->r_symbolnum;
                                                 usesym = (rel->r_extern);                          usesym = (rel->r_extern);
                                                 offset = rel->r_address;                          offset = rel->r_address;
                                                 length = rel->r_length;                          length = rel->r_length;
                                                 pcrel = rel->r_pcrel;                          pcrel = rel->r_pcrel;
                                                 type = rel->r_type;                          type = rel->r_type;
                                         }                      }
                                   
                                         slide = offset - start_offset;                      slide = offset - start_offset;
                   
                                         if (!(offset >= start_offset && offset < start_offset + size))                       if (!(offset >= start_offset && offset < start_offset + size))
                                                 continue;  /* not in our range */                          continue;  /* not in our range */
   
                                         sym_name = get_reloc_name(rel, &sslide);                          sym_name = get_reloc_name(rel, &sslide);
                                           
                                         if(usesym && symtab[isym].n_type & N_STAB)                          if(usesym && symtab[isym].n_type & N_STAB)
                                                 continue; /* don't handle STAB (debug sym) */                              continue; /* don't handle STAB (debug sym) */
                                           
                                         if (sym_name && strstart(sym_name, "__op_jmp", &p)) {                          if (sym_name && strstart(sym_name, "__op_jmp", &p)) {
                                                 int n;                              int n;
                                                 n = strtol(p, NULL, 10);                              n = strtol(p, NULL, 10);
                                                 fprintf(outfile, "    jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",                              fprintf(outfile, "    jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",
                                                         n, slide);                                      n, slide);
                                                 continue; /* Nothing more to do */                              continue; /* Nothing more to do */
                                         }                          }
                                           
                                         if(!sym_name)                          if(!sym_name) {
                                         {                              fprintf(outfile, "/* #warning relocation not handled in %s (value 0x%x, %s, offset 0x%x, length 0x%x, %s, type 0x%x) */\n",
                                                 fprintf(outfile, "/* #warning relocation not handled in %s (value 0x%x, %s, offset 0x%x, length 0x%x, %s, type 0x%x) */\n",                                      name, value, usesym ? "use sym" : "don't use sym", offset, length, pcrel ? "pcrel":"", type);
                                                            name, value, usesym ? "use sym" : "don't use sym", offset, length, pcrel ? "pcrel":"", type);                              continue; /* dunno how to handle without final_sym_name */
                                                 continue; /* dunno how to handle without final_sym_name */                          }
                                         }  
                                                                                                                                      get_reloc_expr(final_sym_name, sizeof(final_sym_name),
                                         get_reloc_expr(final_sym_name, sizeof(final_sym_name),                                          sym_name);
                                                        sym_name);                          switch(type) {
                                         switch(type) {                          case PPC_RELOC_BR24:
                                         case PPC_RELOC_BR24:                              if (!strstart(sym_name,"__op_gen_label",&p)) {
                                             if (!strstart(sym_name,"__op_gen_label",&p)) {                                  fprintf(outfile, "{\n");
                                                 fprintf(outfile, "{\n");                                  fprintf(outfile, "    uint32_t imm = *(uint32_t *)(gen_code_ptr + %d) & 0x3fffffc;\n", slide);
                                                 fprintf(outfile, "    uint32_t imm = *(uint32_t *)(gen_code_ptr + %d) & 0x3fffffc;\n", slide);                                  fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((imm + ((long)%s - (long)gen_code_ptr) + %d) & 0x03fffffc);\n",
                                                 fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((imm + ((long)%s - (long)gen_code_ptr) + %d) & 0x03fffffc);\n",                                           slide, slide, name, sslide);
                                                                                         slide, slide, name, sslide );                                  fprintf(outfile, "}\n");
                                                 fprintf(outfile, "}\n");                              } else {
                                         } else {                                  fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | (((long)%s - (long)gen_code_ptr - %d) & 0x03fffffc);\n",
                                                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | (((long)%s - (long)gen_code_ptr - %d) & 0x03fffffc);\n",                                          slide, slide, final_sym_name, slide);
                                                                                         slide, slide, final_sym_name, slide);                              }
                                         }  
                                                 break;  
                                         case PPC_RELOC_HI16:  
                                                 fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d) >> 16;\n",   
                                                         slide, final_sym_name, sslide);  
                                                 break;  
                                         case PPC_RELOC_LO16:  
                                                 fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d);\n",   
                                         slide, final_sym_name, sslide);  
                             break;                              break;
                                         case PPC_RELOC_HA16:                          case PPC_RELOC_HI16:
                                                 fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d + 0x8000) >> 16;\n",                               fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d) >> 16;\n",
                                                         slide, final_sym_name, sslide);                                      slide, final_sym_name, sslide);
                                                 break;                              break;
                                 default:                          case PPC_RELOC_LO16:
                                         error("unsupported powerpc relocation (%d)", type);                              fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d);\n",
                                 }                                      slide, final_sym_name, sslide);
                         }                              break;
                           case PPC_RELOC_HA16:
                               fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d + 0x8000) >> 16;\n",
                                       slide, final_sym_name, sslide);
                               break;
                           default:
                               error("unsupported powerpc relocation (%d)", type);
                       }
                   }
 #else  #else
 #error unsupport object format  #error unsupport object format
 #endif  #endif
             }              }
 #elif defined(HOST_S390)  #elif defined(HOST_S390)
             {              {
                 char name[256];                  char relname[256];
                 int type;                  int type;
                 int addend;                  int addend;
                 int reloc_offset;                  int reloc_offset;
Line 2068  void gen_code(const char *name, host_ulo Line 2103  void gen_code(const char *name, host_ulo
                     if (rel->r_offset >= start_offset &&                      if (rel->r_offset >= start_offset &&
                         rel->r_offset < start_offset + copy_size) {                          rel->r_offset < start_offset + copy_size) {
                         sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;                          sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
                         get_reloc_expr(name, sizeof(name), sym_name);                          get_reloc_expr(relname, sizeof(relname), sym_name);
                         type = ELF32_R_TYPE(rel->r_info);                          type = ELF32_R_TYPE(rel->r_info);
                         addend = rel->r_addend;                          addend = rel->r_addend;
                         reloc_offset = rel->r_offset - start_offset;                          reloc_offset = rel->r_offset - start_offset;
                         switch(type) {                          switch(type) {
                         case R_390_32:                          case R_390_32:
                             fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                               fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
                                     reloc_offset, name, addend);                                      reloc_offset, relname, addend);
                             break;                              break;
                         case R_390_16:                          case R_390_16:
                             fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = %s + %d;\n",                               fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = %s + %d;\n",
                                     reloc_offset, name, addend);                                      reloc_offset, relname, addend);
                             break;                              break;
                         case R_390_8:                          case R_390_8:
                             fprintf(outfile, "    *(uint8_t *)(gen_code_ptr + %d) = %s + %d;\n",                               fprintf(outfile, "    *(uint8_t *)(gen_code_ptr + %d) = %s + %d;\n",
                                     reloc_offset, name, addend);                                      reloc_offset, relname, addend);
                               break;
                           case R_390_PC32DBL:
                               if (ELF32_ST_TYPE(symtab[ELFW(R_SYM)(rel->r_info)].st_info) == STT_SECTION) {
                                   fprintf(outfile,
                                           "    *(uint32_t *)(gen_code_ptr + %d) += "
                                           "((long)&%s - (long)gen_code_ptr) >> 1;\n",
                                           reloc_offset, name);
                               }
                               else
                                   fprintf(outfile,
                                           "    *(uint32_t *)(gen_code_ptr + %d) = "
                                           "(%s + %d - ((uint32_t)gen_code_ptr + %d)) >> 1;\n",
                                           reloc_offset, relname, addend, reloc_offset);
                             break;                              break;
                         default:                          default:
                             error("unsupported s390 relocation (%d)", type);                              error("unsupported s390 relocation (%d)", type);
Line 2151  void gen_code(const char *name, host_ulo Line 2199  void gen_code(const char *name, host_ulo
             {              {
                 unsigned long sym_idx;                  unsigned long sym_idx;
                 long code_offset;                  long code_offset;
                 char name[256];                  char relname[256];
                 int type;                  int type;
                 long addend;                  long addend;
   
Line 2174  void gen_code(const char *name, host_ulo Line 2222  void gen_code(const char *name, host_ulo
                                 n, code_offset);                                  n, code_offset);
                         continue;                          continue;
                     }                      }
                     get_reloc_expr(name, sizeof(name), sym_name);                      get_reloc_expr(relname, sizeof(relname), sym_name);
                     type = ELF64_R_TYPE(rel->r_info);                      type = ELF64_R_TYPE(rel->r_info);
                     addend = rel->r_addend;                      addend = rel->r_addend;
                     switch(type) {                      switch(type) {
Line 2182  void gen_code(const char *name, host_ulo Line 2230  void gen_code(const char *name, host_ulo
                           fprintf(outfile,                            fprintf(outfile,
                                   "    ia64_imm64(gen_code_ptr + %ld, "                                    "    ia64_imm64(gen_code_ptr + %ld, "
                                   "%s + %ld);\n",                                    "%s + %ld);\n",
                                   code_offset, name, addend);                                    code_offset, relname, addend);
                           break;                            break;
                       case R_IA64_LTOFF22X:                        case R_IA64_LTOFF22X:
                       case R_IA64_LTOFF22:                        case R_IA64_LTOFF22:
                           fprintf(outfile, "    IA64_LTOFF(gen_code_ptr + %ld,"                            fprintf(outfile, "    IA64_LTOFF(gen_code_ptr + %ld,"
                                   " %s + %ld, %d);\n",                                    " %s + %ld, %d);\n",
                                   code_offset, name, addend,                                    code_offset, relname, addend,
                                   (type == R_IA64_LTOFF22X));                                    (type == R_IA64_LTOFF22X));
                           break;                            break;
                       case R_IA64_LDXMOV:                        case R_IA64_LDXMOV:
                           fprintf(outfile,                            fprintf(outfile,
                                   "    ia64_ldxmov(gen_code_ptr + %ld,"                                    "    ia64_ldxmov(gen_code_ptr + %ld,"
                                   " %s + %ld);\n", code_offset, name, addend);                                    " %s + %ld);\n", code_offset, relname, addend);
                           break;                            break;
   
                       case R_IA64_PCREL21B:                        case R_IA64_PCREL21B:
Line 2203  void gen_code(const char *name, host_ulo Line 2251  void gen_code(const char *name, host_ulo
                                       "    ia64_imm21b(gen_code_ptr + %ld,"                                        "    ia64_imm21b(gen_code_ptr + %ld,"
                                       " (long) (%s + %ld -\n\t\t"                                        " (long) (%s + %ld -\n\t\t"
                                       "((long) gen_code_ptr + %ld)) >> 4);\n",                                        "((long) gen_code_ptr + %ld)) >> 4);\n",
                                       code_offset, name, addend,                                        code_offset, relname, addend,
                                       code_offset & ~0xfUL);                                        code_offset & ~0xfUL);
                           } else {                            } else {
                               fprintf(outfile,                                fprintf(outfile,
Line 2224  void gen_code(const char *name, host_ulo Line 2272  void gen_code(const char *name, host_ulo
             }              }
 #elif defined(HOST_SPARC)  #elif defined(HOST_SPARC)
             {              {
                 char name[256];                  char relname[256];
                 int type;                  int type;
                 int addend;                  int addend;
                 int reloc_offset;                  int reloc_offset;
Line 2232  void gen_code(const char *name, host_ulo Line 2280  void gen_code(const char *name, host_ulo
                     if (rel->r_offset >= start_offset &&                      if (rel->r_offset >= start_offset &&
                         rel->r_offset < start_offset + copy_size) {                          rel->r_offset < start_offset + copy_size) {
                         sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;                          sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
                         get_reloc_expr(name, sizeof(name), sym_name);                          get_reloc_expr(relname, sizeof(relname), sym_name);
                         type = ELF32_R_TYPE(rel->r_info);                          type = ELF32_R_TYPE(rel->r_info);
                         addend = rel->r_addend;                          addend = rel->r_addend;
                         reloc_offset = rel->r_offset - start_offset;                          reloc_offset = rel->r_offset - start_offset;
                         switch(type) {                          switch(type) {
                         case R_SPARC_32:                          case R_SPARC_32:
                             fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                               fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
                                     reloc_offset, name, addend);                                      reloc_offset, relname, addend);
                             break;                              break;
                         case R_SPARC_HI22:                          case R_SPARC_HI22:
                             fprintf(outfile,                              fprintf(outfile,
Line 2247  void gen_code(const char *name, host_ulo Line 2295  void gen_code(const char *name, host_ulo
                                     "((*(uint32_t *)(gen_code_ptr + %d)) "                                      "((*(uint32_t *)(gen_code_ptr + %d)) "
                                     " & ~0x3fffff) "                                      " & ~0x3fffff) "
                                     " | (((%s + %d) >> 10) & 0x3fffff);\n",                                      " | (((%s + %d) >> 10) & 0x3fffff);\n",
                                     reloc_offset, reloc_offset, name, addend);                                      reloc_offset, reloc_offset, relname, addend);
                             break;                              break;
                         case R_SPARC_LO10:                          case R_SPARC_LO10:
                             fprintf(outfile,                              fprintf(outfile,
Line 2255  void gen_code(const char *name, host_ulo Line 2303  void gen_code(const char *name, host_ulo
                                     "((*(uint32_t *)(gen_code_ptr + %d)) "                                      "((*(uint32_t *)(gen_code_ptr + %d)) "
                                     " & ~0x3ff) "                                      " & ~0x3ff) "
                                     " | ((%s + %d) & 0x3ff);\n",                                      " | ((%s + %d) & 0x3ff);\n",
                                     reloc_offset, reloc_offset, name, addend);                                      reloc_offset, reloc_offset, relname, addend);
                             break;                              break;
                         case R_SPARC_WDISP30:                          case R_SPARC_WDISP30:
                             fprintf(outfile,                              fprintf(outfile,
Line 2264  void gen_code(const char *name, host_ulo Line 2312  void gen_code(const char *name, host_ulo
                                     " & ~0x3fffffff) "                                      " & ~0x3fffffff) "
                                     " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "                                      " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
                                     "    & 0x3fffffff);\n",                                      "    & 0x3fffffff);\n",
                                     reloc_offset, reloc_offset, name, addend,                                      reloc_offset, reloc_offset, relname, addend,
                                     reloc_offset);                                      reloc_offset);
                             break;                              break;
                         case R_SPARC_WDISP22:                          case R_SPARC_WDISP22:
Line 2276  void gen_code(const char *name, host_ulo Line 2324  void gen_code(const char *name, host_ulo
                                     "    & 0x3fffff);\n",                                      "    & 0x3fffff);\n",
                                     rel->r_offset - start_offset,                                      rel->r_offset - start_offset,
                                     rel->r_offset - start_offset,                                      rel->r_offset - start_offset,
                                     name, addend,                                      relname, addend,
                                     rel->r_offset - start_offset);                                      rel->r_offset - start_offset);
                             break;                              break;
                         default:                          default:
Line 2287  void gen_code(const char *name, host_ulo Line 2335  void gen_code(const char *name, host_ulo
             }              }
 #elif defined(HOST_SPARC64)  #elif defined(HOST_SPARC64)
             {              {
                 char name[256];                  char relname[256];
                 int type;                  int type;
                 int addend;                  int addend;
                 int reloc_offset;                  int reloc_offset;
Line 2295  void gen_code(const char *name, host_ulo Line 2343  void gen_code(const char *name, host_ulo
                     if (rel->r_offset >= start_offset &&                      if (rel->r_offset >= start_offset &&
                         rel->r_offset < start_offset + copy_size) {                          rel->r_offset < start_offset + copy_size) {
                         sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;                          sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
                         get_reloc_expr(name, sizeof(name), sym_name);                          get_reloc_expr(relname, sizeof(relname), sym_name);
                         type = ELF32_R_TYPE(rel->r_info);                          type = ELF32_R_TYPE(rel->r_info);
                         addend = rel->r_addend;                          addend = rel->r_addend;
                         reloc_offset = rel->r_offset - start_offset;                          reloc_offset = rel->r_offset - start_offset;
                         switch(type) {                          switch(type) {
                         case R_SPARC_32:                          case R_SPARC_32:
                             fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                              fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
                                     reloc_offset, name, addend);                                      reloc_offset, relname, addend);
                             break;                              break;
                         case R_SPARC_HI22:                          case R_SPARC_HI22:
                             fprintf(outfile,                              fprintf(outfile,
Line 2310  void gen_code(const char *name, host_ulo Line 2358  void gen_code(const char *name, host_ulo
                                     "((*(uint32_t *)(gen_code_ptr + %d)) "                                      "((*(uint32_t *)(gen_code_ptr + %d)) "
                                     " & ~0x3fffff) "                                      " & ~0x3fffff) "
                                     " | (((%s + %d) >> 10) & 0x3fffff);\n",                                      " | (((%s + %d) >> 10) & 0x3fffff);\n",
                                     reloc_offset, reloc_offset, name, addend);                                      reloc_offset, reloc_offset, relname, addend);
                             break;                              break;
                         case R_SPARC_LO10:                          case R_SPARC_LO10:
                             fprintf(outfile,                              fprintf(outfile,
Line 2318  void gen_code(const char *name, host_ulo Line 2366  void gen_code(const char *name, host_ulo
                                     "((*(uint32_t *)(gen_code_ptr + %d)) "                                      "((*(uint32_t *)(gen_code_ptr + %d)) "
                                     " & ~0x3ff) "                                      " & ~0x3ff) "
                                     " | ((%s + %d) & 0x3ff);\n",                                      " | ((%s + %d) & 0x3ff);\n",
                                     reloc_offset, reloc_offset, name, addend);                                      reloc_offset, reloc_offset, relname, addend);
                             break;                              break;
                         case R_SPARC_OLO10:                          case R_SPARC_OLO10:
                             addend += ELF64_R_TYPE_DATA (rel->r_info);                              addend += ELF64_R_TYPE_DATA (rel->r_info);
Line 2327  void gen_code(const char *name, host_ulo Line 2375  void gen_code(const char *name, host_ulo
                                     "((*(uint32_t *)(gen_code_ptr + %d)) "                                      "((*(uint32_t *)(gen_code_ptr + %d)) "
                                     " & ~0x3ff) "                                      " & ~0x3ff) "
                                     " | ((%s + %d) & 0x3ff);\n",                                      " | ((%s + %d) & 0x3ff);\n",
                                     reloc_offset, reloc_offset, name, addend);                                      reloc_offset, reloc_offset, relname, addend);
                             break;                              break;
                         case R_SPARC_WDISP30:                          case R_SPARC_WDISP30:
                             fprintf(outfile,                              fprintf(outfile,
Line 2336  void gen_code(const char *name, host_ulo Line 2384  void gen_code(const char *name, host_ulo
                                     " & ~0x3fffffff) "                                      " & ~0x3fffffff) "
                                     " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "                                      " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
                                     "    & 0x3fffffff);\n",                                      "    & 0x3fffffff);\n",
                                     reloc_offset, reloc_offset, name, addend,                                      reloc_offset, reloc_offset, relname, addend,
                                     reloc_offset);                                      reloc_offset);
                             break;                              break;
                         case R_SPARC_WDISP22:                          case R_SPARC_WDISP22:
Line 2346  void gen_code(const char *name, host_ulo Line 2394  void gen_code(const char *name, host_ulo
                                     " & ~0x3fffff) "                                      " & ~0x3fffff) "
                                     " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "                                      " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
                                     "    & 0x3fffff);\n",                                      "    & 0x3fffff);\n",
                                     reloc_offset, reloc_offset, name, addend,                                      reloc_offset, reloc_offset, relname, addend,
                                     reloc_offset);                                      reloc_offset);
                             break;                              break;
                           case R_SPARC_HH22:
                               fprintf(outfile,
                                       "    *(uint32_t *)(gen_code_ptr + %d) = "
                                       "((*(uint32_t *)(gen_code_ptr + %d)) "
                                       " & ~0x00000000) "
                                       " | (((%s + %d) >> 42) & 0x00000000);\n",
                                       reloc_offset, reloc_offset, relname, addend);
                                break;
   
                           case R_SPARC_LM22:
                               fprintf(outfile,
                                       "    *(uint32_t *)(gen_code_ptr + %d) = "
                                       "((*(uint32_t *)(gen_code_ptr + %d)) "
                                       " & ~0x00000000) "
                                       " | (((%s + %d) >> 10) & 0x00000000);\n",
                                       reloc_offset, reloc_offset, relname, addend);
                               break;
   
                           case R_SPARC_HM10:
                               fprintf(outfile,
                                       "    *(uint32_t *)(gen_code_ptr + %d) = "
                                       "((*(uint32_t *)(gen_code_ptr + %d)) "
                                       " & ~0x00000000) "
                                       " | ((((%s + %d) >> 32 & 0x3ff)) & 0x00000000);\n",
                                       reloc_offset, reloc_offset, relname, addend);
                               break;
   
                         default:                          default:
                             error("unsupported sparc64 relocation (%d) for symbol %s", type, name);                              error("unsupported sparc64 relocation (%d) for symbol %s", type, relname);
                         }                          }
                     }                      }
                 }                  }
             }              }
 #elif defined(HOST_ARM)  #elif defined(HOST_ARM)
             {              {
                 char name[256];                  char relname[256];
                 int type;                  int type;
                 int addend;                  int addend;
                 int reloc_offset;                  int reloc_offset;
Line 2392  void gen_code(const char *name, host_ulo Line 2467  void gen_code(const char *name, host_ulo
                     fprintf(outfile,                      fprintf(outfile,
                             "    *(uint32_t *)gen_code_ptr = 0x%x;\n", opcode);                              "    *(uint32_t *)gen_code_ptr = 0x%x;\n", opcode);
                 }                  }
                 arm_emit_ldr_info(name, start_offset, outfile, p_start, p_end,                  arm_emit_ldr_info(relname, start_offset, outfile, p_start, p_end,
                                   relocs, nb_relocs);                                    relocs, nb_relocs);
   
                 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {                  for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
Line 2402  void gen_code(const char *name, host_ulo Line 2477  void gen_code(const char *name, host_ulo
                     /* the compiler leave some unnecessary references to the code */                      /* the compiler leave some unnecessary references to the code */
                     if (sym_name[0] == '\0')                      if (sym_name[0] == '\0')
                         continue;                          continue;
                     get_reloc_expr(name, sizeof(name), sym_name);                      get_reloc_expr(relname, sizeof(relname), sym_name);
                     type = ELF32_R_TYPE(rel->r_info);                      type = ELF32_R_TYPE(rel->r_info);
                     addend = get32((uint32_t *)(text + rel->r_offset));                      addend = get32((uint32_t *)(text + rel->r_offset));
                     reloc_offset = rel->r_offset - start_offset;                      reloc_offset = rel->r_offset - start_offset;
                     switch(type) {                      switch(type) {
                     case R_ARM_ABS32:                      case R_ARM_ABS32:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                           fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
                                 reloc_offset, name, addend);                                  reloc_offset, relname, addend);
                         break;                          break;
                     case R_ARM_PC24:                      case R_ARM_PC24:
                     case R_ARM_JUMP24:                      case R_ARM_JUMP24:
                     case R_ARM_CALL:                      case R_ARM_CALL:
                         fprintf(outfile, "    arm_reloc_pc24((uint32_t *)(gen_code_ptr + %d), 0x%x, %s);\n",                           fprintf(outfile, "    arm_reloc_pc24((uint32_t *)(gen_code_ptr + %d), 0x%x, %s);\n",
                                 reloc_offset, addend, name);                                  reloc_offset, addend, relname);
                         break;                          break;
                     default:                      default:
                         error("unsupported arm relocation (%d)", type);                          error("unsupported arm relocation (%d)", type);
Line 2425  void gen_code(const char *name, host_ulo Line 2500  void gen_code(const char *name, host_ulo
             }              }
 #elif defined(HOST_M68K)  #elif defined(HOST_M68K)
             {              {
                 char name[256];                  char relname[256];
                 int type;                  int type;
                 int addend;                  int addend;
                 int reloc_offset;                  int reloc_offset;
Line 2435  void gen_code(const char *name, host_ulo Line 2510  void gen_code(const char *name, host_ulo
                     rel->r_offset < start_offset + copy_size) {                      rel->r_offset < start_offset + copy_size) {
                     sym = &(symtab[ELFW(R_SYM)(rel->r_info)]);                      sym = &(symtab[ELFW(R_SYM)(rel->r_info)]);
                     sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;                      sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
                     get_reloc_expr(name, sizeof(name), sym_name);                      get_reloc_expr(relname, sizeof(relname), sym_name);
                     type = ELF32_R_TYPE(rel->r_info);                      type = ELF32_R_TYPE(rel->r_info);
                     addend = get32((uint32_t *)(text + rel->r_offset)) + rel->r_addend;                      addend = get32((uint32_t *)(text + rel->r_offset)) + rel->r_addend;
                     reloc_offset = rel->r_offset - start_offset;                      reloc_offset = rel->r_offset - start_offset;
                     switch(type) {                      switch(type) {
                     case R_68K_32:                      case R_68K_32:
                         fprintf(outfile, "    /* R_68K_32 RELOC, offset %x */\n", rel->r_offset) ;                          fprintf(outfile, "    /* R_68K_32 RELOC, offset %x */\n", rel->r_offset) ;
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %#x;\n",                           fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %#x;\n",
                                 reloc_offset, name, addend );                                  reloc_offset, relname, addend );
                         break;                          break;
                     case R_68K_PC32:                      case R_68K_PC32:
                         fprintf(outfile, "    /* R_68K_PC32 RELOC, offset %x */\n", rel->r_offset);                          fprintf(outfile, "    /* R_68K_PC32 RELOC, offset %x */\n", rel->r_offset);
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %#x) + %#x;\n",                           fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %#x) + %#x;\n",
                                 reloc_offset, name, reloc_offset, /*sym->st_value+*/ addend);                                  reloc_offset, relname, reloc_offset, /*sym->st_value+*/ addend);
                         break;                          break;
                     default:                      default:
                         error("unsupported m68k relocation (%d)", type);                          error("unsupported m68k relocation (%d)", type);
Line 2456  void gen_code(const char *name, host_ulo Line 2531  void gen_code(const char *name, host_ulo
                 }                  }
                 }                  }
             }              }
   #elif defined(HOST_MIPS) || defined(HOST_MIPS64)
               {
                   for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
                       if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
                           char relname[256];
                           int type;
                           int addend;
                           int reloc_offset;
   
                           sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
                           /* the compiler leave some unnecessary references to the code */
                           if (sym_name[0] == '\0')
                               continue;
                           get_reloc_expr(relname, sizeof(relname), sym_name);
                           type = ELF32_R_TYPE(rel->r_info);
                           addend = get32((uint32_t *)(text + rel->r_offset));
                           reloc_offset = rel->r_offset - start_offset;
                           switch (type) {
                           case R_MIPS_26:
                               fprintf(outfile, "    /* R_MIPS_26 RELOC, offset 0x%x, name %s */\n",
                                       rel->r_offset, sym_name);
                               fprintf(outfile,
                                       "    *(uint32_t *)(gen_code_ptr + 0x%x) = "
                                       "(0x%x & ~0x3fffff) "
                                       "| ((0x%x + ((%s - (*(uint32_t *)(gen_code_ptr + 0x%x))) >> 2)) "
                                       "   & 0x3fffff);\n",
                                       reloc_offset, addend, addend, relname, reloc_offset);
                               break;
                           case R_MIPS_HI16:
                               fprintf(outfile, "    /* R_MIPS_HI16 RELOC, offset 0x%x, name %s */\n",
                                       rel->r_offset, sym_name);
                               fprintf(outfile,
                                       "    *(uint32_t *)(gen_code_ptr + 0x%x) = "
                                       "((*(uint32_t *)(gen_code_ptr + 0x%x)) "
                                       " & ~0xffff) "
                                       " | (((%s - 0x8000) >> 16) & 0xffff);\n",
                                       reloc_offset, reloc_offset, relname);
                               break;
                           case R_MIPS_LO16:
                               fprintf(outfile, "    /* R_MIPS_LO16 RELOC, offset 0x%x, name %s */\n",
                                       rel->r_offset, sym_name);
                               fprintf(outfile,
                                       "    *(uint32_t *)(gen_code_ptr + 0x%x) = "
                                       "((*(uint32_t *)(gen_code_ptr + 0x%x)) "
                                       " & ~0xffff) "
                                       " | (%s & 0xffff);\n",
                                       reloc_offset, reloc_offset, relname);
                               break;
                           case R_MIPS_PC16:
                               fprintf(outfile, "    /* R_MIPS_PC16 RELOC, offset 0x%x, name %s */\n",
                                       rel->r_offset, sym_name);
                               fprintf(outfile,
                                       "    *(uint32_t *)(gen_code_ptr + 0x%x) = "
                                       "(0x%x & ~0xffff) "
                                       "| ((0x%x + ((%s - (*(uint32_t *)(gen_code_ptr + 0x%x))) >> 2)) "
                                       "   & 0xffff);\n",
                                       reloc_offset, addend, addend, relname, reloc_offset);
                               break;
                           case R_MIPS_GOT16:
                           case R_MIPS_CALL16:
                               fprintf(outfile, "    /* R_MIPS_GOT16 RELOC, offset 0x%x, name %s */\n",
                                       rel->r_offset, sym_name);
                               fprintf(outfile,
                                       "    *(uint32_t *)(gen_code_ptr + 0x%x) = "
                                       "((*(uint32_t *)(gen_code_ptr + 0x%x)) "
                                       " & ~0xffff) "
                                       " | (((%s - 0x8000) >> 16) & 0xffff);\n",
                                       reloc_offset, reloc_offset, relname);
                               break;
                           default:
                               error("unsupported MIPS relocation (%d)", type);
                           }
                       }
                   }
               }
 #else  #else
 #error unsupported CPU  #error unsupported CPU
 #endif  #endif
Line 2515  int gen_file(FILE *outfile, int out_type Line 2665  int gen_file(FILE *outfile, int out_type
                 gen_code(name, sym->st_value, sym->st_size, outfile, 0);                  gen_code(name, sym->st_value, sym->st_size, outfile, 0);
             }              }
         }          }
           
     } else {      } else {
         /* generate big code generation switch */          /* generate big code generation switch */
   
Line 2558  fprintf(outfile, Line 2708  fprintf(outfile,
    eliminating the neeed to jump around the pool.     eliminating the neeed to jump around the pool.
   
    We currently generate:     We currently generate:
      
    [ For this example we assume merging would move op1_pool out of range.     [ For this example we assume merging would move op1_pool out of range.
      In practice we should be able to combine many ops before the offset       In practice we should be able to combine many ops before the offset
      limits are reached. ]       limits are reached. ]
Line 2645  fprintf(outfile, Line 2795  fprintf(outfile,
 "    opc_ptr = opc_buf;\n"  "    opc_ptr = opc_buf;\n"
 "    opparam_ptr = opparam_buf;\n");  "    opparam_ptr = opparam_buf;\n");
   
         /* Generate prologue, if needed. */           /* Generate prologue, if needed. */
   
 fprintf(outfile,  fprintf(outfile,
 "    for(;;) {\n");  "    for(;;) {\n");
Line 2671  fprintf(outfile, Line 2821  fprintf(outfile,
             name = get_sym_name(sym);              name = get_sym_name(sym);
             if (strstart(name, OP_PREFIX, NULL)) {              if (strstart(name, OP_PREFIX, NULL)) {
 #if 0  #if 0
                 printf("%4d: %s pos=0x%08x len=%d\n",                   printf("%4d: %s pos=0x%08x len=%d\n",
                        i, name, sym->st_value, sym->st_size);                         i, name, sym->st_value, sym->st_size);
 #endif  #endif
 #if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF)  #if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF)
Line 2713  fprintf(outfile, Line 2863  fprintf(outfile,
             "plt_target, plt_offset);\n    }\n");              "plt_target, plt_offset);\n    }\n");
 #endif  #endif
   
 /* generate some code patching */   /* generate some code patching */
 #ifdef HOST_ARM  #ifdef HOST_ARM
 fprintf(outfile,  fprintf(outfile,
 "if (arm_data_ptr != arm_data_table + ARM_LDR_TABLE_SIZE)\n"  "if (arm_data_ptr != arm_data_table + ARM_LDR_TABLE_SIZE)\n"

Removed from v.1.1.1.4  
changed lines
  Added in v.1.1.1.5


unix.superglobalmegacorp.com