toolsandutils/e32tools/elftools/def2dll.pl
changeset 0 83f4b4db085c
child 1 d4b442d23379
equal deleted inserted replaced
-1:000000000000 0:83f4b4db085c
       
     1 # Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 # All rights reserved.
       
     3 # This component and the accompanying materials are made available
       
     4 # under the terms of "Eclipse Public License v1.0"
       
     5 # which accompanies this distribution, and is available
       
     6 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 #
       
     8 # Initial Contributors:
       
     9 # Nokia Corporation - initial contribution.
       
    10 #
       
    11 # Contributors:
       
    12 #
       
    13 # Description:
       
    14 #
       
    15 
       
    16 use strict;
       
    17 use FindBin;		# for FindBin::Bin
       
    18 use Getopt::Long;
       
    19 use Cwd;
       
    20 
       
    21 my $PerlLibPath;    # fully qualified pathname of the directory containing our Perl modules
       
    22 
       
    23 BEGIN {
       
    24 # check user has a version of perl that will cope
       
    25 	require 5.005_03;
       
    26 # establish the path to the Perl libraries: currently the same directory as this script
       
    27 	$PerlLibPath = $FindBin::Bin;	# X:/epoc32/tools
       
    28 	if ($^O eq "MSWin32")
       
    29 	{
       
    30 		$PerlLibPath =~ s/\//\\/g;	# X:\epoc32\tools
       
    31 		$PerlLibPath .= "\\";
       
    32 	}	
       
    33 }
       
    34 
       
    35 use lib $PerlLibPath;
       
    36 use Defutl;
       
    37 
       
    38 my %opts = ();
       
    39 
       
    40 my $result = GetOptions(\%opts,
       
    41 						"path:s",
       
    42 						"bldpath:s",
       
    43 						"deffile:s",
       
    44 						"linkAs:s",
       
    45 						"import:s",
       
    46 						"export:s",
       
    47 						"absent:s",
       
    48 						"inter",
       
    49 						"sym_name_lkup"
       
    50 						);
       
    51 
       
    52 my $gPath = $opts{"path"}; # 0
       
    53 my $gBldPath = $opts{"bldpath"}; # 0
       
    54 my $compName = $opts{"import"}; # 1
       
    55 my $gDefFile = $opts{"deffile"}; # 2
       
    56 my $gDllName = $opts{"linkAs"};  # 3
       
    57 my $gExpFile = $opts{"export"};
       
    58 my $gLibFile = "$compName.lib" if $compName;
       
    59 my $gSymbolNameLookup = $opts{"sym_name_lkup"};
       
    60 
       
    61 my $oP = '--';
       
    62 
       
    63 my $floatingpointmodel = "${oP}fpu softvfp";
       
    64 my $interworkingp = $opts{"inter"};
       
    65 my $interworking = "${oP}apcs /nointer";
       
    66 $interworking = "${oP}apcs /inter" if ($interworkingp);
       
    67 
       
    68 my @objectFiles;
       
    69 
       
    70 &main;
       
    71 
       
    72 my @DefDataStruct;
       
    73 
       
    74 sub main ()
       
    75 {
       
    76        unless($gDefFile)
       
    77        {
       
    78                usage();
       
    79        }
       
    80 	my $FrzExportsOn=0;
       
    81 	eval { &Def_ReadFileL(\@DefDataStruct, $gDefFile, $FrzExportsOn); };
       
    82 	die $@ if $@;
       
    83 
       
    84     &parseDefFile(\@DefDataStruct, $opts{absent}, $gDefFile);
       
    85     &genExpFile($gPath, $gBldPath, $gExpFile) if $gExpFile;
       
    86     &genLibFile($gPath, $gBldPath, $gLibFile, $gDllName) if $gLibFile;
       
    87 }
       
    88 
       
    89 # Usage subroutine
       
    90 sub usage( )
       
    91 {
       
    92         print "\n";
       
    93         print "DEF2DLL -Creates binary objects used to implement the Symbian OS DLL model\n";
       
    94         print "\n";
       
    95         print "Usage: def2dll --deffile=<file> [--path=<dir>] [--bldpath=<dir>] [--import=<file>]  [--linkas=<file>] [--inter] [--export=<file>] [--sym_name_lkup]\n";
       
    96 
       
    97         print "\nOptions:\n";
       
    98 	print "\t--deffile=<file>   	 	: def file to be converted\n";
       
    99         print "\t--path =<direcotry>		: destination path\n";
       
   100         print "\t--bldpath=<direcotry>		: build path for dll\n";
       
   101         print "\t--import=<file>			: import from file name\n";
       
   102         print "\t--linkas=<file>     		: linkas to file name specified\n";
       
   103         print "\t--inter                 	: enables interworking on ARM and THUMB\n";
       
   104         print "\t--export=<file>			: export to filename\n";
       
   105         print "\t--sym_name_lkup         	: symbol name ordinal number lookupç\n";
       
   106         print "\n";
       
   107         exit 1;
       
   108 }
       
   109 
       
   110 my %symbols = ();
       
   111 my %symbolIndexMap = ();
       
   112 my $exports = 0;
       
   113 
       
   114 sub parseDefFile ($$$)
       
   115 {
       
   116     my ($defStructRef, $AbsentSubst, $defFile) = @_;
       
   117 	my $Ref;
       
   118 	foreach $Ref (@$defStructRef) {
       
   119 		next if (!$Ref);
       
   120 		next if (!defined ($$Ref{Ordinal}));
       
   121 		my $symbol = $$Ref{Name};
       
   122 		my $index = $$Ref{Ordinal};
       
   123 		my $rest = $$Ref{Comment};
       
   124 		my $symbolType = 'CODE';
       
   125 		if ($$Ref{Data} || ($symbol =~ /^(_ZTV|_ZTI|_ZTT)/)){
       
   126 			$symbolType = 'DATA';
       
   127 		}
       
   128 		else {
       
   129 			$exports = 1;
       
   130 		}
       
   131 		if ($symbols{$symbol} and !$$Ref{Absent}) {
       
   132 			warn "DEF2DLL - WARNING: $symbol duplicated in $defFile\n";
       
   133 		} else {
       
   134 			if ($$Ref{Absent}) {
       
   135 				$symbolIndexMap{$index} = $AbsentSubst;
       
   136 			} else {
       
   137 				$symbols{$symbol} = $symbolType;
       
   138 				$symbolIndexMap{$index} = $symbol;
       
   139 			}
       
   140 		}
       
   141     }
       
   142 }
       
   143 
       
   144 sub genExpFile ($$$)
       
   145 {
       
   146     my ($path, $bldpath, $expFile) = @_;
       
   147     my $numkeys = keys %symbolIndexMap;
       
   148     my $failed = 0;
       
   149 
       
   150     open EXPFILE, ">$path\\$expFile.s" or
       
   151 		die "Error: can't create $path\\$expFile.s\n";
       
   152 
       
   153     print EXPFILE "\tEXPORT __DLL_Export_Table__\n\n";
       
   154     print EXPFILE "\tEXPORT |DLL\#\#ExportTable|\n\n";
       
   155     print EXPFILE "\tEXPORT |DLL\#\#ExportTableSize|\n\n";
       
   156     print EXPFILE "\tAREA ExportTable, CODE\n";
       
   157 
       
   158 
       
   159     print EXPFILE "__DLL_Export_Table__\n";
       
   160 	if ($interworkingp) {
       
   161 	  print EXPFILE "\tBX lr\n";
       
   162 	} else {
       
   163 	  print EXPFILE "\tMOV pc, lr\n";
       
   164 	}
       
   165 
       
   166     print EXPFILE "|DLL\#\#ExportTableSize|\n";
       
   167     printf EXPFILE "\tDCD %d\n", $numkeys;
       
   168 	if($gSymbolNameLookup) {
       
   169 		print EXPFILE "\tDCD 0 \n";# This is the 0th ordinal for elftran to fill in.
       
   170 	}
       
   171     print EXPFILE "|DLL\#\#ExportTable|\n";
       
   172 
       
   173     my @orderedSyms;
       
   174     my $maxIndex = 0;
       
   175     my $index;
       
   176     foreach $index (keys %symbolIndexMap) {
       
   177 		$maxIndex = $index if $index > $maxIndex;
       
   178 		$orderedSyms[$index] = $symbolIndexMap{$index};
       
   179     }
       
   180 
       
   181     print EXPFILE "\tPRESERVE8\n\n";
       
   182     my $n;
       
   183     for ($n = 1; $n <= $maxIndex ; $n++) {
       
   184 		my $entry = $orderedSyms[$n];
       
   185 		if ($entry) {
       
   186 			print EXPFILE "\tIMPORT $entry\n";
       
   187 			print EXPFILE "\tDCD $entry \t; @ $n\n";
       
   188 		} else {
       
   189 			warn "WARNING: missing entry at index $n\n";
       
   190 			print EXPFILE "\tDCD 0 ; missing symbol\n";
       
   191 		}
       
   192     }
       
   193 
       
   194 
       
   195     # create a .directive section
       
   196     print EXPFILE "\n\n\tAREA |.directive|, READONLY, NOALLOC\n";
       
   197     # Mark the section as armlink edit commands
       
   198     print EXPFILE "\tDCB  \"#<SYMEDIT>#\\n\"\n"; 
       
   199     # mark the imported symbol for 'dynamic' export
       
   200     print EXPFILE "\tDCB  \"EXPORT DLL##ExportTable\\n\"\n";
       
   201     print EXPFILE "\tDCB  \"EXPORT DLL##ExportTableSize\\n\"\n";
       
   202 
       
   203     print EXPFILE "\tEND";
       
   204     close EXPFILE;
       
   205 
       
   206     $failed = system "armasm $floatingpointmodel $interworking -o $path\\$expFile.exp $path\\$expFile.s";
       
   207     unlink ("$path\\$expFile.s") unless $failed;
       
   208     die "Error: cant create $path\\$expFile.exp\n" if $failed;
       
   209 }
       
   210 
       
   211 my %DataSymbols = ();
       
   212 
       
   213 sub genVtblExportFile($$)
       
   214 {
       
   215     my ($bldpath, $dllName) = @_;
       
   216     my $FileName = "VtblExports";
       
   217 
       
   218     open VTBLFILE, ">$bldpath\\$FileName.s" or
       
   219 		die "Error: can't create $bldpath\\$FileName.s\n";
       
   220 
       
   221     print VTBLFILE "\tAREA |.directive|, NOALLOC, READONLY, ALIGN=2\n";
       
   222     printf VTBLFILE "\tDCB \"\#\<SYMEDIT\>\#\\n\"\n";
       
   223 
       
   224     my $symbol;
       
   225     foreach $symbol (sort keys %DataSymbols) {
       
   226 		my $index = $DataSymbols{$symbol};
       
   227 		
       
   228 		$symbol =~ s/^"(.*)"$/$1/;	# remove enclosing quotes
       
   229 		printf VTBLFILE "\tDCB \"IMPORT \#\<DLL\>$dllName\#\<\\\\DLL\>%x AS $symbol \\n\"\n", $index;
       
   230     }
       
   231 #    printf VTBLFILE "\tDCB \"\#\<\\\\VTBLSYMS\>\#\\n\"\n";
       
   232     print VTBLFILE "\tEND";
       
   233     close VTBLFILE;
       
   234 
       
   235     my $failed = system "armasm $floatingpointmodel $interworking -o $bldpath\\$FileName.o $bldpath\\$FileName.s";
       
   236     unlink ("$bldpath\\$FileName.s");
       
   237     die "Error: cant create $bldpath\\$FileName.o\n" if $failed;
       
   238     push @objectFiles, "$bldpath\\$FileName.o";
       
   239 }
       
   240 
       
   241 sub genLibFile ($$$$)
       
   242 {
       
   243     my ($path, $bldpath, $libFile, $dllName) = @_;
       
   244     my $tempFileName = "$bldpath\\$compName";
       
   245     my $viaFileName = sprintf("$bldpath\\_t%x_via_.txt", time);
       
   246     my $keyz = keys %symbolIndexMap;
       
   247     my $failed = 0;
       
   248     my $key;
       
   249 
       
   250     if ($keyz > 0) {
       
   251 		open STUBGEN, "|$ENV{'EPOCROOT'}/epoc32/tools/genstubs" if $exports;
       
   252 		foreach $key (sort keys %symbolIndexMap) {
       
   253 			my $symbol = $symbolIndexMap{$key};
       
   254 			my $stubFileName = "$tempFileName-$key";
       
   255 			if ( $symbols{$symbol} eq 'DATA') {
       
   256 				$DataSymbols{$symbol} = $key;
       
   257 			} else {
       
   258 				printf STUBGEN "$stubFileName.o $symbol #<DLL>$dllName#<\\DLL>%x\n", $key;
       
   259 				push @objectFiles, "$stubFileName.o";
       
   260 			}
       
   261 		}
       
   262 		genVtblExportFile($bldpath, $dllName);
       
   263     } else {
       
   264 		# create dummy stub so armar creates a .lib for us
       
   265 		open STUBGEN, "|$ENV{'EPOCROOT'}/epoc32/tools/genstubs";
       
   266 		print STUBGEN "$tempFileName-stub.o $tempFileName##stub $dllName##dummy\n";
       
   267 		push @objectFiles, "$tempFileName-stub.o";
       
   268     }
       
   269     close STUBGEN;
       
   270 
       
   271     open VIAFILE, ">$viaFileName" or
       
   272 		die "Error: can't create VIA fie $viaFileName\n";
       
   273 
       
   274     print VIAFILE "${oP}create \"$path\\$libFile\"\n";
       
   275     my $objectFile;
       
   276     foreach $objectFile (@objectFiles) {
       
   277 		print VIAFILE "\"$objectFile\"\n";
       
   278     }
       
   279     close VIAFILE;
       
   280 
       
   281     $failed = system( "armar ${oP}via $viaFileName");
       
   282     push @objectFiles, $viaFileName;
       
   283     unlink @objectFiles;
       
   284     die "Error: can't create $path\\$libFile\n" if $failed;
       
   285 }
       
   286 
       
   287 __END__
       
   288