qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [patch] 64-bit host support broken


From: Paul Brook
Subject: [Qemu-devel] [patch] 64-bit host support broken
Date: Tue, 27 Dec 2005 19:11:42 +0000
User-agent: KMail/1.8.3

The attached patch fixes building qemu on a 32-bit machine for a 64-bit host. 
The problem is that dyngen.c passes 64-bit values for "%d" or "%ld" printf 
formats. This seems to work entirely by chance on amd64, and because 
long==int64_t on other hosts.
These are all small offsets, so "int" should be more than sufficient.

Paul
Index: dyngen.c
===================================================================
RCS file: /sources/qemu/qemu/dyngen.c,v
retrieving revision 1.40
diff -u -p -r1.40 dyngen.c
--- dyngen.c    27 Apr 2005 19:55:58 -0000      1.40
+++ dyngen.c    27 Dec 2005 19:01:23 -0000
@@ -1679,7 +1679,7 @@ void gen_code(const char *name, host_ulo
 #endif                    
                     if (val >= start_offset && val <= start_offset + 
copy_size) {
                         n = strtol(p, NULL, 10);
-                        fprintf(outfile, "    label_offsets[%d] = %ld + 
(gen_code_ptr - gen_code_buf);\n", n, val - start_offset);
+                        fprintf(outfile, "    label_offsets[%d] = %ld + 
(gen_code_ptr - gen_code_buf);\n", n, (long)(val - start_offset));
                     }
                 }
             }
@@ -1696,12 +1696,14 @@ void gen_code(const char *name, host_ulo
                 char name[256];
                 int type;
                 int addend;
+                int reloc_offset;
                 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 = get_rel_sym_name(rel);
                     if (!sym_name)
                         continue;
+                    reloc_offset = rel->r_offset - start_offset;
                     if (strstart(sym_name, "__op_jmp", &p)) {
                         int n;
                         n = strtol(p, NULL, 10);
@@ -1710,10 +1712,10 @@ void gen_code(const char *name, host_ulo
                            chaining: the offset of the instruction
                            needs to be stored */
                         fprintf(outfile, "    jmp_offsets[%d] = %d + 
(gen_code_ptr - gen_code_buf);\n",
-                                n, rel->r_offset - start_offset);
+                                n, reloc_offset);
                         continue;
                     }
-                        
+
                     get_reloc_expr(name, sizeof(name), sym_name);
                     addend = get32((uint32_t *)(text + rel->r_offset));
 #ifdef CONFIG_FORMAT_ELF
@@ -1721,11 +1723,11 @@ void gen_code(const char *name, host_ulo
                     switch(type) {
                     case R_386_32:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) 
= %s + %d;\n", 
-                                rel->r_offset - start_offset, name, addend);
+                                reloc_offset, name, addend);
                         break;
                     case R_386_PC32:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) 
= %s - (long)(gen_code_ptr + %d) + %d;\n", 
-                                rel->r_offset - start_offset, name, 
rel->r_offset - start_offset, addend);
+                                reloc_offset, name, reloc_offset, addend);
                         break;
                     default:
                         error("unsupported i386 relocation (%d)", type);
@@ -1748,11 +1750,11 @@ void gen_code(const char *name, host_ulo
                     switch(type) {
                     case DIR32:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) 
= %s + %d;\n", 
-                                rel->r_offset - start_offset, name, addend);
+                                reloc_offset, name, addend);
                         break;
                     case DISP32:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) 
= %s - (long)(gen_code_ptr + %d) + %d -4;\n", 
-                                rel->r_offset - start_offset, name, 
rel->r_offset - start_offset, addend);
+                                reloc_offset, name, reloc_offset, addend);
                         break;
                     default:
                         error("unsupported i386 relocation (%d)", type);
