Merge branch 'master' of github.com:lgeorget/KayrebtGlobsym
authorLaurent Georget <laurent.georget@inria.fr>
Wed, 1 Jul 2015 15:18:00 +0000 (17:18 +0200)
committerLaurent Georget <laurent.georget@inria.fr>
Wed, 1 Jul 2015 15:18:00 +0000 (17:18 +0200)
count_global_symbols.sh [new file with mode: 0755]
extract_global_symbols.pl [new file with mode: 0755]

diff --git a/count_global_symbols.sh b/count_global_symbols.sh
new file mode 100755 (executable)
index 0000000..f2bb2ea
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/zsh
+
+for i in $(find -name '*.dwo' -a ! -name '*built-in*' -a ! -wholename '*/drivers/*' -a ! -wholename '*/lib/*' ) ; do
+       if [[ ! -e ${i/%.dwo/.mod.c} ]]; then
+               for symbol in $(nm ${i/%.dwo/.o} | awk '$2 == "T" { print $3; }') ; do
+                       echo "$symbol $i" >> symbols.list
+               done
+       fi
+done
diff --git a/extract_global_symbols.pl b/extract_global_symbols.pl
new file mode 100755 (executable)
index 0000000..5911489
--- /dev/null
@@ -0,0 +1,81 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use File::Find ();
+use File::Basename;
+use Cwd;
+
+# Set the variable $File::Find::dont_use_nlink if you're using AFS,
+# since AFS cheats.
+
+# for the convenience of &wanted calls, including -eval statements:
+use vars qw/*name *dir *prune/;
+*name   = *File::Find::name;
+*dir    = *File::Find::dir;
+*prune  = *File::Find::prune;
+
+sub wanted;
+
+
+print <<'EOF';
+CREATE TABLE global_symbols   (        symbol TEXT,
+dir TEXT,
+file TEXT,
+line INTEGER);
+EOF
+
+# Traverse desired filesystems
+File::Find::find({wanted => \&wanted}, '.');
+
+sub wanted {
+    my ($dev,$ino,$mode,$nlink,$uid,$gid);
+
+    (
+       (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
+       $File::Find::name =~ /^\.\/lib\z/s
+       ||
+       $File::Find::name =~ /^\.\/arch\/x86\/lib\z/s
+       ||
+       $File::Find::name =~ /^\.\/drivers\z/s
+    ) &&
+    ($File::Find::prune = 1)
+    ||
+    (
+       /^.*\.dwo\z/s &&
+       ($nlink || (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_))) &&
+       ! /^.*built-in.*\z/s
+    ) &&
+    look_for_symbols_in_file($name);
+}
+
+
+sub look_for_symbols_in_file
+{
+       my $file = shift;
+       my ($base,$path,$suffix) = fileparse($file,('.dwo'));
+       if (! -e "$base.mod.c" && -e "$base.o")
+       {
+               #print STDERR "$base\n";
+               my $nm_output;
+               open ($nm_output, "-|", "nm -l -g --defined-only --no-sort $base.o");
+               while (<$nm_output>)
+               {
+                       if (/.*\s+T\s+(\w+).*:(\d+)/)
+                       {
+                               # print STDERR $_;
+                               my ($symbol,$line) = ($1,$2);
+                               # Special case for system calls
+                               next if $symbol =~ /^SyS_/;
+                               $symbol =~ s/^sys_/SYSC_/;
+
+                               print "INSERT INTO global_symbols (symbol,dir,file,line) VALUES ('$symbol', '$path', '$base.c', '$line');\n"
+                       }
+               }
+       }
+}
+
+1;
+
+__END__