9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] more on why vc can't produce amd64 executables
@ 2013-08-21 18:36 erik quanstrom
  2013-08-21 18:49 ` Bakul Shah
  0 siblings, 1 reply; 8+ messages in thread
From: erik quanstrom @ 2013-08-21 18:36 UTC (permalink / raw)
  To: 9fans

vc vlongs are broken for cast

for example, _v2uc produces the code:

acid; asm(_v2uc)
_v2uc 0x00005360	MOVW	rv+8(FP),R1
_v2uc+0x4 0x00005364	JMP	(R31)
_v2uc+0x8 0x00005368	AND	$0xff,R1

i think this should be
	MOVW	rv+12(FP),R1
	JMP	(R31)
	AND	$0xff,R1

since the high 32-bits of the vlong should be first, since
this is a BE machine.  perhaps there's supposed to be a
special calling convention for vlongs?

here's an example of the issue:

void
main(void)
{
	uvlong x;

	x = 0x012345678abcdefull;
	print("(uchar)x	%.2ux\n", (uchar)x);
	exits("");
}

mikro; v.x
x = 0012345678abcdef
(uchar)x	ef

marshalling a 64-bit pointer in this way will lay down the
bytes with the hi and lo reversed.

- erik



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [9fans] more on why vc can't produce amd64 executables
  2013-08-21 18:36 [9fans] more on why vc can't produce amd64 executables erik quanstrom
@ 2013-08-21 18:49 ` Bakul Shah
  2013-08-21 18:57   ` erik quanstrom
  0 siblings, 1 reply; 8+ messages in thread
From: Bakul Shah @ 2013-08-21 18:49 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

On Wed, 21 Aug 2013 14:36:40 EDT erik quanstrom <quanstro@quanstro.net> wrote:
> 	uvlong x;
>
> 	x = 0x012345678abcdefull;
> 	print("(uchar)x	%.2ux\n", (uchar)x);
...
> x = 0012345678abcdef
> (uchar)x	ef

You're casting a large int into a small int and this seems right.
Just as (uchar)0x1234 => 0x34

> marshalling a 64-bit pointer in this way will lay down the
> bytes with the hi and lo reversed.

Perhaps you meant to do *(uchar*)&x?




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [9fans] more on why vc can't produce amd64 executables
  2013-08-21 18:49 ` Bakul Shah
@ 2013-08-21 18:57   ` erik quanstrom
  2013-08-21 19:25     ` Bakul Shah
  0 siblings, 1 reply; 8+ messages in thread
From: erik quanstrom @ 2013-08-21 18:57 UTC (permalink / raw)
  To: 9fans

> You're casting a large int into a small int and this seems right.
> Just as (uchar)0x1234 => 0x34
>
> > marshalling a 64-bit pointer in this way will lay down the
> > bytes with the hi and lo reversed.
>
> Perhaps you meant to do *(uchar*)&x?

you're right.  what was i thinking.  still, pointers are marshaled wrong.
compiled on mips, this program

#include <u.h>
#include <libc.h>

void
main(void)
{
	char *p;

	p = malloc(100);
	print("%p\n", p);
}
does this
; 6.crash
6.crash 203443: suicide: sys: trap: #SS pc=0x2048f2

- erik



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [9fans] more on why vc can't produce amd64 executables
  2013-08-21 18:57   ` erik quanstrom
@ 2013-08-21 19:25     ` Bakul Shah
  2013-08-21 19:29       ` erik quanstrom
  2013-08-21 21:44       ` erik quanstrom
  0 siblings, 2 replies; 8+ messages in thread
From: Bakul Shah @ 2013-08-21 19:25 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs


On Aug 21, 2013, at 11:57 AM, erik quanstrom <quanstro@quanstro.net> wrote:

>> You're casting a large int into a small int and this seems right.
>> Just as (uchar)0x1234 => 0x34
>>
>>> marshalling a 64-bit pointer in this way will lay down the
>>> bytes with the hi and lo reversed.
>>
>> Perhaps you meant to do *(uchar*)&x?

