* [Qemu-devel] [patch] 64-bit host support broken
@ 2005-12-27 19:11 Paul Brook
0 siblings, 0 replies; only message in thread
From: Paul Brook @ 2005-12-27 19:11 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 331 bytes --]
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
[-- Attachment #2: patch.qemu_cross64 --]
[-- Type: text/x-diff, Size: 22047 bytes --]
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);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2005-12-27 19:13 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-12-27 19:11 [Qemu-devel] [patch] 64-bit host support broken Paul Brook
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.