Structure symbol decorations, optimize label handling...
This commit is contained in:
		| @@ -4,9 +4,11 @@ package x86nasm; | |||||||
|  |  | ||||||
| *out=\@::out; | *out=\@::out; | ||||||
|  |  | ||||||
| $lprfx="\@L"; | $lbdecor="\@L";			# local label decoration | ||||||
|  | $nmdecor=$::netware?"":"_";	# external name decoration | ||||||
|  | $drdecor=$::mwerks?".":"";	# directive decoration | ||||||
|  |  | ||||||
| $label="000"; | $label="000"; | ||||||
| $under=($::netware)?'':'_'; |  | ||||||
| $initseg=""; | $initseg=""; | ||||||
|  |  | ||||||
| sub ::generic | sub ::generic | ||||||
| @@ -29,7 +31,7 @@ sub ::movz	{ &::movzx(@_);		} | |||||||
| sub ::pushf	{ &::pushfd;		} | sub ::pushf	{ &::pushfd;		} | ||||||
| sub ::popf	{ &::popfd;		} | sub ::popf	{ &::popfd;		} | ||||||
|  |  | ||||||
| sub ::call	{ &::emit("call",(&islabel($_[0]) or "$under$_[0]")); } | sub ::call	{ &::emit("call",(&islabel($_[0]) or "$nmdecor$_[0]")); } | ||||||
| sub ::call_ptr	{ &::emit("call",@_);	} | sub ::call_ptr	{ &::emit("call",@_);	} | ||||||
| sub ::jmp_ptr	{ &::emit("jmp",@_);	} | sub ::jmp_ptr	{ &::emit("jmp",@_);	} | ||||||
|  |  | ||||||
| @@ -58,7 +60,7 @@ sub get_mem | |||||||
|  |  | ||||||
|     $addr =~ s/^\s+//; |     $addr =~ s/^\s+//; | ||||||
|     # prepend global references with optional underscore |     # prepend global references with optional underscore | ||||||
|     $addr =~ s/^([^\+\-0-9][^\+\-]*)/islabel($1) or "$under$1"/ige; |     $addr =~ s/^([^\+\-0-9][^\+\-]*)/islabel($1) or "$nmdecor$1"/ige; | ||||||
|     # put address arithmetic expression in parenthesis |     # put address arithmetic expression in parenthesis | ||||||
|     $addr="($addr)" if ($addr =~ /^.+[\-\+].+$/); |     $addr="($addr)" if ($addr =~ /^.+[\-\+].+$/); | ||||||
|  |  | ||||||
| @@ -102,20 +104,22 @@ ___ | |||||||
|  |  | ||||||
| sub ::function_begin_B | sub ::function_begin_B | ||||||
| { my $func=shift; | { my $func=shift; | ||||||
|   my $begin="${lprfx}_${func}_begin"; |   my $global=($func !~ /^_/); | ||||||
|   my $tmp=<<___; |   my $begin="${lbdecor}_${func}_begin"; | ||||||
| global	$func |  | ||||||
| align	16 |     $label{$func}=$global?"$begin":"$nmdecor$func"; | ||||||
| $under$func: |     $func=$nmdecor.$func; | ||||||
| $begin: |  | ||||||
| ___ |     push(@out,"${drdecor}global	$func\n")	if ($global); | ||||||
|     $label{$func}=$begin; |     push(@out,"${drdecor}align	16\n"); | ||||||
|     push(@out,$tmp); |     push(@out,"$func:\n"); | ||||||
|  |     push(@out,"$begin:\n")			if ($global); | ||||||
|     $::stack=4; |     $::stack=4; | ||||||
| } | } | ||||||
| sub ::function_end_B | sub ::function_end_B | ||||||
| { my $i; | { my $i; | ||||||
|     foreach $i (keys %label) { delete $label{$i} if ($label{$i} =~ /^${lprfx}[0-9]{3}/);  } |     foreach $i (keys %label) | ||||||
|  |     {	delete $label{$i} if ($label{$i} =~ /^${lbdecor}[0-9]{3}/);	} | ||||||
|     $::stack=0; |     $::stack=0; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -126,10 +130,10 @@ sub ::file_end | |||||||
| 	# was initialized already... | 	# was initialized already... | ||||||
| 	my $code=<<___; | 	my $code=<<___; | ||||||
| align	16 | align	16 | ||||||
| ${lprfx}OPENSSL_ia32cap_init: | ${lbdecor}OPENSSL_ia32cap_init: | ||||||
| 	lea	edx,[${under}OPENSSL_ia32cap_P] | 	lea	edx,[${nmdecor}OPENSSL_ia32cap_P] | ||||||
| 	cmp	DWORD [edx],0 | 	cmp	DWORD [edx],0 | ||||||
| 	jne	NEAR ${lprfx}nocpuid | 	jne	NEAR ${lbdecor}nocpuid | ||||||
| 	mov	DWORD [edx],1<<10 | 	mov	DWORD [edx],1<<10 | ||||||
| 	pushfd | 	pushfd | ||||||
| 	pop	eax | 	pop	eax | ||||||
| @@ -141,7 +145,7 @@ ${lprfx}OPENSSL_ia32cap_init: | |||||||
| 	pop	eax | 	pop	eax | ||||||
| 	xor	eax,ecx | 	xor	eax,ecx | ||||||
| 	bt	eax,21 | 	bt	eax,21 | ||||||
| 	jnc	NEAR ${lprfx}nocpuid | 	jnc	NEAR ${lbdecor}nocpuid | ||||||
| 	push	ebp | 	push	ebp | ||||||
| 	push	edi | 	push	edi | ||||||
| 	push	ebx | 	push	ebx | ||||||
| @@ -161,38 +165,38 @@ ${lprfx}OPENSSL_ia32cap_init: | |||||||
| 	mov	eax,1 | 	mov	eax,1 | ||||||
| 	cpuid | 	cpuid | ||||||
| 	cmp	ebp,0 | 	cmp	ebp,0 | ||||||
| 	jne	${lprfx}notP4 | 	jne	${lbdecor}notP4 | ||||||
| 	and	ah,15 | 	and	ah,15 | ||||||
| 	cmp	ah,15 | 	cmp	ah,15 | ||||||
| 	jne	${lprfx}notP4 | 	jne	${lbdecor}notP4 | ||||||
| 	or	edx,1<<20 | 	or	edx,1<<20 | ||||||
| ${lprfx}notP4: | ${lbdecor}notP4: | ||||||
| 	bt	edx,28 | 	bt	edx,28 | ||||||
| 	jnc	${lprfx}done | 	jnc	${lbdecor}done | ||||||
| 	shr	ebx,16 | 	shr	ebx,16 | ||||||
| 	cmp	bl,1 | 	cmp	bl,1 | ||||||
| 	ja	${lprfx}done | 	ja	${lbdecor}done | ||||||
| 	and	edx,0xefffffff | 	and	edx,0xefffffff | ||||||
| ${lprfx}done: | ${lbdecor}done: | ||||||
| 	or	edx,1<<10 | 	or	edx,1<<10 | ||||||
| 	mov	DWORD [edi],edx | 	mov	DWORD [edi],edx | ||||||
| 	pop	ebx | 	pop	ebx | ||||||
| 	pop	edi | 	pop	edi | ||||||
| 	pop	ebp | 	pop	ebp | ||||||
| ${lprfx}nocpuid: | ${lbdecor}nocpuid: | ||||||
| 	ret | 	ret | ||||||
| segment	.CRT\$XCU data align=4 | segment	.CRT\$XCU data align=4 | ||||||
| dd	${lprfx}OPENSSL_ia32cap_init | dd	${lbdecor}OPENSSL_ia32cap_init | ||||||
| ___ | ___ | ||||||
| 	my $data=<<___; | 	my $data=<<___; | ||||||
| segment	.bss | segment	.bss | ||||||
| common	${under}OPENSSL_ia32cap_P 4 | common	${nmdecor}OPENSSL_ia32cap_P 4 | ||||||
| ___ | ___ | ||||||
|  |  | ||||||
| 	#<not needed in OpenSSL context>#push (@out,$code); | 	#<not needed in OpenSSL context>#push (@out,$code); | ||||||
|  |  | ||||||
| 	# comment out OPENSSL_ia32cap_P declarations | 	# comment out OPENSSL_ia32cap_P declarations | ||||||
| 	grep {s/(^extern\s+${under}OPENSSL_ia32cap_P)/\;$1/} @out; | 	grep {s/(^extern\s+${nmdecor}OPENSSL_ia32cap_P)/\;$1/} @out; | ||||||
| 	push (@out,$data) | 	push (@out,$data) | ||||||
|     } |     } | ||||||
|     push (@out,$initseg) if ($initseg);		 |     push (@out,$initseg) if ($initseg);		 | ||||||
| @@ -209,19 +213,17 @@ sub islabel	# see is argument is known label | |||||||
| sub ::external_label | sub ::external_label | ||||||
| {   push(@labels,@_); | {   push(@labels,@_); | ||||||
|     foreach (@_) |     foreach (@_) | ||||||
|     {	push(@out,".") if ($::mwerks); |     {	push(@out, "${drdecor}extern\t${nmdecor}$_\n");	} | ||||||
| 	push(@out, "extern\t${under}$_\n"); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| sub ::public_label | sub ::public_label | ||||||
| {   $label{$_[0]}="${under}${_[0]}" if (!defined($label{$_[0]})); | {   $label{$_[0]}="${nmdecor}${_[0]}" if (!defined($label{$_[0]})); | ||||||
|     push(@out,"global\t$label{$_[0]}\n"); |     push(@out,"${drdecor}global\t$label{$_[0]}\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
| sub ::label | sub ::label | ||||||
| {   if (!defined($label{$_[0]})) | {   if (!defined($label{$_[0]})) | ||||||
|     {	$label{$_[0]}="${lprfx}${label}${_[0]}"; $label++;   } |     {	$label{$_[0]}="${lbdecor}${label}${_[0]}"; $label++;   } | ||||||
|   $label{$_[0]}; |   $label{$_[0]}; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -238,7 +240,7 @@ sub ::data_word | |||||||
| {   push(@out,(($::mwerks)?".long\t":"dd\t").join(',',@_)."\n");	} | {   push(@out,(($::mwerks)?".long\t":"dd\t").join(',',@_)."\n");	} | ||||||
|  |  | ||||||
| sub ::align | sub ::align | ||||||
| {   push(@out,".") if ($::mwerks); push(@out,"align\t$_[0]\n");	} | {   push(@out,"${drdecor}align\t$_[0]\n");	} | ||||||
|  |  | ||||||
| sub ::picmeup | sub ::picmeup | ||||||
| { my($dst,$sym)=@_; | { my($dst,$sym)=@_; | ||||||
| @@ -246,7 +248,7 @@ sub ::picmeup | |||||||
| } | } | ||||||
|  |  | ||||||
| sub ::initseg | sub ::initseg | ||||||
| { my($f)=$under.shift; | { my($f)=$nmdecor.shift; | ||||||
|     if ($::win32) |     if ($::win32) | ||||||
|     {	$initseg=<<___; |     {	$initseg=<<___; | ||||||
| segment	.CRT\$XCU data align=4 | segment	.CRT\$XCU data align=4 | ||||||
|   | |||||||
| @@ -4,11 +4,13 @@ package x86unix;	# GAS actually... | |||||||
|  |  | ||||||
| *out=\@::out; | *out=\@::out; | ||||||
|  |  | ||||||
| $label="L000"; | $lbdecor=$::aout?"L":".L";		# local label decoration | ||||||
|  | $nmdecor=($::aout or $::coff)?"_":"";	# external name decoration | ||||||
|  |  | ||||||
| $align=($::aout)?"4":"16"; | $label="000"; | ||||||
| $under=($::aout or $::coff)?"_":""; |  | ||||||
| $dot=($::aout)?"":"."; | $align=16; | ||||||
|  | $align=log($align)/log(2) if ($::aout); | ||||||
| $com_start="#" if ($::aout or $::coff); | $com_start="#" if ($::aout or $::coff); | ||||||
|  |  | ||||||
| sub opsize() | sub opsize() | ||||||
| @@ -63,7 +65,7 @@ sub ::popf	{ &::popfl;			} | |||||||
| sub ::cpuid	{ &::emit(".byte\t0x0f,0xa2");	} | sub ::cpuid	{ &::emit(".byte\t0x0f,0xa2");	} | ||||||
| sub ::rdtsc	{ &::emit(".byte\t0x0f,0x31");	} | sub ::rdtsc	{ &::emit(".byte\t0x0f,0x31");	} | ||||||
|  |  | ||||||
| sub ::call	{ &::emit("call",(&islabel($_[0]) or "$under$_[0]")); } | sub ::call	{ &::emit("call",(&islabel($_[0]) or "$nmdecor$_[0]")); } | ||||||
| sub ::call_ptr	{ &::generic("call","*$_[0]");	} | sub ::call_ptr	{ &::generic("call","*$_[0]");	} | ||||||
| sub ::jmp_ptr	{ &::generic("jmp","*$_[0]");	} | sub ::jmp_ptr	{ &::generic("jmp","*$_[0]");	} | ||||||
|  |  | ||||||
| @@ -89,7 +91,7 @@ sub ::DWP | |||||||
|  |  | ||||||
|     $addr =~ s/^\s+//; |     $addr =~ s/^\s+//; | ||||||
|     # prepend global references with optional underscore |     # prepend global references with optional underscore | ||||||
|     $addr =~ s/^([^\+\-0-9][^\+\-]*)/islabel($1) or "$under$1"/ige; |     $addr =~ s/^([^\+\-0-9][^\+\-]*)/islabel($1) or "$nmdecor$1"/ige; | ||||||
|  |  | ||||||
|     $reg1 = "%$reg1" if ($reg1); |     $reg1 = "%$reg1" if ($reg1); | ||||||
|     $reg2 = "%$reg2" if ($reg2); |     $reg2 = "%$reg2" if ($reg2); | ||||||
| @@ -115,14 +117,15 @@ sub ::file | |||||||
|  |  | ||||||
| sub ::function_begin_B | sub ::function_begin_B | ||||||
| { my($func,$extra)=@_; | { my($func,$extra)=@_; | ||||||
|   my $begin; |   my $global=($func !~ /^_/); | ||||||
|  |   my $begin="${lbdecor}_${func}_begin"; | ||||||
|  |  | ||||||
|     &::external_label($func); |     &::external_label($func); | ||||||
|     $label{$func} = $begin = "${dot}L_${func}_begin"; |     $label{$func} = $global?"$begin":"$nmdecor$func"; | ||||||
|     $func=$under.$func; |     $func=$nmdecor.$func; | ||||||
|  |  | ||||||
|     push(@out,".text\n"); |     push(@out,".text\n"); | ||||||
|     push(@out,".globl\t$func\n") if ($func !~ /^${under}_/); |     push(@out,".globl\t$func\n")	if ($global); | ||||||
|     if ($::coff) |     if ($::coff) | ||||||
|     {	push(@out,".def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } |     {	push(@out,".def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } | ||||||
|     elsif ($::aout and !$::pic) |     elsif ($::aout and !$::pic) | ||||||
| @@ -131,7 +134,7 @@ sub ::function_begin_B | |||||||
|     {	push(@out,".type	$func,\@function\n"); } |     {	push(@out,".type	$func,\@function\n"); } | ||||||
|     push(@out,".align\t$align\n"); |     push(@out,".align\t$align\n"); | ||||||
|     push(@out,"$func:\n"); |     push(@out,"$func:\n"); | ||||||
|     push(@out,"$begin:\n"); |     push(@out,"$begin:\n")		if ($global); | ||||||
|     $::stack=4; |     $::stack=4; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -139,11 +142,10 @@ sub ::function_end_B | |||||||
| { my($func)=@_; | { my($func)=@_; | ||||||
|   my $i; |   my $i; | ||||||
|  |  | ||||||
|     push(@out,"${dot}L_${func}_end:\n"); |     push(@out,".size\t$nmdecor$func,.-$label{$func}\n") if ($::elf); | ||||||
|     if ($::elf) |     foreach $i (keys %label) | ||||||
|     {	push(@out,".size\t$under$func,${dot}L_${func}_end-${dot}L_${func}_begin\n"); } |     {	delete $label{$i} if ($label{$i} =~ /^${lbdecor}[0-9]{3}/);	} | ||||||
|     $::stack=0; |     $::stack=0; | ||||||
|     foreach $i (keys %label) { delete $label{$i} if ($label{$i} =~ /^${dot}L[0-9]{3}/); } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| sub ::comment | sub ::comment | ||||||
| @@ -172,13 +174,13 @@ sub islabel	# see is argument is a known label | |||||||
| sub ::external_label { push(@labels,@_); } | sub ::external_label { push(@labels,@_); } | ||||||
|  |  | ||||||
| sub ::public_label | sub ::public_label | ||||||
| {   $label{$_[0]}="${under}${_[0]}"	if (!defined($label{$_[0]})); | {   $label{$_[0]}="${nmdecor}${_[0]}"	if (!defined($label{$_[0]})); | ||||||
|     push(@out,".globl\t$label{$_[0]}\n"); |     push(@out,".globl\t$label{$_[0]}\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
| sub ::label | sub ::label | ||||||
| {   if (!defined($label{$_[0]})) | {   if (!defined($label{$_[0]})) | ||||||
|     {	$label{$_[0]}="${dot}${label}${_[0]}"; $label++;   } |     {	$label{$_[0]}="${lbdecor}${label}${_[0]}"; $label++;   } | ||||||
|   $label{$_[0]}; |   $label{$_[0]}; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -193,7 +195,7 @@ sub ::file_end | |||||||
|     if ($::elf && grep {/\b%[x]?mm[0-7]\b|OPENSSL_ia32cap_P\b/i} @out) { |     if ($::elf && grep {/\b%[x]?mm[0-7]\b|OPENSSL_ia32cap_P\b/i} @out) { | ||||||
|  |  | ||||||
| 	push (@out,"\n.section\t.bss\n"); | 	push (@out,"\n.section\t.bss\n"); | ||||||
| 	push (@out,".comm\t${under}OPENSSL_ia32cap_P,4,4\n"); | 	push (@out,".comm\t${nmdecor}OPENSSL_ia32cap_P,4,4\n"); | ||||||
|  |  | ||||||
| 	return;	# below is not needed in OpenSSL context | 	return;	# below is not needed in OpenSSL context | ||||||
|  |  | ||||||
| @@ -280,14 +282,14 @@ sub ::picmeup | |||||||
| 	{   &::call(&::label("PIC_me_up")); | 	{   &::call(&::label("PIC_me_up")); | ||||||
| 	    &::set_label("PIC_me_up"); | 	    &::set_label("PIC_me_up"); | ||||||
| 	    &::blindpop($dst); | 	    &::blindpop($dst); | ||||||
| 	    &::add($dst,"\$${under}_GLOBAL_OFFSET_TABLE_+[.-". | 	    &::add($dst,"\$${nmdecor}_GLOBAL_OFFSET_TABLE_+[.-". | ||||||
| 			    &::label("PIC_me_up") . "]"); | 			    &::label("PIC_me_up") . "]"); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{   &::lea($dst,&::DWP("${under}_GLOBAL_OFFSET_TABLE_+[.-$reflabel]", | 	{   &::lea($dst,&::DWP("${nmdecor}_GLOBAL_OFFSET_TABLE_+[.-$reflabel]", | ||||||
| 			    $base)); | 			    $base)); | ||||||
| 	} | 	} | ||||||
| 	&::mov($dst,&::DWP($under.$sym."\@GOT",$dst)); | 	&::mov($dst,&::DWP("$nmdecor$sym\@GOT",$dst)); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     {	&::lea($dst,&::DWP($sym));	} |     {	&::lea($dst,&::DWP($sym));	} | ||||||
| @@ -300,7 +302,7 @@ sub ::initseg | |||||||
|     if ($::elf) |     if ($::elf) | ||||||
|     {	$tmp=<<___; |     {	$tmp=<<___; | ||||||
| .section	.init | .section	.init | ||||||
| 	call	$under$f | 	call	$nmdecor$f | ||||||
| 	jmp	.Linitalign | 	jmp	.Linitalign | ||||||
| .align	$align | .align	$align | ||||||
| .Linitalign: | .Linitalign: | ||||||
| @@ -309,18 +311,18 @@ ___ | |||||||
|     elsif ($::coff) |     elsif ($::coff) | ||||||
|     {   $tmp=<<___;	# applies to both Cygwin and Mingw |     {   $tmp=<<___;	# applies to both Cygwin and Mingw | ||||||
| .section	.ctors | .section	.ctors | ||||||
| .long	$under$f | .long	$nmdecor$f | ||||||
| ___ | ___ | ||||||
|     } |     } | ||||||
|     elsif ($::aout) |     elsif ($::aout) | ||||||
|     {	$ctor="${under}_GLOBAL_\$I\$$f"; |     {	$ctor="${nmdecor}_GLOBAL_\$I\$$f"; | ||||||
| 	$tmp=".text\n"; | 	$tmp=".text\n"; | ||||||
| 	$tmp.=".type	$ctor,\@function\n" if ($::pic); | 	$tmp.=".type	$ctor,\@function\n" if ($::pic); | ||||||
| 	$tmp.=<<___;	# OpenBSD way... | 	$tmp.=<<___;	# OpenBSD way... | ||||||
| .globl	$ctor | .globl	$ctor | ||||||
| .align	2 | .align	2 | ||||||
| $ctor: | $ctor: | ||||||
| 	jmp	$under$f | 	jmp	$nmdecor$f | ||||||
| ___ | ___ | ||||||
|     } |     } | ||||||
|     push(@out,$tmp) if ($tmp); |     push(@out,$tmp) if ($tmp); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Andy Polyakov
					Andy Polyakov