]> git.proxmox.com Git - qemu.git/blobdiff - dyngen.c
sparc update
[qemu.git] / dyngen.c
index 1138ca4551a8cb6a48e3aed580aae48815382212..5823e0767782d0646efba2f9bcf116add762bbae 100644 (file)
--- a/dyngen.c
+++ b/dyngen.c
@@ -996,11 +996,11 @@ static const char * get_reloc_name(EXE_RELOC * rel, int * sslide)
 
        switch(rel->r_type)
        {
-               case PPC_RELOC_LO16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset & 0xffff);
+               case PPC_RELOC_LO16: fetch_next_pair_value(rel+1, &other_half); sectoffset |= (other_half << 16);
                        break;
-               case PPC_RELOC_HI16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (other_half & 0xffff);
+               case PPC_RELOC_HI16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset << 16) | (uint16_t)(other_half & 0xffff);
                        break;
-               case PPC_RELOC_HA16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (other_half & 0xffff);
+               case PPC_RELOC_HA16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset << 16) + (int16_t)(other_half & 0xffff);
                        break;
                case PPC_RELOC_BR24:
                        sectoffset = ( *(uint32_t *)(text + rel->r_address) & 0x03fffffc );
@@ -1146,13 +1146,11 @@ int load_object(const char *filename)
        
        /* 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++) {
-        const char *name;
         struct nlist *sym_follow, *sym_next = 0;
         unsigned int j;
-        name = find_str_by_index(sym->n_un.n_strx);
                memset(sym, 0, sizeof(*sym));
                
-               if ( sym->n_type & N_STAB ) /* Debug symbols are skipped */
+               if ( syment->n_type & N_STAB ) /* Debug symbols are skipped */
             continue;
                        
                memcpy(sym, syment, sizeof(*syment));
@@ -1185,6 +1183,26 @@ int load_object(const char *filename)
 
 #endif /* CONFIG_FORMAT_MACH */
 
+void get_reloc_expr(char *name, int name_size, const char *sym_name)
+{
+    const char *p;
+
+    if (strstart(sym_name, "__op_param", &p)) {
+        snprintf(name, name_size, "param%s", p);
+    } else if (strstart(sym_name, "__op_gen_label", &p)) {
+        snprintf(name, name_size, "gen_labels[param%s]", p);
+    } else {
+#ifdef HOST_SPARC
+        if (sym_name[0] == '.')
+            snprintf(name, sizeof(name),
+                     "(long)(&__dot_%s)",
+                     sym_name + 1);
+        else
+#endif
+            snprintf(name, name_size, "(long)(&%s)", sym_name);
+    }
+}
+
 #ifdef HOST_ARM
 
 int arm_emit_ldr_info(const char *name, unsigned long start_offset,
@@ -1244,11 +1262,7 @@ int arm_emit_ldr_info(const char *name, unsigned long start_offset,
                         if (rel->r_offset == (pc_offset + start_offset)) {
                             sym_name = get_rel_sym_name(rel);
                             /* the compiler leave some unnecessary references to the code */
-                            if (strstart(sym_name, "__op_param", &p)) {
-                                snprintf(relname, sizeof(relname), "param%s", p);
-                            } else {
-                                snprintf(relname, sizeof(relname), "(long)(&%s)", sym_name);
-                            }
+                            get_reloc_expr(relname, sizeof(relname), sym_name);
                             type = ELF32_R_TYPE(rel->r_info);
                             if (type != R_ARM_ABS32)
                                 error("%s: unsupported data relocation", name);
@@ -1641,13 +1655,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                         continue;
                     }
                         
-                    if (strstart(sym_name, "__op_param", &p)) {
-                        snprintf(name, sizeof(name), "param%s", p);
-                    } else if (strstart(sym_name, "__op_gen_label", &p)) {
-                        snprintf(name, sizeof(name), "gen_labels[param%s]", p);
-                    } else {
-                        snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
-                    }
+                    get_reloc_expr(name, sizeof(name), sym_name);
                     addend = get32((uint32_t *)(text + rel->r_offset));
 #ifdef CONFIG_FORMAT_ELF
                     type = ELF32_R_TYPE(rel->r_info);
@@ -1705,11 +1713,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                 if (rel->r_offset >= start_offset &&
                    rel->r_offset < start_offset + copy_size) {
                     sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
-                    if (strstart(sym_name, "__op_param", &p)) {
-                        snprintf(name, sizeof(name), "param%s", p);
-                    } else {
-                        snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
-                    }
+                    get_reloc_expr(name, sizeof(name), sym_name);
                     type = ELF32_R_TYPE(rel->r_info);
                     addend = rel->r_addend;
                     switch(type) {
@@ -1753,11 +1757,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                             continue;
                         }
                         
-                        if (strstart(sym_name, "__op_param", &p)) {
-                            snprintf(name, sizeof(name), "param%s", p);
-                        } else {
-                            snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
-                        }
+                        get_reloc_expr(name, sizeof(name), sym_name);
                         type = ELF32_R_TYPE(rel->r_info);
                         addend = rel->r_addend;
                         switch(type) {
@@ -1842,19 +1842,20 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                                                continue; /* dunno how to handle without final_sym_name */
                                        }
                                                                                                           
-                                       if (strstart(sym_name, "__op_param", &p)) {
-                                               snprintf(final_sym_name, sizeof(final_sym_name), "param%s", p);
-                                       } else {
-                                               snprintf(final_sym_name, sizeof(final_sym_name), "(long)(&%s)", sym_name);
-                                       }
-                       
+                                        get_reloc_expr(final_sym_name, sizeof(final_sym_name), 
+                                                       sym_name);
                                        switch(type) {
                                        case PPC_RELOC_BR24:
-                                               fprintf(outfile, "{\n");
-                                               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", 
+                                           if (!strstart(sym_name,"__op_gen_label",&p)) {
+                                               fprintf(outfile, "{\n");
+                                               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", 
                                                                                        slide, slide, name, sslide );
-                                               fprintf(outfile, "}\n");
+                                               fprintf(outfile, "}\n");
+                                       } 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",
+                                                                                       slide, slide, final_sym_name, slide);
+                                       }
                                                break;
                                        case PPC_RELOC_HI16:
                                                fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d) >> 16;\n", 