@@ -1768,6 +1770,7 @@ void gen_code(const char *name, host_ulo
                 char name[256];
                 int type;
                 int addend;
+                int reloc_offset;
                 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
                 if (rel->r_offset >= start_offset &&
                    rel->r_offset < start_offset + copy_size) {
@@ -1775,18 +1778,19 @@ void gen_code(const char *name, host_ulo
                     get_reloc_expr(name, sizeof(name), sym_name);
                     type = ELF32_R_TYPE(rel->r_info);
                     addend = rel->r_addend;
+                    reloc_offset = rel->r_offset - start_offset;
                     switch(type) {
                     case R_X86_64_32:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) 
= (uint32_t)%s + %d;\n", 
-                                rel->r_offset - start_offset, name, addend);
+                                reloc_offset, name, addend);
                         break;
                     case R_X86_64_32S:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) 
= (int32_t)%s + %d;\n", 
-                                rel->r_offset - start_offset, name, addend);
+                                reloc_offset, name, addend);
                         break;
                     case R_X86_64_PC32:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) 
= %s - (long)(gen_code_ptr + %d) + %d;\n", 
-                                rel->r_offset - start_offset, name, 
rel->r_offset - start_offset, addend);
+                                reloc_offset, name, reloc_offset, addend);
                         break;
                     default:
                         error("unsupported X86_64 relocation (%d)", type);
@@ -1800,10 +1804,12 @@ void gen_code(const char *name, host_ulo
                 char name[256];
                 int type;
                 int addend;
+                int reloc_offset;
                 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[ELFW(R_SYM)(rel->r_info)].st_name;
+                        reloc_offset = rel->r_offset - start_offset;
                         if (strstart(sym_name, "__op_jmp", &p)) {
                             int n;
                             n = strtol(p, NULL, 10);
@@ -1812,7 +1818,7 @@ void gen_code(const char *name, host_ulo
                                chaining: the offset of the instruction
                                needs to be stored */
                             fprintf(outfile, "    jmp_offsets[%d] = %d + 
(gen_code_ptr - gen_code_buf);\n",
-                                    n, rel->r_offset - start_offset);
+                                    n, reloc_offset);
                             continue;
                         }
                         
@@ -1822,24 +1828,24 @@ void gen_code(const char *name, host_ulo
                         switch(type) {
                         case R_PPC_ADDR32:
                             fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + 
%d) = %s + %d;\n", 
-                                    rel->r_offset - start_offset, name, 
addend);
+                                    reloc_offset, name, addend);
                             break;
                         case R_PPC_ADDR16_LO:
                             fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + 
%d) = (%s + %d);\n", 
-                                    rel->r_offset - start_offset, name, 
addend);
+                                    reloc_offset, name, addend);
                             break;
                         case R_PPC_ADDR16_HI:
                             fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + 
%d) = (%s + %d) >> 16;\n", 
-                                    rel->r_offset - start_offset, name, 
addend);
+                                    reloc_offset, name, addend);
                             break;
                         case R_PPC_ADDR16_HA:
                             fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + 
