1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/f32test/loader/dlltree.pl Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,854 @@
1.4 +# Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +# All rights reserved.
1.6 +# This component and the accompanying materials are made available
1.7 +# under the terms of the License "Eclipse Public License v1.0"
1.8 +# which accompanies this distribution, and is available
1.9 +# at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +#
1.11 +# Initial Contributors:
1.12 +# Nokia Corporation - initial contribution.
1.13 +#
1.14 +# Contributors:
1.15 +#
1.16 +# Description:
1.17 +# \f32test\loader\dlltree.pl
1.18 +# Generate header and build files for one or more trees
1.19 +# of DLLs and EXEs according to a description file.
1.20 +#
1.21 +#
1.22 +
1.23 +require Cwd;
1.24 +
1.25 +my $dllbasename='dllt';
1.26 +my $dllext='.dll';
1.27 +my $exebasename='exet';
1.28 +my $exeext='.exe';
1.29 +my $mmpext='.mmp';
1.30 +my $defext='.def';
1.31 +my $libext='.lib';
1.32 +
1.33 +my $source0ext='.cpp';
1.34 +my $source1ext='.cia';
1.35 +my $xippath="sys\\bin\\";
1.36 +my $nonxippath="sys\\bin\\";
1.37 +
1.38 +my $hostpath="\\Epoc32\\Release\\##MAIN##\\##BUILD##\\";
1.39 +
1.40 +my $flag_value_exe=1;
1.41 +my $flag_value_fixed=2;
1.42 +my $flag_value_data=4;
1.43 +my $flag_value_xip=8;
1.44 +my $flag_value_dll_in_cycle=16;
1.45 +my $flag_value_data_in_tree=32;
1.46 +my $flag_value_xip_data_in_tree=64;
1.47 +my $flag_value_exports=128;
1.48 +my $flag_value_pagedcode=256;
1.49 +my $flag_value_unpagedcode=512;
1.50 +my $flag_value_idrive=1024;
1.51 +my $flag_value_vdrive=2048;
1.52 +my $flag_value_bytepair=4096;
1.53 +my $flag_value_uncompressed=8192;
1.54 +my $flag_value_targetonly=16384;
1.55 +my $flag_value_pageddata=32768;
1.56 +my $flag_value_unpageddata=65536;
1.57 +
1.58 +my $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst;
1.59 +($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime;
1.60 +my $copy_end=$year+1900;
1.61 +
1.62 +my $argc=scalar(@ARGV);
1.63 +($argc==1 or $argc==2 or $argc==3) or die "Usage: perl dlltree.pl <filename> <dir> [-allowbad]\n";
1.64 +my $infile=$ARGV[0];
1.65 +open IN, $infile or die "Cannot open input file $infile\n";
1.66 +my @in;
1.67 +while (<IN>) {
1.68 + push @in, $_;
1.69 +}
1.70 +close IN;
1.71 +my $destdir='';
1.72 +if ($argc>=2) {
1.73 + $destdir=$ARGV[1];
1.74 + unless (-d $destdir) {
1.75 + mkdir $destdir, 0777 or die "Can't create directory $destdir\n";
1.76 + }
1.77 + chdir $destdir or die "Can't chdir to directory $destdir\n";
1.78 +}
1.79 +my $allowbad;
1.80 +if ($argc==3) {
1.81 + if ($ARGV[2] eq '-allowbad') {
1.82 + $allowbad = 1;
1.83 + }
1.84 +}
1.85 +$cwd=Cwd::getcwd();
1.86 +$destpath=$cwd;
1.87 +$destpath=~s/\//\\/g;
1.88 +if ($destpath=~/^\w\:(.*)/) {
1.89 + $destpath=$1;
1.90 +}
1.91 +unless ($destpath=~/^(.*?)\\$/) {
1.92 + $destpath.='\\';
1.93 +}
1.94 +#print "$cwd\n";
1.95 +#print "$destpath\n";
1.96 +
1.97 +my @modules;
1.98 +my @testcases;
1.99 +my $line=0;
1.100 +my $modnum=0;
1.101 +my $state=0;
1.102 +my $concat;
1.103 +foreach (@in) {
1.104 + ++$line;
1.105 + next if (/^\s*$/ or /^\s*\#/);
1.106 + if ($state==0) {
1.107 + if (/^\!TESTCASES/) {
1.108 + $state=1;
1.109 + next;
1.110 + }
1.111 + my @moddesc=split;
1.112 + my $modname=shift @moddesc;
1.113 + if (grep {lc($$_{name}) eq lc($modname)} @modules) {
1.114 + die "Duplicate module specification at line $line\n";
1.115 + }
1.116 + my %module;
1.117 + $module{name}=$modname;
1.118 + $module{num}=$modnum;
1.119 + $module{exports}=1;
1.120 + $module{nclients}=0; # number of modules which import from this one
1.121 + while (scalar(@moddesc)) {
1.122 + my $att=shift @moddesc;
1.123 + if ($att=~/^\:$/) {
1.124 + last;
1.125 + } elsif ($att=~/^X$/i) {
1.126 + $module{exe}=1;
1.127 + } elsif ($att=~/^F$/i) {
1.128 + $module{fixed}=1;
1.129 + } elsif ($att=~/^D$/i) {
1.130 + $module{data}=1;
1.131 + } elsif ($att=~/^P$/i) {
1.132 + $module{pagedcode}=1;
1.133 + } elsif ($att=~/^PD$/i) {
1.134 + $module{pageddata}=1;
1.135 + } elsif ($att=~/^B$/i) {
1.136 + $module{bytepair}=1;
1.137 + } elsif ($att=~/^U$/i) {
1.138 + $module{uncompressed}=1;
1.139 + } elsif ($att=~/^I$/i) {
1.140 + $module{idrive}=1;
1.141 + } elsif ($att=~/^V$/i) {
1.142 + $module{vdrive}=1;
1.143 + } elsif ($att=~/^N$/i) {
1.144 + $module{unpagedcode}=1;
1.145 + } elsif ($att=~/^T$/i) {
1.146 + $module{targetonly}=1;
1.147 + } elsif ($att=~/^R(.*?)$/i) {
1.148 + $module{xip}=1;
1.149 + my $attp=$1;
1.150 + if ($attp=~/^\,(.*?)$/) {
1.151 + $module{attpname}=$1;
1.152 + } elsif (!($attp=~/^\s*$/)) {
1.153 + die "Garbage following R attribute at line $line\n";
1.154 + }
1.155 + }
1.156 + }
1.157 + if ($module{fixed} && !$module{exe}) {
1.158 + die "Can't have FIXED without EXE at line $line\n";
1.159 + }
1.160 + if ($module{pagedcode} && $module{xip}) {
1.161 + die "Can't have PAGEDCODE with XIP at line $line\n";
1.162 + }
1.163 +
1.164 + # makmake won't support paged binaries which aren't bytepair or uncompressed.
1.165 + # However, P can be specified without them in dlltree.txt. This program generates
1.166 + # an MMP file with neither flag. The flag is added when the files are copied to
1.167 + # internal media by T_LDRTST. (It would be pointless to copy the files to removable
1.168 + # media and then edit them because removable media doesn't support paging.)
1.169 +
1.170 + my $bothCodePageFlags = $module{pagedcode} && $module{unpagedcode};
1.171 + if ($bothCodePageFlags && !$module{idrive}) {
1.172 + die "Can't have PAGEDCODE and UNPAGEDCODE without INTERNAL DRIVE at line $line\n";
1.173 + }
1.174 + if ($module{unpagedcode} && $module{xip}) {
1.175 + die "Can't have UNPAGEDCODE with XIP at line $line\n";
1.176 + }
1.177 + if ($module{pageddata} && !$module{exe}) {
1.178 + die "Can't have PAGEDDATA without EXE at line $line\n";
1.179 + }
1.180 + if ($module{idrive} && $module{xip}) {
1.181 + die "Can't have INTERNAL DRIVE with XIP at line $line\n";
1.182 + }
1.183 + if ($module{vdrive} && $module{xip}) {
1.184 + die "Can't have REMOVABLE DRIVE with XIP at line $line\n";
1.185 + }
1.186 + if ($module{idrive} && $module{vdrive}) {
1.187 + die "Can't have INTERNAL DRIVE with REMOVABLE DRIVE at line $line\n";
1.188 + }
1.189 + if ($module{bytepair} && $module{uncompressed}) {
1.190 + die "Can't have BYTEPAIR with UNCOMPRESSED at line $line\n";
1.191 + }
1.192 + if ($module{exe}) {
1.193 + if ($module{attpname}) {
1.194 + warn "Attach process with EXE ignored at line $line\n";
1.195 + delete $module{attpname};
1.196 + }
1.197 + $module{basefilename}=$exebasename.$modnum;
1.198 + $module{filename}=$module{basefilename}.$exeext;
1.199 + $module{source0}=$exebasename.$source0ext;
1.200 + $module{source1}="";
1.201 + $module{trgtype}='exexp';
1.202 + $module{lib}=$module{basefilename}.$libext;
1.203 + } else {
1.204 + $module{basefilename}=$dllbasename.$modnum;
1.205 + $module{filename}=$module{basefilename}.$dllext;
1.206 + $module{source0}=$dllbasename.$source0ext;
1.207 + $module{source1}=$dllbasename.$source1ext;
1.208 + $module{trgtype}='dll';
1.209 + $module{lib}=$module{basefilename}.$libext;
1.210 + }
1.211 + $module{depnames}=\@moddesc; # dependency names are left over
1.212 + $module{line}=$line;
1.213 + $module{mark}=0;
1.214 + push @modules, \%module;
1.215 + ++$modnum;
1.216 + } elsif ($state<=2) {
1.217 + if ($state==1) {
1.218 + $concat="";
1.219 + die "Syntax error at line $line\n" unless (/^(\w+)\:/);
1.220 + }
1.221 + if (/^(.*?)\\$/) {
1.222 + $concat.=$1;
1.223 + $concat.=' ';
1.224 + $state=2;
1.225 + next;
1.226 + } else {
1.227 + $concat.=$_;
1.228 + $state=1;
1.229 + }
1.230 + my @modlist=split(/\s+/, $concat);
1.231 + my $tcname=shift @modlist;
1.232 + $tcname=~/^(.*?)\:$/ or die "???\n";
1.233 + $tcname=$1;
1.234 + my %tc;
1.235 + $tc{name}=$tcname;
1.236 + $tc{mod_names}=\@modlist;
1.237 + push @testcases, \%tc;
1.238 + }
1.239 +}
1.240 +foreach $modref (@modules) {
1.241 + my $moddepref=$$modref{depnames};
1.242 + my @deps;
1.243 + foreach (@$moddepref) {
1.244 + my $depname=lc($_);
1.245 + my @match=grep {lc($$_{name}) eq $depname} @modules;
1.246 + if (scalar(@match)==0) {
1.247 + die "Unknown dependent module $depname at line $$modref{line}\n";
1.248 + }
1.249 + my $depref=$match[0];
1.250 + if ($$modref{xip} and !$$depref{xip}) {
1.251 + die "Illegal dependency: $$modref{name} (XIP) on $$depref{name} (non-XIP)\n";
1.252 + }
1.253 + push @deps, $$depref{num};
1.254 + ++$$depref{nclients};
1.255 + }
1.256 + $$modref{deps}=\@deps;
1.257 + my $attpname=$$modref{attpname};
1.258 + if ($attpname) {
1.259 + my @match=grep {lc($$_{name}) eq lc($attpname)} @modules;
1.260 + if (scalar(@match)==0) {
1.261 + die "Unknown attach process $attpname at line $$modref{line}\n";
1.262 + }
1.263 + my $attpref=$match[0];
1.264 + if (!$$attpref{exe}) {
1.265 + die "Specified attach process is not EXE at line $$modref{line}\n";
1.266 + } elsif (!$$attpref{xip}) {
1.267 + die "Specified attach process is not XIP at line $$modref{line}\n";
1.268 + }
1.269 + $$modref{attp}=$attpref;
1.270 + }
1.271 +}
1.272 +foreach $tcref (@testcases) {
1.273 + my $modlistref=$$tcref{mod_names};
1.274 + my @modnums;
1.275 + foreach $modname (@$modlistref) {
1.276 + next if ($modname=~/^\s*$/);
1.277 + my @match=grep {lc($$_{name}) eq lc($modname)} @modules;
1.278 + if (scalar(@match)==0) {
1.279 + die "Unknown module $modname in test case $$tcref{name}\n";
1.280 + }
1.281 + push @modnums, $match[0]->{num};
1.282 + }
1.283 + $$tcref{modules}=\@modnums;
1.284 + $$tcref{count}=scalar(@modnums);
1.285 +}
1.286 +my $next_mark=0;
1.287 +foreach $modref (@modules) {
1.288 + if ($$modref{nclients}==0 and $$modref{exe}) {
1.289 + # EXE with no exports
1.290 + $$modref{exports}=0;
1.291 + $$modref{trgtype}='exe';
1.292 + }
1.293 + ++$next_mark;
1.294 + my $modnum=$$modref{num};
1.295 + my @tcdeps;
1.296 + calc_tc(\@tcdeps, \@modules, $modref, $next_mark);
1.297 + $$modref{tcdeps}=\@tcdeps;
1.298 + if (grep {$_==$modnum} @tcdeps) {
1.299 + $$modref{cycle}=1;
1.300 + }
1.301 + my @exes=grep {$modules[$_]->{exe}} @tcdeps;
1.302 + my $nexes=scalar(@exes);
1.303 +
1.304 + unless ($allowbad) {
1.305 + if ($nexes>1) {
1.306 + die "Module $$modref{name} links to more than one EXE\n";
1.307 + } elsif ($nexes==1) {
1.308 + my $exeref=$modules[$exes[0]];
1.309 + $$modref{linkexe}=$exeref;
1.310 + if ($$modref{exe}) {
1.311 + if ($$exeref{num}!=$modnum) {
1.312 + die "EXE $modref{name} links to another EXE\n";
1.313 + }
1.314 + } else {
1.315 + if ($$modref{attp} and $$exeref{num}!=$modref->{attp}->{num}) {
1.316 + die "DLL $$modref{name} ($modnum) incompatible attach process\n";
1.317 + }
1.318 + if (!$$modref{attp}) {
1.319 + $$modref{attp}=$exeref;
1.320 + }
1.321 + }
1.322 + }
1.323 + }
1.324 + if ($$modref{exe}) {
1.325 + foreach $depnum (@tcdeps) {
1.326 + my $depref=$modules[$depnum];
1.327 + my $depattpref=$depref->{attp};
1.328 + if ($depattpref and $depattpref->{num}!=$modnum) {
1.329 + die "DEP DLL $$depref{name} ($$depref{num}) incompatible attach process\n";
1.330 + }
1.331 +# if (!$depattpref) {
1.332 +# $$depref{attp}=$modref;
1.333 +# }
1.334 + }
1.335 + }
1.336 +}
1.337 +foreach $modref (@modules) {
1.338 + my @total_deps;
1.339 + my $tcdepref=$$modref{tcdeps};
1.340 + push @total_deps, @$tcdepref;
1.341 + my $linkexe=$$modref{linkexe};
1.342 + if ($linkexe) {
1.343 + my $exetcdepref=$$linkexe{tcdeps};
1.344 + push @total_deps, @$exetcdepref;
1.345 + }
1.346 + push @total_deps, $$modref{num};
1.347 + my $data=scalar(grep {$modules[$_]->{data}} @total_deps);
1.348 + if ($data!=0) {
1.349 + $$modref{dataintree}=1;
1.350 + }
1.351 + my $xipdata=scalar(grep {$modules[$_]->{data} and $modules[$_]->{xip}} @total_deps);
1.352 + if ($xipdata!=0) {
1.353 + $$modref{xipdataintree}=1;
1.354 + }
1.355 +}
1.356 +
1.357 +#foreach $modref (@modules) {
1.358 +# print "Module $$modref{num}:\n";
1.359 +# print "\tName: $$modref{name}\n";
1.360 +# print "\tFilename: $$modref{filename}\n";
1.361 +# my $depref=$$modref{deps};
1.362 +# my $ndeps=scalar(@$depref);
1.363 +# print "\t#Deps: $ndeps\n";
1.364 +# print "\tDeps: ",join(',',@$depref),"\n";
1.365 +#}
1.366 +
1.367 +my @bldinf;
1.368 +my $bldname='dlltree.inf';
1.369 +push @bldinf, "// $destpath$bldname\n";
1.370 +push @bldinf, "//\n";
1.371 +push @bldinf, "// Copyright (c) 2000-$copy_end Symbian Ltd. All rights reserved.\n";
1.372 +push @bldinf, "//\n";
1.373 +push @bldinf, "\n";
1.374 +push @bldinf, "PRJ_PLATFORMS\n";
1.375 +push @bldinf, "BASEUSERDEFAULT\n";
1.376 +push @bldinf, "\n";
1.377 +push @bldinf, "PRJ_TESTMMPFILES\n";
1.378 +push @bldinf, "\n";
1.379 +
1.380 +my @dlltree;
1.381 +my $dlltreename='dlltree.h';
1.382 +push @dlltree, "// $destpath$dlltreename\n";
1.383 +push @dlltree, "//\n";
1.384 +push @dlltree, "// Copyright (c) 2000-$copy_end Symbian Ltd. All rights reserved.\n";
1.385 +push @dlltree, "//\n";
1.386 +push @dlltree, "\n";
1.387 +push @dlltree, "#ifndef __DLLTREE_H__\n";
1.388 +push @dlltree, "#define __DLLTREE_H__\n";
1.389 +push @dlltree, "#include <e32std.h>\n";
1.390 +push @dlltree, "\n";
1.391 +push @dlltree, "class MDllList;\n";
1.392 +push @dlltree, "\n";
1.393 +
1.394 +my $ibyname='ldrtest.iby';
1.395 +my @iby;
1.396 +
1.397 +foreach $modref (@modules) {
1.398 + my @mmp;
1.399 + my $num=$$modref{num};
1.400 + my $mmpname=$$modref{basefilename}.$mmpext;
1.401 + my $defname=$$modref{basefilename}.$defext;
1.402 + my $depsref=$$modref{deps};
1.403 + my $ndeps=scalar(@$depsref);
1.404 + push @mmp, "// $destpath$mmpname\n";
1.405 + push @mmp, "//\n";
1.406 + push @mmp, "// Copyright (c) 2000-$copy_end Symbian Ltd. All rights reserved.\n";
1.407 + push @mmp, "//\n";
1.408 + push @mmp, "// Generated from $$modref{name}\n";
1.409 + push @mmp, "\n";
1.410 + push @mmp, "macro __DLLNUM$num\n";
1.411 + push @mmp, "target $$modref{filename}\n";
1.412 + push @mmp, "targettype $$modref{trgtype}\n";
1.413 + push @mmp, "sourcepath .\n";
1.414 + push @mmp, "source $$modref{source0} $$modref{source1}\n";
1.415 + push @mmp, "library euser.lib efsrv.lib\n";
1.416 + push @mmp, "Capability NONE\n";
1.417 + foreach (@$depsref) {
1.418 + my $depref=$modules[$_];
1.419 + push @mmp, "library $$depref{lib}\n";
1.420 + }
1.421 + if ($$modref{exports}) {
1.422 + push @mmp, "deffile ./$defname\n";
1.423 + push @mmp, "nostrictdef\n";
1.424 + }
1.425 + push @mmp, "OS_LAYER_SYSTEMINCLUDE_SYMBIAN \n";
1.426 + push @mmp, "systeminclude ../../../e32test/mmu \n";
1.427 + push @mmp, "userinclude . \n";
1.428 + if ($$modref{fixed}) {
1.429 + push @mmp, "epocfixedprocess\n";
1.430 + }
1.431 +
1.432 + # if both paged flags are set or the compression is not pageable then print neither.
1.433 + # T_LDRTST will add the required flags when it copies the file to internal media.
1.434 +
1.435 + my $bothCodePageFlags = $$modref{pagedcode} && $$modref{unpagedcode};
1.436 + my $pageableCompression = $$modref{bytepair} || $$modref{uncompressed};
1.437 + if (!$bothCodePageFlags && $pageableCompression) {
1.438 + push @mmp, "pagedcode\n" if $$modref{pagedcode};
1.439 + push @mmp, "unpagedcode\n" if $$modref{unpagedcode};
1.440 + }
1.441 +
1.442 + if ($$modref{exe}) {
1.443 + # make exes unpageddata by default
1.444 + if (!$$modref{pageddata}) {
1.445 + $$modref{unpageddata}=1;
1.446 + }
1.447 + if ($$modref{pageddata}) {
1.448 + push @mmp, "pageddata\n";
1.449 + }
1.450 + if ($$modref{unpageddata}) {
1.451 + push @mmp, "unpageddata\n";
1.452 + }
1.453 + }
1.454 +
1.455 + if ($$modref{bytepair}) {
1.456 + push @mmp, "bytepaircompresstarget\n";
1.457 + }
1.458 +
1.459 + if ($$modref{uncompressed}) {
1.460 + push @mmp, "nocompresstarget\n";
1.461 + }
1.462 +
1.463 + if ($$modref{data} && !$$modref{exe}) {
1.464 + push @mmp, "epocallowdlldata\n";
1.465 + }
1.466 + push @mmp, sprintf("uid 0x00000000 0x%08x\n", $num+256);
1.467 + push @mmp, "SMPSAFE\n";
1.468 + $$modref{mmp}=\@mmp;
1.469 +
1.470 + if ($$modref{exports}) {
1.471 + my @def;
1.472 + push @def, "EXPORTS\n";
1.473 + if ($$modref{exe}) {
1.474 + push @def, "\tRegisterConstructorCall @ 1 NONAME\n";
1.475 + push @def, "\tRegisterInitCall @ 2 NONAME\n";
1.476 + push @def, "\tRegisterDestructorCall @ 3 NONAME\n";
1.477 + } else {
1.478 + push @def, "\tInit$num @ 1 NONAME\n";
1.479 + push @def, "\tChkC$num @ 2 NONAME\n";
1.480 + push @def, "\tBlkI$num @ 3 NONAME\n";
1.481 + push @def, "\tGetGeneration @ 4 NONAME\n";
1.482 + push @def, "\tRBlkI$num @ 5 NONAME\n";
1.483 + push @def, "\tSetCloseLib @ 6 NONAME\n";
1.484 + }
1.485 + $$modref{def}=\@def;
1.486 + }
1.487 +
1.488 + push @bldinf, "$$modref{basefilename}\t\tsupport\n";
1.489 +
1.490 + if ($num==0) {
1.491 + push @dlltree, "#if defined(__DLLNUM$num)\n";
1.492 + } else {
1.493 + push @dlltree, "#elif defined(__DLLNUM$num)\n";
1.494 + }
1.495 + push @dlltree, "#define DLLNUM $num\n";
1.496 + if ($$modref{exe}) {
1.497 + push @dlltree, "#define EXENUM $num\n";
1.498 + push @dlltree, "_LIT(KServerName, \"$$modref{name}\");\n";
1.499 + }
1.500 + push @dlltree, "#define INITFUNC Init$num\n";
1.501 + push @dlltree, "#define CHKCFUNC ChkC$num\n";
1.502 + push @dlltree, "#define BLKIFUNC BlkI$num\n";
1.503 + push @dlltree, "#define RBLKIFUNC RBlkI$num\n";
1.504 + push @dlltree, "#define CHKDEPS(r) (\\\n";
1.505 + foreach (@$depsref) {
1.506 + my $depref=$modules[$_];
1.507 + unless ($$depref{exe}) {
1.508 + my $func="ChkC$_";
1.509 + push @dlltree, "\t((r)=$func())!=0 ||\\\n";
1.510 + }
1.511 + }
1.512 + push @dlltree, "\t((r)=0)!=0 )\n";
1.513 + push @dlltree, "#define INITDEPS(r,l) (\\\n";
1.514 + foreach (@$depsref) {
1.515 + my $depref=$modules[$_];
1.516 + unless ($$depref{exe}) {
1.517 + my $func="Init$_";
1.518 + push @dlltree, "\t((r)=$func(l))!=0 ||\\\n";
1.519 + }
1.520 + }
1.521 + push @dlltree, "\t((r)=0)!=0 )\n";
1.522 + my $link_to_exe;
1.523 + push @dlltree, "#define RBLKIFUNC_DEPS(i,g) {\\\n";
1.524 + foreach (@$depsref) {
1.525 + my $depref=$modules[$_];
1.526 + if ($$depref{exe}) {
1.527 + $link_to_exe=1;
1.528 + } else {
1.529 + my $func="RBlkI$_";
1.530 + push @dlltree, "\t(i)=$func(i,g);\\\n";
1.531 + }
1.532 + }
1.533 + push @dlltree, "\t}\n";
1.534 + if ($link_to_exe) {
1.535 + push @dlltree, "#define __DLL_LINK_TO_EXE\n";
1.536 + }
1.537 + if ($$modref{cycle}) {
1.538 + push @dlltree, "#define __DLL_IN_CYCLE\n";
1.539 + }
1.540 + if ($$modref{data}) {
1.541 + push @dlltree, "#define __MODULE_HAS_DATA\n";
1.542 + }
1.543 + if ($$modref{exports}) {
1.544 + push @dlltree, "#define __MODULE_EXPORT\t\tEXPORT_C\n";
1.545 + push @dlltree, "#define __MODULE_IMPORT\t\tIMPORT_C\n";
1.546 + } else {
1.547 + push @dlltree, "#define __MODULE_EXPORT\n";
1.548 + push @dlltree, "#define __MODULE_IMPORT\n";
1.549 + }
1.550 + foreach (@$depsref) {
1.551 + my $depref=$modules[$_];
1.552 + if ($$depref{exe}) {
1.553 + } else {
1.554 + push @dlltree, "extern \"C\" IMPORT_C TInt Init$_(MDllList&);\n";
1.555 + push @dlltree, "extern \"C\" IMPORT_C TInt ChkC$_();\n";
1.556 + push @dlltree, "extern \"C\" IMPORT_C TInt RBlkI$_(TInt, TInt);\n";
1.557 + }
1.558 + }
1.559 + my $hostfullpathname=$hostpath.$$modref{filename};
1.560 + if ($$modref{xip}) {
1.561 + my $epocfullpathname=$xippath.$$modref{filename};
1.562 + my $flags;
1.563 + if ($$modref{attp}) {
1.564 + $flags='process '.$modref->{attp}->{filename};
1.565 + }
1.566 + push @iby, "file=$hostfullpathname\t\t$epocfullpathname\t\t$flags\n";
1.567 + } else {
1.568 + my $epocfullpathname=$nonxippath.$$modref{filename};
1.569 + push @iby, "data=$hostfullpathname\t\t$epocfullpathname\n";
1.570 + }
1.571 +}
1.572 +
1.573 +#push @dlltree, "#else\n";
1.574 +#push @dlltree, "#error No __DLLNUM macro defined\n";
1.575 +push @dlltree, "#endif\n";
1.576 +push @dlltree, "\n";
1.577 +
1.578 +my $module_count=scalar(@modules);
1.579 +push @dlltree, "const TInt KNumModules=$module_count;\n";
1.580 +push @dlltree, "\n";
1.581 +push @dlltree, "#ifdef __INCLUDE_DEPENDENCY_GRAPH\n";
1.582 +push @dlltree, "static const TText* const ModuleName[KNumModules] =\n";
1.583 +push @dlltree, "\t\{\n";
1.584 +foreach $modref (@modules) {
1.585 + my $string="\t(const TText*)L\"$$modref{name}\"";
1.586 + unless ($$modref{num}==$module_count-1) {
1.587 + $string.=',';
1.588 + }
1.589 + push @dlltree, $string;
1.590 + my $pad=41-length($string);
1.591 + $pad=($pad+3)/4;
1.592 + push @dlltree, "\t"x$pad, "\/*", $$modref{num}, "*\/\n";
1.593 +}
1.594 +push @dlltree, "\t\};\n";
1.595 +push @dlltree, "\n";
1.596 +push @dlltree, "#define MODULE_NAME(n) TPtrC(ModuleName[n])\n";
1.597 +push @dlltree, "\n";
1.598 +push @dlltree, "static const TText* const ModuleFileName[KNumModules] =\n";
1.599 +push @dlltree, "\t\{\n";
1.600 +foreach $modref (@modules) {
1.601 + if ($$modref{idrive} || $$modref{vdrive}) {
1.602 + my $fn = $$modref{filename};
1.603 + my $used_nxip_path = "?:\\$nonxippath$fn";
1.604 + $used_nxip_path =~ s/\\/\\\\/g; # double backslashes
1.605 + substr($used_nxip_path,0,1) = $$modref{idrive} ? "0" : "1";
1.606 + push @dlltree, "\t(const TText*)L\"$used_nxip_path\"";
1.607 + } else {
1.608 + push @dlltree, "\t(const TText*)L\"$$modref{filename}\"";
1.609 + }
1.610 + if ($$modref{num}==$module_count-1) {
1.611 + push @dlltree, "\n";
1.612 + } else {
1.613 + push @dlltree, ",\n";
1.614 + }
1.615 +}
1.616 +push @dlltree, "\t\};\n";
1.617 +push @dlltree, "\n";
1.618 +push @dlltree, "#define MODULE_FILENAME(n) TPtrC(ModuleFileName[n])\n";
1.619 +push @dlltree, "\n";
1.620 +foreach $modref (@modules) {
1.621 + my $modnum=$$modref{num};
1.622 + my $tcdepsref=$$modref{tcdeps};
1.623 + my $numdeps=scalar(@$tcdepsref);
1.624 + push @dlltree, "static const TInt Module$modnum","Deps[] =\n";
1.625 + push @dlltree, "\t\{$numdeps";
1.626 + if ($numdeps) {
1.627 + push @dlltree, ",", join(',',@$tcdepsref)
1.628 + }
1.629 + push @dlltree, "\};\n";
1.630 +}
1.631 +push @dlltree, "static const TInt* const ModuleDependencies[KNumModules] =\n";
1.632 +push @dlltree, "\t\{\n";
1.633 +foreach $modref (@modules) {
1.634 + my $modnum=$$modref{num};
1.635 + push @dlltree, "\tModule$modnum","Deps";
1.636 + if ($$modref{num}==$module_count-1) {
1.637 + push @dlltree, "\n";
1.638 + } else {
1.639 + push @dlltree, ",\n";
1.640 + }
1.641 +}
1.642 +push @dlltree, "\t\};\n";
1.643 +push @dlltree, "\n";
1.644 +push @dlltree, sprintf "const TInt KModuleFlagExe=0x%04x;\n", $flag_value_exe;
1.645 +push @dlltree, sprintf "const TInt KModuleFlagFixed=0x%04x;\n", $flag_value_fixed;
1.646 +push @dlltree, sprintf "const TInt KModuleFlagData=0x%04x;\n", $flag_value_data;
1.647 +#push @dlltree, "#ifdef __EPOC32__\n";
1.648 +push @dlltree, sprintf "const TInt KModuleFlagXIP=0x%04x;\n", $flag_value_xip;
1.649 +push @dlltree, sprintf "const TInt KModuleFlagPagedCode=0x%04x;\n", $flag_value_pagedcode;
1.650 +push @dlltree, sprintf "const TInt KModuleFlagUnpagedCode=0x%04x;\n", $flag_value_unpagedcode;
1.651 +push @dlltree, sprintf "const TInt KModuleFlagIDrive=0x%04x;\n", $flag_value_idrive;
1.652 +push @dlltree, sprintf "const TInt KModuleFlagVDrive=0x%04x;\n", $flag_value_vdrive;
1.653 +push @dlltree, sprintf "const TInt KModuleFlagBytePair=0x%04x;\n", $flag_value_bytepair;
1.654 +push @dlltree, sprintf "const TInt KModuleFlagUncompressed=0x%04x;\n", $flag_value_uncompressed;
1.655 +#push @dlltree, "#else\n";
1.656 +#push @dlltree, sprintf "const TInt KModuleFlagXIP=0x%04x;\n", 0; # no XIPs on emulator
1.657 +#push @dlltree, "#endif\n";
1.658 +push @dlltree, sprintf "const TInt KModuleFlagDllInCycle=0x%04x;\n", $flag_value_dll_in_cycle;
1.659 +push @dlltree, sprintf "const TInt KModuleFlagDataInTree=0x%04x;\n", $flag_value_data_in_tree;
1.660 +#push @dlltree, "#ifdef __EPOC32__\n";
1.661 +push @dlltree, sprintf "const TInt KModuleFlagXIPDataInTree=0x%04x;\n", $flag_value_xip_data_in_tree;
1.662 +#push @dlltree, "#else\n";
1.663 +#push @dlltree, sprintf "const TInt KModuleFlagXIPDataInTree=0x%04x;\n", 0;
1.664 +#push @dlltree, "#endif\n";
1.665 +push @dlltree, sprintf "const TInt KModuleFlagExports=0x%04x;\n", $flag_value_exports;
1.666 +push @dlltree, sprintf "const TInt KModuleFlagTargetOnly=0x%04x;\n", $flag_value_targetonly;
1.667 +push @dlltree, sprintf "const TInt KModuleFlagPagedData=0x%04x;\n", $flag_value_pageddata;
1.668 +push @dlltree, sprintf "const TInt KModuleFlagUnpagedData=0x%04x;\n", $flag_value_unpageddata;
1.669 +push @dlltree, "static const TInt ModuleFlags[KNumModules] =\n";
1.670 +push @dlltree, "\t\{\n";
1.671 +foreach $modref (@modules) {
1.672 + my $flags=0;
1.673 + my @flagNames = ();
1.674 +
1.675 + push @flagNames, "KModuleFlagExe" if ($$modref{exe});
1.676 + push @flagNames, "KModuleFlagFixed" if ($$modref{fixed});
1.677 + push @flagNames, "KModuleFlagData" if ($$modref{data});
1.678 + push @flagNames, "KModuleFlagXIP" if ($$modref{xip});
1.679 + push @flagNames, "KModuleFlagPagedCode" if ($$modref{pagedcode});
1.680 + push @flagNames, "KModuleFlagUnpagedCode" if ($$modref{unpagedcode});
1.681 + push @flagNames, "KModuleFlagPagedData" if ($$modref{pageddata});
1.682 + push @flagNames, "KModuleFlagUnpagedData" if (!$$modref{pageddata});
1.683 + push @flagNames, "KModuleFlagIDrive" if ($$modref{idrive});
1.684 + push @flagNames, "KModuleFlagVDrive" if ($$modref{vdrive});
1.685 + push @flagNames, "KModuleFlagBytePair" if ($$modref{bytepair});
1.686 + push @flagNames, "KModuleFlagDllInCycle" if ($$modref{cycle});
1.687 + push @flagNames, "KModuleFlagDataInTree" if ($$modref{dataintree});
1.688 + push @flagNames, "KModuleFlagXIPDataInTree" if ($$modref{xipdataintree});
1.689 + push @flagNames, "KModuleFlagExports" if ($$modref{exports});
1.690 + push @flagNames, "KModuleFlagUncompressed" if ($$modref{uncompressed});
1.691 + push @flagNames, "KModuleFlagTargetOnly" if ($$modref{targetonly});
1.692 +
1.693 + @flagNames = qw(0) if (scalar(@flagNames) == 0);
1.694 + my $flagString = "/\* " . $$modref{num} . " \*/\t" . join(' | ', @flagNames);
1.695 + unless ($$modref{num}==$module_count-1) {
1.696 + $flagString.=',';
1.697 + }
1.698 + push @dlltree, $flagString . "\n";
1.699 +}
1.700 +push @dlltree, "\t\};\n";
1.701 +push @dlltree, "\n";
1.702 +foreach $modref (@modules) {
1.703 + my $modnum=$$modref{num};
1.704 + my @rblki;
1.705 + ++$next_mark;
1.706 + calc_rblki(\@rblki, \@modules, $modref, $next_mark);
1.707 + my $rblki_count=scalar(@rblki);
1.708 + my $rblki_sum=0;
1.709 + foreach (@rblki) {
1.710 + $rblki_sum += $_;
1.711 + }
1.712 + push @dlltree, "static const TInt Module$modnum","RBlkIParams[2] = \{ $rblki_count, $rblki_sum \};\n";
1.713 +}
1.714 +push @dlltree, "\n";
1.715 +push @dlltree, "static const TInt* const ModuleRBlkIParams[KNumModules] =\n";
1.716 +push @dlltree, "\t\{\n";
1.717 +foreach $modref (@modules) {
1.718 + my $modnum=$$modref{num};
1.719 + push @dlltree, "\tModule$modnum","RBlkIParams";
1.720 + if ($$modref{num}==$module_count-1) {
1.721 + push @dlltree, "\n";
1.722 + } else {
1.723 + push @dlltree, ",\n";
1.724 + }
1.725 +}
1.726 +push @dlltree, "\t\};\n";
1.727 +push @dlltree, "\n";
1.728 +foreach $modref (@modules) {
1.729 + my $modnum=$$modref{num};
1.730 + my $mod_attp=$modnum;
1.731 + my $mod_linkp=$modnum;
1.732 + unless ($$modref{exe}) {
1.733 + $mod_attp = ($$modref{attp}) ? ($modref->{attp}->{num}) : -1;
1.734 + $mod_linkp = ($$modref{linkexe}) ? ($modref->{linkexe}->{num}) : -1;
1.735 + }
1.736 + push @dlltree, "static const TInt Module$modnum","ExeInfo[2] = \{ $mod_attp, $mod_linkp \};\n";
1.737 +}
1.738 +push @dlltree, "\n";
1.739 +push @dlltree, "static const TInt* const ModuleExeInfo[KNumModules] =\n";
1.740 +push @dlltree, "\t\{\n";
1.741 +foreach $modref (@modules) {
1.742 + my $modnum=$$modref{num};
1.743 + push @dlltree, "\tModule$modnum","ExeInfo";
1.744 + if ($$modref{num}==$module_count-1) {
1.745 + push @dlltree, "\n";
1.746 + } else {
1.747 + push @dlltree, ",\n";
1.748 + }
1.749 +}
1.750 +push @dlltree, "\t\};\n";
1.751 +
1.752 +foreach $tcref (@testcases) {
1.753 + push @dlltree, "\n";
1.754 + my $modlistref=$$tcref{modules};
1.755 + my $count=$$tcref{count};
1.756 + my $arraysize=$count+1;
1.757 + push @dlltree, "static const TInt TC_$$tcref{name}\[$arraysize\]=\n\t\{\n";
1.758 + if ($count==0) {
1.759 + push @dlltree, "\t$count\n";
1.760 + } else {
1.761 + push @dlltree, "\t$count\,\n";
1.762 + }
1.763 + foreach (@$modlistref) {
1.764 + --$count;
1.765 + if ($count==0) {
1.766 + push @dlltree, "\t$_\n";
1.767 + } else {
1.768 + push @dlltree, "\t$_\,\n";
1.769 + }
1.770 + }
1.771 + push @dlltree, "\t\};\n";
1.772 +}
1.773 +
1.774 +push @dlltree, "#endif\n";
1.775 +push @dlltree, "\n";
1.776 +push @dlltree, "#endif\n";
1.777 +
1.778 +foreach $modref (@modules) {
1.779 + my $mmpname=$$modref{basefilename}.$mmpext;
1.780 + my $mmpref=$$modref{mmp};
1.781 + open OUT, ">$mmpname" or die "Could not open $mmpname for output\n";
1.782 + print OUT @$mmpref;
1.783 + close OUT;
1.784 + if ($$modref{exports}) {
1.785 + my $defname=$$modref{basefilename}.$defext;
1.786 + my $defref=$$modref{def};
1.787 + open OUT, ">$defname" or die "Could not open $defname for output\n";
1.788 + print OUT @$defref;
1.789 + close OUT;
1.790 + }
1.791 +}
1.792 +if (!$allowbad) {
1.793 + push @bldinf, "t_ldrtst\n";
1.794 +}
1.795 +open OUT, ">$bldname" or die "Could not open $bldname for output\n";
1.796 +print OUT @bldinf;
1.797 +close OUT;
1.798 +open OUT, ">$dlltreename" or die "Could not open $dlltreename for output\n";
1.799 +print OUT @dlltree;
1.800 +close OUT;
1.801 +my $testbatch = "$ENV{EPOCROOT}epoc32\\build";
1.802 +$destpath =~ s/\//\\/go;
1.803 +$testbatch.="\\" unless ($destpath =~ /^\\/);
1.804 +$testbatch.=$destpath;
1.805 +$testbatch.="##MAIN##.auto.bat";
1.806 +if (!$allowbad) {
1.807 + push @iby, "data=$testbatch\t\ttest\\loader.auto.bat\n";
1.808 +}
1.809 +open OUT, ">$ibyname" or die "Could not open $ibyname for output\n";
1.810 +print OUT @iby;
1.811 +close OUT;
1.812 +
1.813 +#
1.814 +# Accumulate list of dependency numbers
1.815 +# 1st arg = \output list
1.816 +# 2nd arg = \module list
1.817 +# 3rd arg = \module to start from
1.818 +# 4th arg = mark value to use
1.819 +#
1.820 +sub calc_tc($$$$) {
1.821 + my ($out, $mods, $modref, $mark)=@_;
1.822 + my $depsref=$$modref{deps};
1.823 + foreach $dep (@$depsref) {
1.824 + my $depref=$$mods[$dep];
1.825 + if ($$depref{mark} != $mark) {
1.826 + $$depref{mark}=$mark;
1.827 + unless ($$depref{exe}) {
1.828 + calc_tc($out, $mods, $depref, $mark);
1.829 + }
1.830 + push @$out, $dep;
1.831 + }
1.832 + }
1.833 +}
1.834 +
1.835 +#
1.836 +# Accumulate RBlkI parameters
1.837 +# 1st arg = \output list
1.838 +# 2nd arg = \module list
1.839 +# 3rd arg = \module to start from
1.840 +# 4th arg = mark value to use
1.841 +#
1.842 +sub calc_rblki($$$$) {
1.843 + my ($out, $mods, $modref, $mark)=@_;
1.844 + if ($$modref{mark} != $mark) {
1.845 + $$modref{mark}=$mark;
1.846 + if (!$$modref{exe} and $$modref{data}) {
1.847 + push @$out, $$modref{num};
1.848 + my $depsref=$$modref{deps};
1.849 + foreach $dep (@$depsref) {
1.850 + calc_rblki($out, $mods, $$mods[$dep], $mark);
1.851 + }
1.852 + }
1.853 + }
1.854 +}
1.855 +
1.856 +
1.857 +