[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: perl script to find symbols for libgcc-compat



Daniel,
     Okay. Here is a version called dpkgdeb-findsyms.pl which
will take packages on the command line as below...

./dpkgdeb-findsyms.pl nautilus2-gtkhtml_0.3.2-5_powerpc.deb
sendmail_8.12.5-1_powerpc.deb

and after extracting them in ./dpkg-deb-tmpdir with dpkg-deb -x
will check them for libgcc symbols. The tmpdir is cleaned out the
start each run but you will have to do something to script 
archiving of the final.list and found.list after each call to
dpkgdeb-findsyms.pl.
                                 Jack
#!/usr/bin/perl
# findsym perl script by Jack Howarth <howarth@bromo.med.uc.edu>
# v 1.0.7 Sept. 7, 2002
#
# This program creates a table of symbols being resolved in libgcc_s.so.1
# as parsed.list. These symbols are then searched for in all the paths set
# below in the creation of the files.list. The program keeps a running tally
# of whether a symbol has been found in the array "symused" which matches
# those in the "symbols" array. The progress of the search is displayed by
# listing the file being examined. At the end of the run, those symbols discovered
# are saved to the file final.list. Any symbol found in this final.list will
# have to be present in a sysdeps/<arch>/libgcc-compat.S or .c to allow for
# run-time resolution (BUT NOT EXPORTED FOR LINKING). Failure to do this for
# gcc >= 3.1 built glibc will result in those binaries with the symbols in
# files.list failing under that glibc because of unresolvable symbols.
#
# Note: no output is created in files.list until the run is completed so
# be patient...
#
# v.1.0 initial release
# v 1.0.3 added found.list to log which files had which symbols
# v 1.0.5 don't look at binaries or libraries linked to libstdc++
#         or in libstdc++.so or libgcj.so and also discard
#         any symbols c++ frame related symbols
# v 1.0.6 avoid libgcj.so and libstdc++ since c++ code
# v 1.0.7 customized for use with dpkg-deb
#
# for comparision the symbols found for libgcc-compat on ppc are...
# __divdi3; __moddi3; __udivdi3; __umoddi3; __cmpdi2; __ucmpdi2;
# __ashldi3; __ashrdi3; __lshrdi3; __fixdfdi; __fixunsdfdi;
# __fixsfdi; __fixunssfdi; __floatdidf; __floatdisf;
#
# and the symbols found on ia64 for libgcc-compat are
# __divtf3; __divdf3; __divsf3; __divdi3; __moddi3; __udivdi3; __umoddi3;
# __multi3;
#
#
# ************************************************
# EDIT THE LINE BELOW TO ADJUST THE SEARCH PATH!!!
# ************************************************
#system "find /lib /bin /sbin /usr/lib /usr/bin /usr/sbin /usr/X11R6 > files.list";

$command="rm -fr ./dpkg-deb-tmpdir";
system $command;
$command="mkdir ./dpkg-deb-tmpdir";
system $command;
foreach $i (0 .. $#ARGV) {
        $debpackage=$ARGV[$i];
	$command="dpkg-deb -x ".$debpackage." ./dpkg-deb-tmpdir";
	system $command;
	}
 
system "find ./dpkg-deb-tmpdir > files.list";


system "nm --defined-only -D /lib/libgcc_s.so.1 > raw.list";
open (FILESLIST,"files.list");
open (RAWLIST,"raw.list");
open (PARSEDLIST,">parsed.list");
open (FOUNDLIST,">found.list");

print "parsing raw.list into parsed.list...\n";
$numsyms=0;
while (<RAWLIST>) {
	@fields = split(' ',$_);
	if (($fields[$#fields-1] eq "T") && ($fields[$#fields] =~ "__") && !($fields[$#fields] =~ "frame")) {
	print PARSEDLIST $fields[$#fields],"\n";
	$numsyms = $numsyms+1;
	}
}
close(RAWLIST);
close(PARSEDLIST);
print "total number of symbols in libgcc_s.so.1 was ",$numsyms,"\n";
$#symbols=$numsyms;
$#symused=$numsyms;
open (PARSEDLIST,"parsed.list");
$counter=0;
while (<PARSEDLIST>) {
	chop($_);
	@symbols[$counter] = $_;
	@symused[$counter] = 0;
	$counter = $counter+1;
}
close(PARSEDLIST);


print "Searching for libgcc symbols in...\n";
while (<FILESLIST>) {
	chop;
	$currentfile=$_;
	$command="ldd ".$currentfile." | grep libstdc++ > hascplusplus";
	system $command;
	open (HASCPLUSPLUS, "hascplusplus");
	if (eof(HASCPLUSPLUS)) {
		if (!($currentfile =~ "libgcj.so")) {
			if (!($currentfile =~ "libstdc")) {
				$command="nm -D ".$currentfile." > current.list";
				system $command;
				print $currentfile,"\n";
				open (CURRENTLIST, "current.list");
				while (<CURRENTLIST>) {
					for ($counter=0;$counter<=$numsyms;$counter++) {
						if (/U $symbols[$counter]$/)  {
							@symused[$counter]=1;
							print FOUNDLIST $currentfile,"  ",$symbols[$counter],"\n";
						}
					}
				}
				close(CURRENTLIST);
			}
		}
	}
	close (HASCPLUSPLUS);
}
open (FINALLIST,">final.list");
for ($counter=0;$counter<=$numsyms;$counter++) {
	if (@symused[$counter]!=0) {
		print FINALLIST @symbols[$counter],"\n";
	}
}
close(FINALLIST);
close(FOUNDLIST);
print "Symbol search complete...\n";
print "  final.list contains the list of candidate libgcc symbols for libgcc-compat.\n";
print "  found.list contains the list of which symbol was undefined in which file.\n";
print "From the symbols found you must eliminate those versioned references\n";
print "which are satisfied because of linking against libgcc_s.so (like\n";
print "all c++ programs).\n";

Reply to: