| 
									
										
										
										
											2016-04-20 10:10:43 +08:00
										 |  |  | #! /usr/bin/env perl | 
					
						
							|  |  |  | # Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											2018-12-06 20:48:38 +08:00
										 |  |  | # Licensed under the Apache License 2.0 (the "License").  You may not use | 
					
						
							| 
									
										
										
										
											2016-04-20 10:10:43 +08:00
										 |  |  | # this file except in compliance with the License.  You can obtain a copy | 
					
						
							|  |  |  | # in the file LICENSE in the source distribution or at | 
					
						
							|  |  |  | # https://www.openssl.org/source/license.html | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  | package x86gas; | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | *out=\@::out; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  | $::lbdecor=$::aout?"L":".L";		# local label decoration | 
					
						
							| 
									
										
										
										
											2007-11-25 00:03:57 +08:00
										 |  |  | $nmdecor=($::aout or $::coff)?"_":"";	# external name decoration | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  | $initseg=""; | 
					
						
							| 
									
										
										
										
											2007-11-25 00:03:57 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | $align=16; | 
					
						
							|  |  |  | $align=log($align)/log(2) if ($::aout); | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | $com_start="#" if ($::aout or $::coff); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sub opsize() | 
					
						
							|  |  |  | { my $reg=shift; | 
					
						
							|  |  |  |     if    ($reg =~ m/^%e/o)		{ "l"; } | 
					
						
							|  |  |  |     elsif ($reg =~ m/^%[a-d][hl]$/o)	{ "b"; } | 
					
						
							| 
									
										
										
										
											2015-12-14 04:40:20 +08:00
										 |  |  |     elsif ($reg =~ m/^%[yxm]/o)		{ undef; } | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  |     else				{ "w"; } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # swap arguments; | 
					
						
							|  |  |  | # expand opcode with size suffix; | 
					
						
							|  |  |  | # prefix numeric constants with $; | 
					
						
							|  |  |  | sub ::generic | 
					
						
							| 
									
										
										
										
											2008-12-18 03:56:48 +08:00
										 |  |  | { my($opcode,@arg)=@_; | 
					
						
							|  |  |  |   my($suffix,$dst,$src); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @arg=reverse(@arg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (@arg) | 
					
						
							|  |  |  |     {	s/^(\*?)(e?[a-dsixphl]{2})$/$1%$2/o;	# gp registers | 
					
						
							|  |  |  | 	s/^([xy]?mm[0-7])$/%$1/o;		# xmm/mmx registers | 
					
						
							|  |  |  | 	s/^(\-?[0-9]+)$/\$$1/o;			# constants | 
					
						
							|  |  |  | 	s/^(\-?0x[0-9a-f]+)$/\$$1/o;		# constants | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-18 03:56:48 +08:00
										 |  |  |     $dst = $arg[$#arg]		if ($#arg>=0); | 
					
						
							|  |  |  |     $src = $arg[$#arg-1]	if ($#arg>=1); | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  |     if    ($dst =~ m/^%/o)	{ $suffix=&opsize($dst); } | 
					
						
							|  |  |  |     elsif ($src =~ m/^%/o)	{ $suffix=&opsize($src); } | 
					
						
							|  |  |  |     else			{ $suffix="l";           } | 
					
						
							|  |  |  |     undef $suffix if ($dst =~ m/^%[xm]/o || $src =~ m/^%[xm]/o); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ($#_==0)				{ &::emit($opcode);		} | 
					
						
							| 
									
										
										
										
											2011-12-10 03:16:20 +08:00
										 |  |  |     elsif ($#_==1 && $opcode =~ m/^(call|clflush|j|loop|set)/o) | 
					
						
							|  |  |  | 					{ &::emit($opcode,@arg);	} | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  |     else				{ &::emit($opcode.$suffix,@arg);} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											1998-12-21 18:56:39 +08:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | # opcodes not covered by ::generic above, mostly inconsistent namings... | 
					
						
							| 
									
										
										
										
											1998-12-21 18:56:39 +08:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  | sub ::movzx	{ &::movzb(@_);			} | 
					
						
							|  |  |  | sub ::pushfd	{ &::pushfl;			} | 
					
						
							|  |  |  | sub ::popfd	{ &::popfl;			} | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | sub ::cpuid	{ &::emit(".byte\t0x0f,0xa2");	} | 
					
						
							|  |  |  | sub ::rdtsc	{ &::emit(".byte\t0x0f,0x31");	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  | sub ::call	{ &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); } | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | sub ::call_ptr	{ &::generic("call","*$_[0]");	} | 
					
						
							|  |  |  | sub ::jmp_ptr	{ &::generic("jmp","*$_[0]");	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | *::bswap = sub	{ &::emit("bswap","%$_[0]");	} if (!$::i386); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sub ::DWP | 
					
						
							|  |  |  | { my($addr,$reg1,$reg2,$idx)=@_; | 
					
						
							|  |  |  |   my $ret=""; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-18 03:04:15 +08:00
										 |  |  |     if (!defined($idx) && 1*$reg2) { $idx=$reg2; $reg2=$reg1; undef $reg1; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  |     $addr =~ s/^\s+//; | 
					
						
							|  |  |  |     # prepend global references with optional underscore | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  |     $addr =~ s/^([^\+\-0-9][^\+\-]*)/&::islabel($1) or "$nmdecor$1"/ige; | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     $reg1 = "%$reg1" if ($reg1); | 
					
						
							|  |  |  |     $reg2 = "%$reg2" if ($reg2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $ret .= $addr if (($addr ne "") && ($addr ne 0)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ($reg2) | 
					
						
							|  |  |  |     {	$idx!= 0 or $idx=1; | 
					
						
							|  |  |  | 	$ret .= "($reg1,$reg2,$idx)"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     elsif ($reg1) | 
					
						
							|  |  |  |     {	$ret .= "($reg1)";	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   $ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | sub ::QWP	{ &::DWP(@_);	} | 
					
						
							|  |  |  | sub ::BP	{ &::DWP(@_);	} | 
					
						
							| 
									
										
										
										
											2010-06-04 21:13:18 +08:00
										 |  |  | sub ::WP	{ &::DWP(@_);	} | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | sub ::BC	{ @_;		} | 
					
						
							|  |  |  | sub ::DWC	{ @_;		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sub ::file | 
					
						
							| 
									
										
										
										
											2017-05-11 02:24:56 +08:00
										 |  |  | {   push(@out,".text\n");	} | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | sub ::function_begin_B | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  | { my $func=shift; | 
					
						
							| 
									
										
										
										
											2007-11-25 00:03:57 +08:00
										 |  |  |   my $global=($func !~ /^_/); | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  |   my $begin="${::lbdecor}_${func}_begin"; | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  |     &::LABEL($func,$global?"$begin":"$nmdecor$func"); | 
					
						
							| 
									
										
										
										
											2007-11-25 00:03:57 +08:00
										 |  |  |     $func=$nmdecor.$func; | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-25 00:03:57 +08:00
										 |  |  |     push(@out,".globl\t$func\n")	if ($global); | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  |     if ($::coff) | 
					
						
							| 
									
										
										
										
											2008-07-22 16:44:31 +08:00
										 |  |  |     {	push(@out,".def\t$func;\t.scl\t".(3-$global).";\t.type\t32;\t.endef\n"); } | 
					
						
							| 
									
										
										
										
											2007-12-19 01:28:22 +08:00
										 |  |  |     elsif (($::aout and !$::pic) or $::macosx) | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  |     { } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     {	push(@out,".type	$func,\@function\n"); } | 
					
						
							|  |  |  |     push(@out,".align\t$align\n"); | 
					
						
							|  |  |  |     push(@out,"$func:\n"); | 
					
						
							| 
									
										
										
										
											2007-11-25 00:03:57 +08:00
										 |  |  |     push(@out,"$begin:\n")		if ($global); | 
					
						
							| 
									
										
										
										
											2020-01-31 21:07:01 +08:00
										 |  |  |     &::endbranch(); | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  |     $::stack=4; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sub ::function_end_B | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  | { my $func=shift; | 
					
						
							|  |  |  |     push(@out,".size\t$nmdecor$func,.-".&::LABEL($func)."\n") if ($::elf); | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  |     $::stack=0; | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  |     &::wipe_labels(); | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sub ::comment | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	if (!defined($com_start) or $::elf) | 
					
						
							|  |  |  | 		{	# Regarding $::elf above... | 
					
						
							| 
									
										
										
										
											2004-08-02 05:16:26 +08:00
										 |  |  | 			# GNU and SVR4 as'es use different comment delimiters, | 
					
						
							|  |  |  | 		push(@out,"\n");	# so we just skip ELF comments... | 
					
						
							| 
									
										
										
										
											2003-01-04 01:37:53 +08:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 	foreach (@_) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 		if (/^\s*$/) | 
					
						
							| 
									
										
										
										
											1998-12-21 18:56:39 +08:00
										 |  |  | 			{ push(@out,"\n"); } | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											1998-12-21 18:56:39 +08:00
										 |  |  | 			{ push(@out,"\t$com_start $_ $com_end\n"); } | 
					
						
							| 
									
										
										
										
											1998-12-21 18:52:47 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  | sub ::external_label | 
					
						
							| 
									
										
										
										
											2008-01-05 06:58:50 +08:00
										 |  |  | {   foreach(@_) { &::LABEL($_,$nmdecor.$_); }   } | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | sub ::public_label | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  | {   push(@out,".globl\t".&::LABEL($_[0],$nmdecor.$_[0])."\n");   } | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | sub ::file_end | 
					
						
							| 
									
										
										
										
											2011-05-19 00:28:53 +08:00
										 |  |  | {   if ($::macosx) | 
					
						
							| 
									
										
										
										
											2008-01-05 06:58:50 +08:00
										 |  |  |     {	if (%non_lazy_ptr) | 
					
						
							| 
									
										
										
										
											2007-12-19 01:28:22 +08:00
										 |  |  |     	{   push(@out,".section __IMPORT,__pointers,non_lazy_symbol_pointers\n"); | 
					
						
							|  |  |  | 	    foreach $i (keys %non_lazy_ptr) | 
					
						
							|  |  |  | 	    {	push(@out,"$non_lazy_ptr{$i}:\n.indirect_symbol\t$i\n.long\t0\n");   } | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-05-19 00:28:53 +08:00
										 |  |  |     if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) { | 
					
						
							| 
									
										
										
										
											2012-11-18 03:04:15 +08:00
										 |  |  | 	my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,16"; | 
					
						
							| 
									
										
										
										
											2011-11-12 20:16:11 +08:00
										 |  |  | 	if ($::macosx)	{ push (@out,"$tmp,2\n"); } | 
					
						
							|  |  |  | 	elsif ($::elf)	{ push (@out,"$tmp,4\n"); } | 
					
						
							| 
									
										
										
										
											2011-05-19 00:28:53 +08:00
										 |  |  | 	else		{ push (@out,"$tmp\n"); } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  |     push(@out,$initseg) if ($initseg); | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sub ::data_byte	{   push(@out,".byte\t".join(',',@_)."\n");   } | 
					
						
							| 
									
										
										
										
											2011-02-11 05:24:24 +08:00
										 |  |  | sub ::data_short{   push(@out,".value\t".join(',',@_)."\n");  } | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | sub ::data_word {   push(@out,".long\t".join(',',@_)."\n");   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sub ::align | 
					
						
							| 
									
										
										
										
											2012-04-28 18:36:58 +08:00
										 |  |  | { my $val=$_[0]; | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  |     if ($::aout) | 
					
						
							| 
									
										
										
										
											2012-04-28 18:36:58 +08:00
										 |  |  |     {	$val=int(log($val)/log(2)); | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | 	$val.=",0x90"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     push(@out,".align\t$val\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sub ::picmeup | 
					
						
							|  |  |  | { my($dst,$sym,$base,$reflabel)=@_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-27 21:22:13 +08:00
										 |  |  |     if (($::pic && ($::elf || $::aout)) || $::macosx) | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  |     {	if (!defined($base)) | 
					
						
							|  |  |  | 	{   &::call(&::label("PIC_me_up")); | 
					
						
							|  |  |  | 	    &::set_label("PIC_me_up"); | 
					
						
							|  |  |  | 	    &::blindpop($dst); | 
					
						
							| 
									
										
										
										
											2007-12-19 01:28:22 +08:00
										 |  |  | 	    $base=$dst; | 
					
						
							|  |  |  | 	    $reflabel=&::label("PIC_me_up"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if ($::macosx) | 
					
						
							|  |  |  | 	{   my $indirect=&::static_label("$nmdecor$sym\$non_lazy_ptr"); | 
					
						
							|  |  |  | 	    &::mov($dst,&::DWP("$indirect-$reflabel",$base)); | 
					
						
							|  |  |  | 	    $non_lazy_ptr{"$nmdecor$sym"}=$indirect; | 
					
						
							| 
									
										
										
										
											2000-12-05 13:10:05 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-27 21:22:13 +08:00
										 |  |  | 	elsif ($sym eq "OPENSSL_ia32cap_P" && $::elf>0) | 
					
						
							|  |  |  | 	{   &::lea($dst,&::DWP("$sym-$reflabel",$base));   } | 
					
						
							| 
									
										
										
										
											2003-01-04 01:37:53 +08:00
										 |  |  | 	else | 
					
						
							| 
									
										
										
										
											2008-01-05 06:58:50 +08:00
										 |  |  | 	{   &::lea($dst,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]", | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | 			    $base)); | 
					
						
							| 
									
										
										
										
											2008-01-05 06:58:50 +08:00
										 |  |  | 	    &::mov($dst,&::DWP("$sym\@GOT",$dst)); | 
					
						
							| 
									
										
										
										
											2002-12-14 01:56:14 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     {	&::lea($dst,&::DWP($sym));	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2002-12-14 01:56:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  | sub ::initseg | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  | { my $f=$nmdecor.shift; | 
					
						
							| 
									
										
										
										
											2004-07-27 04:18:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-15 16:32:16 +08:00
										 |  |  |     if ($::android) | 
					
						
							|  |  |  |     {	$initseg.=<<___; | 
					
						
							|  |  |  | .section	.init_array | 
					
						
							|  |  |  | .align	4 | 
					
						
							|  |  |  | .long	$f | 
					
						
							|  |  |  | ___ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     elsif ($::elf) | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  |     {	$initseg.=<<___; | 
					
						
							| 
									
										
										
										
											2004-08-30 00:10:27 +08:00
										 |  |  | .section	.init | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  | 	call	$f | 
					
						
							| 
									
										
										
										
											2004-07-27 04:18:55 +08:00
										 |  |  | ___ | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     elsif ($::coff) | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  |     {   $initseg.=<<___;	# applies to both Cygwin and Mingw | 
					
						
							| 
									
										
										
										
											2004-08-30 00:10:27 +08:00
										 |  |  | .section	.ctors | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  | .long	$f | 
					
						
							| 
									
										
										
										
											2007-12-19 01:28:22 +08:00
										 |  |  | ___ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     elsif ($::macosx) | 
					
						
							|  |  |  |     {	$initseg.=<<___; | 
					
						
							|  |  |  | .mod_init_func | 
					
						
							|  |  |  | .align 2 | 
					
						
							|  |  |  | .long   $f | 
					
						
							| 
									
										
										
										
											2004-08-30 00:10:27 +08:00
										 |  |  | ___ | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     elsif ($::aout) | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  |     {	my $ctor="${nmdecor}_GLOBAL_\$I\$$f"; | 
					
						
							|  |  |  | 	$initseg.=".text\n"; | 
					
						
							|  |  |  | 	$initseg.=".type	$ctor,\@function\n" if ($::pic); | 
					
						
							|  |  |  | 	$initseg.=<<___;	# OpenBSD way... | 
					
						
							| 
									
										
										
										
											2004-08-30 05:36:37 +08:00
										 |  |  | .globl	$ctor | 
					
						
							| 
									
										
										
										
											2004-08-30 00:10:27 +08:00
										 |  |  | .align	2 | 
					
						
							| 
									
										
										
										
											2004-08-30 05:36:37 +08:00
										 |  |  | $ctor: | 
					
						
							| 
									
										
										
										
											2007-12-18 17:18:49 +08:00
										 |  |  | 	jmp	$f | 
					
						
							| 
									
										
										
										
											2004-08-30 00:10:27 +08:00
										 |  |  | ___ | 
					
						
							| 
									
										
										
										
											2006-09-19 03:17:09 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2004-08-30 00:10:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 16:44:31 +08:00
										 |  |  | sub ::dataseg | 
					
						
							|  |  |  | {   push(@out,".data\n");   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-29 22:19:59 +08:00
										 |  |  | *::hidden = sub { push(@out,".hidden\t$nmdecor$_[0]\n"); } if ($::elf); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-08-30 00:10:27 +08:00
										 |  |  | 1; |