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