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