%d) = (%s + %d + 0x8000) >> 16;\n", 
-                                    rel->r_offset - start_offset, name, 
addend);
+                                    reloc_offset, name, addend);
                             break;
                         case R_PPC_REL24:
                             /* 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", 
-                                    rel->r_offset - start_offset, 
rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
+                                    reloc_offset, reloc_offset, name, 
reloc_offset, addend);
                             break;
                         default:
                             error("unsupported powerpc relocation (%d)", type);
@@ -1941,6 +1947,7 @@ void gen_code(const char *name, host_ulo
                 char name[256];
                 int type;
                 int addend;
+                int reloc_offset;
                 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
                     if (rel->r_offset >= start_offset &&
                        rel->r_offset < start_offset + copy_size) {
@@ -1948,18 +1955,19 @@ void gen_code(const char *name, host_ulo
                         get_reloc_expr(name, sizeof(name), sym_name);
                         type = ELF32_R_TYPE(rel->r_info);
                         addend = rel->r_addend;
+                        reloc_offset = rel->r_offset - start_offset;
                         switch(type) {
                         case R_390_32:
                             fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + 
%d) = %s + %d;\n", 
-                                    rel->r_offset - start_offset, name, 
addend);
+                                    reloc_offset, name, addend);
                             break;
                         case R_390_16:
                             fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + 
%d) = %s + %d;\n", 
-                                    rel->r_offset - start_offset, name, 
addend);
+                                    reloc_offset, name, addend);
                             break;
                         case R_390_8:
                             fprintf(outfile, "    *(uint8_t *)(gen_code_ptr + 
%d) = %s + %d;\n", 
-                                    rel->r_offset - start_offset, name, 
addend);
+                                    reloc_offset, name, addend);
                             break;
                         default:
                             error("unsupported s390 relocation (%d)", type);
@@ -1972,17 +1980,19 @@ void gen_code(const char *name, host_ulo
                 for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
                    if (rel->r_offset >= start_offset && rel->r_offset < 
start_offset + copy_size) {
                        int type;
+                        long reloc_offset;
 
                        type = ELF64_R_TYPE(rel->r_info);
                        sym_name = strtab + 
symtab[ELF64_R_SYM(rel->r_info)].st_name;
+                        reloc_offset = rel->r_offset - start_offset;
                        switch (type) {
                        case R_ALPHA_GPDISP:
                            /* The gp is just 32 bit, and never changes, so 
it's easiest to emit it
                               as an immediate instead of constructing it from 
the pv or ra.  */
                            fprintf(outfile, "    immediate_ldah(gen_code_ptr + 
%ld, gp);\n",
-                                   rel->r_offset - start_offset);
+                                   reloc_offset);
                            fprintf(outfile, "    immediate_lda(gen_code_ptr + 
%ld, gp);\n",
-                                   rel->r_offset - start_offset + 
rel->r_addend);
+                                   reloc_offset + (int)rel->r_addend);
                            break;
                        case R_ALPHA_LITUSE:
                            /* jsr to literal hint. Could be used to optimize 
to bsr. Ignore for
@@ -2002,18 +2012,18 @@ void gen_code(const char *name, host_ulo
                               special treatment.  */
                            if (strstart(sym_name, "__op_param", &p))
                                fprintf(outfile, "    
immediate_ldah(gen_code_ptr + %ld, param%s);\n",
-                                       rel->r_offset - start_offset, p);
+                                       reloc_offset, p);
                            break;
                        case R_ALPHA_GPRELLOW:
                            if (strstart(sym_name, "__op_param", &p))
                                fprintf(outfile, "    
immediate_lda(gen_code_ptr + %ld, param%s);\n",
-                                       rel->r_offset - start_offset, p);
+                                       reloc_offset, p);
                            break;
                        case R_ALPHA_BRSGP:
                            /* PC-relative jump. Tweak offset to skip the two 
instructions that try to
                               set up the gp from the pv.  */
                            fprintf(outfile, "    fix_bsr(gen_code_ptr + %ld, 
(uint8_t *) &%s - (gen_code_ptr + %ld + 4) + 8);\n",
-                                   rel->r_offset - start_offset, sym_name, 
rel->r_offset - start_offset);
+                                   reloc_offset, sym_name, reloc_offset);
                            break;
                        default:
                            error("unsupported Alpha relocation (%d)", type);
@@ -2035,6 +2045,7 @@ void gen_code(const char *name, host_ulo
                        || rel->r_offset >= start_offset + copy_size)
                        continue;
                    sym_name = (strtab + symtab[sym_idx].st_name);