@@ -1885,11 +1886,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                     if (rel->r_offset >= start_offset &&
                        rel->r_offset < start_offset + copy_size) {
                         sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
-                        if (strstart(sym_name, "__op_param", &p)) {
-                            snprintf(name, sizeof(name), "param%s", p);
-                        } else {
-                            snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
-                        }
+                        get_reloc_expr(name, sizeof(name), sym_name);
                         type = ELF32_R_TYPE(rel->r_info);
                         addend = rel->r_addend;
                         switch(type) {
@@ -1973,11 +1970,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
                     if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
                         sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
-                        if (strstart(sym_name, "__op_param", &p)) {
-                            snprintf(name, sizeof(name), "param%s", p);
-                        } else {
-                            snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
-                        }
+                        get_reloc_expr(name, sizeof(name), sym_name);
                         type = ELF64_R_TYPE(rel->r_info);
                         addend = rel->r_addend;
                         switch(type) {
@@ -2000,17 +1993,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                     if (rel->r_offset >= start_offset &&
                        rel->r_offset < start_offset + copy_size) {
                         sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
-                        if (strstart(sym_name, "__op_param", &p)) {
-                            snprintf(name, sizeof(name), "param%s", p);
-                        } else {
-                               if (sym_name[0] == '.')
-                                       snprintf(name, sizeof(name),
-                                                "(long)(&__dot_%s)",
-                                                sym_name + 1);
-                               else
-                                       snprintf(name, sizeof(name),
-                                                "(long)(&%s)", sym_name);
-                        }
+                        get_reloc_expr(name, sizeof(name), sym_name);
                         type = ELF32_R_TYPE(rel->r_info);
                         addend = rel->r_addend;
                         switch(type) {
@@ -2065,11 +2048,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                     if (rel->r_offset >= start_offset &&
                        rel->r_offset < start_offset + copy_size) {
                         sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
-                        if (strstart(sym_name, "__op_param", &p)) {
-                            snprintf(name, sizeof(name), "param%s", p);
-                        } else {
-                            snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
-                        }
+                        get_reloc_expr(name, sizeof(name), sym_name);
                         type = ELF64_R_TYPE(rel->r_info);
                         addend = rel->r_addend;
                         switch(type) {
@@ -2131,11 +2110,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                     /* the compiler leave some unnecessary references to the code */
                     if (sym_name[0] == '\0')
                         continue;
-                    if (strstart(sym_name, "__op_param", &p)) {
-                        snprintf(name, sizeof(name), "param%s", p);
-                    } else {
-                        snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
-                    }
+                    get_reloc_expr(name, sizeof(name), sym_name);
                     type = ELF32_R_TYPE(rel->r_info);
                     addend = get32((uint32_t *)(text + rel->r_offset));
                     switch(type) {
@@ -2164,11 +2139,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                    rel->r_offset < start_offset + copy_size) {
                    sym = &(symtab[ELFW(R_SYM)(rel->r_info)]);
                     sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
-                    if (strstart(sym_name, "__op_param", &p)) {
-                        snprintf(name, sizeof(name), "param%s", p);
-                    } else {
-                        snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
-                    }
+                    get_reloc_expr(name, sizeof(name), sym_name);
                     type = ELF32_R_TYPE(rel->r_info);
                     addend = get32((uint32_t *)(text + rel->r_offset)) + rel->r_addend;
                     switch(type) {