diff -r 000000000000 -r a41df078684a kerneltest/f32test/loader/dlltree.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/f32test/loader/dlltree.pl Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,854 @@ +# Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "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: +# \f32test\loader\dlltree.pl +# Generate header and build files for one or more trees +# of DLLs and EXEs according to a description file. +# +# + +require Cwd; + +my $dllbasename='dllt'; +my $dllext='.dll'; +my $exebasename='exet'; +my $exeext='.exe'; +my $mmpext='.mmp'; +my $defext='.def'; +my $libext='.lib'; + +my $source0ext='.cpp'; +my $source1ext='.cia'; +my $xippath="sys\\bin\\"; +my $nonxippath="sys\\bin\\"; + +my $hostpath="\\Epoc32\\Release\\##MAIN##\\##BUILD##\\"; + +my $flag_value_exe=1; +my $flag_value_fixed=2; +my $flag_value_data=4; +my $flag_value_xip=8; +my $flag_value_dll_in_cycle=16; +my $flag_value_data_in_tree=32; +my $flag_value_xip_data_in_tree=64; +my $flag_value_exports=128; +my $flag_value_pagedcode=256; +my $flag_value_unpagedcode=512; +my $flag_value_idrive=1024; +my $flag_value_vdrive=2048; +my $flag_value_bytepair=4096; +my $flag_value_uncompressed=8192; +my $flag_value_targetonly=16384; +my $flag_value_pageddata=32768; +my $flag_value_unpageddata=65536; + +my $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst; +($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime; +my $copy_end=$year+1900; + +my $argc=scalar(@ARGV); +($argc==1 or $argc==2 or $argc==3) or die "Usage: perl dlltree.pl [-allowbad]\n"; +my $infile=$ARGV[0]; +open IN, $infile or die "Cannot open input file $infile\n"; +my @in; +while () { + push @in, $_; +} +close IN; +my $destdir=''; +if ($argc>=2) { + $destdir=$ARGV[1]; + unless (-d $destdir) { + mkdir $destdir, 0777 or die "Can't create directory $destdir\n"; + } + chdir $destdir or die "Can't chdir to directory $destdir\n"; +} +my $allowbad; +if ($argc==3) { + if ($ARGV[2] eq '-allowbad') { + $allowbad = 1; + } +} +$cwd=Cwd::getcwd(); +$destpath=$cwd; +$destpath=~s/\//\\/g; +if ($destpath=~/^\w\:(.*)/) { + $destpath=$1; +} +unless ($destpath=~/^(.*?)\\$/) { + $destpath.='\\'; +} +#print "$cwd\n"; +#print "$destpath\n"; + +my @modules; +my @testcases; +my $line=0; +my $modnum=0; +my $state=0; +my $concat; +foreach (@in) { + ++$line; + next if (/^\s*$/ or /^\s*\#/); + if ($state==0) { + if (/^\!TESTCASES/) { + $state=1; + next; + } + my @moddesc=split; + my $modname=shift @moddesc; + if (grep {lc($$_{name}) eq lc($modname)} @modules) { + die "Duplicate module specification at line $line\n"; + } + my %module; + $module{name}=$modname; + $module{num}=$modnum; + $module{exports}=1; + $module{nclients}=0; # number of modules which import from this one + while (scalar(@moddesc)) { + my $att=shift @moddesc; + if ($att=~/^\:$/) { + last; + } elsif ($att=~/^X$/i) { + $module{exe}=1; + } elsif ($att=~/^F$/i) { + $module{fixed}=1; + } elsif ($att=~/^D$/i) { + $module{data}=1; + } elsif ($att=~/^P$/i) { + $module{pagedcode}=1; + } elsif ($att=~/^PD$/i) { + $module{pageddata}=1; + } elsif ($att=~/^B$/i) { + $module{bytepair}=1; + } elsif ($att=~/^U$/i) { + $module{uncompressed}=1; + } elsif ($att=~/^I$/i) { + $module{idrive}=1; + } elsif ($att=~/^V$/i) { + $module{vdrive}=1; + } elsif ($att=~/^N$/i) { + $module{unpagedcode}=1; + } elsif ($att=~/^T$/i) { + $module{targetonly}=1; + } elsif ($att=~/^R(.*?)$/i) { + $module{xip}=1; + my $attp=$1; + if ($attp=~/^\,(.*?)$/) { + $module{attpname}=$1; + } elsif (!($attp=~/^\s*$/)) { + die "Garbage following R attribute at line $line\n"; + } + } + } + if ($module{fixed} && !$module{exe}) { + die "Can't have FIXED without EXE at line $line\n"; + } + if ($module{pagedcode} && $module{xip}) { + die "Can't have PAGEDCODE with XIP at line $line\n"; + } + + # makmake won't support paged binaries which aren't bytepair or uncompressed. + # However, P can be specified without them in dlltree.txt. This program generates + # an MMP file with neither flag. The flag is added when the files are copied to + # internal media by T_LDRTST. (It would be pointless to copy the files to removable + # media and then edit them because removable media doesn't support paging.) + + my $bothCodePageFlags = $module{pagedcode} && $module{unpagedcode}; + if ($bothCodePageFlags && !$module{idrive}) { + die "Can't have PAGEDCODE and UNPAGEDCODE without INTERNAL DRIVE at line $line\n"; + } + if ($module{unpagedcode} && $module{xip}) { + die "Can't have UNPAGEDCODE with XIP at line $line\n"; + } + if ($module{pageddata} && !$module{exe}) { + die "Can't have PAGEDDATA without EXE at line $line\n"; + } + if ($module{idrive} && $module{xip}) { + die "Can't have INTERNAL DRIVE with XIP at line $line\n"; + } + if ($module{vdrive} && $module{xip}) { + die "Can't have REMOVABLE DRIVE with XIP at line $line\n"; + } + if ($module{idrive} && $module{vdrive}) { + die "Can't have INTERNAL DRIVE with REMOVABLE DRIVE at line $line\n"; + } + if ($module{bytepair} && $module{uncompressed}) { + die "Can't have BYTEPAIR with UNCOMPRESSED at line $line\n"; + } + if ($module{exe}) { + if ($module{attpname}) { + warn "Attach process with EXE ignored at line $line\n"; + delete $module{attpname}; + } + $module{basefilename}=$exebasename.$modnum; + $module{filename}=$module{basefilename}.$exeext; + $module{source0}=$exebasename.$source0ext; + $module{source1}=""; + $module{trgtype}='exexp'; + $module{lib}=$module{basefilename}.$libext; + } else { + $module{basefilename}=$dllbasename.$modnum; + $module{filename}=$module{basefilename}.$dllext; + $module{source0}=$dllbasename.$source0ext; + $module{source1}=$dllbasename.$source1ext; + $module{trgtype}='dll'; + $module{lib}=$module{basefilename}.$libext; + } + $module{depnames}=\@moddesc; # dependency names are left over + $module{line}=$line; + $module{mark}=0; + push @modules, \%module; + ++$modnum; + } elsif ($state<=2) { + if ($state==1) { + $concat=""; + die "Syntax error at line $line\n" unless (/^(\w+)\:/); + } + if (/^(.*?)\\$/) { + $concat.=$1; + $concat.=' '; + $state=2; + next; + } else { + $concat.=$_; + $state=1; + } + my @modlist=split(/\s+/, $concat); + my $tcname=shift @modlist; + $tcname=~/^(.*?)\:$/ or die "???\n"; + $tcname=$1; + my %tc; + $tc{name}=$tcname; + $tc{mod_names}=\@modlist; + push @testcases, \%tc; + } +} +foreach $modref (@modules) { + my $moddepref=$$modref{depnames}; + my @deps; + foreach (@$moddepref) { + my $depname=lc($_); + my @match=grep {lc($$_{name}) eq $depname} @modules; + if (scalar(@match)==0) { + die "Unknown dependent module $depname at line $$modref{line}\n"; + } + my $depref=$match[0]; + if ($$modref{xip} and !$$depref{xip}) { + die "Illegal dependency: $$modref{name} (XIP) on $$depref{name} (non-XIP)\n"; + } + push @deps, $$depref{num}; + ++$$depref{nclients}; + } + $$modref{deps}=\@deps; + my $attpname=$$modref{attpname}; + if ($attpname) { + my @match=grep {lc($$_{name}) eq lc($attpname)} @modules; + if (scalar(@match)==0) { + die "Unknown attach process $attpname at line $$modref{line}\n"; + } + my $attpref=$match[0]; + if (!$$attpref{exe}) { + die "Specified attach process is not EXE at line $$modref{line}\n"; + } elsif (!$$attpref{xip}) { + die "Specified attach process is not XIP at line $$modref{line}\n"; + } + $$modref{attp}=$attpref; + } +} +foreach $tcref (@testcases) { + my $modlistref=$$tcref{mod_names}; + my @modnums; + foreach $modname (@$modlistref) { + next if ($modname=~/^\s*$/); + my @match=grep {lc($$_{name}) eq lc($modname)} @modules; + if (scalar(@match)==0) { + die "Unknown module $modname in test case $$tcref{name}\n"; + } + push @modnums, $match[0]->{num}; + } + $$tcref{modules}=\@modnums; + $$tcref{count}=scalar(@modnums); +} +my $next_mark=0; +foreach $modref (@modules) { + if ($$modref{nclients}==0 and $$modref{exe}) { + # EXE with no exports + $$modref{exports}=0; + $$modref{trgtype}='exe'; + } + ++$next_mark; + my $modnum=$$modref{num}; + my @tcdeps; + calc_tc(\@tcdeps, \@modules, $modref, $next_mark); + $$modref{tcdeps}=\@tcdeps; + if (grep {$_==$modnum} @tcdeps) { + $$modref{cycle}=1; + } + my @exes=grep {$modules[$_]->{exe}} @tcdeps; + my $nexes=scalar(@exes); + + unless ($allowbad) { + if ($nexes>1) { + die "Module $$modref{name} links to more than one EXE\n"; + } elsif ($nexes==1) { + my $exeref=$modules[$exes[0]]; + $$modref{linkexe}=$exeref; + if ($$modref{exe}) { + if ($$exeref{num}!=$modnum) { + die "EXE $modref{name} links to another EXE\n"; + } + } else { + if ($$modref{attp} and $$exeref{num}!=$modref->{attp}->{num}) { + die "DLL $$modref{name} ($modnum) incompatible attach process\n"; + } + if (!$$modref{attp}) { + $$modref{attp}=$exeref; + } + } + } + } + if ($$modref{exe}) { + foreach $depnum (@tcdeps) { + my $depref=$modules[$depnum]; + my $depattpref=$depref->{attp}; + if ($depattpref and $depattpref->{num}!=$modnum) { + die "DEP DLL $$depref{name} ($$depref{num}) incompatible attach process\n"; + } +# if (!$depattpref) { +# $$depref{attp}=$modref; +# } + } + } +} +foreach $modref (@modules) { + my @total_deps; + my $tcdepref=$$modref{tcdeps}; + push @total_deps, @$tcdepref; + my $linkexe=$$modref{linkexe}; + if ($linkexe) { + my $exetcdepref=$$linkexe{tcdeps}; + push @total_deps, @$exetcdepref; + } + push @total_deps, $$modref{num}; + my $data=scalar(grep {$modules[$_]->{data}} @total_deps); + if ($data!=0) { + $$modref{dataintree}=1; + } + my $xipdata=scalar(grep {$modules[$_]->{data} and $modules[$_]->{xip}} @total_deps); + if ($xipdata!=0) { + $$modref{xipdataintree}=1; + } +} + +#foreach $modref (@modules) { +# print "Module $$modref{num}:\n"; +# print "\tName: $$modref{name}\n"; +# print "\tFilename: $$modref{filename}\n"; +# my $depref=$$modref{deps}; +# my $ndeps=scalar(@$depref); +# print "\t#Deps: $ndeps\n"; +# print "\tDeps: ",join(',',@$depref),"\n"; +#} + +my @bldinf; +my $bldname='dlltree.inf'; +push @bldinf, "// $destpath$bldname\n"; +push @bldinf, "//\n"; +push @bldinf, "// Copyright (c) 2000-$copy_end Symbian Ltd. All rights reserved.\n"; +push @bldinf, "//\n"; +push @bldinf, "\n"; +push @bldinf, "PRJ_PLATFORMS\n"; +push @bldinf, "BASEUSERDEFAULT\n"; +push @bldinf, "\n"; +push @bldinf, "PRJ_TESTMMPFILES\n"; +push @bldinf, "\n"; + +my @dlltree; +my $dlltreename='dlltree.h'; +push @dlltree, "// $destpath$dlltreename\n"; +push @dlltree, "//\n"; +push @dlltree, "// Copyright (c) 2000-$copy_end Symbian Ltd. All rights reserved.\n"; +push @dlltree, "//\n"; +push @dlltree, "\n"; +push @dlltree, "#ifndef __DLLTREE_H__\n"; +push @dlltree, "#define __DLLTREE_H__\n"; +push @dlltree, "#include \n"; +push @dlltree, "\n"; +push @dlltree, "class MDllList;\n"; +push @dlltree, "\n"; + +my $ibyname='ldrtest.iby'; +my @iby; + +foreach $modref (@modules) { + my @mmp; + my $num=$$modref{num}; + my $mmpname=$$modref{basefilename}.$mmpext; + my $defname=$$modref{basefilename}.$defext; + my $depsref=$$modref{deps}; + my $ndeps=scalar(@$depsref); + push @mmp, "// $destpath$mmpname\n"; + push @mmp, "//\n"; + push @mmp, "// Copyright (c) 2000-$copy_end Symbian Ltd. All rights reserved.\n"; + push @mmp, "//\n"; + push @mmp, "// Generated from $$modref{name}\n"; + push @mmp, "\n"; + push @mmp, "macro __DLLNUM$num\n"; + push @mmp, "target $$modref{filename}\n"; + push @mmp, "targettype $$modref{trgtype}\n"; + push @mmp, "sourcepath .\n"; + push @mmp, "source $$modref{source0} $$modref{source1}\n"; + push @mmp, "library euser.lib efsrv.lib\n"; + push @mmp, "Capability NONE\n"; + foreach (@$depsref) { + my $depref=$modules[$_]; + push @mmp, "library $$depref{lib}\n"; + } + if ($$modref{exports}) { + push @mmp, "deffile ./$defname\n"; + push @mmp, "nostrictdef\n"; + } + push @mmp, "OS_LAYER_SYSTEMINCLUDE_SYMBIAN \n"; + push @mmp, "systeminclude ../../../e32test/mmu \n"; + push @mmp, "userinclude . \n"; + if ($$modref{fixed}) { + push @mmp, "epocfixedprocess\n"; + } + + # if both paged flags are set or the compression is not pageable then print neither. + # T_LDRTST will add the required flags when it copies the file to internal media. + + my $bothCodePageFlags = $$modref{pagedcode} && $$modref{unpagedcode}; + my $pageableCompression = $$modref{bytepair} || $$modref{uncompressed}; + if (!$bothCodePageFlags && $pageableCompression) { + push @mmp, "pagedcode\n" if $$modref{pagedcode}; + push @mmp, "unpagedcode\n" if $$modref{unpagedcode}; + } + + if ($$modref{exe}) { + # make exes unpageddata by default + if (!$$modref{pageddata}) { + $$modref{unpageddata}=1; + } + if ($$modref{pageddata}) { + push @mmp, "pageddata\n"; + } + if ($$modref{unpageddata}) { + push @mmp, "unpageddata\n"; + } + } + + if ($$modref{bytepair}) { + push @mmp, "bytepaircompresstarget\n"; + } + + if ($$modref{uncompressed}) { + push @mmp, "nocompresstarget\n"; + } + + if ($$modref{data} && !$$modref{exe}) { + push @mmp, "epocallowdlldata\n"; + } + push @mmp, sprintf("uid 0x00000000 0x%08x\n", $num+256); + push @mmp, "SMPSAFE\n"; + $$modref{mmp}=\@mmp; + + if ($$modref{exports}) { + my @def; + push @def, "EXPORTS\n"; + if ($$modref{exe}) { + push @def, "\tRegisterConstructorCall @ 1 NONAME\n"; + push @def, "\tRegisterInitCall @ 2 NONAME\n"; + push @def, "\tRegisterDestructorCall @ 3 NONAME\n"; + } else { + push @def, "\tInit$num @ 1 NONAME\n"; + push @def, "\tChkC$num @ 2 NONAME\n"; + push @def, "\tBlkI$num @ 3 NONAME\n"; + push @def, "\tGetGeneration @ 4 NONAME\n"; + push @def, "\tRBlkI$num @ 5 NONAME\n"; + push @def, "\tSetCloseLib @ 6 NONAME\n"; + } + $$modref{def}=\@def; + } + + push @bldinf, "$$modref{basefilename}\t\tsupport\n"; + + if ($num==0) { + push @dlltree, "#if defined(__DLLNUM$num)\n"; + } else { + push @dlltree, "#elif defined(__DLLNUM$num)\n"; + } + push @dlltree, "#define DLLNUM $num\n"; + if ($$modref{exe}) { + push @dlltree, "#define EXENUM $num\n"; + push @dlltree, "_LIT(KServerName, \"$$modref{name}\");\n"; + } + push @dlltree, "#define INITFUNC Init$num\n"; + push @dlltree, "#define CHKCFUNC ChkC$num\n"; + push @dlltree, "#define BLKIFUNC BlkI$num\n"; + push @dlltree, "#define RBLKIFUNC RBlkI$num\n"; + push @dlltree, "#define CHKDEPS(r) (\\\n"; + foreach (@$depsref) { + my $depref=$modules[$_]; + unless ($$depref{exe}) { + my $func="ChkC$_"; + push @dlltree, "\t((r)=$func())!=0 ||\\\n"; + } + } + push @dlltree, "\t((r)=0)!=0 )\n"; + push @dlltree, "#define INITDEPS(r,l) (\\\n"; + foreach (@$depsref) { + my $depref=$modules[$_]; + unless ($$depref{exe}) { + my $func="Init$_"; + push @dlltree, "\t((r)=$func(l))!=0 ||\\\n"; + } + } + push @dlltree, "\t((r)=0)!=0 )\n"; + my $link_to_exe; + push @dlltree, "#define RBLKIFUNC_DEPS(i,g) {\\\n"; + foreach (@$depsref) { + my $depref=$modules[$_]; + if ($$depref{exe}) { + $link_to_exe=1; + } else { + my $func="RBlkI$_"; + push @dlltree, "\t(i)=$func(i,g);\\\n"; + } + } + push @dlltree, "\t}\n"; + if ($link_to_exe) { + push @dlltree, "#define __DLL_LINK_TO_EXE\n"; + } + if ($$modref{cycle}) { + push @dlltree, "#define __DLL_IN_CYCLE\n"; + } + if ($$modref{data}) { + push @dlltree, "#define __MODULE_HAS_DATA\n"; + } + if ($$modref{exports}) { + push @dlltree, "#define __MODULE_EXPORT\t\tEXPORT_C\n"; + push @dlltree, "#define __MODULE_IMPORT\t\tIMPORT_C\n"; + } else { + push @dlltree, "#define __MODULE_EXPORT\n"; + push @dlltree, "#define __MODULE_IMPORT\n"; + } + foreach (@$depsref) { + my $depref=$modules[$_]; + if ($$depref{exe}) { + } else { + push @dlltree, "extern \"C\" IMPORT_C TInt Init$_(MDllList&);\n"; + push @dlltree, "extern \"C\" IMPORT_C TInt ChkC$_();\n"; + push @dlltree, "extern \"C\" IMPORT_C TInt RBlkI$_(TInt, TInt);\n"; + } + } + my $hostfullpathname=$hostpath.$$modref{filename}; + if ($$modref{xip}) { + my $epocfullpathname=$xippath.$$modref{filename}; + my $flags; + if ($$modref{attp}) { + $flags='process '.$modref->{attp}->{filename}; + } + push @iby, "file=$hostfullpathname\t\t$epocfullpathname\t\t$flags\n"; + } else { + my $epocfullpathname=$nonxippath.$$modref{filename}; + push @iby, "data=$hostfullpathname\t\t$epocfullpathname\n"; + } +} + +#push @dlltree, "#else\n"; +#push @dlltree, "#error No __DLLNUM macro defined\n"; +push @dlltree, "#endif\n"; +push @dlltree, "\n"; + +my $module_count=scalar(@modules); +push @dlltree, "const TInt KNumModules=$module_count;\n"; +push @dlltree, "\n"; +push @dlltree, "#ifdef __INCLUDE_DEPENDENCY_GRAPH\n"; +push @dlltree, "static const TText* const ModuleName[KNumModules] =\n"; +push @dlltree, "\t\{\n"; +foreach $modref (@modules) { + my $string="\t(const TText*)L\"$$modref{name}\""; + unless ($$modref{num}==$module_count-1) { + $string.=','; + } + push @dlltree, $string; + my $pad=41-length($string); + $pad=($pad+3)/4; + push @dlltree, "\t"x$pad, "\/*", $$modref{num}, "*\/\n"; +} +push @dlltree, "\t\};\n"; +push @dlltree, "\n"; +push @dlltree, "#define MODULE_NAME(n) TPtrC(ModuleName[n])\n"; +push @dlltree, "\n"; +push @dlltree, "static const TText* const ModuleFileName[KNumModules] =\n"; +push @dlltree, "\t\{\n"; +foreach $modref (@modules) { + if ($$modref{idrive} || $$modref{vdrive}) { + my $fn = $$modref{filename}; + my $used_nxip_path = "?:\\$nonxippath$fn"; + $used_nxip_path =~ s/\\/\\\\/g; # double backslashes + substr($used_nxip_path,0,1) = $$modref{idrive} ? "0" : "1"; + push @dlltree, "\t(const TText*)L\"$used_nxip_path\""; + } else { + push @dlltree, "\t(const TText*)L\"$$modref{filename}\""; + } + if ($$modref{num}==$module_count-1) { + push @dlltree, "\n"; + } else { + push @dlltree, ",\n"; + } +} +push @dlltree, "\t\};\n"; +push @dlltree, "\n"; +push @dlltree, "#define MODULE_FILENAME(n) TPtrC(ModuleFileName[n])\n"; +push @dlltree, "\n"; +foreach $modref (@modules) { + my $modnum=$$modref{num}; + my $tcdepsref=$$modref{tcdeps}; + my $numdeps=scalar(@$tcdepsref); + push @dlltree, "static const TInt Module$modnum","Deps[] =\n"; + push @dlltree, "\t\{$numdeps"; + if ($numdeps) { + push @dlltree, ",", join(',',@$tcdepsref) + } + push @dlltree, "\};\n"; +} +push @dlltree, "static const TInt* const ModuleDependencies[KNumModules] =\n"; +push @dlltree, "\t\{\n"; +foreach $modref (@modules) { + my $modnum=$$modref{num}; + push @dlltree, "\tModule$modnum","Deps"; + if ($$modref{num}==$module_count-1) { + push @dlltree, "\n"; + } else { + push @dlltree, ",\n"; + } +} +push @dlltree, "\t\};\n"; +push @dlltree, "\n"; +push @dlltree, sprintf "const TInt KModuleFlagExe=0x%04x;\n", $flag_value_exe; +push @dlltree, sprintf "const TInt KModuleFlagFixed=0x%04x;\n", $flag_value_fixed; +push @dlltree, sprintf "const TInt KModuleFlagData=0x%04x;\n", $flag_value_data; +#push @dlltree, "#ifdef __EPOC32__\n"; +push @dlltree, sprintf "const TInt KModuleFlagXIP=0x%04x;\n", $flag_value_xip; +push @dlltree, sprintf "const TInt KModuleFlagPagedCode=0x%04x;\n", $flag_value_pagedcode; +push @dlltree, sprintf "const TInt KModuleFlagUnpagedCode=0x%04x;\n", $flag_value_unpagedcode; +push @dlltree, sprintf "const TInt KModuleFlagIDrive=0x%04x;\n", $flag_value_idrive; +push @dlltree, sprintf "const TInt KModuleFlagVDrive=0x%04x;\n", $flag_value_vdrive; +push @dlltree, sprintf "const TInt KModuleFlagBytePair=0x%04x;\n", $flag_value_bytepair; +push @dlltree, sprintf "const TInt KModuleFlagUncompressed=0x%04x;\n", $flag_value_uncompressed; +#push @dlltree, "#else\n"; +#push @dlltree, sprintf "const TInt KModuleFlagXIP=0x%04x;\n", 0; # no XIPs on emulator +#push @dlltree, "#endif\n"; +push @dlltree, sprintf "const TInt KModuleFlagDllInCycle=0x%04x;\n", $flag_value_dll_in_cycle; +push @dlltree, sprintf "const TInt KModuleFlagDataInTree=0x%04x;\n", $flag_value_data_in_tree; +#push @dlltree, "#ifdef __EPOC32__\n"; +push @dlltree, sprintf "const TInt KModuleFlagXIPDataInTree=0x%04x;\n", $flag_value_xip_data_in_tree; +#push @dlltree, "#else\n"; +#push @dlltree, sprintf "const TInt KModuleFlagXIPDataInTree=0x%04x;\n", 0; +#push @dlltree, "#endif\n"; +push @dlltree, sprintf "const TInt KModuleFlagExports=0x%04x;\n", $flag_value_exports; +push @dlltree, sprintf "const TInt KModuleFlagTargetOnly=0x%04x;\n", $flag_value_targetonly; +push @dlltree, sprintf "const TInt KModuleFlagPagedData=0x%04x;\n", $flag_value_pageddata; +push @dlltree, sprintf "const TInt KModuleFlagUnpagedData=0x%04x;\n", $flag_value_unpageddata; +push @dlltree, "static const TInt ModuleFlags[KNumModules] =\n"; +push @dlltree, "\t\{\n"; +foreach $modref (@modules) { + my $flags=0; + my @flagNames = (); + + push @flagNames, "KModuleFlagExe" if ($$modref{exe}); + push @flagNames, "KModuleFlagFixed" if ($$modref{fixed}); + push @flagNames, "KModuleFlagData" if ($$modref{data}); + push @flagNames, "KModuleFlagXIP" if ($$modref{xip}); + push @flagNames, "KModuleFlagPagedCode" if ($$modref{pagedcode}); + push @flagNames, "KModuleFlagUnpagedCode" if ($$modref{unpagedcode}); + push @flagNames, "KModuleFlagPagedData" if ($$modref{pageddata}); + push @flagNames, "KModuleFlagUnpagedData" if (!$$modref{pageddata}); + push @flagNames, "KModuleFlagIDrive" if ($$modref{idrive}); + push @flagNames, "KModuleFlagVDrive" if ($$modref{vdrive}); + push @flagNames, "KModuleFlagBytePair" if ($$modref{bytepair}); + push @flagNames, "KModuleFlagDllInCycle" if ($$modref{cycle}); + push @flagNames, "KModuleFlagDataInTree" if ($$modref{dataintree}); + push @flagNames, "KModuleFlagXIPDataInTree" if ($$modref{xipdataintree}); + push @flagNames, "KModuleFlagExports" if ($$modref{exports}); + push @flagNames, "KModuleFlagUncompressed" if ($$modref{uncompressed}); + push @flagNames, "KModuleFlagTargetOnly" if ($$modref{targetonly}); + + @flagNames = qw(0) if (scalar(@flagNames) == 0); + my $flagString = "/\* " . $$modref{num} . " \*/\t" . join(' | ', @flagNames); + unless ($$modref{num}==$module_count-1) { + $flagString.=','; + } + push @dlltree, $flagString . "\n"; +} +push @dlltree, "\t\};\n"; +push @dlltree, "\n"; +foreach $modref (@modules) { + my $modnum=$$modref{num}; + my @rblki; + ++$next_mark; + calc_rblki(\@rblki, \@modules, $modref, $next_mark); + my $rblki_count=scalar(@rblki); + my $rblki_sum=0; + foreach (@rblki) { + $rblki_sum += $_; + } + push @dlltree, "static const TInt Module$modnum","RBlkIParams[2] = \{ $rblki_count, $rblki_sum \};\n"; +} +push @dlltree, "\n"; +push @dlltree, "static const TInt* const ModuleRBlkIParams[KNumModules] =\n"; +push @dlltree, "\t\{\n"; +foreach $modref (@modules) { + my $modnum=$$modref{num}; + push @dlltree, "\tModule$modnum","RBlkIParams"; + if ($$modref{num}==$module_count-1) { + push @dlltree, "\n"; + } else { + push @dlltree, ",\n"; + } +} +push @dlltree, "\t\};\n"; +push @dlltree, "\n"; +foreach $modref (@modules) { + my $modnum=$$modref{num}; + my $mod_attp=$modnum; + my $mod_linkp=$modnum; + unless ($$modref{exe}) { + $mod_attp = ($$modref{attp}) ? ($modref->{attp}->{num}) : -1; + $mod_linkp = ($$modref{linkexe}) ? ($modref->{linkexe}->{num}) : -1; + } + push @dlltree, "static const TInt Module$modnum","ExeInfo[2] = \{ $mod_attp, $mod_linkp \};\n"; +} +push @dlltree, "\n"; +push @dlltree, "static const TInt* const ModuleExeInfo[KNumModules] =\n"; +push @dlltree, "\t\{\n"; +foreach $modref (@modules) { + my $modnum=$$modref{num}; + push @dlltree, "\tModule$modnum","ExeInfo"; + if ($$modref{num}==$module_count-1) { + push @dlltree, "\n"; + } else { + push @dlltree, ",\n"; + } +} +push @dlltree, "\t\};\n"; + +foreach $tcref (@testcases) { + push @dlltree, "\n"; + my $modlistref=$$tcref{modules}; + my $count=$$tcref{count}; + my $arraysize=$count+1; + push @dlltree, "static const TInt TC_$$tcref{name}\[$arraysize\]=\n\t\{\n"; + if ($count==0) { + push @dlltree, "\t$count\n"; + } else { + push @dlltree, "\t$count\,\n"; + } + foreach (@$modlistref) { + --$count; + if ($count==0) { + push @dlltree, "\t$_\n"; + } else { + push @dlltree, "\t$_\,\n"; + } + } + push @dlltree, "\t\};\n"; +} + +push @dlltree, "#endif\n"; +push @dlltree, "\n"; +push @dlltree, "#endif\n"; + +foreach $modref (@modules) { + my $mmpname=$$modref{basefilename}.$mmpext; + my $mmpref=$$modref{mmp}; + open OUT, ">$mmpname" or die "Could not open $mmpname for output\n"; + print OUT @$mmpref; + close OUT; + if ($$modref{exports}) { + my $defname=$$modref{basefilename}.$defext; + my $defref=$$modref{def}; + open OUT, ">$defname" or die "Could not open $defname for output\n"; + print OUT @$defref; + close OUT; + } +} +if (!$allowbad) { + push @bldinf, "t_ldrtst\n"; +} +open OUT, ">$bldname" or die "Could not open $bldname for output\n"; +print OUT @bldinf; +close OUT; +open OUT, ">$dlltreename" or die "Could not open $dlltreename for output\n"; +print OUT @dlltree; +close OUT; +my $testbatch = "$ENV{EPOCROOT}epoc32\\build"; +$destpath =~ s/\//\\/go; +$testbatch.="\\" unless ($destpath =~ /^\\/); +$testbatch.=$destpath; +$testbatch.="##MAIN##.auto.bat"; +if (!$allowbad) { + push @iby, "data=$testbatch\t\ttest\\loader.auto.bat\n"; +} +open OUT, ">$ibyname" or die "Could not open $ibyname for output\n"; +print OUT @iby; +close OUT; + +# +# Accumulate list of dependency numbers +# 1st arg = \output list +# 2nd arg = \module list +# 3rd arg = \module to start from +# 4th arg = mark value to use +# +sub calc_tc($$$$) { + my ($out, $mods, $modref, $mark)=@_; + my $depsref=$$modref{deps}; + foreach $dep (@$depsref) { + my $depref=$$mods[$dep]; + if ($$depref{mark} != $mark) { + $$depref{mark}=$mark; + unless ($$depref{exe}) { + calc_tc($out, $mods, $depref, $mark); + } + push @$out, $dep; + } + } +} + +# +# Accumulate RBlkI parameters +# 1st arg = \output list +# 2nd arg = \module list +# 3rd arg = \module to start from +# 4th arg = mark value to use +# +sub calc_rblki($$$$) { + my ($out, $mods, $modref, $mark)=@_; + if ($$modref{mark} != $mark) { + $$modref{mark}=$mark; + if (!$$modref{exe} and $$modref{data}) { + push @$out, $$modref{num}; + my $depsref=$$modref{deps}; + foreach $dep (@$depsref) { + calc_rblki($out, $mods, $$mods[$dep], $mark); + } + } + } +} + + +