+                   code_offset = rel->r_offset - start_offset;
                    if (strstart(sym_name, "__op_jmp", &p)) {
                        int n;
                        n = strtol(p, NULL, 10);
@@ -2044,13 +2055,12 @@ void gen_code(const char *name, host_ulo
                           needs to be stored */
                        fprintf(outfile, "    jmp_offsets[%d] ="
                                "%ld + (gen_code_ptr - gen_code_buf);\n",
-                               n, rel->r_offset - start_offset);
+                               n, code_offset);
                        continue;
                    }
                    get_reloc_expr(name, sizeof(name), sym_name);
                    type = ELF64_R_TYPE(rel->r_info);
                    addend = rel->r_addend;
-                   code_offset = rel->r_offset - start_offset;
                    switch(type) {
                      case R_IA64_IMM64:
                          fprintf(outfile,
@@ -2101,6 +2111,7 @@ void gen_code(const char *name, host_ulo
                 char name[256];
                 int type;
                 int addend;
+                int reloc_offset;
                 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
                     if (rel->r_offset >= start_offset &&
                        rel->r_offset < start_offset + copy_size) {
@@ -2108,10 +2119,11 @@ void gen_code(const char *name, host_ulo
                         get_reloc_expr(name, sizeof(name), sym_name);
                         type = ELF32_R_TYPE(rel->r_info);
                         addend = rel->r_addend;
+                        reloc_offset = rel->r_offset - start_offset;
                         switch(type) {
                         case R_SPARC_32:
                             fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + 
%d) = %s + %d;\n", 
-                                    rel->r_offset - start_offset, name, 
addend);
+                                    reloc_offset, name, addend);
                            break;
                        case R_SPARC_HI22:
                             fprintf(outfile,
@@ -2119,9 +2131,7 @@ void gen_code(const char *name, host_ulo
                                    "((*(uint32_t *)(gen_code_ptr + %d)) "
                                    " & ~0x3fffff) "
                                    " | (((%s + %d) >> 10) & 0x3fffff);\n",
-                                    rel->r_offset - start_offset,
-                                   rel->r_offset - start_offset,
-                                   name, addend);
+                                    reloc_offset, reloc_offset, name, addend);
                            break;
                        case R_SPARC_LO10:
                             fprintf(outfile,
@@ -2129,9 +2139,7 @@ void gen_code(const char *name, host_ulo
                                    "((*(uint32_t *)(gen_code_ptr + %d)) "
                                    " & ~0x3ff) "
                                    " | ((%s + %d) & 0x3ff);\n",
-                                    rel->r_offset - start_offset,
-                                   rel->r_offset - start_offset,
-                                   name, addend);
+                                    reloc_offset, reloc_offset, name, addend);
                            break;
                        case R_SPARC_WDISP30:
                            fprintf(outfile,
@@ -2140,10 +2148,8 @@ void gen_code(const char *name, host_ulo
                                    " & ~0x3fffffff) "
                                    " | ((((%s + %d) - (long)(gen_code_ptr + 
%d))>>2) "
                                    "    & 0x3fffffff);\n",
-                                   rel->r_offset - start_offset,
-                                   rel->r_offset - start_offset,
-                                   name, addend,
-                                   rel->r_offset - start_offset);
+                                   reloc_offset, reloc_offset, name, addend,
+                                   reloc_offset);
                            break;
                         default:
                             error("unsupported sparc relocation (%d)", type);
