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

Re: perl script to find symbols for libgcc-compat



Matthias,
      Here is a new version that has a -h usage option as well
as a -d flag to define the directory path to libgcc_s.so.1. 
For example if you have libgcc_s.so.1 in the current
directory as well as two debian packages you can do...

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

This works here. Everyone should be using this version as the previous
version, 1.0.7, was dropping off the last package listed on the command
line! 
                             Jack
ps Again note if you script this you have to move off the final.list and
found.list after each run.

On Sun, 2002-09-08 at 08:14, Matthias Klose wrote:
> another improvement would be to read the used libgcc_s.so from the
> command line, use binutils-multiarch and run it nice'd on ftp-master
> or a mirror for all architectures ...
> 

#!/usr/bin/perl
# findsym perl script by Jack Howarth <howarth@bromo.med.uc.edu>
# v 1.0.8 Sept. 8, 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
# v 1.0.8 added -d flag for libgcc_s.so.1 directory path and 
#         -h flag for usage help
#
# 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";

$help = "debian-findsyms -- a program to identify undefined libgcc symbols\n";
$help = $help."------------------------------------------------------------------\n";
$help = $help."usage: debian-findsyms <-d libgcc_dir> debian_package_name... \n";
$help = $help."libgcc_dir: directory path to the desired libgcc_s.so.1\n";
$help = $help."debian_package_name...: space separated list of debian packages to be tested\n";

$libgccpath="/lib";

$command="rm -fr ./dpkg-deb-tmpdir ";
system $command;
$command="mkdir ./dpkg-deb-tmpdir";
system $command;

foreach $i (0 .. $#ARGV) {
	if ($ARGV[$i] =~ /-h/) {
			die $help;
		}
	elsif ($ARGV[$i] =~ /-d/) {
		$libgccpath=$ARGV[$i+1];
		# hack around having undesired arguments for dpkg-deb
		shift @ARGV;
		shift @ARGV;
	}
	else {
		# ugly hack warning...wonder how do do this cleanly
        	if ($ARGV[$i-1] ne "") { $debpackage=$ARGV[$i-1] };
		$command="dpkg-deb -x ".$debpackage." ./dpkg-deb-tmpdir";
		system $command;
	}
}


system "find ./dpkg-deb-tmpdir > files.list";

system "nm --defined-only -D ".$libgccpath."/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: