MONO crosscompile mit Freetz

Emulieren währe schön, da man da nix kaputt machen kann :), so richtig für den Prozessor habe ich nichts gefunden.

Die Test habe ich wieder mit den original sourcen durchgeführt, ich wollte ja erstmal das Problem sehen, und war überrascht, dass ich keines finden konnte. Normalerweise kann man den binärcode zwischenspeichern, dafür benötige ich ein AS und OBJDUMP für die box unter /bin. Die müssten aber auch erstmal erstellt werden?

In den Sourcen sieht man schön das mips unterstützt wird, es fehlt aber der Maintainer. Dadurch ist es nicht mehr up to date, vielleicht sollte man die Lücke mal schließen.

Mal schauen, ich schau morgen auch noch mal. Geht nicht gibt es eigentlich nicht. Und der Lerneffekt ist bisher nicht zu verachten.
 
Emulieren währe schön, da man da nix kaputt machen kann :), so richtig für den Prozessor habe ich nichts gefunden.

Du meinst zu mips und Qemu? Wie wäre es hiermit (schon etwas älter, aber das sind die FB-Kernel ja auch ;-)) oder hiermit? Die Dinge zur FB auf Qemu sind hauptsächlich hier zu finden.
 
So ich hab mal die Konstante 0x1234567890ABCDEF eingetragen.

Code:
Hello World False!
Test: ms=0x0, ls=0xFFFFFFFF, 0x90ABCDEF12345678

Greift wohl weit daneben.

@MaxMuster:
Link 1: Ist leider leicht veraltet
Link 2: Sieht kompliziert aus.
Link 3: Das dauert ne weile, daraus die Informationen zu ziehen. Mal sehen.

Wäre schon einen Versuch wert mal zu schauen, ob unter qemu das selbe verhalten auftritt. Muss ich wohl mal schauen wie man das am besten macht.
 
Was für einen Vorteil erwartest Du von qemu? Erfahrungsgemäß ist qemu ähnlich langsam wie die alten Boxen, also langsamer als die neuen. Wenn unter qemu das Problem in der gleichen Weise auftritt, wie bringt Dich das weiter? Und wenn es dort nicht in der gleichen Weise auftritt, dann hilft es überhaupt nicht.

Gibt es keine Möglichkeit, sich das Ergebnis des JIT-Compilers anzuschauen? Vorzugsweise dieses auch zu speichern, es wäre ja schließlich vorteilhaft, wenn man nicht bei jedem Aufruf eines Programms neu compilieren muss.
Außerdem gibt es die Möglichkeit, Mono ohne JIT zu konfigurieren. Kommt dann das richtige Ergebnis heraus?
 
Was für einen Vorteil erwartest Du von qemu? Erfahrungsgemäß ist qemu ähnlich langsam wie die alten Boxen, also langsamer als die neuen. Wenn unter qemu das Problem in der gleichen Weise auftritt, wie bringt Dich das weiter?
Es Verbindet sich die Hoffnung das Problem besser untersuchen zu können. Lieber wäre es mir die Box um ein paar Programme zu erweitern. Davor hab ich nur ein wenig Respekt, da über meine Box das Internet läuft, und ich ins Image eingreifen müsste.

Und wenn es dort nicht in der gleichen Weise auftritt, dann hilft es überhaupt nicht.
Das wäre schlimm, wenn man vorher viel Zeit reingesteckt hätte. Zumal wie ich gesehen haben qemu nur ziemlich alte Prozessoren emuliert.

Gibt es keine Möglichkeit, sich das Ergebnis des JIT-Compilers anzuschauen? Vorzugsweise dieses auch zu speichern, es wäre ja schließlich vorteilhaft, wenn man nicht bei jedem Aufruf eines Programms neu compilieren muss.
Ja, genau daher kommt die Ausgabe die ich gepostet habe. Leider bleibt mir mangels as und objdump das Ergebnis verborgen.

Außerdem gibt es die Möglichkeit, Mono ohne JIT zu konfigurieren. Kommt dann das richtige Ergebnis heraus?
Ich kenn nur die Variante mkbundle, die kombiniert aber nur den JIT und die Runtime in einer Datei. Sowas für IL2CPU hab ich leider nicht gefunden. Und das geht leider nur unter x86.
 
Du musst nicht für jede Änderung ein neues Image auf die Box bringen, Du kannst auch ein neues Programm über Netzwerk oder USB Stick auf die Box kopieren und dort ausführen.

Die Ausgabe sieht nicht nach MIPS Code aus, sondern nach einer internen Zwischenrepräsentation. Die Bezeichnungen a0, a3, v0, v1 sehen zwar stark nach MIPS aus, sind aber vermutlich nur daran angelehnt. Wie Du schon geschrieben hast, sieht dieser Zwischencode gut aus. Die Frage ist also, was für CPU Code wird daraus erzeugt.

Objdump muss nicht auf der Box laufen, es ist einfacher, eine Datei auf den PC zu kopieren und dort mit objdump zu untersuchen.
Wo wird as verwendet? Offensichtlich passiert auch etwas, ohne dass as vorhanden ist. Wenn es aber eine Option gibt, um as zu nutzen, kannst Du ein einfaches Skript erstellen, dass die Eingabe von as speichert:
Code:
#!/bin/sh
cat > /tmp/as.$$.txt
exit 1 # oder exit 0
Damit wird die Eingabe von as in /tmp gespeichert und man kann sie sich nachher ansehen.
 
Hatte ich auch schon versucht, nur ist /bin auf einem Read-Only-Dateisystem. Und ich habe noch keine Möglichkeit gefunden, wie man das Ergebnis umleitet.

Der Aufruf der Datei läuft via
Code:
MONO_VERBOSE_METHOD=Main ./hallo
und ich erhalte am Ende
Code:
Basic block 1 starting at offset 0x124
Method TestMono.MainClass:Main (string[]) emitted at 0x2ab1c2c0 to 0x2ab1c3f4 (code length 308) [TestMono.exe]
/bin/sh: as: not found
/bin/sh: objdump: not found
 
Datei /tmp/as, und /tmp/objdump entsprechend.
Code:
#!/bin/sh
exec > /tmp/as.$$.txt 2>&1
echo $0 $@
cat -- "$@"
Dann Aufruf mit
PATH=/tmp:$PATH MONO_VERBOSE_METHOD=Main ./hallo
 
Der Tracer erzeugt schon eine Tempdatei mit einem seltsamen Namen, die konnte ich so abfangen.

Code:
main.obj:     file format elf32-tradbigmips

Contents of section .text:
 0000 27bdffc0 afbf003c afa40040 afa00014  '......<...@....
 0010 afa00010 3c04009d 2484de4c 3c192ab2  ....<...$..L<.*.
 0020 2739c2a0 0320f809 00200825 00402821  '9... ... .%.@(!
 0030 a0a00008 3c042ab4 2484aea0 3c192ab2  ....<.*.$...<.*.
 0040 2739c418 0320f809 00200825 3c0290ac  '9... ... .%<...
 0050 2442cdef afa20014 3c021234 24425678  $B......<..4$BVx
 0060 afa20010 27a20010 00401821 8c630000  ....'....@.!.c..
 0070 afa30034 24420004 8c420000 afa20030  ...4$B...B.....0
 0080 3c04009d 2484db64 3c192ab2 2739c2a0  <...$..d<.*.'9..
 0090 0320f809 00200825 8fa30034 ac430008  . ... .%...4.C..
 00a0 afa20028 3c04009d 2484db64 3c192ab2  ...(<...$..d<.*.
 00b0 2739c2a0 0320f809 00200825 8fa30030  '9... ... .%...0
 00c0 ac430008 afa2002c 8fa20014 afa20020  .C.....,....... 
 00d0 8fa20010 afa20024 3c04009d 2484df1c  .......$<...$...
 00e0 3c192ab2 2739c2a0 0320f809 00200825  <.*.'9... ... .%
 00f0 00403821 8fa20020 8fa30024 8fa50028  .@8!... ...$...(
 0100 8fa6002c ace30008 ace2000c 3c042ab5  ...,........<.*.
 0110 2484cf60 3c192ab2 2739c3f8 0320f809  $..`<.*.'9... ..
 0120 00200825 8fbf003c 27bd0040 03e00008  . .%...<'..@....
 0130 00200825 00000000 00000000 00000000  . .%............
Contents of section .reginfo:
 0000 00000000 00000000 00000000 00000000  ................
 0010 00000000 00000000                    ........        

Disassembly of section .text:

00000000 <tMono_MainClass_Main>:
   0:	27bdffc0 	addiu	sp,sp,-64
   4:	afbf003c 	sw	ra,60(sp)
   8:	afa40040 	sw	a0,64(sp)
   c:	afa00014 	sw	zero,20(sp)
  10:	afa00010 	sw	zero,16(sp)
  14:	3c04009d 	lui	a0,0x9d
  18:	2484de4c 	addiu	a0,a0,-8628
  1c:	3c192ab2 	lui	t9,0x2ab2
  20:	2739c2a0 	addiu	t9,t9,-15712
  24:	0320f809 	jalr	t9
  28:	00200825 	move	at,at
  2c:	00402821 	move	a1,v0
  30:	a0a00008 	sb	zero,8(a1)
  34:	3c042ab4 	lui	a0,0x2ab4
  38:	2484aea0 	addiu	a0,a0,-20832
  3c:	3c192ab2 	lui	t9,0x2ab2
  40:	2739c418 	addiu	t9,t9,-15336
  44:	0320f809 	jalr	t9
  48:	00200825 	move	at,at
  4c:	3c0290ac 	lui	v0,0x90ac
  50:	2442cdef 	addiu	v0,v0,-12817
  54:	afa20014 	sw	v0,20(sp)
  58:	3c021234 	lui	v0,0x1234
  5c:	24425678 	addiu	v0,v0,22136
  60:	afa20010 	sw	v0,16(sp)
  64:	27a20010 	addiu	v0,sp,16
  68:	00401821 	move	v1,v0
  6c:	8c630000 	lw	v1,0(v1)
  70:	afa30034 	sw	v1,52(sp)
  74:	24420004 	addiu	v0,v0,4
  78:	8c420000 	lw	v0,0(v0)
  7c:	afa20030 	sw	v0,48(sp)
  80:	3c04009d 	lui	a0,0x9d
  84:	2484db64 	addiu	a0,a0,-9372
  88:	3c192ab2 	lui	t9,0x2ab2
  8c:	2739c2a0 	addiu	t9,t9,-15712
  90:	0320f809 	jalr	t9
  94:	00200825 	move	at,at
  98:	8fa30034 	lw	v1,52(sp)
  9c:	ac430008 	sw	v1,8(v0)
  a0:	afa20028 	sw	v0,40(sp)
  a4:	3c04009d 	lui	a0,0x9d
  a8:	2484db64 	addiu	a0,a0,-9372
  ac:	3c192ab2 	lui	t9,0x2ab2
  b0:	2739c2a0 	addiu	t9,t9,-15712
  b4:	0320f809 	jalr	t9
  b8:	00200825 	move	at,at
  bc:	8fa30030 	lw	v1,48(sp)
  c0:	ac430008 	sw	v1,8(v0)
  c4:	afa2002c 	sw	v0,44(sp)
  c8:	8fa20014 	lw	v0,20(sp)
  cc:	afa20020 	sw	v0,32(sp)
  d0:	8fa20010 	lw	v0,16(sp)
  d4:	afa20024 	sw	v0,36(sp)
  d8:	3c04009d 	lui	a0,0x9d
  dc:	2484df1c 	addiu	a0,a0,-8420
  e0:	3c192ab2 	lui	t9,0x2ab2
  e4:	2739c2a0 	addiu	t9,t9,-15712
  e8:	0320f809 	jalr	t9
  ec:	00200825 	move	at,at
  f0:	00403821 	move	a3,v0
  f4:	8fa20020 	lw	v0,32(sp)
  f8:	8fa30024 	lw	v1,36(sp)
  fc:	8fa50028 	lw	a1,40(sp)
 100:	8fa6002c 	lw	a2,44(sp)
 104:	ace30008 	sw	v1,8(a3)
 108:	ace2000c 	sw	v0,12(a3)
 10c:	3c042ab5 	lui	a0,0x2ab5
 110:	2484cf60 	addiu	a0,a0,-12448
 114:	3c192ab2 	lui	t9,0x2ab2
 118:	2739c3f8 	addiu	t9,t9,-15368
 11c:	0320f809 	jalr	t9
 120:	00200825 	move	at,at
 124:	8fbf003c 	lw	ra,60(sp)
 128:	27bd0040 	addiu	sp,sp,64
 12c:	03e00008 	jr	ra
 130:	00200825 	move	at,at
	...

Da müsste noch ein call auf WriteLine am anfange sein.
 
Kein Problem:
Code:
main.obj:     file format elf32-tradbigmips

Contents of section .text:
 0000 27bdffc0 afbf003c afa40040 afa00014  '......<...@....
 0010 afa00010 3c04009d 2484de4c 3c192ab2  ....<...$..L<.*.
 0020 2739c2a0 0320f809 00200825 00402821  '9... ... .%.@(!
 0030 a0a00008 3c042ab4 2484aea0 3c192ab2  ....<.*.$...<.*.
 0040 2739c418 0320f809 00200825 3c0290ac  '9... ... .%<...
 0050 2442cdef afa20014 3c021234 24425678  $B......<..4$BVx
 0060 afa20010 27a20010 00401821 8c630000  ....'....@.!.c..
 0070 afa30034 24420004 8c420000 afa20030  ...4$B...B.....0
 0080 3c04009d 2484db64 3c192ab2 2739c2a0  <...$..d<.*.'9..
 0090 0320f809 00200825 8fa30034 ac430008  . ... .%...4.C..
 00a0 afa20028 3c04009d 2484db64 3c192ab2  ...(<...$..d<.*.
 00b0 2739c2a0 0320f809 00200825 8fa30030  '9... ... .%...0
 00c0 ac430008 afa2002c 8fa20014 afa20020  .C.....,....... 
 00d0 8fa20010 afa20024 3c04009d 2484df1c  .......$<...$...
 00e0 3c192ab2 2739c2a0 0320f809 00200825  <.*.'9... ... .%
 00f0 00403821 8fa20020 8fa30024 8fa50028  .@8!... ...$...(
 0100 8fa6002c ace30008 ace2000c 3c042ab5  ...,........<.*.
 0110 2484cf60 3c192ab2 2739c3f8 0320f809  $..`<.*.'9... ..
 0120 00200825 8fbf003c 27bd0040 03e00008  . .%...<'..@....
 0130 00200825 00000000 00000000 00000000  . .%............
Contents of section .reginfo:
 0000 00000000 00000000 00000000 00000000  ................
 0010 00000000 00000000                    ........

Dateien kann man hier nicht anhängen?
 
Das ist eher weniger als mehr gegenüber vorher. Normalerweise sollte "objdump -dr" disassemblieren und die Relocation Einträge zeigen. Es kann aber auch sein, dass es hier keine gibt. Zum Teil werden recht hohe Adressen verwendet, das spricht dafür, dass das schon konkrete Adressen sind, wo der Mono Runtime geladen ist. Adressen wie 0x2ab1c2a0 passen von der Größenordnung zu den in #67 erwähnten wie 0x2ab1c2c0

Ich habe mir den Code angeschaut, er sieht soweit gut aus. Es bleibt somit noch die Variante, dass die Funktion WriteLine fehlerhaft ist. Kannst Du eine Funktion schreiben, die einen int bzw. long Wert in Hex ausgibt?
 
Ich kann nur einzelne Funktionen ausgeben. Ich kann ja mal die verdächtigen versuchen zu finden. Ich tippe gerade eher auf die Box-Befehle.

@edit: Das ist ne richtig lange Liste.

Das Problem scheint langsam nix mehr mit dem JIT zu tun zu haben. Ich habe mal die Hex-Formatter entfernt und schon zeigt er mir die Daten richtig an:
Code:
Hello World False!
Test: ms=305419896, ls=-1867788817, 305419896
Dafür ist die dritte Ausgabe völlig daneben?
 
Zuletzt bearbeitet:
Das Problem liegt also im managed code? Aber wie kommt es, dass writeline auf zig Platformen funktioniert nur eben auf MIPS nicht?

Ich denke das Problem ist doch tiefer begraben: z.B. bei DateTime.Now wirft auch Fehler (soweit ich mich errinnere eine out of range expception)...
 
Nicht unbedingt im Managed Code, aber in dem, was Mono auf MIPS daraus macht. Der MIPS Code oben entspricht dem IL Code und tut, was er soll. Das sieht man auch daran, dass zumindest für die i4 Werte die Ausgabe korrekt ist in dezimal, aber nicht in hex.
Eine Ausgabe als Hex ist relativ einfach, ggf. noch auf c# anpassen.
Code:
WriteInt (int val)
{
char buf[10];
int i;
int size = 8;
const char *hex = "0123456789ABCDEF";
for (i = 0; i < size; i++)
  buf[i] = hex[(val >> ((size - i - 1) * 4)) & 0xF];
buf[size] = '\0';
WriteLine (buf);
}
Wenn Du diese Funktion einmal für int und einmal für long erstellst, kannst Du erst einmal testen, ob das richtige Ergebnis herauskommt und dann, welche Operationen korrekt ausgeführt werden und welche nicht.
Allerdings kann es sein, dass noch viele Fehler da lauern und nicht alle gleich offensichtlich sein.
Ein anderer Ansatz wäre, die Quellen von WriteLine zu nehmen und dort Debug Ausgaben einzubauen um zu sehen, was schief läuft.
 
Also so wie ich das sehe liegt das nicht am Writeline. Hier stimmt generell was mit den Long Datentyp nicht. Sieht so aus als würde Long genauso wie Int behandelt....

Code:
 static void Main(string[] args)
        {
            
            Console.WriteLine((int.MaxValue + 1L).ToString());
            WriteInt(int.MaxValue + 1L );
            Console.ReadLine();

        }


        static  void WriteInt(long  val)
        {
            byte[] buf = new byte[10];
            int i;
            int size = 8;
            byte[] hex = Encoding.ASCII.GetBytes("0123456789ABCDEF");
            for (i = 0; i < size; i++)
            {
                buf[i] = hex[(val >> ((size - i - 1) * 4)) & 0xF];
            }
            //buf[size] = @'\0';

            Console.WriteLine(Encoding.ASCII.GetString(buf));
        }


Ausgabe unter MIPS Mono:

-2147483648
00000000
 
Man das ist ja mal ne harte Nuss:
Code:
		private const string csAlpha = "0123456789ABCDEF";

		private static void WriteInt(int v)
		{
			char[] b = new char[8];
			Console.Write ("Int: 0x");

			for (int i = 0; i < b.Length; i++)
			{
				b [b.Length - i - 1] = csAlpha [v & 0xF];
				v = v >> 4;
			}
			Console.WriteLine (b);
		}

		private static void  WriteLong(long v)
		{
			char[] b = new char[16];
			Console.Write ("Long: 0x");

			for (int i = 0; i < b.Length; i++)
			{
				b [b.Length - i - 1] = csAlpha [(int)(v & 0xF)];
				v = v >> 4;
			}

			Console.WriteLine (b);
		}

		public static unsafe int Main (string[] args)
		{
			//Console.WriteLine ("Hello World {0}!", BitConverter.IsLittleEndian);
			long b = 0x1234567890ABCDEF;
			int* a = (int*)(void*)&b;
			int ms = *a;
			int ls = *(a + 1);
			WriteInt (ms);
			WriteInt (ls);
			WriteLong (b);
			return ms;
		}

Ergibt:
Code:
Int: 0x12345678
Int: 0x90ABCDEF
Long: 0x90ABCDEF12345678
 
Aha, die Parameterübergabe hab ich nun in verdacht:
Code:
		private static unsafe void  WriteLong2(long v)
		{
			int* a = (int*)(void*)&v;
			int ms = *a;
			int ls = *(a + 1);
			WriteInt (ms);
			WriteInt (ls);
		}
Code:
Int: 0x12345678
Int: 0x90ABCDEF
Long: 0x90ABCDEF12345678
Int: 0x90ABCDEF
Int: 0x12345678

Tatsache die Parameterübergabe verdreht es. Oder seh ich das falsch?

Code:
Aufruf:
  88:	8fa50014 	lw	a1,20(sp)
  8c:	8fa40010 	lw	a0,16(sp)
  90:	3c192ab2 	lui	t9,0x2ab2
  94:	2739c1b0 	addiu	t9,t9,-15952
  98:	0320f809 	jalr	t9
  9c:	00200825 	move	at,at

00000000 <tMono_MainClass_WriteLong2>:
   0:	27bdffd0 	addiu	sp,sp,-48
   4:	afbf002c 	sw	ra,44(sp)
   8:	afa40034 	sw	a0,52(sp)
   c:	afa50030 	sw	a1,48(sp)
  10:	27a20030 	addiu	v0,sp,48
  14:	00401821 	move	v1,v0
  18:	8c640000 	lw	a0,0(v1)
  1c:	24420004 	addiu	v0,v0,4
  20:	8c420000 	lw	v0,0(v0)
  24:	afa20020 	sw	v0,32(sp)
  28:	3c192ab2 	lui	t9,0x2ab2
  2c:	2739c1f0 	addiu	t9,t9,-15888
  30:	0320f809 	jalr	t9
  34:	00200825 	move	at,at
  38:	8fa40020 	lw	a0,32(sp)
  3c:	3c192ab2 	lui	t9,0x2ab2
  40:	2739c1f0 	addiu	t9,t9,-15888
  44:	0320f809 	jalr	t9
  48:	00200825 	move	at,at
  4c:	8fbf002c 	lw	ra,44(sp)
  50:	27bd0030 	addiu	sp,sp,48
  54:	03e00008 	jr	ra
  58:	00200825 	move	at,at
  5c:	00000000 	nop
 
Zuletzt bearbeitet:
mini-mips.c Zeile 5167:
Code:
#if (SIZEOF_REGISTER == 4)
					mips_sw (code, ainfo->reg, inst->inst_basereg, basereg_offset + ms_word_offset);
					mips_sw (code, ainfo->reg + 1, inst->inst_basereg, basereg_offset + ls_word_offset);
#elif (SIZEOF_REGISTER == 8)
mini-mips.c Zeile 5205:
Code:
#if _MIPS_SIM == _ABIO32
					mips_swc1 (code, ainfo->reg, inst->inst_basereg, inst->inst_offset + ms_word_offset);
					mips_swc1 (code, ainfo->reg+1, inst->inst_basereg, inst->inst_offset + ls_word_offset);
#elif _MIPS_SIM == _ABIN32

Meiner bescheidenen Meinung nach hat der Autor da etwas vertauscht. Bin mir aber nicht sicher, wir sollten mal versuchen die Test zum Laufen zu bringen?

Code:
Int: 0x12345678
Int: 0x90ABCDEF
Long: 0x1234567890ABCDEF
Int: 0x12345678
Int: 0x90ABCDEF
;)
 
Zuletzt bearbeitet:

Zurzeit aktive Besucher

Keine Mitglieder online.

Statistik des Forums

Themen
246,703
Beiträge
2,256,224
Mitglieder
374,700
Neuestes Mitglied
biseragabric
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.