[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Swarm-Support] x86_64 and message forwarding
From: |
Marcus Daniels |
Subject: |
[Swarm-Support] x86_64 and message forwarding |
Date: |
Sun, 27 Aug 2006 18:04:29 -0600 |
User-agent: |
Thunderbird 1.5.0.5 (X11/20060808) |
Bill Northcott wrote:
Marcus Daniels wrote:
Paul Johnson wrote: The objective C support with these new RPMs
works fine. I did not test
the Java version.
I know there are problems with Java message forwarding on x86_64, but
i386
seems to works fine.
Is this a problem with avcall/libffi? I am trying to get libffi to
work for Darwin x86 and x86_64 but I don't have a machine to test the
latter.
I can test on AMD64/Linux, but unfortunately there's more to it than
finding the right frame offsets.
Traditionally, GCC compiles-in information on the call frame it uses for
Objective C calls. For applications like distributed objects or
inter-language message forwarding, application code can use those
strings to understand the frame.
For example, if you run "make check" in tests/defobj, on an AMD64 Linux
system you'll get a failure that ends with
m1: [1 0 0]. Just above that on the right, you'll see two copies of the
same string:
{r*@:ifd} address@hidden:address@hidden:8i16f20d24}
but what it should be is this:
{r*@:ifd} address@hidden:address@hidden:+8i+16f+48d+64}
The left variant. "address@hidden:8i16f20d24" means "expect to return a string
in offset 32 of the stack". Expect to find these objects on the stack
At position 0, an object
At position 8, a selector
At position 16, an integer
At position 20, a single precision floating point number
At position 24, a double precision floating point number
Unfortunately, the x86_64 calling conventions fill up registers
instead. With that `m1' check in tests/defobj it should be
"address@hidden:+8i+16f+48d+64"
The "+" signs mean to populate the registers instead of the stack.
Also, the layout differs per page 15 of this:
http://www.x86-64.org/documentation/abi-0.96.pdf
The point is the compiler isn't telling us what it really did!
Here's a test case that compares x86 to x86_64. Compare the offsets in
the `forward' call with the Objective C signatures shown in the two
"#if" cases. i386 follows what the compiler does, but x86_64 does not.
Note this doesn't link against Swarm or use Swarm headers -- it's just
straight Objective C.
I haven't tried to compile the program below on MacOS X with the GNU
runtime. I'd be interested to know what typing string it comes up
with.. I expect it will be the same as that MacOS X probably shares
most of the same GCC compiler code.
As for what to do about this, I can think of several options:
1) Depend on gnustep libraries that don't use mframe (that won't work if
they rely on the same compiler metadata as mframe).
2) Depend on vacall, ignoring the register/stack offsets but using the
types provided from the compiler (which are correct)
3) improve the compiler
Marcus
#include <objc/Object.h>
id obj = nil;
@interface Alt: Object
{
}
@end
@implementation Alt
- (retval_t)forward: (SEL)aSel : (arglist_t)argFrame
{
#ifdef __i386__
/* GCC reports: address@hidden:4f8i12i16d20 */
int base = 32;
printf ("%p\n", * (void **) ((void *) argFrame + base + 0));
printf ("%s\n", sel_get_name (*(SEL *) ((void *) argFrame + base + 4)));
printf ("a: %f\n", *(float *) ((void *) argFrame + base + 8));
printf ("b: %d\n", *(int *) ((void *) argFrame + base + 12));
printf ("c: %d\n", *(int *) ((void *) argFrame + base + 16));
printf ("d: %f\n", *(double *) ((void *) argFrame + base + 20));
#elif defined(__x86_64__)
/* GCC reports: address@hidden:8f16i20i24d28 */
printf ("%p\n", *(void **) ((void *) argFrame + 40));
printf ("%s\n", sel_get_name (*(SEL *) ((void *) argFrame + 32)));
printf ("a: %f\n", *(float *) ((void *) argFrame + 48));
printf ("b: %d\n", *(int *) ((void *) argFrame + 16));
printf ("c: %d\n", *(int *) ((void *) argFrame + 24));
printf ("d: %f\n", *(double *) ((void *) argFrame + 64));
#endif
return 0;
}
@end
@interface Test: Object
- (void)fooBar: (float)a val2: (int)b val3: (int)c val4: (double)d;
@end
@implementation Test
- (void)fooBar: (float)a val2: (int)b val3: (int)c val4: (double)d;
{
printf ("%f %d %d %f\n", a, b, c, d);
}
@end
int
main (int argc, const char **argv)
{
[[[Test alloc] init] fooBar: 1 val2: 2 val3: 3 val4: 4.0];
printf ("%s\n", sel_get_type (sel_get_any_typed_uid (sel_get_name
(@selector (fooBar:val2:val3:val4:)))));
obj = [[Alt alloc] init];
printf ("target object: %p\n", obj);
[obj fooBar: 11.0 val2: 22 val3: 33 val4: 44.0];
}
- [Swarm-Support] Fedora Core users: Swarm-2.2.3 RPMS posted, solved lispAppArchiver problem, Paul Johnson, 2006/08/22
- Re: [Swarm-Support] Fedora Core users: Swarm-2.2.3 RPMS posted, solved lispAppArchiver problem, mgd, 2006/08/22
- Message not available
- Message not available
- [Swarm-Support] x86_64 and message forwarding,
Marcus Daniels <=
- Re: [Swarm-Support] x86_64 and message forwarding, Bill Northcott, 2006/08/27
- Re: [Swarm-Support] x86_64 and message forwarding, Marcus G. Daniels, 2006/08/27
- Re: [Swarm-Support] x86_64 and message forwarding, Bill Northcott, 2006/08/28
- Re: [Swarm-Support] x86_64 and message forwarding, Marcus Daniels, 2006/08/28
- Re: [Swarm-Support] x86_64 and message forwarding, mgd, 2006/08/29
- Re: [Swarm-Support] x86_64 and message forwarding, Bill Northcott, 2006/08/29
- Re: [Swarm-Support] x86_64 and message forwarding, Marcus G. Daniels, 2006/08/29
- Message not available
- Re: [Swarm-Support] x86_64 and message forwarding, Paul Johnson, 2006/08/30
- Re: [Swarm-Support] x86_64 and message forwarding, mgd, 2006/08/30
Re: [Swarm-Support] Fedora Core users: Swarm-2.2.3 RPMS posted, solved lispAppArchiver problem, Pietro Terna, 2006/08/31