Incidentally, on a little endian machine you'd still get
0xef out of 0x0123456789abcdefull!

>
> you're right.  what was i thinking.  still, pointers are marshaled wrong.

> compiled on mips, this program
>
> #include <u.h>
> #include <libc.h>
>
> void
> main(void)
> {
> 	char *p;
>
> 	p = malloc(100);
> 	print("%p\n", p);
> }

> does this
> ; 6.crash
> 6.crash 203443: suicide: sys: trap: #SS pc=0x2048f2

How %p is treated is really upto the implementation but
it should not crash since p is never dereferenced. Does
this work?

	uintptr q;
	print("%p", q);







^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [9fans] more on why vc can't produce amd64 executables
  2013-08-21 19:25     ` Bakul Shah
@ 2013-08-21 19:29       ` erik quanstrom
  2013-08-21 21:44       ` erik quanstrom
  1 sibling, 0 replies; 8+ messages in thread
From: erik quanstrom @ 2013-08-21 19:29 UTC (permalink / raw)
  To: 9fans

> How %p is treated is really upto the implementation but
> it should not crash since p is never dereferenced. Does
> this work?
>
> 	uintptr q;
> 	print("%p", q);

no.  if i change the print to print an integer, it still fails.

in fact, it's really the indirect call in print that fails.
this is the instruction

	CALL	*AX

acid; *AX
0x002014b300000000
acid; src(*AX>>32)
/sys/src/libc/fmt/dofmt.c:310
 305		return _fmtrcpy(f, x, 1);
 306	}
 307
 308	/* fmt an integer */
 309	int
>310	_ifmt(Fmt *f)
 311	{
 312		char buf[88], *p, *conv;
 313		uvlong vu;
 314		ulong u;
 315		uintptr pu;

- erik



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [9fans] more on why vc can't produce amd64 executables
  2013-08-21 19:25     ` Bakul Shah
  2013-08-21 19:29       ` erik quanstrom
@ 2013-08-21 21:44       ` erik quanstrom
  2013-08-22 15:32         ` Bakul Shah
  1 sibling, 1 reply; 8+ messages in thread
From: erik quanstrom @ 2013-08-21 21:44 UTC (permalink / raw)
  To: 9fans

#include <u.h>
#include <libc.h>

void
f(void)
{
	write(1, "hello\n", 6);
}

void (*call)(void) = f;

void
main(void)
{
	call();
	exits("");
}

the asm is the same when compiled on any arch,

; acid 6.crash4-mips
6.crash4-mips:amd64 plan 9 executable
/sys/lib/acid/port
/sys/lib/acid/amd64
acid; asm(main)
main 0x0020004e	SUBQ	$0x8,SP
main+0x4 0x00200052	MOVQ	call(SB),AX
main+0xc 0x0020005a	CALL*	AX
main+0xe 0x0020005c	MOVL	$.string+0x7(SB),BP
main+0x13 0x00200061	CALL	exits(SB)
main+0x18 0x00200066	ADDQ	$0x8,SP
main+0x1c 0x0020006a	RET
_main 0x0020006b	SUBQ	$0x90,SP

but the data is incorrect in the mips-compiled binary.
	acid; *(call\Y)
	0x0020002800000000

mikro; diff -c crash4-mipsa crash4-amd64a
crash4-mipsa:417,423 - crash4-amd64a:417,423
  2005af 48c7c532000000	(4)	MOVQ	$50,BP
  2005b6 0f05	(5)	SYSCALL	,
  2005b8 c3	(6)	RET	,
- 400010 0000000028002000	(823)	DATA	call+0(SB)/8,$f+0(SB)
+ 400010 2800200000000000	(823)	DATA	call+0(SB)/8,$f+0(SB)
  400030 68656c6c6f0a0000	(829)	DATA	.string<1>+0(SB)/8,$"hello\n\z\z"
  400028 6d61696e	(18)	DATA	_exits<2>+0(SB)/4,$"main\z\z\z\z"
  400000 23632f7069640000	(829)	DATA	.string<7>+0(SB)/8,$"#c/pid\z\z"

i think a bug is setting inuxi8[i+4] = inuxi8[i] for 0<=i<4.
mikro; diffy -c *.c
diff -c /n/dump/2013/0821/sys/src/cmd/6l/obj.c obj.c
/n/dump/2013/0821/sys/src/cmd/6l/obj.c:1455,1471 - obj.c:1455,1471
  	int i, c;

  	for(i=0; i<4; i++) {
- 		c = find1(0x04030201L, i+1);
+ 		c = find1(0x0807060504030201ULL, i+1);
  		if(i < 2)
  			inuxi2[i] = c;
  		if(i < 1)
  			inuxi1[i] = c;
- 		inuxi4[i] = c;
+ 		if(i < 4){
+ 			inuxi4[i] = c;
+ 			fnuxi4[i] = c;
+ 		}
  		inuxi8[i] = c;
- 		inuxi8[i+4] = c+4;
- 		fnuxi4[i] = c;
  		fnuxi8[i] = c;
- 		fnuxi8[i+4] = c+4;
  	}
  	if(debug['v']) {
  		Bprint(&bso, "inuxi = ");
/n/dump/2013/0821/sys/src/cmd/6l/obj.c:1492,1504 - obj.c:1492,1504
  }

  int
- find1(long l, int c)
+ find1(uvlong l, int c)
  {
  	char *p;
  	int i;

  	p = (char*)&l;
- 	for(i=0; i<4; i++)
+ 	for(i=0; i<8; i++)
  		if(*p++ == c)
  			return i;
  	return 0;
/n/dump/2013/0821/sys/src/cmd/6l/obj.c:1505,1517 - obj.c:1505,1517
  }

  int
- find2(long l, int c)
+ find2(uvlong l, int c)
  {
  	short *p;
  	int i;

  	p = (short*)&l;
- 	for(i=0; i<4; i+=2) {
+ 	for(i=0; i<8; i+=2) {
  		if(((*p >> 8) & 0xff) == c)
  			return i;
  		if((*p++ & 0xff) == c)


unfortunately, compiling on mips *still* doesn't work right.
print prints %%p for %p.  i don't know if my fix is wrong, or
if there is another bug.

- erik



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [9fans] more on why vc can't produce amd64 executables
  2013-08-21 21:44       ` erik quanstrom
