New dispatch table for NSM
This commit is contained in:
Родитель
050ccab3fc
Коммит
1f15f5d9e2
|
@ -1196,12 +1196,14 @@ ifdef NETSCAPE_OFFICIAL
|
|||
@echo Creating a list of all object files ... objs.txt
|
||||
@echo $(OBJS) > $(OBJDIR)/objs.txt
|
||||
@echo $(EXPORT_OBJS) >> $(OBJDIR)/objs.txt
|
||||
@echo -L$(DIST)/bin >> $(OBJDIR)/objs.txt
|
||||
@echo -L$(DIST)/lib >> $(OBJDIR)/objs.txt
|
||||
@echo $(DSO_EX_LIBS) >> $(OBJDIR)/objs.txt
|
||||
@echo Creating a list of all symbols ... symbols.txt
|
||||
$(PERL) listsymb.pl objs.txt symbols.txt
|
||||
perl5 listsymb.pl $(OBJDIR)/objs.txt $(OBJDIR)/symbols.txt
|
||||
@echo Generating dispatch table ... dispunix.h dispunix.c cmoffset.h
|
||||
$(PERL) gendisp.pl symbols.txt dispunix.h dispunix.c cmoffset.h
|
||||
$(CC) -c -o $(OBJDIR)/dispunix.o -I$(DIST)/include dispunix.c
|
||||
perl5 gendisp.pl $(OBJDIR)/symbols.txt $(OBJDIR)/dispunix.h $(OBJDIR)/dispunix.c
|
||||
$(CC) -c -o $(OBJDIR)/dispunix.o -I$(DIST)/include -I$(OBJDIR) $(OBJDIR)/dispunix.c
|
||||
$(CCLD) -o $@ $(LDFLAGS) $(OBJDIR)/dispunix.o $(OBJS) $(EXPORT_OBJS) -L$(DIST)/bin -L$(DIST)/lib $(DSO_EX_LIBS) $(DNS_LIB)
|
||||
else
|
||||
$(CCLD) -o $@ $(LDFLAGS) $(OBJS) $(EXPORT_OBJS) -L$(DIST)/bin -L$(DIST)/lib $(DSO_EX_LIBS) $(DNS_LIB)
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
########################################################
|
||||
# gendispw.pl
|
||||
# Generates a table of pointers pointing to
|
||||
# functions in Communicator being exported.
|
||||
#
|
||||
# The list of functions are read from the input file.
|
||||
#
|
||||
########################################################
|
||||
|
||||
@symbols = ();
|
||||
|
||||
#####################################################
|
||||
#Step 0: Get command line options
|
||||
#####################################################
|
||||
$input_file = $ARGV[0];
|
||||
$header_file = $ARGV[1];
|
||||
$source_file = $ARGV[2];
|
||||
$cmoffset_file = $ARGV[3];
|
||||
UsageAndExit() if (scalar(@ARGV) != 4);
|
||||
|
||||
#####################################################
|
||||
# Step 1: Read $input_file which contains list of functions
|
||||
#####################################################
|
||||
GetFunctionList($input_file, \@symbols);
|
||||
|
||||
#####################################################
|
||||
# Step 2: Open dispatch.h and dispatch.c for output
|
||||
#####################################################
|
||||
open (DISPATCH_H, ">$header_file") or die("Can't open $header_file for output.\n");
|
||||
open (DISPATCH_C, ">$source_file") or die("Can't open $source_file for output.\n");
|
||||
open (CMOFFSET_H, ">$cmoffset_file") or die("Can't open $cmoffset_file for output.\n");
|
||||
|
||||
|
||||
#####################################################
|
||||
# Step 3: Write out the declarations in of header file
|
||||
#####################################################
|
||||
print DISPATCH_H ("#include \"nspr.h\"\n");
|
||||
print DISPATCH_H ("\n");
|
||||
print DISPATCH_H ("typedef void (*void_fun)(void);\n");
|
||||
print DISPATCH_H ("\n");
|
||||
print DISPATCH_H ("PR_EXTERN_DATA (void_fun) DISPT_Dispatch_Table[];\n");
|
||||
print DISPATCH_H ("\n");
|
||||
print DISPATCH_H ("PR_EXTERN (void_fun*) DISPT_GetDispatchTable(void);\n");
|
||||
print DISPATCH_H ("\n");
|
||||
print DISPATCH_H ("PR_EXTERN (int) DISPT_NumDispatchPoints(void);\n");
|
||||
print DISPATCH_H ("\n");
|
||||
|
||||
foreach (@symbols) {
|
||||
print DISPATCH_H ("PR_EXTERN (void) $_(void);\n");
|
||||
}
|
||||
print DISPATCH_H ("\n");
|
||||
|
||||
#####################################################
|
||||
# Step 4: Write out the definitions in source file
|
||||
#####################################################
|
||||
$header_file = ExtractFilename($header_file);
|
||||
print DISPATCH_C ("#include \"$header_file\"\n");
|
||||
print DISPATCH_C ("\n");
|
||||
print DISPATCH_C ("PR_IMPLEMENT_DATA (void_fun) DISPT_Dispatch_Table[] = {\n");
|
||||
|
||||
$first_entry = 1;
|
||||
foreach (@symbols) {
|
||||
if (!$first_entry) {
|
||||
print DISPATCH_C (",\n");
|
||||
}
|
||||
print DISPATCH_C ("\t$_");
|
||||
$first_entry = 0;
|
||||
}
|
||||
|
||||
print DISPATCH_C ("\n};\n");
|
||||
print DISPATCH_C ("\n");
|
||||
print DISPATCH_C ("PR_IMPLEMENT (void_fun*) DISPT_GetDispatchTable(void) {\n");
|
||||
print DISPATCH_C (" return DISPT_Dispatch_Table;\n");
|
||||
print DISPATCH_C ("}\n");
|
||||
print DISPATCH_C ("\n");
|
||||
print DISPATCH_C ("PR_IMPLEMENT (int) DISPT_NumDispatchPoints(void) {\n");
|
||||
print DISPATCH_C (" return (sizeof(DISPT_Dispatch_Table)/sizeof(DISPT_Dispatch_Table[0]));\n");
|
||||
print DISPATCH_C ("}\n");
|
||||
|
||||
|
||||
#####################################################
|
||||
# Step 7: Write out cmoffset.h
|
||||
#####################################################
|
||||
$offset = 0;
|
||||
foreach (@symbols) {
|
||||
printf CMOFFSET_H ("#define CM_OFFSET_%-45s %5d\n",$_, $offset);
|
||||
$offset++;
|
||||
}
|
||||
|
||||
# ---------------------- Sub-routines -------------------------
|
||||
sub UsageAndExit {
|
||||
print ("Usage: perl gendisp.pl <symbols.txt> <out.h> <out.c> <offset.h>\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
# GetFunctionLIst reads in a file containing a list
|
||||
# of function names, and returns an array containing
|
||||
# them
|
||||
sub GetFunctionList {
|
||||
my($function_list) = $_[1];
|
||||
open (FUN_LIST, $_[0]) or die ("Can't open $_[0] for reading.\n");
|
||||
while ($line = <FUN_LIST>) {
|
||||
if ($line =~ m/^\s*(\w+)/) {
|
||||
push(@{$function_list}, $1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Extract the filename part of a full path.
|
||||
# Extracts the part of the string that appears after the last '\' or '/'.
|
||||
sub ExtractFilename {
|
||||
my $slash_offset = rindex($_[0], "/");
|
||||
my $bslash_offset = rindex($_[0],"\\");
|
||||
my $offset = (($slash_offset > $bslash_offset)? $slash_offset : $bslash_offset);
|
||||
return substr($_[0], $offset+1);
|
||||
}
|
||||
|
|
@ -1,223 +0,0 @@
|
|||
########################################################
|
||||
# listsymb.pl
|
||||
# Generates a list of all global C function names
|
||||
# defined in Communicator except those with
|
||||
# unwanted prefix specified below.
|
||||
#
|
||||
########################################################
|
||||
|
||||
# Functions with the following prefixes will not be listed.
|
||||
# DISPT_GetDispatchTable & DISPT_NumDispatchPoints are exported
|
||||
# using linker facilities and should always be filtered.
|
||||
@unwanted_prefixes = ("__","Java_","java_","awt_","sun_","PR_", "PL_", "LL_",
|
||||
"DISPT_GetDispatchTable", "DISPT_NumDispatchPoints");
|
||||
|
||||
@objfiles = ();
|
||||
@symbols = ();
|
||||
$debug = 0;
|
||||
|
||||
#Step 1: Get command line options
|
||||
$input_file = $ARGV[0];
|
||||
$output_file = $ARGV[1];
|
||||
UsageAndExit() if (scalar(@ARGV) != 2);
|
||||
|
||||
# Step 2: Open output file for output
|
||||
open (SYMB_LIST, ">$output_file") or die("Can't open \"$output_file\" for writing.\n");
|
||||
|
||||
# Step 3: Read input file to determine list of all obj / lib files
|
||||
# needed to link the executable
|
||||
GetObjFileList($input_file, \@objfiles);
|
||||
|
||||
# Step 4: Run NM on every single obj / lib file
|
||||
# to get the complelete list of global functions
|
||||
CallNM(\@objfiles, \@symbols);
|
||||
|
||||
# Step 5: Put all the symbols in output file
|
||||
foreach (@symbols) {
|
||||
print SYMB_LIST ("$_\n");
|
||||
}
|
||||
|
||||
|
||||
# --------------- Sub-Routines -----------------
|
||||
#
|
||||
|
||||
|
||||
sub UsageAndExit {
|
||||
print ("Usage: perl gendisp.pl <list of obj files> <symbol list>\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
# CallNM calls nm on each file in objfiles
|
||||
# and finds out all symbols defined in them.
|
||||
# The list of symbols is returned.
|
||||
sub CallNM {
|
||||
my($objfiles) = $_[0];
|
||||
my($symbols) = $_[1];
|
||||
my(%unique) = ();
|
||||
|
||||
foreach (@{$objfiles}) {
|
||||
my($file) = $_;
|
||||
my(@results) = ();
|
||||
|
||||
# if such file exists, call nm
|
||||
# otherwise, print a warning
|
||||
if (-f $file) {
|
||||
# nm -g prints only global symbols
|
||||
# nm --demangle demangles C++ names
|
||||
@results = `nm --demangle -g $file`;
|
||||
foreach (@results) {
|
||||
my($symbol) = ExtractFunctionSymbol($_);
|
||||
if ($symbol ne "") {
|
||||
$unique{$symbol} = "exists";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (sort(keys(%unique))) {
|
||||
$symbol = FilterUnwantedPrefix($_);
|
||||
push(@{$symbols}, ($symbol)) if $symbol ne "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub IsObjFile {
|
||||
# if 1st argument ends with .o .a or .so
|
||||
if ($_[0] =~ m/\.(o)|\.(a)|\.(so)\s*$/) {
|
||||
$firstchar = substr($_[0], 0, 1);
|
||||
return $_[0] if $firstchar ne '/';
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
sub IsLibFile {
|
||||
($_[0] =~ m/^\s*-l\s*(.+)\s*$/);
|
||||
return $1;
|
||||
}
|
||||
|
||||
sub IsLibPath {
|
||||
# if begins with -L, it's a path
|
||||
if ($_[0] =~ m/^\s*-L\s*(.+)\s*$/) {
|
||||
# Igore absolute path, because they
|
||||
# tend to be system libraries
|
||||
$firstchar = substr($1, 0, 1);
|
||||
return "" if ($firstchar eq '/');
|
||||
|
||||
# Make sure it ends with a '/'
|
||||
# so that appending it to filename will work
|
||||
$lastchar = substr($1, length($1)-1, 1);
|
||||
return (($lastchar eq '/')? $1 : $1.'/');
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
# FilterUnwantedPrefix() returns 1st argument
|
||||
# if
|
||||
# its prefix doesn't match any of those
|
||||
# defined in @unwanted_prefixes
|
||||
# and
|
||||
# it contains at least at least 1 upper-case letter or
|
||||
# an underscore.
|
||||
sub FilterUnwantedPrefix {
|
||||
if ($_[0] !~ m/[A-Z_]/) {
|
||||
print ("Warning: $_[0] is probably a system symbol, and so filtered.\n") if $debug > 1;
|
||||
return "";
|
||||
}
|
||||
foreach $prefix (@unwanted_prefixes) {
|
||||
if ($_[0] =~ m/^$prefix/) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
return $_[0];
|
||||
}
|
||||
|
||||
# Returns a non-empty string if the line contains a function symbol
|
||||
# Returns an empty string otherwise
|
||||
# Note: a line containing a function symbol looks like this:
|
||||
# 048 00000000 SECTA notype () External | _lm_DefinePkcs11
|
||||
# This function searches for entries that contains SECT,(),External
|
||||
sub ExtractFunctionSymbol {
|
||||
if ($_[0] =~ m/ T (\w+)\s*$/) {
|
||||
print ("Matched :$_[0]\n") if $debug > 1;
|
||||
return $1;
|
||||
} else {
|
||||
print ("Not Matched:$_[0]\n") if $debug > 1;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
# GetObjFileLIst reads in a file containing LINK options
|
||||
# and returns the list of .obj & .lib files in 1st argu
|
||||
sub GetObjFileList {
|
||||
my($objfiles) = $_[1]; # path to .o's, .a's, and .so's
|
||||
my @libpath = (); # -Lstuff
|
||||
my @libfiles = ();# -lstuff
|
||||
my @junkoptions = (); # any other options
|
||||
|
||||
# 1. Separate different kinds of options
|
||||
open (OBJS_LIST, $_[0]) or die ("Can't open $_[0] for reading.\n");
|
||||
while ($line = <OBJS_LIST>) {
|
||||
# For each line, break up into words
|
||||
$line =~ s/^\s+//; # eat white spaces at beginning of line
|
||||
@words = split(/\s+/, $line);
|
||||
foreach (@words) {
|
||||
if (IsObjFile($_) ne "") {
|
||||
# If the option ends with .so, .a , or .o,
|
||||
# assume it is an object file to be linked in.
|
||||
print ("SEPARATE: $_ is obj file.\n") if $debug;
|
||||
push(@{$objfiles}, ($_));
|
||||
|
||||
} elsif (($temp = IsLibPath($_)) ne "") {
|
||||
# If begins with -L
|
||||
print ("SEPARATE: $_ is -L$temp.\n") if $debug;
|
||||
push(@libpath, $temp);
|
||||
|
||||
} elsif (($temp = IsLibFile($_)) ne "") {
|
||||
# If begins with -l
|
||||
print ("SEPARATE: $_ is -l$temp.\n") if $debug;
|
||||
push(@libfiles, $temp);
|
||||
|
||||
} else {
|
||||
# Unrecognized Options
|
||||
print ("SEPARATE: $_ option ignored.\n") if $debug;
|
||||
push(@junkoptions, $_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 2. check to see if .a or .so exists under the specified path
|
||||
foreach (@libfiles) {
|
||||
if (-f $_) { #file exists?
|
||||
push (@{$objfiles}, $_);
|
||||
|
||||
} else {
|
||||
#file doesn't exist, try prepending libpath prefix
|
||||
$file = $_;
|
||||
$found = 0;
|
||||
foreach (@libpath) {
|
||||
if (-f $_."lib".$file.".a") {
|
||||
print ("SEARCH: $_+lib+$file+.a found.\n") if $debug;
|
||||
push (@{$objfiles}, $_."lib".$file.".a");
|
||||
$found = 1;
|
||||
last;
|
||||
|
||||
} elsif (-f $_."lib".$file.".so") {
|
||||
print ("SEARCH: $_+lib+$file+.so found.\n") if $debug;
|
||||
push (@{$objfiles}, $_."lib".$file.".so");
|
||||
$found = 1;
|
||||
last;
|
||||
|
||||
}
|
||||
}
|
||||
if ($found == 0) {
|
||||
print ("SEARCH: $file not found.\n") if $debug;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 3. Returns the list of all object, .a, .so files
|
||||
foreach (@{$objfiles}) {
|
||||
print ("OBJ: $_\n") if $debug;
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче