Index: third_party/codesighs/readelf_wrap.pl |
=================================================================== |
--- third_party/codesighs/readelf_wrap.pl (revision 0) |
+++ third_party/codesighs/readelf_wrap.pl (revision 0) |
@@ -0,0 +1,192 @@ |
+#!/usr/bin/perl -w |
+# -*- Mode: perl; tab-width: 4; indent-tabs-mode: nil; -*- |
+# ***** BEGIN LICENSE BLOCK ***** |
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
+# |
+# The contents of this file are subject to the Mozilla Public License Version |
+# 1.1 (the "License"); you may not use this file except in compliance with |
+# the License. You may obtain a copy of the License at |
+# http://www.mozilla.org/MPL/ |
+# |
+# Software distributed under the License is distributed on an "AS IS" basis, |
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
+# for the specific language governing rights and limitations under the |
+# License. |
+# |
+# The Original Code is readelf_wrap.pl. |
+# |
+# The Initial Developer of the Original Code is |
+# IBM Corporation. |
+# Portions created by the Initial Developer are Copyright (C) 2003 |
+# the Initial Developer. All Rights Reserved. |
+# |
+# Contributor(s): |
+# Brian Ryner <bryner@brianryner.com> |
+# |
+# Alternatively, the contents of this file may be used under the terms of |
+# either the GNU General Public License Version 2 or later (the "GPL"), or |
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
+# in which case the provisions of the GPL or the LGPL are applicable instead |
+# of those above. If you wish to allow use of your version of this file only |
+# under the terms of either the GPL or the LGPL, and not to allow others to |
+# use your version of this file under the terms of the MPL, indicate your |
+# decision by deleting the provisions above and replace them with the notice |
+# and other provisions required by the GPL or the LGPL. If you do not delete |
+# the provisions above, a recipient may use your version of this file under |
+# the terms of any one of the MPL, the GPL or the LGPL. |
+# |
+# ***** END LICENSE BLOCK ***** |
+ |
+use strict; |
+ |
+# Section fields (the full list of values is in <elf.h>) |
+my $SECT_NUM = 0; # section index |
+my $SECT_NAME = 1; # section name |
+my $SECT_TYPE = 2; # section type |
+my $SECT_ADDR = 3; # section virtual address |
+my $SECT_OFF = 4; # section offset in file |
+my $SECT_SIZE = 5; # size of section |
+my $SECT_ES = 6; # section entry size |
+my $SECT_FLG = 7; # section flags |
+my $SECT_LK = 8; # link to another section |
+my $SECT_INF = 9; # additional section info |
+my $SECT_AL = 10; # section alignment |
+ |
+ |
+# Symbol fields (note: the full list of possible values for each field |
+# is given in <elf.h>) |
+ |
+my $SYM_NUM = 0; # unique index of the symbol |
+my $SYM_VALUE = 1; # value of the symbol |
+my $SYM_SIZE = 2; # size of the symbol |
+my $SYM_TYPE = 3; # type (NOTYPE, OBJECT, FUNC, SECTION, FILE, ...) |
+my $SYM_BIND = 4; # binding/scope (LOCAL, GLOBAL, WEAK, ...) |
+my $SYM_VIS = 5; # visibility (DEFAULT, INTERNAL, HIDDEN, PROTECTED) |
+my $SYM_NDX = 6; # index of section the symbol is in |
+my $SYM_NAME = 7; # name of the symbol |
+my $SYM_FILE = 8; # (not part of readelf) file for symbol |
+ |
+# Tell readelf to print out the list of sections and then the symbols |
+die "Usage: $^X <binary>\n" unless ($#ARGV >= 0); |
+my $readelf = $ENV{'READELF_PROG'}; |
+if (!$readelf) { |
+ $readelf = 'readelf'; |
+} |
+open(READELF_OUTPUT, "$readelf -Ss $ARGV[0] 2>/dev/null | c++filt |") or die "readelf failed to run on $ARGV[0]\n"; |
+ |
+my @section_list; |
+my @symbol_list; |
+my ($module) = ($ARGV[0] =~ /([^\/]+)$/); |
+my $in_symbols = 0; |
+ |
+while (<READELF_OUTPUT>) { |
+ |
+ if (!$in_symbols) { |
+ if (/^ *\[ *(\d+)\]/) { |
+ my @section; |
+ |
+ # note that we strip off the leading '.' of section names for |
+ # readability |
+ if (! (@section = (/^ *\[ *(\d+)\] \.([\w\.\-]+) *(\w+) *(.{8}) (.{6}[0-9a-fA-F]*) (.{6}[0-9a-fA-F]*) *(\d+) ([a-zA-Z]+ +| +[a-zA-Z]+|) *(\d+) *(\w+) *(\d+)/))) { |
+ # capture the 'null' section which has no name, so that the |
+ # array indices are the same as the section indices. |
+ |
+ @section = ($1, '', 'NULL', '00000000', '000000', '000000', |
+ '00', '', '0', '0', '0'); |
+ } |
+ |
+ push (@section_list, \@section); |
+ } elsif (/^Symbol table/) { |
+ $in_symbols = 1; |
+ } |
+ } else { |
+ |
+ my @sym; |
+ |
+ if (@sym = /^\s*(\d+): (\w+)\s*(\d+)\s*(\w+)\s*(\w+)\s*(\w+)\s*(\w+) (.*)/) |
+ { |
+ # Filter out types of symbols that we don't care about: |
+ # - anything that's not of type OBJECT or FUNC |
+ # - any undefined symbols (ndx = UND[EF]) |
+ # - any 0-size symbols |
+ |
+ if (($sym[$SYM_TYPE] !~ /^(OBJECT|FUNC)$/) || |
+ $sym[$SYM_NDX] eq 'UND' || $sym[$SYM_NDX] eq 'UNDEF' |
+ || $sym[$SYM_SIZE] eq '0') { |
+ next; |
+ } |
+ push (@symbol_list, \@sym); |
+ } |
+ elsif (/^Symbol table .*'\.symtab'/) { |
+ # We've been using .dynsym up to this point, but if we have .symtab |
+ # available, it will have everything in .dynsym and more. |
+ # So, reset our symbol list. |
+ |
+ @symbol_list = (); |
+ } |
+ } |
+} |
+ |
+close(READELF_OUTPUT); |
+ |
+# spit them out in codesighs TSV format |
+my $sym; |
+my @section_sizes; |
+$#section_sizes = $#section_list; |
+foreach (@section_sizes) { $_ = 0; } |
+ |
+foreach $sym (@symbol_list) { |
+ # size |
+ printf "%08x\t", $sym->[$SYM_SIZE]; |
+ |
+ # code or data |
+ if ($sym->[$SYM_TYPE] eq 'FUNC') { |
+ print "CODE\t"; |
+ } else { # OBJECT |
+ print "DATA\t"; |
+ } |
+ |
+ # scope |
+ if ($sym->[$SYM_BIND] eq 'LOCAL') { |
+ print "STATIC\t"; |
+ } elsif ($sym->[$SYM_BIND] =~ /(GLOBAL|WEAK)/) { |
+ print "PUBLIC\t"; |
+ } else { |
+ print "UNDEF\t"; |
+ } |
+ |
+ # module name |
+ |
+ print "$module\t"; |
+ |
+ # section |
+ my $section = $section_list[$sym->[$SYM_NDX]]->[$SECT_NAME]; |
+ print "$section\t"; |
+ |
+ # should be the object file, but for now just module/section |
+ print "UNDEF:$module:$section\t"; |
+ |
+ # now the symbol name |
+ print $sym->[$SYM_NAME]."\n"; |
+ |
+ # update our cumulative section sizes |
+ $section_sizes[$section_list[$sym->[$SYM_NDX]]->[$SECT_NUM]] += $sym->[$SYM_SIZE]; |
+} |
+ |
+# Output extra entries to make the sum of the symbol sizes equal the |
+# section size. |
+ |
+my $section; |
+foreach $section (@section_list) { |
+ |
+ my $diff = hex($section->[$SECT_SIZE]) - $section_sizes[$section->[$SECT_NUM]]; |
+ if ($diff > 0) { |
+ my $sectname = $section->[$SECT_NAME]; |
+ if ($section->[$SECT_NAME] =~ /^(rodata|data|text|bss)/) { |
+ printf "%08x", $diff; |
+ print "\tDATA\tSTATIC\t$module\t$sectname\tUNDEF:$module:$sectname\t.nosyms.$sectname\n"; |
+# } else { |
+# print "ignoring $diff bytes of empty space in $sectname section\n"; |
+ } |
+ } |
+} |
Property changes on: third_party/codesighs/readelf_wrap.pl |
___________________________________________________________________ |
Added: svn:executable |
+ * |
Added: svn:eol-style |
+ LF |