]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/tool/backtrace
update
[l4.git] / kernel / fiasco / tool / backtrace
1 #! /usr/bin/perl -W
2
3 use Math::BigInt;
4 use strict;
5
6 my %sym_tab = (new Math::BigInt(0) => "ERRRRRRROR");
7 my $sections = "BdDdTtVvWwuU";
8 my $img = shift;
9 my %sec_tab;
10
11 my %test;
12
13 sub as_hex($)
14 {
15   my $i = shift;
16   my $h = substr $i->as_hex(), 2;
17   $h = ('0' x (16-length($h))) . $h;
18   return $h;
19 }
20
21 if (!defined $img)
22 {
23   print "$0 image\n";
24   print " input is read from stdin\n";
25   exit 1;
26 }
27
28 my $nm = 'nm';
29 $nm = "$ENV{'SYSTEM_TARGET'}$nm" if defined $ENV{"SYSTEM_TARGET"};
30 $nm = 'arm-softfloat-elf-nm' if !(system("file -L $img | grep -qw ARM") >> 8);
31
32 foreach my $l (split('\n', qx{$nm $img | c++filt}))
33 {
34   if ($l =~ /^([0-9a-fA-F]*)\s+([$sections])\s+(.*)$/)
35   {
36     my ($addr, $sec, $sym) = (new Math::BigInt("0x$1"), $2, $3);
37     if (defined $addr && ref $addr && !$addr->is_nan())
38     {
39       $sym_tab{as_hex($addr)} = $sym;
40       $sec_tab{as_hex($addr)} = $sec;
41     }
42   }
43 }
44 my @sorted_sym_tab_keys = sort keys %sym_tab;
45 my $min_addr = $sorted_sym_tab_keys[0];
46 my $max_addr = $sorted_sym_tab_keys[@sorted_sym_tab_keys - 1];
47
48 print "Scanning image done, proceed.\n";
49
50 sub find_sym($)
51 {
52   my $addr = as_hex(shift);
53   my $hit = '0';
54
55   return new Math::BigInt(0)
56     if $addr lt $min_addr or $addr gt $max_addr;
57
58   foreach my $s (@sorted_sym_tab_keys)
59   {
60     if ($s gt $addr)
61     {
62       return new Math::BigInt("0x$hit");
63     }
64
65     $hit = $s;
66   }
67
68   return new Math::BigInt(0);
69 }
70
71 sub print_func($)
72 {
73   my $addr = new Math::BigInt("0x".shift);
74   my $hit  = find_sym($addr);
75   my $offset = $addr-$hit;
76   my $o = $hit->as_hex();
77
78   return unless $hit;
79
80   printf " %s %30s(%s) + %6s = %s\n",
81          $addr->as_hex(), $sym_tab{as_hex($hit)}, $sec_tab{as_hex($hit)},
82          $offset->as_hex(), $hit->as_hex();
83 }
84
85
86 my $last_f = 0;
87 while (<>)
88 {
89   if (/^\s+#(\d+)\s+([0-9a-f]+)\s+([0-9a-f]+)/i) # fiasco bt without debuginfo
90   {
91     my $fn = $1;
92     my $stack = new Math::BigInt("0x$2");
93     my $addr = $3;
94     my $fsize = $stack - $last_f;
95
96     $last_f = $stack;
97     printf "%2d %s ", $fn, $stack->as_hex();
98     if ($fsize >= 0 && $fsize <= 2000)
99     {
100       printf "%4d", $fsize;
101     } else {
102       printf "....";
103     }
104     print_func($addr);
105   }
106   elsif (/^(?:.*?\|)?\s*(0x)?([0-9a-f]+)\s*$/i) # simple figure
107   {
108     print_func($2);
109   }
110   elsif (/^[\da-f]+:([\d\sa-f]+)$/i) # fiasco memory dump (mostly user stack)
111   {
112     my $l = $1;
113     for my $addr (split(/\s+/, $l))
114     {
115       print_func($addr);
116     }
117   }
118   elsif (/^\s*[\da-f]+\s+([\d\sa-f]+)\s*$/i) # fiasco tcb view stack
119   {
120     my $l = $1;
121     for my $val (split(/\s+/, $l))
122     {
123       next if $val eq '35353535'; # stack poison
124       if ($val =~ /^f.......(?:........)?$/i) {
125         print_func($val);
126       } else {
127         print " 0x$val  ... value ...\n";
128       }
129     }
130   }
131 }
132
133