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

perl script to find symbols for libgcc-compat



Hello,
    As an aid to those arches which haven't yet clearly determined if
they need to add a libgcc-compat for run-time resolution of the newly
.hidden libgcc symbols, I have created a perl script to gather these
symbols. Whether you can find all the symbols with it may be effected
by how many binaries/libraries you have available to search. However
it should at least clarify which arches need a libgcc-compat file added.
The perl script is based on the following assumptions

1) that only defined internal symbols in libgcc_s.so.1 are of interest
2) that "frame" related libgcc symbols can be ignored as they arrived
    after the .hidden change
3) that of the files to be searched for these symbols, those compiled 
    with c++ (as determined by libstdc++ linkage) can be ignored
4) likewise libgcj.so and libstdc++ themselves as c++ code can be
    ignored.

To run the program, place it in a directory with write access and
execute it. When finished you will have a list of candidate symbols
for libgcc-compat in final.list and a list of their occurrences in
the files searched in found.list. If anyone finds any flaws in this
search approach let me know and I'll see if I can fix it.
                                        Jack


#!/usr/bin/perl
# findsym perl script by Jack Howarth <howarth@bromo.med.uc.edu>
# v 1.0.6 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
#
# 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";


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: