Revision 379f6698

b/configure
184 184
linux_user="no"
185 185
darwin_user="no"
186 186
bsd_user="no"
187
guest_base=""
187 188
build_docs="yes"
188 189
uname_release=""
189 190
curses="yes"
......
465 466
  ;;
466 467
  --enable-bsd-user) bsd_user="yes"
467 468
  ;;
469
  --enable-guest-base) guest_base="yes"
470
  ;;
471
  --disable-guest-base) guest_base="no"
472
  ;;
468 473
  --enable-uname-release=*) uname_release="$optarg"
469 474
  ;;
470 475
  --sparc_cpu=*)
......
544 549
# If cpu ~= sparc and  sparc_cpu hasn't been defined, plug in the right
545 550
# ARCH_CFLAGS/ARCH_LDFLAGS (assume sparc_v8plus for 32-bit and sparc_v9 for 64-bit)
546 551
#
552
host_guest_base="no"
547 553
case "$cpu" in
548 554
    sparc) if test -z "$sparc_cpu" ; then
549 555
               ARCH_CFLAGS="-m32 -mcpu=ultrasparc -D__sparc_v8plus__"
......
576 582
    i386)
577 583
           ARCH_CFLAGS="-m32"
578 584
           ARCH_LDFLAGS="-m32"
585
           host_guest_base="yes"
579 586
           ;;
580 587
    x86_64)
581 588
           ARCH_CFLAGS="-m64"
582 589
           ARCH_LDFLAGS="-m64"
590
           host_guest_base="yes"
591
           ;;
592
    arm*)
593
           host_guest_base="yes"
583 594
           ;;
584 595
esac
585 596

  
597
[ -z "$guest_base" ] && guest_base="$host_guest_base"
598

  
586 599
if test x"$show_help" = x"yes" ; then
587 600
cat << EOF
588 601

  
......
641 654
echo "  --disable-darwin-user    disable all darwin usermode emulation targets"
642 655
echo "  --enable-bsd-user        enable all BSD usermode emulation targets"
643 656
echo "  --disable-bsd-user       disable all BSD usermode emulation targets"
657
echo "  --enable-guest-base      enable GUEST_BASE support for usermode"
658
echo "                           emulation targets"
659
echo "  --disable-guest-base     disable GUEST_BASE support"
644 660
echo "  --fmod-lib               path to FMOD library"
645 661
echo "  --fmod-inc               path to FMOD includes"
646 662
echo "  --oss-lib                path to OSS library"
......
1446 1462
[ ! -z "$uname_release" ] && \
1447 1463
echo "uname -r          $uname_release"
1448 1464
echo "NPTL support      $nptl"
1465
echo "GUEST_BASE        $guest_base"
1449 1466
echo "vde support       $vde"
1450 1467
echo "AIO support       $aio"
1451 1468
echo "IO thread         $io_thread"
......
2070 2087
if test "$target_user_only" = "yes" -a "$elfload32" = "yes"; then
2071 2088
  echo "TARGET_HAS_ELFLOAD32=y" >> $config_mak
2072 2089
fi
2090
if test "$target_user_only" = "yes" -a "$guest_base" = "yes"; then
2091
  echo "CONFIG_USE_GUEST_BASE=y" >> $config_mak
2092
fi
2073 2093
if test "$target_bsd_user" = "yes" ; then
2074 2094
  echo "CONFIG_BSD_USER=y" >> $config_mak
2075 2095
fi
b/cpu-all.h
624 624
/* On some host systems the guest address space is reserved on the host.
625 625
 * This allows the guest address space to be offset to a convenient location.
626 626
 */
627
//#define GUEST_BASE 0x20000000
628
#define GUEST_BASE 0
627
#if defined(CONFIG_USE_GUEST_BASE)
628
extern unsigned long guest_base;
629
extern int have_guest_base;
630
#define GUEST_BASE guest_base
631
#else
632
#define GUEST_BASE 0ul
633
#endif
629 634

  
630 635
/* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
631 636
#define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
b/linux-user/elfload.c
1545 1545
    info->mmap = 0;
1546 1546
    elf_entry = (abi_ulong) elf_ex.e_entry;
1547 1547

  
1548
#if defined(CONFIG_USE_GUEST_BASE)
1549
    /*
1550
     * In case where user has not explicitly set the guest_base, we
1551
     * probe here that should we set it automatically.
1552
     */
