* CodeGenerator.cs, ObjectReader.cs, ObjectWriter.cs: Serialize decimals
[mono.git] / mcs / class / Mono.PEToolkit / PEHeader.cs
1 /*\r
2  * Copyright (c) 2002 Sergey Chaban <serge@wildwestsoftware.com>\r
3  */\r
4 \r
5 using System;\r
6 using System.IO;\r
7 using System.Runtime.InteropServices;\r
8 \r
9 namespace Mono.PEToolkit {\r
10 \r
11         // IMAGE_OPTIONAL_HEADER\r
12         public class PEHeader {\r
13 \r
14                 /// <summary>\r
15                 /// Standard PE/COFF fields.\r
16                 /// </summary>\r
17                 public class StdFields {\r
18                         internal short magic; // always 0x10B?\r
19                         internal byte lMajor;\r
20                         internal byte lMinor;\r
21                         internal uint codeSize;\r
22                         internal uint initDataSize;\r
23                         internal uint uninitDataSize;\r
24                         internal RVA  entryRVA;\r
25                         internal RVA  codeBase;\r
26                         internal RVA  dataBase;\r
27 \r
28                         public StdFields ()\r
29                         {\r
30 \r
31                         }\r
32 \r
33                         public StdFields (BinaryReader reader)\r
34                         {\r
35                                 Read (reader);\r
36                         }\r
37 \r
38                         public void Read (BinaryReader reader)\r
39                         {\r
40                                 magic = reader.ReadInt16 ();\r
41                                 lMajor = reader.ReadByte ();\r
42                                 lMinor = reader.ReadByte ();\r
43                                 codeSize = reader.ReadUInt32 ();\r
44                                 initDataSize = reader.ReadUInt32 ();\r
45                                 uninitDataSize = reader.ReadUInt32 ();\r
46                                 entryRVA = new RVA (reader.ReadUInt32 ());\r
47                                 codeBase = new RVA (reader.ReadUInt32 ());\r
48                                 dataBase = new RVA (reader.ReadUInt32 ());\r
49                         }\r
50 \r
51                         public void Write (BinaryWriter writer)\r
52                         {\r
53                                 writer.Write (magic);\r
54                                 writer.Write (lMajor);\r
55                                 writer.Write (lMinor);\r
56                                 writer.Write (codeSize);\r
57                                 writer.Write (initDataSize);\r
58                                 writer.Write (uninitDataSize);\r
59                                 entryRVA.Write (writer);\r
60                                 codeBase.Write (writer);\r
61                                 dataBase.Write (writer);\r
62                         }\r
63 \r
64                         public string LinkerVersion {\r
65                                 get {\r
66                                         return String.Format("{0}.{1}", lMajor, lMinor);\r
67                                 }\r
68                         }\r
69                         \r
70                         public override string ToString() {\r
71                                 return String.Format(\r
72                                         "Magic                           : 0x{0}" + Environment.NewLine +\r
73                                         "Linker ver.                     : {1}" + Environment.NewLine +\r
74                                         "Size of code                    : {2}" + Environment.NewLine +\r
75                                         "Size of initialized data        : {3}" + Environment.NewLine +\r
76                                         "Size of uinitialized data (BSS) : {4}" + Environment.NewLine,\r
77                                         magic.ToString("X"), LinkerVersion,\r
78                                         codeSize, initDataSize, uninitDataSize\r
79                                 );\r
80                         }\r
81                 }\r
82                 \r
83 \r
84                 /// <summary>\r
85                 /// Windows-specific fields.\r
86                 /// </summary>\r
87                 /// <remarks>\r
88                 /// See Partition II, 24.2.3.2\r
89                 /// </remarks>\r
90                 public class NTFields {\r
91                         internal uint      imgBase;\r
92                         internal uint      sectAlign;\r
93                         internal uint      fileAlign;\r
94                         internal short     osMaj;\r
95                         internal short     osMin;\r
96                         internal short     imgMaj;\r
97                         internal short     imgMin;\r
98                         internal short     subSysMaj;\r
99                         internal short     subSysMin;\r
100                         internal int       reserved_win32ver;\r
101                         internal uint      imgSize;\r
102                         internal uint      hdrSize;\r
103                         internal uint      chksum;\r
104                         internal Subsystem subSys;\r
105                         internal short     dllFlags;\r
106                         internal uint      stackRes;\r
107                         internal uint      stackCommit;\r
108                         internal uint      heapRes;\r
109                         internal uint      heapCommit;\r
110                         internal uint      ldrFlags;\r
111                         internal uint      numDirs;\r
112 \r
113                         public NTFields ()\r
114                         {\r
115 \r
116                         }\r
117                         \r
118                         public NTFields (BinaryReader reader) \r
119                         {\r
120                                 Read (reader);\r
121                         }\r
122 \r
123                         public void Read (BinaryReader reader) \r
124                         {\r
125                                 imgBase = reader.ReadUInt32 ();\r
126                                 sectAlign = reader.ReadUInt32 ();\r
127                                 fileAlign = reader.ReadUInt32 ();\r
128                                 osMaj = reader.ReadInt16 ();\r
129                                 osMin = reader.ReadInt16 ();\r
130                                 imgMaj = reader.ReadInt16 ();\r
131                                 imgMin = reader.ReadInt16 ();\r
132                                 subSysMaj = reader.ReadInt16 ();\r
133                                 subSysMin = reader.ReadInt16 ();\r
134                                 reserved_win32ver = reader.ReadInt32 ();\r
135                                 imgSize = reader.ReadUInt32 ();\r
136                                 hdrSize = reader.ReadUInt32 ();\r
137                                 chksum = reader.ReadUInt32 ();\r
138                                 subSys = (Subsystem) reader.ReadInt16 ();\r
139                                 dllFlags = reader.ReadInt16 ();\r
140                                 stackRes = reader.ReadUInt32 ();\r
141                                 stackCommit  = reader.ReadUInt32 ();\r
142                                 heapRes  = reader.ReadUInt32 ();\r
143                                 heapCommit  = reader.ReadUInt32 ();\r
144                                 ldrFlags  = reader.ReadUInt32 ();\r
145                                 numDirs  = reader.ReadUInt32 ();\r
146                         }\r
147 \r
148                         public void Write (BinaryWriter writer) \r
149                         {\r
150                                 writer.Write (imgBase);\r
151                                 writer.Write (sectAlign);\r
152                                 writer.Write (fileAlign);\r
153                                 writer.Write (osMaj);\r
154                                 writer.Write (osMin);\r
155                                 writer.Write (imgMaj);\r
156                                 writer.Write (imgMin);\r
157                                 writer.Write (subSysMaj);\r
158                                 writer.Write (subSysMin);\r
159                                 writer.Write (reserved_win32ver);\r
160                                 writer.Write (imgSize);\r
161                                 writer.Write (hdrSize);\r
162                                 writer.Write (chksum);\r
163                                 writer.Write ((short)subSys);\r
164                                 writer.Write (dllFlags);\r
165                                 writer.Write (stackRes);\r
166                                 writer.Write (stackCommit);\r
167                                 writer.Write (heapRes);\r
168                                 writer.Write (heapCommit);\r
169                                 writer.Write (ldrFlags);\r
170                                 writer.Write (numDirs);\r
171                         }\r
172 \r
173                         public string OSVersion {\r
174                                 get {\r
175                                         return String.Format("{0}.{1}", osMaj, osMin);\r
176                                 }\r
177                         }\r
178 \r
179                         public string ImageVersion {\r
180                                 get {\r
181                                         return String.Format("{0}.{1}", imgMaj, imgMin);\r
182                                 }\r
183                         }\r
184 \r
185                         public string SubsysVersion {\r
186                                 get {\r
187                                         return String.Format("{0}.{1}", subSysMaj, subSysMin);\r
188                                 }\r
189                         }\r
190 \r
191 \r
192                         /// <summary>\r
193                         /// </summary>\r
194                         /// <returns></returns>\r
195                         public override string ToString() {\r
196                                 return String.Format(\r
197                                         "Image Base            : 0x{0}" + Environment.NewLine +\r
198                                         "Section Alignment     : 0x{1}" + Environment.NewLine +\r
199                                         "File Alignment        : 0x{2}" + Environment.NewLine +\r
200                                         "OS Version            : {3}" + Environment.NewLine +\r
201                                         "Image Version         : {4}" + Environment.NewLine +\r
202                                         "Subsystem Version     : {5}" + Environment.NewLine +\r
203                                         "Reserved/Win32Ver     : {6}" + Environment.NewLine +\r
204                                         "Image Size            : {7}" + Environment.NewLine +\r
205                                         "Header Size           : {8}" + Environment.NewLine +\r
206                                         "Checksum              : 0x{9}" + Environment.NewLine +\r
207                                         "Subsystem             : {10}" + Environment.NewLine +\r
208                                         "DLL Flags             : {11}" + Environment.NewLine +\r
209                                         "Stack Reserve Size    : 0x{12}" + Environment.NewLine +\r
210                                         "Stack Commit Size     : 0x{13}" + Environment.NewLine +\r
211                                         "Heap Reserve Size     : 0x{14}" + Environment.NewLine +\r
212                                         "Heap Commit Size      : 0x{15}" + Environment.NewLine +\r
213                                         "Loader Flags          : {16}" + Environment.NewLine +\r
214                                         "Number of Directories : {17}" + Environment.NewLine,\r
215                                         imgBase.ToString("X"), sectAlign.ToString("X"), fileAlign.ToString("X"),\r
216                                         OSVersion, ImageVersion, SubsysVersion,\r
217                                         reserved_win32ver,\r
218                                         imgSize, hdrSize, chksum.ToString("X"), subSys, dllFlags,\r
219                                         stackRes.ToString("X"), stackCommit.ToString("X"), heapRes.ToString("X"), heapCommit.ToString ("X"),\r
220                                         ldrFlags, numDirs\r
221                                         );\r
222                         }\r
223                 }\r
224 \r
225 \r
226                 internal StdFields stdFlds;\r
227                 internal NTFields ntFlds;\r
228 \r
229                 internal DataDir exportDir;\r
230                 internal DataDir importDir;\r
231                 internal DataDir resourceDir;\r
232                 internal DataDir exceptionDir;\r
233                 internal DataDir securityDir;\r
234                 internal DataDir baseRelocDir;\r
235                 internal DataDir debugDir;\r
236                 internal DataDir copyrightDir;\r
237                 internal DataDir GPDir;\r
238                 internal DataDir TLSDir;\r
239                 internal DataDir loadCfgDir;\r
240                 internal DataDir boundImpDir;\r
241                 internal DataDir IATDir;\r
242                 internal DataDir delayImpDir;\r
243                 internal DataDir CLIHdrDir;\r
244                 internal DataDir reservedDir;\r
245 \r
246 \r
247                 public bool IsCLIImage {\r
248                         get {\r
249                                 return (CLIHdrDir.virtAddr.Value != 0);\r
250                         }\r
251                 }\r
252 \r
253 \r
254                 //\r
255                 // Accessors for standard COFF fields.\r
256                 //\r
257                 \r
258                 public short Magic {\r
259                         get {\r
260                                 return stdFlds.magic;\r
261                         }\r
262                         set {\r
263                                 stdFlds.magic = value;\r
264                         }\r
265                 }\r
266 \r
267                 public byte MajorLinkerVersion {\r
268                         get {\r
269                                 return stdFlds.lMajor;\r
270                         }\r
271                         set {\r
272                                 stdFlds.lMajor = value;\r
273                         }\r
274                 }\r
275 \r
276                 public byte MinorLinkerVersion {\r
277                         get {\r
278                                 return stdFlds.lMinor;\r
279                         }\r
280                         set {\r
281                                 stdFlds.lMinor = value;\r
282                         }\r
283                 }\r
284 \r
285                 public uint SizeOfCode {\r
286                         get {\r
287                                 return stdFlds.codeSize;\r
288                         }\r
289                         set {\r
290                                 stdFlds.codeSize = value;\r
291                         }\r
292                 }\r
293 \r
294                 public uint SizeOfInitializedData {\r
295                         get {\r
296                                 return stdFlds.initDataSize;\r
297                         }\r
298                         set {\r
299                                 stdFlds.initDataSize = value;\r
300                         }\r
301                 }\r
302 \r
303                 public uint SizeOfUninitializedData {\r
304                         get {\r
305                                 return stdFlds.uninitDataSize;\r
306                         }\r
307                         set {\r
308                                 stdFlds.uninitDataSize = value;\r
309                         }\r
310                 }\r
311 \r
312                 public RVA AddressOfEntryPoint {\r
313                         get {\r
314                                 return stdFlds.entryRVA;\r
315                         }\r
316                         set {\r
317                                 stdFlds.entryRVA.value = value.value;\r
318                         }\r
319                 }\r
320 \r
321                 public RVA BaseOfCode {\r
322                         get {\r
323                                 return stdFlds.codeBase;\r
324                         }\r
325                         set {\r
326                                 stdFlds.codeBase.value = value.value;\r
327                         }\r
328                 }\r
329 \r
330                 public RVA BaseOfData {\r
331                         get {\r
332                                 return stdFlds.dataBase;\r
333                         }\r
334                         set {\r
335                                 stdFlds.dataBase.value = value.value;\r
336                         }\r
337                 }\r
338 \r
339 \r
340                 //\r
341                 // Accessors for Windows-specific fields.\r
342                 //\r
343 \r
344 \r
345                 /// <summary>\r
346                 /// Preferred address of image when loaded into memory.\r
347                 /// </summary>\r
348                 /// <remarks>\r
349                 ///  <para>\r
350                 ///  This is a linear address and not RVA,\r
351                 ///  and must be a multiple of 64K.\r
352                 ///  </para>\r
353                 ///  <para>\r
354                 ///  Table in the Partition II states that for CIL images\r
355                 ///  it must be 0x400000.\r
356                 ///  </para>\r
357                 /// </remarks>\r
358                 public uint ImageBase {\r
359                         get {\r
360                                 return ntFlds.imgBase;\r
361                         }\r
362                         set {\r
363                                 ntFlds.imgBase = value;\r
364                         }\r
365                 }\r
366 \r
367                 /// <summary>\r
368                 ///  Alignment of section when loaded into memory.\r
369                 /// </summary>\r
370                 /// <remarks>\r
371                 ///  Must be greater or equal to FileAlignment.\r
372                 ///  Default is the native page size.\r
373                 ///  According to specs for CIL images it must be set to 8K.\r
374                 /// </remarks>\r
375                 public uint SectionAlignment {\r
376                         get {\r
377                                 return ntFlds.sectAlign;\r
378                         }\r
379                         set {\r
380                                 ntFlds.sectAlign = value;\r
381                         }\r
382                 }\r
383 \r
384                 /// <summary>\r
385                 ///  Byte alignment of pages in image file.\r
386                 /// </summary>\r
387                 /// <remarks>\r
388                 ///  Valid values are powers of 2 between 512 and 64K.\r
389                 ///  For CIL images it must be either 512 or 4K.\r
390                 /// </remarks>\r
391                 public uint FileAlignment {\r
392                         get {\r
393                                 return ntFlds.fileAlign;\r
394                         }\r
395                         set {\r
396                                 ntFlds.fileAlign = value;\r
397                         }\r
398                 }\r
399 \r
400 \r
401                 public short MajorOperatingSystemVersion {\r
402                         get {\r
403                                 return ntFlds.osMaj;\r
404                         }\r
405                         set {\r
406                                 ntFlds.osMaj = value;\r
407                         }\r
408                 }\r
409 \r
410                 public short MinorOperatingSystemVersion {\r
411                         get {\r
412                                 return ntFlds.osMin;\r
413                         }\r
414                         set {\r
415                                 ntFlds.osMin = value;\r
416                         }\r
417                 }\r
418 \r
419                 public short MajorImageVersion {\r
420                         get {\r
421                                 return ntFlds.imgMaj;\r
422                         }\r
423                         set {\r
424                                 ntFlds.imgMaj = value;\r
425                         }\r
426                 }\r
427 \r
428                 public short MinorImageVersion {\r
429                         get {\r
430                                 return ntFlds.imgMin;\r
431                         }\r
432                         set {\r
433                                 ntFlds.imgMin = value;\r
434                         }\r
435                 }\r
436 \r
437                 public short MajorSubsystemVersion {\r
438                         get {\r
439                                 return ntFlds.subSysMaj;\r
440                         }\r
441                         set {\r
442                                 ntFlds.subSysMaj = value;\r
443                         }\r
444                 }\r
445 \r
446                 public short MinorSubsystemVersion {\r
447                         get {\r
448                                 return ntFlds.subSysMin;\r
449                         }\r
450                         set {\r
451                                 ntFlds.subSysMin = value;\r
452                         }\r
453                 }\r
454 \r
455                 public int Win32VersionValue {\r
456                         get {\r
457                                 return ntFlds.reserved_win32ver;\r
458                         }\r
459                         set {\r
460                                 ntFlds.reserved_win32ver = value;\r
461                         }\r
462                 }\r
463 \r
464                 public int Reserved {\r
465                         get {\r
466                                 return ntFlds.reserved_win32ver;\r
467                         }\r
468                         set {\r
469                                 ntFlds.reserved_win32ver = value;\r
470                         }\r
471                 }\r
472 \r
473                 public uint SizeOfImage {\r
474                         get {\r
475                                 return ntFlds.imgSize;\r
476                         }\r
477                         set {\r
478                                 ntFlds.imgSize = value;\r
479                         }\r
480                 }\r
481 \r
482                 public uint SizeOfHeaders {\r
483                         get {\r
484                                 return ntFlds.hdrSize;\r
485                         }\r
486                         set {\r
487                                 ntFlds.hdrSize = value;\r
488                         }\r
489                 }\r
490 \r
491                 public uint CheckSum {\r
492                         get {\r
493                                 return ntFlds.chksum;\r
494                         }\r
495                         set {\r
496                                 ntFlds.chksum = value;\r
497                         }\r
498                 }\r
499 \r
500                 public Subsystem Subsystem {\r
501                         get {\r
502                                 return ntFlds.subSys;\r
503                         }\r
504                         set {\r
505                                 ntFlds.subSys = value;\r
506                         }\r
507                 }\r
508 \r
509                 public short DllCharacteristics {\r
510                         get {\r
511                                 return ntFlds.dllFlags;\r
512                         }\r
513                         set {\r
514                                 ntFlds.dllFlags = value;\r
515                         }\r
516                 }\r
517 \r
518 \r
519                 public uint SizeOfStackReserve {\r
520                         get {\r
521                                 return ntFlds.stackRes;\r
522                         }\r
523                         set {\r
524                                 ntFlds.stackRes = value;\r
525                         }\r
526                 }\r
527 \r
528                 public uint SizeOfStackCommit {\r
529                         get {\r
530                                 return ntFlds.stackCommit;\r
531                         }\r
532                         set {\r
533                                 ntFlds.stackCommit = value;\r
534                         }\r
535                 }\r
536 \r
537                 public uint SizeOfHeapReserve {\r
538                         get {\r
539                                 return ntFlds.heapRes;\r
540                         }\r
541                         set {\r
542                                 ntFlds.heapRes = value;\r
543                         }\r
544                 }\r
545 \r
546                 public uint SizeOfHeapCommit {\r
547                         get {\r
548                                 return ntFlds.heapCommit;\r
549                         }\r
550                         set {\r
551                                 ntFlds.heapCommit = value;\r
552                         }\r
553                 }\r
554 \r
555                 public uint LoaderFlags {\r
556                         get {\r
557                                 return ntFlds.ldrFlags;\r
558                         }\r
559                         set {\r
560                                 ntFlds.ldrFlags = value;\r
561                         }\r
562                 }\r
563 \r
564                 public uint NumberOfRvaAndSizes {\r
565                         get {\r
566                                 return ntFlds.numDirs;\r
567                         }\r
568                         set {\r
569                                 ntFlds.numDirs = value;\r
570                         }\r
571                 }\r
572 \r
573 \r
574 \r
575 \r
576 \r
577                 /// <summary>\r
578                 /// </summary>\r
579                 public void Read(BinaryReader reader)\r
580                 {\r
581                         stdFlds = new StdFields (reader);\r
582                         ntFlds = new NTFields (reader);\r
583 \r
584                         exportDir = new DataDir (reader);\r
585                         importDir = new DataDir (reader);               \r
586                         resourceDir = new DataDir (reader);\r
587                         exceptionDir = new DataDir (reader);\r
588                         securityDir = new DataDir (reader);\r
589                         baseRelocDir = new DataDir (reader);\r
590                         debugDir = new DataDir (reader);\r
591                         copyrightDir = new DataDir (reader);\r
592                         GPDir = new DataDir (reader);\r
593                         TLSDir = new DataDir (reader);\r
594                         loadCfgDir = new DataDir (reader);\r
595                         boundImpDir = new DataDir (reader);\r
596                         IATDir = new DataDir (reader);\r
597                         delayImpDir = new DataDir (reader);\r
598                         CLIHdrDir = new DataDir (reader);\r
599                         reservedDir = new DataDir (reader);\r
600                         \r
601                 }\r
602 \r
603                 public void Write (BinaryWriter writer)\r
604                 {\r
605                         stdFlds.Write (writer);\r
606                         ntFlds.Write (writer);\r
607 \r
608                         exportDir.Write (writer);\r
609                         importDir.Write (writer);\r
610                         resourceDir.Write (writer);\r
611                         exceptionDir.Write (writer);\r
612                         securityDir.Write (writer);\r
613                         baseRelocDir.Write (writer);\r
614                         debugDir.Write (writer);\r
615                         copyrightDir.Write (writer);\r
616                         GPDir.Write (writer);\r
617                         TLSDir.Write (writer);\r
618                         loadCfgDir.Write (writer);\r
619                         boundImpDir.Write (writer);\r
620                         IATDir.Write (writer);\r
621                         delayImpDir.Write (writer);\r
622                         CLIHdrDir.Write (writer);\r
623                         reservedDir.Write (writer);\r
624                 }\r
625 \r
626                 /// <summary>\r
627                 /// </summary>\r
628                 public void Dump(TextWriter writer)\r
629                 {\r
630                         string dirs = String.Format(\r
631                                 "Export Table            : {0}"  + Environment.NewLine +\r
632                                 "Import Table            : {1}"  + Environment.NewLine +\r
633                                 "Win32 Resource Table    : {2}"  + Environment.NewLine +\r
634                                 "Exception Table         : {3}"  + Environment.NewLine +\r
635                                 "Certificate Table       : {4}"  + Environment.NewLine +\r
636                                 "Base Relocation Table   : {5}"  + Environment.NewLine +\r
637                                 "Debug Table             : {6}"  + Environment.NewLine +\r
638                                 "Copyright               : {7}"  + Environment.NewLine +\r
639                                 "MIPS Global Ptr         : {8}"  + Environment.NewLine +\r
640                                 "TLS Table               : {9}"  + Environment.NewLine +\r
641                                 "Load Config Table       : {10}"  + Environment.NewLine +\r
642                                 "Bound Import            : {11}"  + Environment.NewLine +\r
643                                 "IAT                     : {12}"  + Environment.NewLine +\r
644                                 "Delay Import Descriptor : {13}"  + Environment.NewLine +\r
645                                 "CLI Header              : {14}"  + Environment.NewLine +\r
646                                 "Reserved                : {15}"  + Environment.NewLine,\r
647                                 exportDir, importDir, resourceDir, exceptionDir,\r
648                                 securityDir, baseRelocDir, debugDir, copyrightDir,\r
649                                 GPDir, TLSDir, loadCfgDir, boundImpDir, IATDir, delayImpDir,\r
650                                 CLIHdrDir, reservedDir\r
651                         );\r
652 \r
653                         writer.WriteLine(\r
654                                 "Standard Fields:" + Environment.NewLine +\r
655                                 stdFlds.ToString() + Environment.NewLine +\r
656                                 "NT Fields:" + Environment.NewLine +\r
657                                 ntFlds.ToString() + Environment.NewLine +\r
658                                 "Directories: "+ Environment.NewLine +\r
659                                 dirs\r
660                         );\r
661                 }\r
662 \r
663 \r
664                 /// <summary>\r
665                 /// </summary>\r
666                 /// <returns></returns>\r
667                 public override string ToString()\r
668                 {\r
669                         StringWriter sw = new StringWriter();\r
670                         Dump(sw);\r
671                         return sw.ToString();\r
672                 }\r
673 \r
674         }\r
675 \r
676 }\r
677 \r