Fix -split-obj on Mac OS via -fasm
authorClemens Fruhwirth <clemens@endorphin.org>
Fri, 6 Jul 2007 11:24:49 +0000 (11:24 +0000)
committerClemens Fruhwirth <clemens@endorphin.org>
Fri, 6 Jul 2007 11:24:49 +0000 (11:24 +0000)
The problem of the splitter was that it re-emitted section directives
for every dynamic label found. The following was torn apart

.symbol_stubs
.indirect <symbol>
L_<symbol>$stub:
jmp *...
L_<symbol>$stub_binder:
..somebinding code..

into

.symbol_stubs
.indirect_symbol <symbol>
L_<symbol>$stub:
jmp *...
.symbol_stubs <--- NEW
L_<symbol>$stub_binder:
..somebinding code..

This is incorrect as the Mac OS assembler enforces that every new code
section that goes into .symbol_stubs is associated with the linker
directive .indirect_symbol. This sanity check is obviously violated
when we reemit .symbol_stub in the splitter. The solution is to ignore
everything that ends with $stub_binder as new label, and chuck it into
a single label for $stub.

Also the splitter has to recognize .section __DATA... for the lazy_ptr
indirection symbol. Adds a reminder to PositionIndependentCode.hs to
take care of the splitter when the code generation is changed.

This should not affect -fvia-c as the code generated by the C compiler
is entirely different.

compiler/nativeGen/PositionIndependentCode.hs
driver/split/ghc-split.lprl

index 4001078..6a94de2 100644 (file)
@@ -372,6 +372,9 @@ pprGotDeclaration = Pretty.empty
 -- On Darwin, we have to generate our own stub code for lazy binding..
 -- For each processor architecture, there are two versions, one for PIC
 -- and one for non-PIC.
+--
+-- Whenever you change something in this assembler output, make sure
+-- the splitter in driver/split/ghc-split.lprl recognizes the new output
 pprImportedSymbol importedLbl
 #if powerpc_TARGET_ARCH
     | Just (CodeStub, lbl) <- dynamicLinkerLabelInfo importedLbl
index d54e1b2..3bdb04b 100644 (file)
@@ -138,7 +138,7 @@ sub collectDyldStuff_darwin {
     
     while ( 1 ) {
        $_ = <TMPI>;
-       if ( $_ eq '' || /^L(_.+)\$.+:/ ) {
+       if ( $_ eq '' || (/^L(_.+)\$.+:/ && !(/^L(.*)\$stub_binder:/))) {
            if ( $label ne '' ) {
                $DyldChunksDefined{$label} .= $section . $alignment . $chunk_label . $ chunk;
                if( $section =~ s/\.data/\.non_lazy_symbol_pointer/ ) {
@@ -155,7 +155,7 @@ sub collectDyldStuff_darwin {
            $section = $cur_section;
            $alignment = $cur_alignment;
            print STDERR "label: $label\n" if $Dump_asm_splitting_info;
-       } elsif ( /^\s*\.(symbol_stub|picsymbol_stub|lazy_symbol_pointer|non_lazy_symbol_pointer|data|section __IMPORT,.*)/ ) {
+       } elsif ( /^\s*\.(symbol_stub|picsymbol_stub|lazy_symbol_pointer|non_lazy_symbol_pointer|data|section __IMPORT,.*|section __DATA, __la_sym_ptr(2|3),lazy_symbol_pointers)/ ) {
            $cur_section = $_;
            printf STDERR "section: $cur_section\n" if $Dump_asm_splitting_info;
            $cur_alignment = ''