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