1553
    if (!have_guest_base) {
1554
        /*
1555
         * Go through ELF program header table and find out whether
1556
	 * any of the segments drop below our current mmap_min_addr and
1557
         * in that case set guest_base to corresponding address.
1558
         */
1559
        for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum;
1560
            i++, elf_ppnt++) {
1561
            if (elf_ppnt->p_type != PT_LOAD)
1562
                continue;
1563
            if (HOST_PAGE_ALIGN(elf_ppnt->p_vaddr) < mmap_min_addr) {
1564
                guest_base = HOST_PAGE_ALIGN(mmap_min_addr);
1565
                break;
1566
            }
1567
        }
1568
    }
1569
#endif /* CONFIG_USE_GUEST_BASE */
1570

  
1548 1571
    /* Do this so that we can load the interpreter, if need be.  We will
1549 1572
       change some of these later */
1550 1573
    info->rss = 0;
b/linux-user/main.c
39 39
char *exec_path;
40 40

  
41 41
int singlestep;
42
#if defined(CONFIG_USE_GUEST_BASE)
43
unsigned long mmap_min_addr;
44
unsigned long guest_base;
45
int have_guest_base;
46
#endif
42 47

  
43 48
static const char *interp_prefix = CONFIG_QEMU_PREFIX;
44 49
const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
......
2320 2325
           "-E var=value      sets/modifies targets environment variable(s)\n"
2321 2326
           "-U var            unsets targets environment variable(s)\n"
2322 2327
           "-0 argv0          forces target process argv[0] to be argv0\n"
2328
#if defined(CONFIG_USE_GUEST_BASE)
2329
           "-B address        set guest_base address to address\n"
2330
#endif
2323 2331
           "\n"
2324 2332
           "Debug options:\n"
2325 2333
           "-d options   activate log (logfile=%s)\n"
......
2495 2503
#endif
2496 2504
                exit(1);
2497 2505
            }
2506
#if defined(CONFIG_USE_GUEST_BASE)
2507
        } else if (!strcmp(r, "B")) {
2508
           guest_base = strtol(argv[optind++], NULL, 0);
2509
           have_guest_base = 1;
2510
#endif
2498 2511
        } else if (!strcmp(r, "drop-ld-preload")) {
2499 2512
            (void) envlist_unsetenv(envlist, "LD_PRELOAD");
2500 2513
        } else if (!strcmp(r, "singlestep")) {
......
2572 2585
    target_environ = envlist_to_environ(envlist, NULL);
2573 2586
    envlist_free(envlist);
2574 2587

  
2588
#if defined(CONFIG_USE_GUEST_BASE)
2589
    /*
2590
     * Now that page sizes are configured in cpu_init() we can do
2591
     * proper page alignment for guest_base.
2592
     */
2593
    guest_base = HOST_PAGE_ALIGN(guest_base);
2594

  
2595
    /*
2596
     * Read in mmap_min_addr kernel parameter.  This value is used
2597
     * When loading the ELF image to determine whether guest_base
2598
     * is needed.
2599
     *
2600
     * When user has explicitly set the quest base, we skip this
2601
     * test.
2602
     */
2603
    if (!have_guest_base) {
2604
        FILE *fp;
2605

  
2606
        if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
2607
            unsigned long tmp;
2608
            if (fscanf(fp, "%lu", &tmp) == 1) {
2609
                mmap_min_addr = tmp;
2610
                qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr);
2611
            }
2612
            fclose(fp);
2613
        }
2614
    }
2615
#endif /* CONFIG_USE_GUEST_BASE */
2616

  
2575 2617
    /*
2576 2618
     * Prepare copy of argv vector for target.
2577 2619
     */
......
2622 2664
    free(target_environ);
