summaryrefslogtreecommitdiff
path: root/driver/split
diff options
context:
space:
mode:
authorClemens Fruhwirth <clemens@endorphin.org>2007-07-06 11:24:49 +0000
committerClemens Fruhwirth <clemens@endorphin.org>2007-07-06 11:24:49 +0000
commitee40dd6ba3e4effa2cf6c6f06dc2b7477fc55f18 (patch)
tree7bbd1fa41d672f62a01466cf324202c574e05ddc /driver/split
parent39b41e2cbbcc9b672a5f25c2ab5d61ccc004c95e (diff)
downloadhaskell-ee40dd6ba3e4effa2cf6c6f06dc2b7477fc55f18.tar.gz
Fix -split-obj on Mac OS via -fasm
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.
Diffstat (limited to 'driver/split')
-rw-r--r--driver/split/ghc-split.lprl4
1 files changed, 2 insertions, 2 deletions
diff --git a/driver/split/ghc-split.lprl b/driver/split/ghc-split.lprl
index d54e1b206e..3bdb04b4a0 100644
--- a/driver/split/ghc-split.lprl
+++ b/driver/split/ghc-split.lprl
@@ -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 = ''