1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
#!/usr/bin/perl
# Copyright (C) 2012, 2019 Christoph Berg <myon@debian.org>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# Gross hack to read the contents of Pg_magic_data from a .so file
use strict;
use warnings;
my $version_only = 0;
if ($ARGV[0] eq '-v') {
$version_only = 1;
shift @ARGV;
}
my $so = $ARGV[0] || die "Usage: $0 .so";
my $objdump = `objdump -d $so`;
my $address;
# 0000000000006880 <Pg_magic_func>:
# 6880: 48 8d 05 19 06 01 00 lea 0x10619(%rip),%rax # 16ea0 <_fini+0x11c>
if ($objdump =~ /<Pg_magic_func(?:\@\@Base)?>:\n.* # ([[:xdigit:]]+) </) {
$address = hex($1);
# ... # 50a0 <Pg_magic_data.18191>
} elsif ($objdump =~ /# ([[:xdigit:]]+) <Pg_magic_data/) {
$address = hex($1);
} else {
die "No Pg_magic_data found in objdump -d $so output";
}
#print "address is $address ($1)\n";
open F, $so;
seek F, $address, 0;
my $data;
read F, $data, 4; # one integer
my $sizeof_pg_magic_struct = unpack("l", $data);;
#print "sizeof(Pg_magic_struct): $sizeof_pg_magic_struct\n";
read F, $data, $sizeof_pg_magic_struct - 4; # rest of Pg_magic_struct
my @integers = unpack("l*", $data);
my $PG_VERSION_NUM = $integers[0];
if ($version_only) {
printf "%d.%d\n", $PG_VERSION_NUM / 100, $PG_VERSION_NUM % 100;
exit 0;
}
my @fields = qw(PG_VERSION_NUM);
if ($PG_VERSION_NUM <= 803) { # 8.2 and 8.3 (Pg_magic_struct was introduced in 8.2)
@fields = qw(PG_VERSION_NUM FUNC_MAX_ARGS INDEX_MAX_KEYS NAMEDATALEN);
} else { # 8.4 to 9.2
@fields = qw(PG_VERSION_NUM FUNC_MAX_ARGS INDEX_MAX_KEYS NAMEDATALEN FLOAT4PASSBYVAL FLOAT8PASSBYVAL);
}
foreach my $integer (@integers) {
my $field = shift @fields;
print "$field: $integer\n";
}
|