|
1 # Copyright (c) 2001-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 the License "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 # \f32test\loader\dlltree.pl |
|
15 # Generate header and build files for one or more trees |
|
16 # of DLLs and EXEs according to a description file. |
|
17 # |
|
18 # |
|
19 |
|
20 require Cwd; |
|
21 |
|
22 my $dllbasename='dllt'; |
|
23 my $dllext='.dll'; |
|
24 my $exebasename='exet'; |
|
25 my $exeext='.exe'; |
|
26 my $mmpext='.mmp'; |
|
27 my $defext='.def'; |
|
28 my $libext='.lib'; |
|
29 |
|
30 my $source0ext='.cpp'; |
|
31 my $source1ext='.cia'; |
|
32 my $xippath="sys\\bin\\"; |
|
33 my $nonxippath="sys\\bin\\"; |
|
34 |
|
35 my $hostpath="\\Epoc32\\Release\\##MAIN##\\##BUILD##\\"; |
|
36 |
|
37 my $flag_value_exe=1; |
|
38 my $flag_value_fixed=2; |
|
39 my $flag_value_data=4; |
|
40 my $flag_value_xip=8; |
|
41 my $flag_value_dll_in_cycle=16; |
|
42 my $flag_value_data_in_tree=32; |
|
43 my $flag_value_xip_data_in_tree=64; |
|
44 my $flag_value_exports=128; |
|
45 my $flag_value_pagedcode=256; |
|
46 my $flag_value_unpagedcode=512; |
|
47 my $flag_value_idrive=1024; |
|
48 my $flag_value_vdrive=2048; |
|
49 my $flag_value_bytepair=4096; |
|
50 my $flag_value_uncompressed=8192; |
|
51 my $flag_value_targetonly=16384; |
|
52 my $flag_value_pageddata=32768; |
|
53 my $flag_value_unpageddata=65536; |
|
54 |
|
55 my $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst; |
|
56 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime; |
|
57 my $copy_end=$year+1900; |
|
58 |
|
59 my $argc=scalar(@ARGV); |
|
60 ($argc==1 or $argc==2 or $argc==3) or die "Usage: perl dlltree.pl <filename> <dir> [-allowbad]\n"; |
|
61 my $infile=$ARGV[0]; |
|
62 open IN, $infile or die "Cannot open input file $infile\n"; |
|
63 my @in; |
|
64 while (<IN>) { |
|
65 push @in, $_; |
|
66 } |
|
67 close IN; |
|
68 my $destdir=''; |
|
69 if ($argc>=2) { |
|
70 $destdir=$ARGV[1]; |
|
71 unless (-d $destdir) { |
|
72 mkdir $destdir, 0777 or die "Can't create directory $destdir\n"; |
|
73 } |
|
74 chdir $destdir or die "Can't chdir to directory $destdir\n"; |
|
75 } |
|
76 my $allowbad; |
|
77 if ($argc==3) { |
|
78 if ($ARGV[2] eq '-allowbad') { |
|
79 $allowbad = 1; |
|
80 } |
|
81 } |
|
82 $cwd=Cwd::getcwd(); |
|
83 $destpath=$cwd; |
|
84 $destpath=~s/\//\\/g; |
|
85 if ($destpath=~/^\w\:(.*)/) { |
|
86 $destpath=$1; |
|
87 } |
|
88 unless ($destpath=~/^(.*?)\\$/) { |
|
89 $destpath.='\\'; |
|
90 } |
|
91 #print "$cwd\n"; |
|
92 #print "$destpath\n"; |
|
93 |
|
94 my @modules; |
|
95 my @testcases; |
|
96 my $line=0; |
|
97 my $modnum=0; |
|
98 my $state=0; |
|
99 my $concat; |
|
100 foreach (@in) { |
|
101 ++$line; |
|
102 next if (/^\s*$/ or /^\s*\#/); |
|
103 if ($state==0) { |
|
104 if (/^\!TESTCASES/) { |
|
105 $state=1; |
|
106 next; |
|
107 } |
|
108 my @moddesc=split; |
|
109 my $modname=shift @moddesc; |
|
110 if (grep {lc($$_{name}) eq lc($modname)} @modules) { |
|
111 die "Duplicate module specification at line $line\n"; |
|
112 } |
|
113 my %module; |
|
114 $module{name}=$modname; |
|
115 $module{num}=$modnum; |
|
116 $module{exports}=1; |
|
117 $module{nclients}=0; # number of modules which import from this one |
|
118 while (scalar(@moddesc)) { |
|
119 my $att=shift @moddesc; |
|
120 if ($att=~/^\:$/) { |
|
121 last; |
|
122 } elsif ($att=~/^X$/i) { |
|
123 $module{exe}=1; |
|
124 } elsif ($att=~/^F$/i) { |
|
125 $module{fixed}=1; |
|
126 } elsif ($att=~/^D$/i) { |
|
127 $module{data}=1; |
|
128 } elsif ($att=~/^P$/i) { |
|
129 $module{pagedcode}=1; |
|
130 } elsif ($att=~/^PD$/i) { |
|
131 $module{pageddata}=1; |
|
132 } elsif ($att=~/^B$/i) { |
|
133 $module{bytepair}=1; |
|
134 } elsif ($att=~/^U$/i) { |
|
135 $module{uncompressed}=1; |
|
136 } elsif ($att=~/^I$/i) { |
|
137 $module{idrive}=1; |
|
138 } elsif ($att=~/^V$/i) { |
|
139 $module{vdrive}=1; |
|
140 } elsif ($att=~/^N$/i) { |
|
141 $module{unpagedcode}=1; |
|
142 } elsif ($att=~/^T$/i) { |
|
143 $module{targetonly}=1; |
|
144 } elsif ($att=~/^R(.*?)$/i) { |
|
145 $module{xip}=1; |
|
146 my $attp=$1; |
|
147 if ($attp=~/^\,(.*?)$/) { |
|
148 $module{attpname}=$1; |
|
149 } elsif (!($attp=~/^\s*$/)) { |
|
150 die "Garbage following R attribute at line $line\n"; |
|
151 } |
|
152 } |
|
153 } |
|
154 if ($module{fixed} && !$module{exe}) { |
|
155 die "Can't have FIXED without EXE at line $line\n"; |
|
156 } |
|
157 if ($module{pagedcode} && $module{xip}) { |
|
158 die "Can't have PAGEDCODE with XIP at line $line\n"; |
|
159 } |
|
160 |
|
161 # makmake won't support paged binaries which aren't bytepair or uncompressed. |
|
162 # However, P can be specified without them in dlltree.txt. This program generates |
|
163 # an MMP file with neither flag. The flag is added when the files are copied to |
|
164 # internal media by T_LDRTST. (It would be pointless to copy the files to removable |
|
165 # media and then edit them because removable media doesn't support paging.) |
|
166 |
|
167 my $bothCodePageFlags = $module{pagedcode} && $module{unpagedcode}; |
|
168 if ($bothCodePageFlags && !$module{idrive}) { |
|
169 die "Can't have PAGEDCODE and UNPAGEDCODE without INTERNAL DRIVE at line $line\n"; |
|
170 } |
|
171 if ($module{unpagedcode} && $module{xip}) { |
|
172 die "Can't have UNPAGEDCODE with XIP at line $line\n"; |
|
173 } |
|
174 if ($module{pageddata} && !$module{exe}) { |
|
175 die "Can't have PAGEDDATA without EXE at line $line\n"; |
|
176 } |
|
177 if ($module{idrive} && $module{xip}) { |
|
178 die "Can't have INTERNAL DRIVE with XIP at line $line\n"; |
|
179 } |
|
180 if ($module{vdrive} && $module{xip}) { |
|
181 die "Can't have REMOVABLE DRIVE with XIP at line $line\n"; |
|
182 } |
|
183 if ($module{idrive} && $module{vdrive}) { |
|
184 die "Can't have INTERNAL DRIVE with REMOVABLE DRIVE at line $line\n"; |
|
185 } |
|
186 if ($module{bytepair} && $module{uncompressed}) { |
|
187 die "Can't have BYTEPAIR with UNCOMPRESSED at line $line\n"; |
|
188 } |
|
189 if ($module{exe}) { |
|
190 if ($module{attpname}) { |
|
191 warn "Attach process with EXE ignored at line $line\n"; |
|
192 delete $module{attpname}; |
|
193 } |
|
194 $module{basefilename}=$exebasename.$modnum; |
|
195 $module{filename}=$module{basefilename}.$exeext; |
|
196 $module{source0}=$exebasename.$source0ext; |
|
197 $module{source1}=""; |
|
198 $module{trgtype}='exexp'; |
|
199 $module{lib}=$module{basefilename}.$libext; |
|
200 } else { |
|
201 $module{basefilename}=$dllbasename.$modnum; |
|
202 $module{filename}=$module{basefilename}.$dllext; |
|
203 $module{source0}=$dllbasename.$source0ext; |
|
204 $module{source1}=$dllbasename.$source1ext; |
|
205 $module{trgtype}='dll'; |
|
206 $module{lib}=$module{basefilename}.$libext; |
|
207 } |
|
208 $module{depnames}=\@moddesc; # dependency names are left over |
|
209 $module{line}=$line; |
|
210 $module{mark}=0; |
|
211 push @modules, \%module; |
|
212 ++$modnum; |
|
213 } elsif ($state<=2) { |
|
214 if ($state==1) { |
|
215 $concat=""; |
|
216 die "Syntax error at line $line\n" unless (/^(\w+)\:/); |
|
217 } |
|
218 if (/^(.*?)\\$/) { |
|
219 $concat.=$1; |
|
220 $concat.=' '; |
|
221 $state=2; |
|
222 next; |
|
223 } else { |
|
224 $concat.=$_; |
|
225 $state=1; |
|
226 } |
|
227 my @modlist=split(/\s+/, $concat); |
|
228 my $tcname=shift @modlist; |
|
229 $tcname=~/^(.*?)\:$/ or die "???\n"; |
|
230 $tcname=$1; |
|
231 my %tc; |
|
232 $tc{name}=$tcname; |
|
233 $tc{mod_names}=\@modlist; |
|
234 push @testcases, \%tc; |
|
235 } |
|
236 } |
|
237 foreach $modref (@modules) { |
|
238 my $moddepref=$$modref{depnames}; |
|
239 my @deps; |
|
240 foreach (@$moddepref) { |
|
241 my $depname=lc($_); |
|
242 my @match=grep {lc($$_{name}) eq $depname} @modules; |
|
243 if (scalar(@match)==0) { |
|
244 die "Unknown dependent module $depname at line $$modref{line}\n"; |
|
245 } |
|
246 my $depref=$match[0]; |
|
247 if ($$modref{xip} and !$$depref{xip}) { |
|
248 die "Illegal dependency: $$modref{name} (XIP) on $$depref{name} (non-XIP)\n"; |
|
249 } |
|
250 push @deps, $$depref{num}; |
|
251 ++$$depref{nclients}; |
|
252 } |
|
253 $$modref{deps}=\@deps; |
|
254 my $attpname=$$modref{attpname}; |
|
255 if ($attpname) { |
|
256 my @match=grep {lc($$_{name}) eq lc($attpname)} @modules; |
|
257 if (scalar(@match)==0) { |
|
258 die "Unknown attach process $attpname at line $$modref{line}\n"; |
|
259 } |
|
260 my $attpref=$match[0]; |
|
261 if (!$$attpref{exe}) { |
|
262 die "Specified attach process is not EXE at line $$modref{line}\n"; |
|
263 } elsif (!$$attpref{xip}) { |
|
264 die "Specified attach process is not XIP at line $$modref{line}\n"; |
|
265 } |
|
266 $$modref{attp}=$attpref; |
|
267 } |
|
268 } |
|
269 foreach $tcref (@testcases) { |
|
270 my $modlistref=$$tcref{mod_names}; |
|
271 my @modnums; |
|
272 foreach $modname (@$modlistref) { |
|
273 next if ($modname=~/^\s*$/); |
|
274 my @match=grep {lc($$_{name}) eq lc($modname)} @modules; |
|
275 if (scalar(@match)==0) { |
|
276 die "Unknown module $modname in test case $$tcref{name}\n"; |
|
277 } |
|
278 push @modnums, $match[0]->{num}; |
|
279 } |
|
280 $$tcref{modules}=\@modnums; |
|
281 $$tcref{count}=scalar(@modnums); |
|
282 } |
|
283 my $next_mark=0; |
|
284 foreach $modref (@modules) { |
|
285 if ($$modref{nclients}==0 and $$modref{exe}) { |
|
286 # EXE with no exports |
|
287 $$modref{exports}=0; |
|
288 $$modref{trgtype}='exe'; |
|
289 } |
|
290 ++$next_mark; |
|
291 my $modnum=$$modref{num}; |
|
292 my @tcdeps; |
|
293 calc_tc(\@tcdeps, \@modules, $modref, $next_mark); |
|
294 $$modref{tcdeps}=\@tcdeps; |
|
295 if (grep {$_==$modnum} @tcdeps) { |
|
296 $$modref{cycle}=1; |
|
297 } |
|
298 my @exes=grep {$modules[$_]->{exe}} @tcdeps; |
|
299 my $nexes=scalar(@exes); |
|
300 |
|
301 unless ($allowbad) { |
|
302 if ($nexes>1) { |
|
303 die "Module $$modref{name} links to more than one EXE\n"; |
|
304 } elsif ($nexes==1) { |
|
305 my $exeref=$modules[$exes[0]]; |
|
306 $$modref{linkexe}=$exeref; |
|
307 if ($$modref{exe}) { |
|
308 if ($$exeref{num}!=$modnum) { |
|
309 die "EXE $modref{name} links to another EXE\n"; |
|
310 } |
|
311 } else { |
|
312 if ($$modref{attp} and $$exeref{num}!=$modref->{attp}->{num}) { |
|
313 die "DLL $$modref{name} ($modnum) incompatible attach process\n"; |
|
314 } |
|
315 if (!$$modref{attp}) { |
|
316 $$modref{attp}=$exeref; |
|
317 } |
|
318 } |
|
319 } |
|
320 } |
|
321 if ($$modref{exe}) { |
|
322 foreach $depnum (@tcdeps) { |
|
323 my $depref=$modules[$depnum]; |
|
324 my $depattpref=$depref->{attp}; |
|
325 if ($depattpref and $depattpref->{num}!=$modnum) { |
|
326 die "DEP DLL $$depref{name} ($$depref{num}) incompatible attach process\n"; |
|
327 } |
|
328 # if (!$depattpref) { |
|
329 # $$depref{attp}=$modref; |
|
330 # } |
|
331 } |
|
332 } |
|
333 } |
|
334 foreach $modref (@modules) { |
|
335 my @total_deps; |
|
336 my $tcdepref=$$modref{tcdeps}; |
|
337 push @total_deps, @$tcdepref; |
|
338 my $linkexe=$$modref{linkexe}; |
|
339 if ($linkexe) { |
|
340 my $exetcdepref=$$linkexe{tcdeps}; |
|
341 push @total_deps, @$exetcdepref; |
|
342 } |
|
343 push @total_deps, $$modref{num}; |
|
344 my $data=scalar(grep {$modules[$_]->{data}} @total_deps); |
|
345 if ($data!=0) { |
|
346 $$modref{dataintree}=1; |
|
347 } |
|
348 my $xipdata=scalar(grep {$modules[$_]->{data} and $modules[$_]->{xip}} @total_deps); |
|
349 if ($xipdata!=0) { |
|
350 $$modref{xipdataintree}=1; |
|
351 } |
|
352 } |
|
353 |
|
354 #foreach $modref (@modules) { |
|
355 # print "Module $$modref{num}:\n"; |
|
356 # print "\tName: $$modref{name}\n"; |
|
357 # print "\tFilename: $$modref{filename}\n"; |
|
358 # my $depref=$$modref{deps}; |
|
359 # my $ndeps=scalar(@$depref); |
|
360 # print "\t#Deps: $ndeps\n"; |
|
361 # print "\tDeps: ",join(',',@$depref),"\n"; |
|
362 #} |
|
363 |
|
364 my @bldinf; |
|
365 my $bldname='dlltree.inf'; |
|
366 push @bldinf, "// $destpath$bldname\n"; |
|
367 push @bldinf, "//\n"; |
|
368 push @bldinf, "// Copyright (c) 2000-$copy_end Symbian Ltd. All rights reserved.\n"; |
|
369 push @bldinf, "//\n"; |
|
370 push @bldinf, "\n"; |
|
371 push @bldinf, "PRJ_PLATFORMS\n"; |
|
372 push @bldinf, "BASEUSERDEFAULT\n"; |
|
373 push @bldinf, "\n"; |
|
374 push @bldinf, "PRJ_TESTMMPFILES\n"; |
|
375 push @bldinf, "\n"; |
|
376 |
|
377 my @dlltree; |
|
378 my $dlltreename='dlltree.h'; |
|
379 push @dlltree, "// $destpath$dlltreename\n"; |
|
380 push @dlltree, "//\n"; |
|
381 push @dlltree, "// Copyright (c) 2000-$copy_end Symbian Ltd. All rights reserved.\n"; |
|
382 push @dlltree, "//\n"; |
|
383 push @dlltree, "\n"; |
|
384 push @dlltree, "#ifndef __DLLTREE_H__\n"; |
|
385 push @dlltree, "#define __DLLTREE_H__\n"; |
|
386 push @dlltree, "#include <e32std.h>\n"; |
|
387 push @dlltree, "\n"; |
|
388 push @dlltree, "class MDllList;\n"; |
|
389 push @dlltree, "\n"; |
|
390 |
|
391 my $ibyname='ldrtest.iby'; |
|
392 my @iby; |
|
393 |
|
394 foreach $modref (@modules) { |
|
395 my @mmp; |
|
396 my $num=$$modref{num}; |
|
397 my $mmpname=$$modref{basefilename}.$mmpext; |
|
398 my $defname=$$modref{basefilename}.$defext; |
|
399 my $depsref=$$modref{deps}; |
|
400 my $ndeps=scalar(@$depsref); |
|
401 push @mmp, "// $destpath$mmpname\n"; |
|
402 push @mmp, "//\n"; |
|
403 push @mmp, "// Copyright (c) 2000-$copy_end Symbian Ltd. All rights reserved.\n"; |
|
404 push @mmp, "//\n"; |
|
405 push @mmp, "// Generated from $$modref{name}\n"; |
|
406 push @mmp, "\n"; |
|
407 push @mmp, "macro __DLLNUM$num\n"; |
|
408 push @mmp, "target $$modref{filename}\n"; |
|
409 push @mmp, "targettype $$modref{trgtype}\n"; |
|
410 push @mmp, "sourcepath .\n"; |
|
411 push @mmp, "source $$modref{source0} $$modref{source1}\n"; |
|
412 push @mmp, "library euser.lib efsrv.lib\n"; |
|
413 push @mmp, "Capability NONE\n"; |
|
414 foreach (@$depsref) { |
|
415 my $depref=$modules[$_]; |
|
416 push @mmp, "library $$depref{lib}\n"; |
|
417 } |
|
418 if ($$modref{exports}) { |
|
419 push @mmp, "deffile ./$defname\n"; |
|
420 push @mmp, "nostrictdef\n"; |
|
421 } |
|
422 push @mmp, "OS_LAYER_SYSTEMINCLUDE_SYMBIAN \n"; |
|
423 push @mmp, "systeminclude ../../../e32test/mmu \n"; |
|
424 push @mmp, "userinclude . \n"; |
|
425 if ($$modref{fixed}) { |
|
426 push @mmp, "epocfixedprocess\n"; |
|
427 } |
|
428 |
|
429 # if both paged flags are set or the compression is not pageable then print neither. |
|
430 # T_LDRTST will add the required flags when it copies the file to internal media. |
|
431 |
|
432 my $bothCodePageFlags = $$modref{pagedcode} && $$modref{unpagedcode}; |
|
433 my $pageableCompression = $$modref{bytepair} || $$modref{uncompressed}; |
|
434 if (!$bothCodePageFlags && $pageableCompression) { |
|
435 push @mmp, "pagedcode\n" if $$modref{pagedcode}; |
|
436 push @mmp, "unpagedcode\n" if $$modref{unpagedcode}; |
|
437 } |
|
438 |
|
439 if ($$modref{exe}) { |
|
440 # make exes unpageddata by default |
|
441 if (!$$modref{pageddata}) { |
|
442 $$modref{unpageddata}=1; |
|
443 } |
|
444 if ($$modref{pageddata}) { |
|
445 push @mmp, "pageddata\n"; |
|
446 } |
|
447 if ($$modref{unpageddata}) { |
|
448 push @mmp, "unpageddata\n"; |
|
449 } |
|
450 } |
|
451 |
|
452 if ($$modref{bytepair}) { |
|
453 push @mmp, "bytepaircompresstarget\n"; |
|
454 } |
|
455 |
|
456 if ($$modref{uncompressed}) { |
|
457 push @mmp, "nocompresstarget\n"; |
|
458 } |
|
459 |
|
460 if ($$modref{data} && !$$modref{exe}) { |
|
461 push @mmp, "epocallowdlldata\n"; |
|
462 } |
|
463 push @mmp, sprintf("uid 0x00000000 0x%08x\n", $num+256); |
|
464 push @mmp, "SMPSAFE\n"; |
|
465 $$modref{mmp}=\@mmp; |
|
466 |
|
467 if ($$modref{exports}) { |
|
468 my @def; |
|
469 push @def, "EXPORTS\n"; |
|
470 if ($$modref{exe}) { |
|
471 push @def, "\tRegisterConstructorCall @ 1 NONAME\n"; |
|
472 push @def, "\tRegisterInitCall @ 2 NONAME\n"; |
|
473 push @def, "\tRegisterDestructorCall @ 3 NONAME\n"; |
|
474 } else { |
|
475 push @def, "\tInit$num @ 1 NONAME\n"; |
|
476 push @def, "\tChkC$num @ 2 NONAME\n"; |
|
477 push @def, "\tBlkI$num @ 3 NONAME\n"; |
|
478 push @def, "\tGetGeneration @ 4 NONAME\n"; |
|
479 push @def, "\tRBlkI$num @ 5 NONAME\n"; |
|
480 push @def, "\tSetCloseLib @ 6 NONAME\n"; |
|
481 } |
|
482 $$modref{def}=\@def; |
|
483 } |
|
484 |
|
485 push @bldinf, "$$modref{basefilename}\t\tsupport\n"; |
|
486 |
|
487 if ($num==0) { |
|
488 push @dlltree, "#if defined(__DLLNUM$num)\n"; |
|
489 } else { |
|
490 push @dlltree, "#elif defined(__DLLNUM$num)\n"; |
|
491 } |
|
492 push @dlltree, "#define DLLNUM $num\n"; |
|
493 if ($$modref{exe}) { |
|
494 push @dlltree, "#define EXENUM $num\n"; |
|
495 push @dlltree, "_LIT(KServerName, \"$$modref{name}\");\n"; |
|
496 } |
|
497 push @dlltree, "#define INITFUNC Init$num\n"; |
|
498 push @dlltree, "#define CHKCFUNC ChkC$num\n"; |
|
499 push @dlltree, "#define BLKIFUNC BlkI$num\n"; |
|
500 push @dlltree, "#define RBLKIFUNC RBlkI$num\n"; |
|
501 push @dlltree, "#define CHKDEPS(r) (\\\n"; |
|
502 foreach (@$depsref) { |
|
503 my $depref=$modules[$_]; |
|
504 unless ($$depref{exe}) { |
|
505 my $func="ChkC$_"; |
|
506 push @dlltree, "\t((r)=$func())!=0 ||\\\n"; |
|
507 } |
|
508 } |
|
509 push @dlltree, "\t((r)=0)!=0 )\n"; |
|
510 push @dlltree, "#define INITDEPS(r,l) (\\\n"; |
|
511 foreach (@$depsref) { |
|
512 my $depref=$modules[$_]; |
|
513 unless ($$depref{exe}) { |
|
514 my $func="Init$_"; |
|
515 push @dlltree, "\t((r)=$func(l))!=0 ||\\\n"; |
|
516 } |
|
517 } |
|
518 push @dlltree, "\t((r)=0)!=0 )\n"; |
|
519 my $link_to_exe; |
|
520 push @dlltree, "#define RBLKIFUNC_DEPS(i,g) {\\\n"; |
|
521 foreach (@$depsref) { |
|
522 my $depref=$modules[$_]; |
|
523 if ($$depref{exe}) { |
|
524 $link_to_exe=1; |
|
525 } else { |
|
526 my $func="RBlkI$_"; |
|
527 push @dlltree, "\t(i)=$func(i,g);\\\n"; |
|
528 } |
|
529 } |
|
530 push @dlltree, "\t}\n"; |
|
531 if ($link_to_exe) { |
|
532 push @dlltree, "#define __DLL_LINK_TO_EXE\n"; |
|
533 } |
|
534 if ($$modref{cycle}) { |
|
535 push @dlltree, "#define __DLL_IN_CYCLE\n"; |
|
536 } |
|
537 if ($$modref{data}) { |
|
538 push @dlltree, "#define __MODULE_HAS_DATA\n"; |
|
539 } |
|
540 if ($$modref{exports}) { |
|
541 push @dlltree, "#define __MODULE_EXPORT\t\tEXPORT_C\n"; |
|
542 push @dlltree, "#define __MODULE_IMPORT\t\tIMPORT_C\n"; |
|
543 } else { |
|
544 push @dlltree, "#define __MODULE_EXPORT\n"; |
|
545 push @dlltree, "#define __MODULE_IMPORT\n"; |
|
546 } |
|
547 foreach (@$depsref) { |
|
548 my $depref=$modules[$_]; |
|
549 if ($$depref{exe}) { |
|
550 } else { |
|
551 push @dlltree, "extern \"C\" IMPORT_C TInt Init$_(MDllList&);\n"; |
|
552 push @dlltree, "extern \"C\" IMPORT_C TInt ChkC$_();\n"; |
|
553 push @dlltree, "extern \"C\" IMPORT_C TInt RBlkI$_(TInt, TInt);\n"; |
|
554 } |
|
555 } |
|
556 my $hostfullpathname=$hostpath.$$modref{filename}; |
|
557 if ($$modref{xip}) { |
|
558 my $epocfullpathname=$xippath.$$modref{filename}; |
|
559 my $flags; |
|
560 if ($$modref{attp}) { |
|
561 $flags='process '.$modref->{attp}->{filename}; |
|
562 } |
|
563 push @iby, "file=$hostfullpathname\t\t$epocfullpathname\t\t$flags\n"; |
|
564 } else { |
|
565 my $epocfullpathname=$nonxippath.$$modref{filename}; |
|
566 push @iby, "data=$hostfullpathname\t\t$epocfullpathname\n"; |
|
567 } |
|
568 } |
|
569 |
|
570 #push @dlltree, "#else\n"; |
|
571 #push @dlltree, "#error No __DLLNUM macro defined\n"; |
|
572 push @dlltree, "#endif\n"; |
|
573 push @dlltree, "\n"; |
|
574 |
|
575 my $module_count=scalar(@modules); |
|
576 push @dlltree, "const TInt KNumModules=$module_count;\n"; |
|
577 push @dlltree, "\n"; |
|
578 push @dlltree, "#ifdef __INCLUDE_DEPENDENCY_GRAPH\n"; |
|
579 push @dlltree, "static const TText* const ModuleName[KNumModules] =\n"; |
|
580 push @dlltree, "\t\{\n"; |
|
581 foreach $modref (@modules) { |
|
582 my $string="\t(const TText*)L\"$$modref{name}\""; |
|
583 unless ($$modref{num}==$module_count-1) { |
|
584 $string.=','; |
|
585 } |
|
586 push @dlltree, $string; |
|
587 my $pad=41-length($string); |
|
588 $pad=($pad+3)/4; |
|
589 push @dlltree, "\t"x$pad, "\/*", $$modref{num}, "*\/\n"; |
|
590 } |
|
591 push @dlltree, "\t\};\n"; |
|
592 push @dlltree, "\n"; |
|
593 push @dlltree, "#define MODULE_NAME(n) TPtrC(ModuleName[n])\n"; |
|
594 push @dlltree, "\n"; |
|
595 push @dlltree, "static const TText* const ModuleFileName[KNumModules] =\n"; |
|
596 push @dlltree, "\t\{\n"; |
|
597 foreach $modref (@modules) { |
|
598 if ($$modref{idrive} || $$modref{vdrive}) { |
|
599 my $fn = $$modref{filename}; |
|
600 my $used_nxip_path = "?:\\$nonxippath$fn"; |
|
601 $used_nxip_path =~ s/\\/\\\\/g; # double backslashes |
|
602 substr($used_nxip_path,0,1) = $$modref{idrive} ? "0" : "1"; |
|
603 push @dlltree, "\t(const TText*)L\"$used_nxip_path\""; |
|
604 } else { |
|
605 push @dlltree, "\t(const TText*)L\"$$modref{filename}\""; |
|
606 } |
|
607 if ($$modref{num}==$module_count-1) { |
|
608 push @dlltree, "\n"; |
|
609 } else { |
|
610 push @dlltree, ",\n"; |
|
611 } |
|
612 } |
|
613 push @dlltree, "\t\};\n"; |
|
614 push @dlltree, "\n"; |
|
615 push @dlltree, "#define MODULE_FILENAME(n) TPtrC(ModuleFileName[n])\n"; |
|
616 push @dlltree, "\n"; |
|
617 foreach $modref (@modules) { |
|
618 my $modnum=$$modref{num}; |
|
619 my $tcdepsref=$$modref{tcdeps}; |
|
620 my $numdeps=scalar(@$tcdepsref); |
|
621 push @dlltree, "static const TInt Module$modnum","Deps[] =\n"; |
|
622 push @dlltree, "\t\{$numdeps"; |
|
623 if ($numdeps) { |
|
624 push @dlltree, ",", join(',',@$tcdepsref) |
|
625 } |
|
626 push @dlltree, "\};\n"; |
|
627 } |
|
628 push @dlltree, "static const TInt* const ModuleDependencies[KNumModules] =\n"; |
|
629 push @dlltree, "\t\{\n"; |
|
630 foreach $modref (@modules) { |
|
631 my $modnum=$$modref{num}; |
|
632 push @dlltree, "\tModule$modnum","Deps"; |
|
633 if ($$modref{num}==$module_count-1) { |
|
634 push @dlltree, "\n"; |
|
635 } else { |
|
636 push @dlltree, ",\n"; |
|
637 } |
|
638 } |
|
639 push @dlltree, "\t\};\n"; |
|
640 push @dlltree, "\n"; |
|
641 push @dlltree, sprintf "const TInt KModuleFlagExe=0x%04x;\n", $flag_value_exe; |
|
642 push @dlltree, sprintf "const TInt KModuleFlagFixed=0x%04x;\n", $flag_value_fixed; |
|
643 push @dlltree, sprintf "const TInt KModuleFlagData=0x%04x;\n", $flag_value_data; |
|
644 #push @dlltree, "#ifdef __EPOC32__\n"; |
|
645 push @dlltree, sprintf "const TInt KModuleFlagXIP=0x%04x;\n", $flag_value_xip; |
|
646 push @dlltree, sprintf "const TInt KModuleFlagPagedCode=0x%04x;\n", $flag_value_pagedcode; |
|
647 push @dlltree, sprintf "const TInt KModuleFlagUnpagedCode=0x%04x;\n", $flag_value_unpagedcode; |
|
648 push @dlltree, sprintf "const TInt KModuleFlagIDrive=0x%04x;\n", $flag_value_idrive; |
|
649 push @dlltree, sprintf "const TInt KModuleFlagVDrive=0x%04x;\n", $flag_value_vdrive; |
|
650 push @dlltree, sprintf "const TInt KModuleFlagBytePair=0x%04x;\n", $flag_value_bytepair; |
|
651 push @dlltree, sprintf "const TInt KModuleFlagUncompressed=0x%04x;\n", $flag_value_uncompressed; |
|
652 #push @dlltree, "#else\n"; |
|
653 #push @dlltree, sprintf "const TInt KModuleFlagXIP=0x%04x;\n", 0; # no XIPs on emulator |
|
654 #push @dlltree, "#endif\n"; |
|
655 push @dlltree, sprintf "const TInt KModuleFlagDllInCycle=0x%04x;\n", $flag_value_dll_in_cycle; |
|
656 push @dlltree, sprintf "const TInt KModuleFlagDataInTree=0x%04x;\n", $flag_value_data_in_tree; |
|
657 #push @dlltree, "#ifdef __EPOC32__\n"; |
|
658 push @dlltree, sprintf "const TInt KModuleFlagXIPDataInTree=0x%04x;\n", $flag_value_xip_data_in_tree; |
|
659 #push @dlltree, "#else\n"; |
|
660 #push @dlltree, sprintf "const TInt KModuleFlagXIPDataInTree=0x%04x;\n", 0; |
|
661 #push @dlltree, "#endif\n"; |
|
662 push @dlltree, sprintf "const TInt KModuleFlagExports=0x%04x;\n", $flag_value_exports; |
|
663 push @dlltree, sprintf "const TInt KModuleFlagTargetOnly=0x%04x;\n", $flag_value_targetonly; |
|
664 push @dlltree, sprintf "const TInt KModuleFlagPagedData=0x%04x;\n", $flag_value_pageddata; |
|
665 push @dlltree, sprintf "const TInt KModuleFlagUnpagedData=0x%04x;\n", $flag_value_unpageddata; |
|
666 push @dlltree, "static const TInt ModuleFlags[KNumModules] =\n"; |
|
667 push @dlltree, "\t\{\n"; |
|
668 foreach $modref (@modules) { |
|
669 my $flags=0; |
|
670 my @flagNames = (); |
|
671 |
|
672 push @flagNames, "KModuleFlagExe" if ($$modref{exe}); |
|
673 push @flagNames, "KModuleFlagFixed" if ($$modref{fixed}); |
|
674 push @flagNames, "KModuleFlagData" if ($$modref{data}); |
|
675 push @flagNames, "KModuleFlagXIP" if ($$modref{xip}); |
|
676 push @flagNames, "KModuleFlagPagedCode" if ($$modref{pagedcode}); |
|
677 push @flagNames, "KModuleFlagUnpagedCode" if ($$modref{unpagedcode}); |
|
678 push @flagNames, "KModuleFlagPagedData" if ($$modref{pageddata}); |
|
679 push @flagNames, "KModuleFlagUnpagedData" if (!$$modref{pageddata}); |
|
680 push @flagNames, "KModuleFlagIDrive" if ($$modref{idrive}); |
|
681 push @flagNames, "KModuleFlagVDrive" if ($$modref{vdrive}); |
|
682 push @flagNames, "KModuleFlagBytePair" if ($$modref{bytepair}); |
|
683 push @flagNames, "KModuleFlagDllInCycle" if ($$modref{cycle}); |
|
684 push @flagNames, "KModuleFlagDataInTree" if ($$modref{dataintree}); |
|
685 push @flagNames, "KModuleFlagXIPDataInTree" if ($$modref{xipdataintree}); |
|
686 push @flagNames, "KModuleFlagExports" if ($$modref{exports}); |
|
687 push @flagNames, "KModuleFlagUncompressed" if ($$modref{uncompressed}); |
|
688 push @flagNames, "KModuleFlagTargetOnly" if ($$modref{targetonly}); |
|
689 |
|
690 @flagNames = qw(0) if (scalar(@flagNames) == 0); |
|
691 my $flagString = "/\* " . $$modref{num} . " \*/\t" . join(' | ', @flagNames); |
|
692 unless ($$modref{num}==$module_count-1) { |
|
693 $flagString.=','; |
|
694 } |
|
695 push @dlltree, $flagString . "\n"; |
|
696 } |
|
697 push @dlltree, "\t\};\n"; |
|
698 push @dlltree, "\n"; |
|
699 foreach $modref (@modules) { |
|
700 my $modnum=$$modref{num}; |
|
701 my @rblki; |
|
702 ++$next_mark; |
|
703 calc_rblki(\@rblki, \@modules, $modref, $next_mark); |
|
704 my $rblki_count=scalar(@rblki); |
|
705 my $rblki_sum=0; |
|
706 foreach (@rblki) { |
|
707 $rblki_sum += $_; |
|
708 } |
|
709 push @dlltree, "static const TInt Module$modnum","RBlkIParams[2] = \{ $rblki_count, $rblki_sum \};\n"; |
|
710 } |
|
711 push @dlltree, "\n"; |
|
712 push @dlltree, "static const TInt* const ModuleRBlkIParams[KNumModules] =\n"; |
|
713 push @dlltree, "\t\{\n"; |
|
714 foreach $modref (@modules) { |
|
715 my $modnum=$$modref{num}; |
|
716 push @dlltree, "\tModule$modnum","RBlkIParams"; |
|
717 if ($$modref{num}==$module_count-1) { |
|
718 push @dlltree, "\n"; |
|
719 } else { |
|
720 push @dlltree, ",\n"; |
|
721 } |
|
722 } |
|
723 push @dlltree, "\t\};\n"; |
|
724 push @dlltree, "\n"; |
|
725 foreach $modref (@modules) { |
|
726 my $modnum=$$modref{num}; |
|
727 my $mod_attp=$modnum; |
|
728 my $mod_linkp=$modnum; |
|
729 unless ($$modref{exe}) { |
|
730 $mod_attp = ($$modref{attp}) ? ($modref->{attp}->{num}) : -1; |
|
731 $mod_linkp = ($$modref{linkexe}) ? ($modref->{linkexe}->{num}) : -1; |
|
732 } |
|
733 push @dlltree, "static const TInt Module$modnum","ExeInfo[2] = \{ $mod_attp, $mod_linkp \};\n"; |
|
734 } |
|
735 push @dlltree, "\n"; |
|
736 push @dlltree, "static const TInt* const ModuleExeInfo[KNumModules] =\n"; |
|
737 push @dlltree, "\t\{\n"; |
|
738 foreach $modref (@modules) { |
|
739 my $modnum=$$modref{num}; |
|
740 push @dlltree, "\tModule$modnum","ExeInfo"; |
|
741 if ($$modref{num}==$module_count-1) { |
|
742 push @dlltree, "\n"; |
|
743 } else { |
|
744 push @dlltree, ",\n"; |
|
745 } |
|
746 } |
|
747 push @dlltree, "\t\};\n"; |
|
748 |
|
749 foreach $tcref (@testcases) { |
|
750 push @dlltree, "\n"; |
|
751 my $modlistref=$$tcref{modules}; |
|
752 my $count=$$tcref{count}; |
|
753 my $arraysize=$count+1; |
|
754 push @dlltree, "static const TInt TC_$$tcref{name}\[$arraysize\]=\n\t\{\n"; |
|
755 if ($count==0) { |
|
756 push @dlltree, "\t$count\n"; |
|
757 } else { |
|
758 push @dlltree, "\t$count\,\n"; |
|
759 } |
|
760 foreach (@$modlistref) { |
|
761 --$count; |
|
762 if ($count==0) { |
|
763 push @dlltree, "\t$_\n"; |
|
764 } else { |
|
765 push @dlltree, "\t$_\,\n"; |
|
766 } |
|
767 } |
|
768 push @dlltree, "\t\};\n"; |
|
769 } |
|
770 |
|
771 push @dlltree, "#endif\n"; |
|
772 push @dlltree, "\n"; |
|
773 push @dlltree, "#endif\n"; |
|
774 |
|
775 foreach $modref (@modules) { |
|
776 my $mmpname=$$modref{basefilename}.$mmpext; |
|
777 my $mmpref=$$modref{mmp}; |
|
778 open OUT, ">$mmpname" or die "Could not open $mmpname for output\n"; |
|
779 print OUT @$mmpref; |
|
780 close OUT; |
|
781 if ($$modref{exports}) { |
|
782 my $defname=$$modref{basefilename}.$defext; |
|
783 my $defref=$$modref{def}; |
|
784 open OUT, ">$defname" or die "Could not open $defname for output\n"; |
|
785 print OUT @$defref; |
|
786 close OUT; |
|
787 } |
|
788 } |
|
789 if (!$allowbad) { |
|
790 push @bldinf, "t_ldrtst\n"; |
|
791 } |
|
792 open OUT, ">$bldname" or die "Could not open $bldname for output\n"; |
|
793 print OUT @bldinf; |
|
794 close OUT; |
|
795 open OUT, ">$dlltreename" or die "Could not open $dlltreename for output\n"; |
|
796 print OUT @dlltree; |
|
797 close OUT; |
|
798 my $testbatch = "$ENV{EPOCROOT}epoc32\\build"; |
|
799 $destpath =~ s/\//\\/go; |
|
800 $testbatch.="\\" unless ($destpath =~ /^\\/); |
|
801 $testbatch.=$destpath; |
|
802 $testbatch.="##MAIN##.auto.bat"; |
|
803 if (!$allowbad) { |
|
804 push @iby, "data=$testbatch\t\ttest\\loader.auto.bat\n"; |
|
805 } |
|
806 open OUT, ">$ibyname" or die "Could not open $ibyname for output\n"; |
|
807 print OUT @iby; |
|
808 close OUT; |
|
809 |
|
810 # |
|
811 # Accumulate list of dependency numbers |
|
812 # 1st arg = \output list |
|
813 # 2nd arg = \module list |
|
814 # 3rd arg = \module to start from |
|
815 # 4th arg = mark value to use |
|
816 # |
|
817 sub calc_tc($$$$) { |
|
818 my ($out, $mods, $modref, $mark)=@_; |
|
819 my $depsref=$$modref{deps}; |
|
820 foreach $dep (@$depsref) { |
|
821 my $depref=$$mods[$dep]; |
|
822 if ($$depref{mark} != $mark) { |
|
823 $$depref{mark}=$mark; |
|
824 unless ($$depref{exe}) { |
|
825 calc_tc($out, $mods, $depref, $mark); |
|
826 } |
|
827 push @$out, $dep; |
|
828 } |
|
829 } |
|
830 } |
|
831 |
|
832 # |
|
833 # Accumulate RBlkI parameters |
|
834 # 1st arg = \output list |
|
835 # 2nd arg = \module list |
|
836 # 3rd arg = \module to start from |
|
837 # 4th arg = mark value to use |
|
838 # |
|
839 sub calc_rblki($$$$) { |
|
840 my ($out, $mods, $modref, $mark)=@_; |
|
841 if ($$modref{mark} != $mark) { |
|
842 $$modref{mark}=$mark; |
|
843 if (!$$modref{exe} and $$modref{data}) { |
|
844 push @$out, $$modref{num}; |
|
845 my $depsref=$$modref{deps}; |
|
846 foreach $dep (@$depsref) { |
|
847 calc_rblki($out, $mods, $$mods[$dep], $mark); |
|
848 } |
|
849 } |
|
850 } |
|
851 } |
|
852 |
|
853 |
|
854 |