2623 2665

  
2624 2666
    if (qemu_log_enabled()) {
2667
#if defined(CONFIG_USE_GUEST_BASE)
2668
        qemu_log("guest_base  0x%lx\n", guest_base);
2669
#endif
2625 2670
        log_page_dump();
2626 2671

  
2627 2672
        qemu_log("start_brk   0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
b/linux-user/qemu.h
133 133
void task_settid(TaskState *);
134 134
void stop_all_tasks(void);
135 135
extern const char *qemu_uname_release;
136
#if defined(CONFIG_USE_GUEST_BASE)
137
extern unsigned long mmap_min_addr;
138
#endif
136 139

  
137 140
/* ??? See if we can avoid exposing so much of the loader internals.  */
138 141
/*
b/qemu-doc.texi
2026 2026
@subsection Command line options
2027 2027

  
2028 2028
@example
2029
usage: qemu-i386 [-h] [-d] [-L path] [-s size] [-cpu model] [-g port] program [arguments...]
2029
usage: qemu-i386 [-h] [-d] [-L path] [-s size] [-cpu model] [-g port] [-B offset] program [arguments...]
2030 2030
@end example
2031 2031

  
2032 2032
@table @option
......
2038 2038
Set the x86 stack size in bytes (default=524288)
2039 2039
@item -cpu model
2040 2040
Select CPU model (-cpu ? for list and additional feature selection)
2041
@item -B offset
2042
Offset guest address by the specified number of bytes.  This is useful when
2043
the address region rewuired by guest applications is reserved on the host.
2044
Ths option is currently only supported on some hosts.
2041 2045
@end table
2042 2046

  
2043 2047
Debug options:
b/tcg/arm/tcg-target.c
990 990
# endif
991 991

  
992 992
    *label_ptr += ((void *) s->code_ptr - (void *) label_ptr - 8) >> 2;
993
#else
993
#else /* !CONFIG_SOFTMMU */
994
    if (GUEST_BASE) {
995
        uint32_t offset = GUEST_BASE;
996
        int i;
997
        int rot;
998

  
999
        while (offset) {
1000
            i = ctz32(offset) & ~1;
1001
            rot = ((32 - i) << 7) & 0xf00;
1002

  
1003
            tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 8, addr_reg,
1004
                            ((offset >> i) & 0xff) | rot);
1005
            addr_reg = 8;
1006
            offset &= ~(0xff << i);
1007
        }
1008
    }
994 1009
    switch (opc) {
995 1010
    case 0:
996 1011
        tcg_out_ld8_12(s, COND_AL, data_reg, addr_reg, 0);
......
1200 1215
# endif
1201 1216

  
1202 1217
    *label_ptr += ((void *) s->code_ptr - (void *) label_ptr - 8) >> 2;
1203
#else
1218
#else /* !CONFIG_SOFTMMU */
1219
    if (GUEST_BASE) {
1220
        uint32_t offset = GUEST_BASE;
1221
        int i;
1222
        int rot;
1223

  
1224
        while (offset) {
1225
            i = ctz32(offset) & ~1;
1226
            rot = ((32 - i) << 7) & 0xf00;
1227

  
1228
            tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 8, addr_reg,
1229
                            ((offset >> i) & 0xff) | rot);
1230
            addr_reg = 8;
1231
            offset &= ~(0xff << i);
1232
        }
1233
    }
1204 1234
    switch (opc) {
1205 1235
    case 0:
1206 1236
        tcg_out_st8_12(s, COND_AL, data_reg, addr_reg, 0);
b/tcg/arm/tcg-target.h
60 60
#define TCG_TARGET_STACK_ALIGN		8
61 61
#define TCG_TARGET_CALL_STACK_OFFSET	0
62 62

  
63
#define TCG_TARGET_HAS_GUEST_BASE
64

  
63 65
enum {
64 66
    /* Note: must be synced with dyngen-exec.h */
65 67
    TCG_AREG0 = TCG_REG_R7,
b/tcg/i386/tcg-target.c
427 427
};
428 428
#endif
429 429

  
430
#ifndef CONFIG_USER_ONLY
431
#define GUEST_BASE 0
432
#endif
433

  
430 434
/* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
431 435
   EAX. It will be useful once fixed registers globals are less
432 436
   common. */
......
572 576
    switch(opc) {
573 577
    case 0:
574 578
        /* movzbl */
575
        tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, 0);
579
        tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, GUEST_BASE);
576 580
        break;
577 581
    case 0 | 4:
578 582
        /* movsbl */
579
        tcg_out_modrm_offset(s, 0xbe | P_EXT, data_reg, r0, 0);
583
        tcg_out_modrm_offset(s, 0xbe | P_EXT, data_reg, r0, GUEST_BASE);
580 584
        break;
581 585
    case 1:
582 586
        /* movzwl */
583
        tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
587
        tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, GUEST_BASE);
584 588
        if (bswap) {
585 589
            /* rolw $8, data_reg */
586 590
            tcg_out8(s, 0x66); 
......
590 594
        break;
591 595
    case 1 | 4:
592 596
        /* movswl */
593
        tcg_out_modrm_offset(s, 0xbf | P_EXT, data_reg, r0, 0);
597
        tcg_out_modrm_offset(s, 0xbf | P_EXT, data_reg, r0, GUEST_BASE);
594 598
        if (bswap) {
595 599
            /* rolw $8, data_reg */
596 600
            tcg_out8(s, 0x66); 
......
603 607
        break;
604 608
    case 2:
605 609
        /* movl (r0), data_reg */
606
        tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
610
        tcg_out_modrm_offset(s, 0x8b, data_reg, r0, GUEST_BASE);
607 611
        if (bswap) {
608 612
            /* bswap */
609 613
            tcg_out_opc(s, (0xc8 + data_reg) | P_EXT);
......
619 623
            r0 = r1;
620 624
        }
621 625
        if (!bswap) {
622
            tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
623
            tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, 4);
626
            tcg_out_modrm_offset(s, 0x8b, data_reg, r0, GUEST_BASE);
627
            tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, GUEST+BASE + 4);
624 628
        } else {
625
            tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 4);
629
            tcg_out_modrm_offset(s, 0x8b, data_reg, r0, GUEST_BASE + 4);
626 630
            tcg_out_opc(s, (0xc8 + data_reg) | P_EXT);
627 631

  
628
            tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, 0);
632
            tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, GUEST_BASE);
629 633
            /* bswap */
630 634
            tcg_out_opc(s, (0xc8 + data_reg2) | P_EXT);
631 635
        }
......
806 810
    switch(opc) {
807 811
    case 0:
808 812
        /* movb */
809
        tcg_out_modrm_offset(s, 0x88, data_reg, r0, 0);
813
        tcg_out_modrm_offset(s, 0x88, data_reg, r0, GUEST_BASE);
810 814
        break;
811 815
    case 1:
812 816
        if (bswap) {
......
818 822
        }
819 823
        /* movw */
820 824
        tcg_out8(s, 0x66);
821
        tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
825
        tcg_out_modrm_offset(s, 0x89, data_reg, r0, GUEST_BASE);
822 826
        break;
823 827
    case 2:
824 828
        if (bswap) {
......
828 832
            data_reg = r1;
829 833
        }
830 834
        /* movl */
831
        tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
835
        tcg_out_modrm_offset(s, 0x89, data_reg, r0, GUEST_BASE);
832 836
        break;
833 837
    case 3:
834 838
        if (bswap) {
835 839
            tcg_out_mov(s, r1, data_reg2);
836 840
            /* bswap data_reg */
837 841
            tcg_out_opc(s, (0xc8 + r1) | P_EXT);
838
            tcg_out_modrm_offset(s, 0x89, r1, r0, 0);
842
            tcg_out_modrm_offset(s, 0x89, r1, r0, GUEST_BASE);
839 843
            tcg_out_mov(s, r1, data_reg);
840 844
            /* bswap data_reg */
841 845
            tcg_out_opc(s, (0xc8 + r1) | P_EXT);
842
            tcg_out_modrm_offset(s, 0x89, r1, r0, 4);
846
            tcg_out_modrm_offset(s, 0x89, r1, r0, GUEST_BASE + 4);
843 847
        } else {
844
            tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
845
            tcg_out_modrm_offset(s, 0x89, data_reg2, r0, 4);
848
            tcg_out_modrm_offset(s, 0x89, data_reg, r0, GUEST_BASE);
849
            tcg_out_modrm_offset(s, 0x89, data_reg2, r0, GUEST_BASE + 4);
846 850
        }
847 851
        break;
848 852
    default:
b/tcg/i386/tcg-target.h
53 53
#define TCG_TARGET_HAS_ext16s_i32
54 54
#define TCG_TARGET_HAS_rot_i32
55 55

  
56
#define TCG_TARGET_HAS_GUEST_BASE
57

  
56 58
/* Note: must be synced with dyngen-exec.h */
57 59
#define TCG_AREG0 TCG_REG_EBP
58 60
#define TCG_AREG1 TCG_REG_EBX
b/tcg/tcg.c
46 46

  
47 47
#include "qemu-common.h"
48 48
#include "cache-utils.h"
49
#include "host-utils.h"
49 50

  
50 51
/* Note: the long term plan is to reduce the dependancies on the QEMU
51 52
   CPU definitions. Currently they are used for qemu_ld/st
......
57 58
#include "tcg-op.h"
58 59
#include "elf.h"
59 60

  
61
#if defined(CONFIG_USE_GUEST_BASE) && !defined(TCG_TARGET_HAS_GUEST_BASE)
62
#error GUEST_BASE not supported on this host.
63
#endif
60 64

  
61 65
static void patch_reloc(uint8_t *code_ptr, int type, 
62 66
                        tcg_target_long value, tcg_target_long addend);
b/tcg/x86_64/tcg-target.c
508 508
                            int opc)
509 509
{
510 510
    int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw;
511
    int32_t offset;
511 512
#if defined(CONFIG_SOFTMMU)
512 513
    uint8_t *label1_ptr, *label2_ptr;
513 514
#endif
......
604 605
    /* add x(r1), r0 */
605 606
    tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) - 