@ 2013-08-22 15:32         ` Bakul Shah
  2013-08-22 16:54           ` erik quanstrom
  0 siblings, 1 reply; 8+ messages in thread
From: Bakul Shah @ 2013-08-22 15:32 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

On Wed, 21 Aug 2013 17:44:03 EDT erik quanstrom <quanstro@quanstro.net> wrote:
>
> i think a bug is setting inuxi8[i+4] = inuxi8[i] for 0<=i<4.
> mikro; diffy -c *.c
> diff -c /n/dump/2013/0821/sys/src/cmd/6l/obj.c obj.c
> /n/dump/2013/0821/sys/src/cmd/6l/obj.c:1455,1471 - obj.c:1455,1471
>   	int i, c;
>
>   	for(i=0; i<4; i++) {
> - 		c = find1(0x04030201L, i+1);
> + 		c = find1(0x0807060504030201ULL, i+1);

Why not
	for(i=0; i<8; i++) {
Else what is the point of
		c = find1(0x0807060504030201ULL, i+1);
Just eyeballing. I haven't looked at the actual code.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [9fans] more on why vc can't produce amd64 executables
  2013-08-22 15:32         ` Bakul Shah
@ 2013-08-22 16:54           ` erik quanstrom
  0 siblings, 0 replies; 8+ messages in thread
From: erik quanstrom @ 2013-08-22 16:54 UTC (permalink / raw)
  To: 9fans

> > i think a bug is setting inuxi8[i+4] = inuxi8[i] for 0<=i<4.
> > mikro; diffy -c *.c
> > diff -c /n/dump/2013/0821/sys/src/cmd/6l/obj.c obj.c
> > /n/dump/2013/0821/sys/src/cmd/6l/obj.c:1455,1471 - obj.c:1455,1471
> >   	int i, c;
> >
> >   	for(i=0; i<4; i++) {
> > - 		c = find1(0x04030201L, i+1);
> > + 		c = find1(0x0807060504030201ULL, i+1);
>
> Why not
> 	for(i=0; i<8; i++) {
> Else what is the point of
> 		c = find1(0x0807060504030201ULL, i+1);
> Just eyeballing. I haven't looked at the actual code.

as it turns out, floating point is already swapped by Ieee, and
anything less than or equal to 4 bytes is cast uprated to a ulong,
not a uvlong.

this version produces the same output with -a as on amd64.

i think it's a little more clear to straightforwardly set up the nuxi,
and special case the word-swapping in the floating point.
ideally, the low and high words would be merged to a vlong.

this fix likely won't survive its encounter with review intact, but
at least for now i can compile amd64 binaries on mips.
once a final form is in place a fix should be applied to all
compilers.

- erik

----
/n/atom/plan9/sys/src/cmd/6l/obj.c:1449,1472 - obj.c:1449,1482
  	}
  }

+ static uvlong lorder = 0x0706050403020100ull;
+
  void
+ letab(uchar *t, int w, int n)
+ {
+ 	uchar *o;
+ 	uint i;
+
+ 	o = (uchar*)&lorder;
+ 	o += (o[0]!=0)*(8-w);		/* if big endian, use tail not head */
+ 	for(i = 0; i < n; i++)
+ 		t[i] = o[i];
+ }
+
+ void
  nuxiinit(void)
  {
- 	int i, c;
+ 	int i;

- 	for(i=0; i<4; i++) {
- 		c = find1(0x04030201L, i+1);
- 		if(i < 2)
- 			inuxi2[i] = c;
- 		if(i < 1)
- 			inuxi1[i] = c;
- 		inuxi4[i] = c;
- 		inuxi8[i] = c;
- 		inuxi8[i+4] = c+4;
- 		fnuxi4[i] = c;
- 		fnuxi8[i] = c;
- 		fnuxi8[i+4] = c+4;
- 	}
+ 	letab(inuxi1, 4, 1);			/* cast to 4 bytes, 1 byte tab */
+ 	letab(inuxi2, 4, 2);
+ 	letab(inuxi4, 4, 4);
+ 	letab(inuxi8, 8, 8);
+ 	letab(fnuxi4, 4, 4);
+ 	letab(fnuxi8, 4, 4);		/* undo Ieee swapping. */
+ 	for(i = 4; i < 8; i++)
+ 		fnuxi8[i] = fnuxi8[i-4]+4;
+
  	if(debug['v']) {
  		Bprint(&bso, "inuxi = ");
  		for(i=0; i<1; i++)
/n/atom/plan9/sys/src/cmd/6l/obj.c:1489,1523 - obj.c:1499,1504
  		Bprint(&bso, "\n");
  	}
  	Bflush(&bso);
- }
-
- int
- find1(long l, int c)
- {
- 	char *p;
- 	int i;
-
- 	p = (char*)&l;
- 	for(i=0; i<4; i++)
- 		if(*p++ == c)
- 			return i;
- 	return 0;
- }
-
- int
- find2(long l, int c)
- {
- 	short *p;
- 	int i;
-
- 	p = (short*)&l;
- 	for(i=0; i<4; i+=2) {
- 		if(((*p >> 8) & 0xff) == c)
- 			return i;
- 		if((*p++ & 0xff) == c)
- 			return i+1;
- 	}
- 	return 0;
  }

  long



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-08-22 16:54 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-21 18:36 [9fans] more on why vc can't produce amd64 executables erik quanstrom
2013-08-21 18:49 ` Bakul Shah
2013-08-21 18:57   ` erik quanstrom
2013-08-21 19:25     ` Bakul Shah
2013-08-21 19:29       ` erik quanstrom
2013-08-21 21:44       ` erik quanstrom
2013-08-22 15:32         ` Bakul Shah
2013-08-22 16:54           ` erik quanstrom

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).