summaryrefslogtreecommitdiffstats
path: root/src/build/tools/gensyms
blob: 015c39d40894d2b2cfc53ff132c99c35cb17a6c0 (plain)
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/perl

use strict;

use IO::Seekable;

my $littleendian = (unpack("L", pack("N", 0xabcd1234)) != 0xabcd1234);

sub add_image_subdir
{
    my $image = shift;
    if (!($image =~ m/\/img/)) { $image = "./img/".$image };
    return $image;
}

my $image_offset = $ENV{"HAL_IMAGE_OFFSET"};
if (not $image_offset) { $image_offset = "0x0"; };
$image_offset = hex $image_offset;

my $image;
my $all_modules = 0;
my @modules = ();

if ($#ARGV == -1)
{
    die "gensyms <image> [modules]\n";
}
if ($#ARGV == 0)
{
    $all_modules = 1;
}
else
{
    @modules = @ARGV[1..$#ARGV];
}

$image = add_image_subdir($ARGV[0]);
open IMAGE, "< $image";
binmode(IMAGE);

my %module_offsets = ();
open MODINFO, "< $image.modinfo";

while (my $modline = <MODINFO>)
{
    chomp $modline;
    my @splitline = split /,/, $modline;
    $module_offsets{@splitline[0]} = (hex @splitline[1]) + $image_offset;
    if ($all_modules)
    {
	push @modules, @splitline[0];
    }
}

my @output = ();
foreach my $module (@modules)
{
    open OBJDUMP, ("ppc64-mcp6-objdump --syms -C ".add_image_subdir($module)."|");
    while (my $line = <OBJDUMP>)
    {
	if (($line =~ m/\*ABS\*/) || ($line =~ m/\*UND\*/))
	{
	    next;
	}
	if ("d" eq substr($line, 22, 1))
	{
	    next;
	}
	if (!($line =~ m/^[0-9a-f]{16}/))
	{
	    next;
	}

	$line =~ s/[\s]*$//;
	
	my $address = (hex substr($line, 0, 16)) + $module_offsets{$module};
	my $is_function = ("F" eq substr($line, 23, 1));
        my $size = (hex substr($line, 32, 16));
	my $name = substr($line, 48);
	my $code_loc = 0;
	if ($is_function)
	{
            seek IMAGE, ($address - $image_offset), SEEK_SET;
            read IMAGE, $code_loc, 8;
            if ($littleendian)
            {
                $code_loc = unpack("Q", reverse($code_loc)) + $image_offset;
            }
            else
            {
                $code_loc = unpack("Q", $code_loc) + $image_offset;
            }

            my $tmp = $code_loc; $code_loc = $address; $address = $tmp;
	}
	my $outstring = "";
	$outstring = sprintf "%s,%08x,%08x,%08x,%s\n", ($is_function?"F":"V"),$address,$code_loc,$size,$name;

	push @output, $outstring;
    }
    close OBJDUMP;
}

close IMAGE;

foreach my $outstring (sort { substr($a,2) cmp substr($b,2) } @output)
{
    print $outstring;
}
OpenPOWER on IntegriCloud