606 607
                         offsetof(CPUTLBEntry, addr_read));
608
    offset = 0;
607 609
#else
608
    r0 = addr_reg;
610
    if (GUEST_BASE == (int32_t)GUEST_BASE) {
611
        r0 = addr_reg;
612
        offset = GUEST_BASE;
613
    } else {
614
        offset = 0;
615
        /* movq $GUEST_BASE, r0 */
616
        tcg_out_opc(s, (0xb8 + (r0 & 7)) | P_REXW, 0, r0, 0);
617
        tcg_out32(s, GUEST_BASE);
618
        tcg_out32(s, GUEST_BASE >> 32);
619
        /* addq addr_reg, r0 */
620
        tcg_out_modrm(s, 0x01 | P_REXW, addr_reg, r0);
621
    }
609 622
#endif    
610 623

  
611 624
#ifdef TARGET_WORDS_BIGENDIAN
......
616 629
    switch(opc) {
617 630
    case 0:
618 631
        /* movzbl */
619
        tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, 0);
632
        tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, offset);
620 633
        break;
621 634
    case 0 | 4:
622 635
        /* movsbX */
623
        tcg_out_modrm_offset(s, 0xbe | P_EXT | rexw, data_reg, r0, 0);
636
        tcg_out_modrm_offset(s, 0xbe | P_EXT | rexw, data_reg, r0, offset);
624 637
        break;
625 638
    case 1:
626 639
        /* movzwl */
627
        tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
640
        tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, offset);
628 641
        if (bswap) {
629 642
            /* rolw $8, data_reg */
630 643
            tcg_out8(s, 0x66); 
......
635 648
    case 1 | 4:
636 649
        if (bswap) {
637 650
            /* movzwl */
638
            tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
651
            tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, offset);
639 652
            /* rolw $8, data_reg */
640 653
            tcg_out8(s, 0x66); 
641 654
            tcg_out_modrm(s, 0xc1, 0, data_reg);
......
645 658
            tcg_out_modrm(s, 0xbf | P_EXT | rexw, data_reg, data_reg);
646 659
        } else {
647 660
            /* movswX */
648
            tcg_out_modrm_offset(s, 0xbf | P_EXT | rexw, data_reg, r0, 0);
661
            tcg_out_modrm_offset(s, 0xbf | P_EXT | rexw, data_reg, r0, offset);
649 662
        }
650 663
        break;
651 664
    case 2:
652 665
        /* movl (r0), data_reg */
653
        tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
666
        tcg_out_modrm_offset(s, 0x8b, data_reg, r0, offset);
654 667
        if (bswap) {
655 668
            /* bswap */
656 669
            tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0);
......
659 672
    case 2 | 4:
660 673
        if (bswap) {
661 674
            /* movl (r0), data_reg */
662
            tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
675
            tcg_out_modrm_offset(s, 0x8b, data_reg, r0, offset);
663 676
            /* bswap */
664 677
            tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0);
665 678
            /* movslq */
666 679
            tcg_out_modrm(s, 0x63 | P_REXW, data_reg, data_reg);
667 680
        } else {
668 681
            /* movslq */
669
            tcg_out_modrm_offset(s, 0x63 | P_REXW, data_reg, r0, 0);
682
            tcg_out_modrm_offset(s, 0x63 | P_REXW, data_reg, r0, offset);
670 683
        }
671 684
        break;
672 685
    case 3:
673 686
        /* movq (r0), data_reg */
674
        tcg_out_modrm_offset(s, 0x8b | P_REXW, data_reg, r0, 0);
687
        tcg_out_modrm_offset(s, 0x8b | P_REXW, data_reg, r0, offset);
675 688
        if (bswap) {
676 689
            /* bswap */
677 690
            tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT | P_REXW, 0, data_reg, 0);
......
691 704
                            int opc)
692 705
{
693 706
    int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw;
707
    int32_t offset;
694 708
#if defined(CONFIG_SOFTMMU)
695 709
    uint8_t *label1_ptr, *label2_ptr;
696 710
#endif
......
775 789
    /* add x(r1), r0 */
776 790
    tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) - 
777 791
                         offsetof(CPUTLBEntry, addr_write));
792
    offset = 0;
778 793
#else
779
    r0 = addr_reg;
794
    if (GUEST_BASE == (int32_t)GUEST_BASE) {
795
        r0 = addr_reg;
796
        offset = GUEST_BASE;
797
    } else {
798
        offset = 0;
799
        /* movq $GUEST_BASE, r0 */
800
        tcg_out_opc(s, (0xb8 + (r0 & 7)) | P_REXW, 0, r0, 0);
801
        tcg_out32(s, GUEST_BASE);
802
        tcg_out32(s, GUEST_BASE >> 32);
803
        /* addq addr_reg, r0 */
804
        tcg_out_modrm(s, 0x01 | P_REXW, addr_reg, r0);
805
    }
780 806
#endif
781 807

  
782 808
#ifdef TARGET_WORDS_BIGENDIAN
......
787 813
    switch(opc) {
788 814
    case 0:
789 815
        /* movb */
790
        tcg_out_modrm_offset(s, 0x88 | P_REXB, data_reg, r0, 0);
816
        tcg_out_modrm_offset(s, 0x88 | P_REXB, data_reg, r0, offset);
791 817
        break;
792 818
    case 1:
793 819
        if (bswap) {
......
799 825
        }
800 826
        /* movw */
801 827
        tcg_out8(s, 0x66);
802
        tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
828
        tcg_out_modrm_offset(s, 0x89, data_reg, r0, offset);
803 829
        break;
804 830
    case 2:
805 831
        if (bswap) {
......
809 835
            data_reg = r1;
810 836
        }
811 837
        /* movl */
812
        tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
838
        tcg_out_modrm_offset(s, 0x89, data_reg, r0, offset);
813 839
        break;
814 840
    case 3:
815 841
        if (bswap) {
......
819 845
            data_reg = r1;
820 846
        }
821 847
        /* movq */
822
        tcg_out_modrm_offset(s, 0x89 | P_REXW, data_reg, r0, 0);
848
        tcg_out_modrm_offset(s, 0x89 | P_REXW, data_reg, r0, offset);
823 849
        break;
824 850
    default:
825 851
        tcg_abort();
b/tcg/x86_64/tcg-target.h
73 73
#define TCG_TARGET_HAS_rot_i32
74 74
#define TCG_TARGET_HAS_rot_i64
75 75

  
76
#define TCG_TARGET_HAS_GUEST_BASE
77

  
76 78
/* Note: must be synced with dyngen-exec.h */
77 79
#define TCG_AREG0 TCG_REG_R14
78 80
#define TCG_AREG1 TCG_REG_R15

Also available in: Unified diff