[project @ 2002-03-01 09:47:39 by simonmar]
[ghc-hetmet.git] / ghc / driver / mangler / ghc-asm.lprl
index ae8aeaa..3f21c89 100644 (file)
@@ -113,6 +113,7 @@ sub init_TARGET_STUFF {
     $T_HDR_fast            = "\.text\n\t\.align 3\n";
     $T_HDR_vector   = "\.text\n\t\.align 3\n";
     $T_HDR_direct   = "\.text\n\t\.align 3\n";
+    $T_create_word  = "\t.quad";
 
     #--------------------------------------------------------#
     } elsif ( $TargetPlatform =~ /^hppa/ ) {
@@ -140,6 +141,7 @@ sub init_TARGET_STUFF {
     $T_HDR_fast            = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
     $T_HDR_vector   = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
     $T_HDR_direct   = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
+    $T_create_word  = "\t.word";
 
     #--------------------------------------------------------#
     } elsif ( $TargetPlatform =~ /^i386-.*-(linuxaout|freebsd2|openbsd|nextstep3|cygwin32|mingw32)$/ ) {
@@ -171,6 +173,7 @@ sub init_TARGET_STUFF {
     $T_HDR_fast            = "\.text\n\t\.align 2,0x90\n";
     $T_HDR_vector   = "\.text\n\t\.align 2\n"; # NB: requires padding
     $T_HDR_direct   = "\.text\n\t\.align 2,0x90\n";
+    $T_create_word  = "\t.word";
 
     #--------------------------------------------------------#
     } elsif ( $TargetPlatform =~ /^i386-.*-(solaris2|linux|freebsd|netbsd)$/ ) {
@@ -207,6 +210,7 @@ sub init_TARGET_STUFF {
     $T_HDR_fast            = "\.text\n\t\.align 4\n";
     $T_HDR_vector   = "\.text\n\t\.align 4\n"; # NB: requires padding
     $T_HDR_direct   = "\.text\n\t\.align 4\n";
+    $T_create_word  = "\t.word";
 
     #--------------------------------------------------------#
     } elsif ( $TargetPlatform =~ /^m68k-.*-sunos4/ ) {
@@ -234,6 +238,7 @@ sub init_TARGET_STUFF {
     $T_HDR_fast            = "\.text\n\t\.even\n";
     $T_HDR_vector   = "\.text\n\t\.even\n";
     $T_HDR_direct   = "\.text\n\t\.even\n";
+    $T_create_word  = "\t.long";
 
     #--------------------------------------------------------#
     } elsif ( $TargetPlatform =~ /^mips-.*/ ) {
@@ -261,6 +266,7 @@ sub init_TARGET_STUFF {
     $T_HDR_fast            = "\t\.text\n\t\.align 2\n";
     $T_HDR_vector   = "\t\.text\n\t\.align 2\n";
     $T_HDR_direct   = "\t\.text\n\t\.align 2\n";
+    $T_create_word  = "\t.word";
 
     #--------------------------------------------------------#
     } elsif ( $TargetPlatform =~ /^powerpc-.*|^rs6000-.*/ ) {
@@ -289,6 +295,7 @@ sub init_TARGET_STUFF {
     $T_HDR_fast            = "# fast\n\.csect \.text[PR]\n\t\.align 2\n";
     $T_HDR_vector   = "# vector\n\.csect \.data[RW]\n\t\.align 2\n"; #not RO!?
     $T_HDR_direct   = "# direct\n";
+    $T_create_word  = "\t.long";
 
     #--------------------------------------------------------#
     } elsif ( $TargetPlatform =~ /^sparc-.*-solaris2/ ) {
@@ -316,6 +323,7 @@ sub init_TARGET_STUFF {
     $T_HDR_fast            = "\.text\n\t\.align 4\n";
     $T_HDR_vector   = "\.text\n\t\.align 4\n";
     $T_HDR_direct   = "\.text\n\t\.align 4\n";
+    $T_create_word  = "\t.word";
 
     #--------------------------------------------------------#
     } elsif ( $TargetPlatform =~ /^sparc-.*-sunos4/ ) {
@@ -343,6 +351,7 @@ sub init_TARGET_STUFF {
     $T_HDR_fast            = "\.text\n\t\.align 4\n";
     $T_HDR_vector   = "\.text\n\t\.align 4\n";
     $T_HDR_direct   = "\.text\n\t\.align 4\n";
+    $T_create_word  = "\t.word";
 
     #--------------------------------------------------------#
     } else {
@@ -421,7 +430,7 @@ sub mangle_asm {
     $i = 0; $chkcat[0] = 'misc'; $chk[0] = '';
 
     while (<INASM>) {
-       tr/\r//d if $TargetPlatform =~ /-mingw32$/;
+       tr/\r//d if $TargetPlatform =~ /-mingw32$/; # In case Perl doesn't convert line endings
        next if $T_STABBY && /^\.stab.*${T_US}__stg_split_marker/o;
        next if $T_STABBY && /^\.stab.*ghc.*c_ID/;
        next if /^\t\.def.*endef$/;
@@ -589,8 +598,9 @@ sub mangle_asm {
            local($thing);
            chop($thing = $_);
            print STDERR "Funny global thing?: $_"
-               unless $KNOWN_FUNNY_THING{$thing}
-                   || /^${T_US}stg_.*${T_POST_LBL}$/o          # RTS internals
+               unless # $KNOWN_FUNNY_THING{$thing}
+                      /^${T_US}stg_.*${T_POST_LBL}$/o          # RTS internals
+                   || /^${T_US}__stg_.*${T_POST_LBL}$/o        # more RTS internals
                    || /^${T_US}__fexp_.*${T_POST_LBL}$/o       # foreign export
                    || /^${T_US}__stginit.*${T_POST_LBL}$/o     # __stginit<module>
                    || /^${T_US}.*_btm${T_POST_LBL}$/o          # large bitmaps
@@ -1152,6 +1162,25 @@ sub mangle_asm {
                  print OUTASM $chk[$vectorchk{$symb}];
                } else {
                  print OUTASM &rev_tbl($symb, $chk[$vectorchk{$symb}], 0);
+                  # DO NOT DELETE THE NEXT LINE.  It fixes a rather subtle GC bug 
+                  # which showed up as a segfault reported by Ryszard Kubiak.
+                  # Problem is with vector tables.  They wind up as follows:
+                  #      .word some-word
+                  #      .word some-other-word
+                  #   fooble_vtbl:
+                  # Problem is that we want the label fooble_vtbl to be considered 
+                  # in the same section as the vtbl itself, but the label actually 
+                  # lives at the next word along.  If a data segment should happen 
+                  # to immediately follow the vtbl, as it can in GHCi, the label will 
+                  # be malclassified as in the data rather than text segment (during 
+                  # GC), and so we will regard references to it as static closure 
+                  # pointers rather than as code pointers, which is an error which 
+                  # usually crashes the garbage collectors.
+                  # To fix this, we place a dummy word after the label, so as to
+                  # ensure that the label is in the same segment as the vtbl proper.
+                  # The native code generator has an analogous fix; see
+                  # ghc/compiler/nativeGen/AbsCStixGen.lhs line 107.
+                  print OUTASM "${T_create_word} 0\n";
                }
                # direct return code will be put here!
                $chkcat[$vectorchk{$symb}] = 'DONE ALREADY';
@@ -1275,14 +1304,14 @@ sub print_doctored {
 
     if ($StolenX86Regs <= 2 ) { # YURGH! spurious uses of esi?
        s/^\tmovl\s+(.*),\s*\%esi\n\tjmp\s+\*%esi\n/\tmovl $1,\%eax\n\tjmp \*\%eax\n/g;
-       s/^\tjmp\s+\*(-?\d*)\((.*\%esi.*)\)\n/\tmovl $2,\%eax\n\tjmp \*$1\(\%eax\)\n/g;
+       s/^\tjmp\s+\*(.*\(.*\%esi.*\))\n/\tmovl $1,\%eax\n\tjmp \*\%eax\n/g;
        s/^\tjmp\s+\*\%esi\n/\tmovl \%esi,\%eax\n\tjmp \*\%eax\n/g;
        die "$Pgm: (mangler) still have jump involving \%esi!\n$_"
            if /(jmp|call)\s+.*\%esi/;
     }
     if ($StolenX86Regs <= 3 ) { # spurious uses of edi?
        s/^\tmovl\s+(.*),\s*\%edi\n\tjmp\s+\*%edi\n/\tmovl $1,\%eax\n\tjmp \*\%eax\n/g;
-       s/^\tjmp\s+\*(-?\d*\(.*\%edi.*\))\n/\tmovl $1,\%eax\n\tjmp \*\%eax\n/g;
+       s/^\tjmp\s+\*(.*\(.*\%edi.*\))\n/\tmovl $1,\%eax\n\tjmp \*\%eax\n/g;
        s/^\tjmp\s+\*\%edi\n/\tmovl \%edi,\%eax\n\tjmp \*\%eax\n/g;
        die "$Pgm: (mangler) still have jump involving \%edi!\n$_"
            if /(jmp|call)\s+.*\%edi/;
@@ -1443,7 +1472,7 @@ sub rev_tbl {
                    local ($sign, $base, $digits) = ($1, $2, $3);
                    $base = (10, 8, 16)[length $base];
                    local ($hi, $lo) = (0, 0);
-                   foreach $i (split //, $digits) {
+                   foreach $i (split(//, $digits)) {
                        $j = $lo * $base + $i;
                        $lo = $j % 4294967296;
                        $hi = $hi * $base + ($j - $lo) / 4294967296;
@@ -1451,8 +1480,7 @@ sub rev_tbl {
                    ($hi, $lo) = (4294967295 - $hi, 4294967296 - $lo)
                        if $sign eq "-";
                    $_ = "\t.align 3\n\t.long $lo\n\t.long $hi\n";
-                   printf STDERR "TURNING %s into 0x %08x %08x\n",
-                       $number, $hi, $lo;
+                   # printf STDERR "TURNING %s into 0x %08x %08x\n", $number, $hi, $lo;
                } else {
                    print STDERR "Cannot handle \".quad $number\" in info table\n";
                    exit 1;