@@ -2156,6 +2162,7 @@ void gen_code(const char *name, host_ulo
                 char name[256];
                 int type;
                 int addend;
+                int reloc_offset;
                 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
                     if (rel->r_offset >= start_offset &&
                        rel->r_offset < start_offset + copy_size) {
@@ -2163,10 +2170,11 @@ void gen_code(const char *name, host_ulo
                         get_reloc_expr(name, sizeof(name), sym_name);
                         type = ELF64_R_TYPE(rel->r_info);
                         addend = rel->r_addend;
+                        reloc_offset = rel->r_offset - start_offset;
                         switch(type) {
                         case R_SPARC_32:
                             fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + 
%d) = %s + %d;\n",
-                                    rel->r_offset - start_offset, name, 
addend);
+                                    reloc_offset, name, addend);
                            break;
                        case R_SPARC_HI22:
                             fprintf(outfile,
@@ -2174,9 +2182,7 @@ void gen_code(const char *name, host_ulo
                                    "((*(uint32_t *)(gen_code_ptr + %d)) "
                                    " & ~0x3fffff) "
                                    " | (((%s + %d) >> 10) & 0x3fffff);\n",
-                                    rel->r_offset - start_offset,
-                                   rel->r_offset - start_offset,
-                                   name, addend);
+                                    reloc_offset, reloc_offset, name, addend);
                            break;
                        case R_SPARC_LO10:
                             fprintf(outfile,
@@ -2184,9 +2190,7 @@ void gen_code(const char *name, host_ulo
                                    "((*(uint32_t *)(gen_code_ptr + %d)) "
                                    " & ~0x3ff) "
                                    " | ((%s + %d) & 0x3ff);\n",
-                                    rel->r_offset - start_offset,
-                                   rel->r_offset - start_offset,
-                                   name, addend);
+                                    reloc_offset, reloc_offset, name, addend);
                            break;
                        case R_SPARC_WDISP30:
                            fprintf(outfile,
@@ -2195,10 +2199,8 @@ void gen_code(const char *name, host_ulo
                                    " & ~0x3fffffff) "
                                    " | ((((%s + %d) - (long)(gen_code_ptr + 
%d))>>2) "
                                    "    & 0x3fffffff);\n",
-                                   rel->r_offset - start_offset,
-                                   rel->r_offset - start_offset,
-                                   name, addend,
-                                   rel->r_offset - start_offset);
+                                   reloc_offset, reloc_offset, name, addend,
+                                   reloc_offset);
                            break;
                         default:
                            error("unsupported sparc64 relocation (%d)", type);
@@ -2211,6 +2213,7 @@ void gen_code(const char *name, host_ulo
                 char name[256];
                 int type;
                 int addend;
+                int reloc_offset;
 
                 arm_emit_ldr_info(name, start_offset, outfile, p_start, p_end,
                                   relocs, nb_relocs);
@@ -2225,14 +2228,15 @@ void gen_code(const char *name, host_ulo
                     get_reloc_expr(name, sizeof(name), 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_ARM_ABS32:
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) 
= %s + %d;\n", 
-                                rel->r_offset - start_offset, name, addend);
+                                reloc_offset, name, addend);
                         break;
                     case R_ARM_PC24:
                         fprintf(outfile, "    arm_reloc_pc24((uint32_t 
*)(gen_code_ptr + %d), 0x%x, %s);\n", 
-                                rel->r_offset - start_offset, addend, name);
+                                reloc_offset, addend, name);
                         break;
                     default:
                         error("unsupported arm relocation (%d)", type);
@@ -2245,6 +2249,7 @@ void gen_code(const char *name, host_ulo
                 char name[256];
                 int type;
                 int addend;
+                int reloc_offset;
                Elf32_Sym *sym;
                 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
                 if (rel->r_offset >= start_offset &&
@@ -2254,16 +2259,17 @@ void gen_code(const char *name, host_ulo
                     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;
+                    reloc_offset = rel->r_offset - start_offset;
                     switch(type) {
                     case R_68K_32:
                        fprintf(outfile, "    /* R_68K_32 RELOC, offset %x 
*/\n", rel->r_offset) ;
                         fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) 
= %s + %#x;\n", 
-                                rel->r_offset - start_offset, name, addend );
+                                reloc_offset, name, addend );
                         break;
                     case R_68K_PC32:
                        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", 
-                                rel->r_offset - start_offset, name, 
rel->r_offset - start_offset, /*sym->st_value+*/ addend);
+                                reloc_offset, name, reloc_offset, 
/*sym->st_value+*/ addend);
                         break;
                     default:
                         error("unsupported m68k relocation (%d)", type);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]