| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package # Hide from CPAN, since this module is not terribly re-usable (yet) |
|
2
|
|
|
|
|
|
|
CPU::x86_64::InstructionWriter::_int32; |
|
3
|
17
|
|
|
17
|
|
12397
|
use strict; |
|
|
17
|
|
|
|
|
43
|
|
|
|
17
|
|
|
|
|
502
|
|
|
4
|
17
|
|
|
17
|
|
90
|
use warnings; |
|
|
17
|
|
|
|
|
48
|
|
|
|
17
|
|
|
|
|
454
|
|
|
5
|
17
|
|
|
17
|
|
85
|
use Exporter 'import'; |
|
|
17
|
|
|
|
|
36
|
|
|
|
17
|
|
|
|
|
9653
|
|
|
6
|
|
|
|
|
|
|
our @EXPORT_OK = qw( pack int64 ); |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
# ABSTRACT: Handle 64-bit integer operations on 32-bit perl |
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
# This wrapper only handles the specific use ELF::Writer makes of the pack |
|
11
|
|
|
|
|
|
|
# function which are not supported on all perls: |
|
12
|
|
|
|
|
|
|
# - 5.8 perl does not support ">" "<" modifiers. |
|
13
|
|
|
|
|
|
|
# - Perl compiled without 64-bit integers doesn't support "Q". |
|
14
|
|
|
|
|
|
|
# It would be nice if there were a standalone module that enhances 'pack' on |
|
15
|
|
|
|
|
|
|
# those old perls. |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# On 5.8, a 64-bit big-endian system needs to byte-swap 'Q<' fields |
|
18
|
|
|
|
|
|
|
sub _pack_wrapper_64_5_8_be { |
|
19
|
0
|
|
|
0
|
|
0
|
my $fmt= shift; |
|
20
|
0
|
|
|
|
|
0
|
my $new_fmt= ''; |
|
21
|
0
|
|
|
|
|
0
|
my @new_args; |
|
22
|
0
|
|
|
|
|
0
|
for (split / +/, $fmt) { # ELF::Writer uses spaces between all fields |
|
23
|
0
|
0
|
|
|
|
0
|
if ($_ eq 'Q<') { |
|
|
|
0
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
# Convert 64-bit integer into two 32-bit little-endian arguments |
|
25
|
0
|
|
|
|
|
0
|
$new_fmt .= 'VV'; |
|
26
|
0
|
|
|
|
|
0
|
my $qw= shift; |
|
27
|
0
|
|
|
|
|
0
|
push @new_args, ($qw & '4294967295'), ($qw >> 32); |
|
28
|
|
|
|
|
|
|
} elsif ($_ eq 'Q>') { |
|
29
|
0
|
|
|
|
|
0
|
$new_fmt .= 'Q'; |
|
30
|
0
|
|
|
|
|
0
|
push @new_args, shift; |
|
31
|
|
|
|
|
|
|
} else { |
|
32
|
0
|
|
|
|
|
0
|
$new_fmt .= $_; |
|
33
|
0
|
|
|
|
|
0
|
push @new_args, shift; |
|
34
|
|
|
|
|
|
|
} |
|
35
|
|
|
|
|
|
|
} |
|
36
|
0
|
|
|
|
|
0
|
return pack $new_fmt, @new_args; |
|
37
|
|
|
|
|
|
|
} |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
# On 5.8, a 64-bit little-endian system needs to byte-swap 'Q>' fields |
|
40
|
|
|
|
|
|
|
sub _pack_wrapper_64_5_8_le { |
|
41
|
0
|
|
|
0
|
|
0
|
my $fmt= shift; |
|
42
|
0
|
|
|
|
|
0
|
my $new_fmt= ''; |
|
43
|
0
|
|
|
|
|
0
|
my @new_args; |
|
44
|
0
|
|
|
|
|
0
|
for (split / +/, $fmt) { |
|
45
|
0
|
0
|
|
|
|
0
|
if ($_ eq 'Q>') { |
|
|
|
0
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
# Convert 64-bit integer into two 32-bit big-endian arguments |
|
47
|
0
|
|
|
|
|
0
|
$new_fmt .= 'NN'; |
|
48
|
0
|
|
|
|
|
0
|
my $qw= shift; |
|
49
|
0
|
|
|
|
|
0
|
push @new_args, ($qw >> 32), ($qw & '4294967295'); |
|
50
|
|
|
|
|
|
|
} elsif ($_ eq 'Q<') { |
|
51
|
0
|
|
|
|
|
0
|
$new_fmt .= 'Q'; |
|
52
|
0
|
|
|
|
|
0
|
push @new_args, shift; |
|
53
|
|
|
|
|
|
|
} else { |
|
54
|
0
|
|
|
|
|
0
|
$new_fmt .= $_; |
|
55
|
0
|
|
|
|
|
0
|
push @new_args, shift; |
|
56
|
|
|
|
|
|
|
} |
|
57
|
|
|
|
|
|
|
} |
|
58
|
0
|
|
|
|
|
0
|
return pack $new_fmt, @new_args; |
|
59
|
|
|
|
|
|
|
} |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
# On perl without 64-bit support, replace all 'Q' with 32-bit operations |
|
62
|
|
|
|
|
|
|
sub _pack_wrapper_32 { |
|
63
|
0
|
|
|
0
|
|
0
|
my $fmt= shift; |
|
64
|
0
|
|
|
|
|
0
|
my $new_fmt= ''; |
|
65
|
0
|
|
|
|
|
0
|
my @new_args; |
|
66
|
0
|
|
|
|
|
0
|
my $mask32= Math::BigInt->new('4294967295'); |
|
67
|
0
|
|
|
|
|
0
|
for (split / *(?=[A-Za-z])/, $fmt) { |
|
68
|
0
|
0
|
|
|
|
0
|
if ($_ eq 'Q>') { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
# Convert a 64-bit integer into two 32-bit big-endian arguments |
|
70
|
0
|
|
|
|
|
0
|
$new_fmt .= 'NN'; |
|
71
|
0
|
|
|
|
|
0
|
my $qw= Math::BigInt->new(shift); |
|
72
|
0
|
|
|
|
|
0
|
push @new_args, ($qw >> 32)->numify(), ($qw & $mask32)->numify(); |
|
73
|
|
|
|
|
|
|
} elsif ($_ eq 'Q<') { |
|
74
|
|
|
|
|
|
|
# Convert 64-bit integer into two 32-bit little-endian arguments |
|
75
|
0
|
|
|
|
|
0
|
$new_fmt .= 'VV'; |
|
76
|
0
|
|
|
|
|
0
|
my $qw= Math::BigInt->new(shift); |
|
77
|
0
|
|
|
|
|
0
|
push @new_args, ($qw & $mask32)->numify(), ($qw >> 32)->numify(); |
|
78
|
|
|
|
|
|
|
} elsif ($_ eq 'Q') { |
|
79
|
0
|
|
|
|
|
0
|
Carp::croak("Ambiguous 64-bit value"); |
|
80
|
|
|
|
|
|
|
} else { |
|
81
|
0
|
|
|
|
|
0
|
$new_fmt .= $_; |
|
82
|
0
|
|
|
|
|
0
|
push @new_args, shift; |
|
83
|
|
|
|
|
|
|
} |
|
84
|
|
|
|
|
|
|
} |
|
85
|
0
|
|
|
|
|
0
|
return pack $new_fmt, @new_args; |
|
86
|
|
|
|
|
|
|
} |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub _int64_native { |
|
89
|
17
|
|
|
17
|
|
143
|
no warnings 'portable'; |
|
|
17
|
|
|
|
|
65
|
|
|
|
17
|
|
|
|
|
2402
|
|
|
90
|
46
|
100
|
|
46
|
|
47156
|
$_[0] =~ /^(-?)0x(.*)/? hex($2)*($1? -1 : 1) : 0+$_[0] |
|
|
|
50
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
} |
|
92
|
|
|
|
|
|
|
sub _int64_bigint { |
|
93
|
0
|
|
|
0
|
|
|
Math::BigInt->new($_[0]) |
|
94
|
|
|
|
|
|
|
} |
|
95
|
|
|
|
|
|
|
|
|
96
|
17
|
|
|
17
|
|
140
|
no strict 'refs'; |
|
|
17
|
|
|
|
|
37
|
|
|
|
17
|
|
|
|
|
4448
|
|
|
97
|
|
|
|
|
|
|
# Do we have full support? |
|
98
|
|
|
|
|
|
|
if (eval { pack('Q<', 1) }) { |
|
99
|
|
|
|
|
|
|
*pack= CORE->can('pack')? \*CORE::pack : sub { pack(@_) }; |
|
100
|
|
|
|
|
|
|
} |
|
101
|
|
|
|
|
|
|
# Do we have 64bit? |
|
102
|
|
|
|
|
|
|
elsif (eval { pack('Q', 1) }) { |
|
103
|
|
|
|
|
|
|
# choose correct endian |
|
104
|
|
|
|
|
|
|
*pack= (pack('Q', 1) eq "\x01\0\0\0\0\0\0\0") |
|
105
|
|
|
|
|
|
|
? \&_pack_wrapper_64_5_8_le |
|
106
|
|
|
|
|
|
|
: \&_pack_wrapper_64_5_8_be; |
|
107
|
|
|
|
|
|
|
} |
|
108
|
|
|
|
|
|
|
# else need BigInteger implementation |
|
109
|
|
|
|
|
|
|
else { |
|
110
|
|
|
|
|
|
|
require Math::BigInt; |
|
111
|
|
|
|
|
|
|
*pack= \&_pack_wrapper_32; |
|
112
|
|
|
|
|
|
|
} |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# Can scalars hold 64-bit ints natively? |
|
115
|
|
|
|
|
|
|
if ((0x7FFFFFFE << 31) > 0 && (0x7FFFFFFE << 63) == 0) { # 64-bit scalar support |
|
116
|
|
|
|
|
|
|
*int64= \&_int64_native; |
|
117
|
|
|
|
|
|
|
} else { |
|
118
|
|
|
|
|
|
|
*int64= \&_int64_bigint; |
|
119
|
|
|
|
|
|
|
} |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
__END__ |