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