--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv1/abld/platform/sym_lkup_util.pl Wed Jun 30 11:35:58 2010 +0800
@@ -0,0 +1,257 @@
+#!/usr/bin/perl
+# Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+use FindBin; # for FindBin::Bin
+use Getopt::Long;
+
+BEGIN {
+# check user has a version of perl that will cope
+ require 5.005_03;
+# establish the path to the Perl libraries: currently the same directory as this script
+ $PerlLibPath = $FindBin::Bin; # X:/epoc32/tools
+ if ($^O eq "MSWin32")
+ {
+ $PerlLibPath =~ s/\//\\/g; # X:\epoc32\tools
+ $PerlLibPath .= "\\";
+ }
+}
+
+use lib $PerlLibPath;
+
+my $IgnoreExportDir = 0;
+my $ImportSymFile;
+my $CppFile;
+my $mapFile;
+my $SegmentContentSz = 0;
+my $nSyms = 0;
+my $nImports = 0;
+my %Symbols = ();
+my @Imports = ();
+
+# Version
+my $MajorVersion = 1;
+my $MinorVersion = 1;
+my $PatchVersion = 0;
+
+
+{
+ unless (GetOptions(\%Options, 'sym=s', 'o=s', 'map=s', 'ignore_export_dir')) {
+ exit 1;
+ }
+ $ImportSymFile = $Options{sym};
+ $CppFile = $Options{o};
+ $mapFile = $Options{map};
+ $IgnoreExportDir = $Options{ignore_export_dir};
+
+ unless($ImportSymFile)
+ {
+ print(
+ "\n",
+ "SYM_LKUP_UTIL symbol process tool V$MajorVersion.$MinorVersion.$PatchVersion\n",
+ "\n",
+ "options:\n",
+ " -sym symbol file\n",
+ " -o output file\n",
+ " -map map file\n",
+ "\n"
+ );
+ exit 1;
+ }
+
+ ReadSymFile() if $ImportSymFile;
+ ReadMapFile() if $mapFile;
+
+ GenNamedSegment();
+}
+
+sub ReadMapFile() {
+ open FILE, $mapFile or die "Error :SymLookup: Cannot open map file $mapFile\n";
+
+ my $GlbSyms = 0;
+ while(<FILE>) {
+ if($_ =~ /Public Symbols/) {
+ $GlbSyms = 1;
+ }
+ elsif( !$GlbSyms ) {
+ next;
+ }
+ if($_ =~ /([0-9a-fA-F]{8})\s+(\S+)\s+_?(\S+)\s/){
+ $addr = $1;
+ $module = $2;
+ $name = $3;
+ if( defined $Symbols{$name} ) {
+ $Symbols{$name} = $addr;
+ }
+ }
+ }
+# Remove symbols not found in map file
+ foreach my $sym (keys %Symbols){
+ if( !$Symbols{$sym} ){
+ delete $Symbols{$sym};
+ }
+ }
+
+}
+
+sub ReadSymFile() {
+ open FILE, $ImportSymFile or die "Error :SymLookup: Cannot open file $ImportSymFile\n";
+
+ my $ImportDirSeen = 0;
+ my $ExportDirSeen = 0;
+ my $ExportNameTblSeen = 0;
+ my $numOfExportNames = 0;
+ my $nameCount = 0;
+ while (<FILE>) {
+# Ignore export table(s) if the flag '$IgnoreExportDir' is set. This flag is set for stddlls, as symbol listing
+# is not required for them. The windows API GetProcAddr can be used directly. While for stdexe, the symbol names
+# are filtered out and then looked up in the map file for their addresses.
+
+ if($_ =~ /\*\*\* EXPORT DIRECTORY \*\*\*/){
+ next if($IgnoreExportDir);
+ $ExportDirSeen = 1;
+ }
+ elsif($_ =~ /\*\*\* Export Name Pointer Table \*\*\*/){
+ next if($IgnoreExportDir);
+ $ExportNameTblSeen = 1;
+ }
+ elsif($_ =~ /\*\*\* IMPORT DIRECTORY \*\*\*/) {
+ $ImportDirSeen = 1;
+ }
+
+ if($ExportDirSeen){
+ if($_ =~ /numberofnames\s+=\s+0x(\S+)/){
+ $numOfExportNames = hex($1);
+# Reset the flag once done with the export table
+ $ExportDirSeen = 0;
+ }
+ }
+ elsif($ExportNameTblSeen && $numOfExportNames){
+ if($_ =~ /\d+\s+0x[0-9a-fA-F]+\s+(\S+)/){
+ $Symbols{$1}=0;
+# Keep track of the symbols seen in "Export Name Pointer Table"
+ $nameCount++;
+ }
+ if($nameCount == $numOfExportNames){
+# Reset the flag once done with the name table
+ $ExportNameTblSeen = 0;
+ }
+ }
+ elsif($ImportDirSeen) {
+ if($_ =~ /^DLL name\s+=\s+\S+\s+\((\S+)\)/) {
+ my $dllname = $1;
+ push @Imports, $dllname;
+ $ImportDirSeen = 0;
+ }
+ }
+ }
+}
+
+sub GenNamedSegment() {
+
+ my $SegContents = "";
+
+ &Header(\$SegContents);
+
+ &SymAddrTbl(\$SegContents);
+
+ &SymNames(\$SegContents);
+
+ &Footer(\$SegContents);
+
+ open OUTFILE, ">$CppFile" or die "Error :SymLookup:Cannot open file $CppFile\n";
+ print OUTFILE $SegContents;
+}
+
+sub Header(){
+ my $SegContentsRef = shift @_;
+
+ $$SegContentsRef .= "\/\* $CppFile\n";
+ $$SegContentsRef .= " \* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.\n";
+ $$SegContentsRef .= " \* Makmake-generated source file for named symbol lookup\n";
+ $$SegContentsRef .= " \*\/\n";
+ $$SegContentsRef .= "#pragma data_seg(\".expdata\")";
+
+ $$SegContentsRef .= "\n\n";
+}
+
+sub Footer() {
+ my $SegContentsRef = shift @_;
+ $$SegContentsRef .= "\n#pragma data_seg()\n";
+ $$SegContentsRef .= "\n";
+}
+
+sub SymAddrTbl(){
+ my $SegContentsRef = shift @_;
+ $nSyms = keys %Symbols;
+ $nImports = @Imports;
+ $$SegContentsRef .= "int NSymbols = $nSyms;\n";
+ $$SegContentsRef .= "int NImports = $nImports;\n";
+
+ if(!$nSyms) {
+ return;
+ }
+ $$SegContentsRef .= "int addresses[] = {\n";
+
+ foreach $key (sort keys %Symbols) {
+ if($Symbols{$key}){
+ $$SegContentsRef .= "\t0x".$Symbols{$key}.",\n";
+ }
+ }
+ $$SegContentsRef .= "};\n";
+}
+
+sub SymNames() {
+ if(!$nImports && !$nSyms){
+ return;
+ }
+ my $SegContentsRef = shift @_;
+ $$SegContentsRef .= "\nchar data[] = {\n";
+
+ my $symnames ;
+ my $colCnt ;
+ foreach $symnames (sort keys %Symbols) {
+ next if( $Symbols{$symnames} == 0);
+ my @chars = split(//,$symnames);
+ $$SegContentsRef .= "\t";
+ $colCnt =0;
+ foreach $aChar (@chars) {
+ if($colCnt >= 80) {
+ $$SegContentsRef .= "\\\n\t";
+ $colCnt = 0;
+ }
+ $$SegContentsRef .= "\'$aChar\',";
+ $colCnt += 4;
+ }
+ $$SegContentsRef .= "0,\n";
+ }
+
+ foreach my $dll (@Imports) {
+ my @chars = split(//,$dll);
+ $$SegContentsRef .= "\t";
+ $colCnt =0;
+ foreach $aChar (@chars) {
+ if($colCnt >= 80) {
+ $$SegContentsRef .= "\\\n\t";
+ $colCnt = 0;
+ }
+ $$SegContentsRef .= "\'$aChar\',";
+ $colCnt += 4;
+ }
+ $$SegContentsRef .= "0,\n";
+ }
+ $$SegContentsRef .= "\n};\n";
+}
+