qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Weil <weil@mail.berlios.de>
To: Blue Swirl <blauwirbel@gmail.com>
Cc: QEMU Developers <qemu-devel@nongnu.org>
Subject: [Qemu-devel] Re: Porting QEMU to new hosts with unusual ABI (sizeof(long) != sizeof(void *))
Date: Sat, 05 Feb 2011 22:47:28 +0100	[thread overview]
Message-ID: <4D4DC570.8080204@mail.berlios.de> (raw)
In-Reply-To: <AANLkTimvRwJJfMjJQdGkiWrV6ONqcb6KbtfURx0ucOk-@mail.gmail.com>

Am 05.02.2011 16:35, schrieb Blue Swirl:
> On Sat, Feb 5, 2011 at 2:39 PM, Stefan Weil <weil@mail.berlios.de> wrote:
>> Currently, most QEMU code assumes that pointers and long integers have
>> the same size, typically 32 bit on 32 bit hosts, 64 bit on 64 bit hosts.
>>
>> While this assumption works on QEMU's major hosts, it is not 
>> generally true.
>>
>> There exist 64 bit host OS which use an ABI with 32 bit long integers,
>> maybe to be more compatible with an older 32 bit OS version, so here is
>> sizeof(long) < sizeof(void *).
>
> Oh, that OS-Which-Must-Not-Be-Named.

Right.

>
>> Other ABIs might use "near" pointers which may reduce code size and 
>> improve
>> code speed. This results in sizeof(long) > sizeof(void *).
>>
>> Both cases will break current QEMU, because lots of code lines use
>> type casts from pointer to long or vice versa like these two examples:
>>
>> start = (long)mmap((void *)host_start, host_len ...
>> code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + ...))
>>
>> Both variants (unsigned long) and (long) can be found (relation 3:2).
>>
>> Changing the existing limitation of QEMU's code simply needs replacing
>> all those type casts, variable declarations and printf format specifiers
>> by portable code.
>>
>> The standard integral type which matches the size of a pointer is defined
>> in stdint.h (which also defines int8_t, ...). It is intptr_t (signed
>> version)
>> or uintptr_t (unsigned version). There is no need to use both.
>>
>> => Replace (unsigned long), (long) type casts of pointers by (uintptr_t).
>>
>> All variables (auto, struct members, parameters) which hold such values
>> must be fixed, too. In the following examples, ptr_var is of that kind.
>>
>> => Replace unsigned long ptr_var, long ptr_var by uintptr_t ptr_var.
>>
>> Finally, the fixed variables are used in printf-like statements,
>> so here the format specifier needs a change. inttypes.h defines
>> PRIxPTR which should be used.
>>
>> => Replace "%lx" by "%" PRIxPTR to print the integer value ptr_var.
>>
>> A single patch which includes all these changes touches 39 files.
>> Splitting it into smaller patches is not trivial because of cross
>> dependencies. Because of its size, it will raise merge conflicts
>> when it is not applied soon.
>>
>> Would these kind of changes be interesting for QEMU?
>
> Does QEMU work in OS-Which-Must-Not-Be-Named when the patch is applied?

Up to now, I never used OS-Which-Must-Not-Be-Named (64 bit) :-)
The patch allows to build executables (which I have put on my
web page).

I noticed two remaining problems with time_t and GetProcessAffinityMask.
Maybe these are not critical, but of course they have to be fixed, too.

>> Are there suggestions how it should be done?
>
> The change, done properly, should not cause any problems for most
> other hosts, where unsigned long size equals pointer type size.

That's correct. The risk of breaking current hosts is minimal.

>> What about ram_addr_t? Should it be replaced by uintptr_t?
>
> I'd use
> typedef uintptr_t ram_addr_t;

So did I. We could go further and eliminate ram_addr_t.

>> Should we use macros like QEMU_PTR2UINT(p), QEMU_UINT2PTR(u)?
>
> Rather, inline functions if open coding is not clear.
>
>> My current version of the patch is available from
>> http://qemu.weilnetz.de/0001-Fix-conversions-from-pointer-to-integral-type-and-vi.patch.
>
> Some comments:
>
> The patch changes also signed longs to uintptr_t. That could introduce
> regressions, so please use signed/unsigned as original.

I changed the code manually, and there was only one location where
signed/unsigned made a difference. That single case was an int
parameter passed in a void pointer, and I used intptr_t there.

I had the impression that in the current code (long) was
sometimes used because it is shorter than (unsigned long) :-)

As long as changes are made manually with the necessary care,
I'd recommend using uintptr_t where possible.

>
> For example in cpu_physical_memory_reset_dirty() you didn't change
> length, but that should probably become uintptr_t too.

Yes, that would be better (even if dirty memory ranges > 4 GiB
are not common). I'll change that.

>
> */translate.c: exit_tb() helper uses tcg_target_long, so the cast
> should use that instead.

Obviously tcg_target_long has the same size as uintptr_t,
so I can change this, too.

Regards,
Stefan

  reply	other threads:[~2011-02-05 21:47 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-05 14:39 [Qemu-devel] Porting QEMU to new hosts with unusual ABI (sizeof(long) != sizeof(void *)) Stefan Weil
2011-02-05 15:35 ` [Qemu-devel] " Blue Swirl
2011-02-05 21:47   ` Stefan Weil [this message]
2011-02-07  7:23     ` Markus Armbruster
2011-02-07 17:51       ` Stefan Weil
2011-02-07 18:16         ` Markus Armbruster
2011-02-05 16:03 ` [Qemu-devel] " Stefan Hajnoczi
2011-02-05 17:40   ` Stefan Weil
2011-02-11  5:05 ` Rob Landley
2011-02-11 12:47   ` [Qemu-devel] " Paolo Bonzini
2011-02-11 13:04     ` Tristan Gingold
2011-02-11 18:50     ` Blue Swirl
2011-02-11 19:28       ` malc
2011-02-11  8:24 ` [Qemu-devel] " Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4D4DC570.8080204@mail.berlios.de \
    --to=weil@mail.berlios.de \
    --cc=blauwirbel@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).