]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Common/Misc.py
Sync EDKII BaseTools to BaseTools project r2042.
[mirror_edk2.git] / BaseTools / Source / Python / Common / Misc.py
index 2883169f3c6888997e4c028c9a5e5c69d4121d30..311749285f0af2c68ee41fc2ba60e6d0afd8061f 100644 (file)
@@ -1,8 +1,8 @@
 ## @file
 # Common routines used by all tools
 #
-# Copyright (c) 2007, Intel Corporation
-# All rights reserved. This program and the accompanying materials
+# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
 # are licensed and made available under the terms and conditions of the BSD License
 # which accompanies this distribution.  The full text of the license may be found at
 # http://opensource.org/licenses/bsd-license.php
@@ -22,6 +22,7 @@ import threading
 import time
 import re
 import cPickle
+import array
 from UserDict import IterableUserDict
 from UserList import UserList
 
@@ -718,7 +719,7 @@ class TemplateString(object):
         while Template:
             MatchObj = gPlaceholderPattern.search(Template, SearchFrom)
             if not MatchObj:
-                if MatchEnd < len(Template):
+                if MatchEnd <= len(Template):
                     TemplateSection = TemplateString.Section(Template[SectionStart:], PlaceHolderList)
                     TemplateSectionList.append(TemplateSection)
                 break
@@ -1321,7 +1322,12 @@ class PathClass(object):
 
         RealFile, RealRoot = RealPath2(self.File, self.Root, self.AlterRoot)
         if not RealRoot and not RealFile:
-            return FILE_NOT_FOUND, self.File
+            RealFile = self.File
+            if self.AlterRoot:
+                RealFile = os.path.join(self.AlterRoot, self.File)
+            elif self.Root:
+                RealFile = os.path.join(self.Root, self.File)
+            return FILE_NOT_FOUND, os.path.join(self.AlterRoot, RealFile)
 
         ErrorCode = 0
         ErrorInfo = ''
@@ -1343,6 +1349,90 @@ class PathClass(object):
 
     Key = property(_GetFileKey)
 
+## Parse PE image to get the required PE informaion.
+#
+class PeImageClass():
+    ## Constructor
+    #
+    #   @param  File FilePath of PeImage
+    #
+    def __init__(self, PeFile):
+        self.FileName   = PeFile
+        self.IsValid    = False
+        self.Size       = 0
+        self.EntryPoint = 0
+        self.SectionAlignment  = 0
+        self.SectionHeaderList = []
+        self.ErrorInfo = ''
+        try:
+             PeObject = open(PeFile, 'rb')
+        except:
+            self.ErrorInfo = self.FileName + ' can not be found\n'
+            return
+        # Read DOS header
+        ByteArray = array.array('B')
+        ByteArray.fromfile(PeObject, 0x3E)
+        ByteList = ByteArray.tolist()
+        # DOS signature should be 'MZ'
+        if self._ByteListToStr (ByteList[0x0:0x2]) != 'MZ':
+            self.ErrorInfo = self.FileName + ' has no valid DOS signature MZ'
+            return
+
+        # Read 4 byte PE Signature
+        PeOffset = self._ByteListToInt(ByteList[0x3C:0x3E])
+        PeObject.seek(PeOffset)
+        ByteArray = array.array('B')
+        ByteArray.fromfile(PeObject, 4)
+        # PE signature should be 'PE\0\0'
+        if ByteArray.tostring() != 'PE\0\0':
+            self.ErrorInfo = self.FileName + ' has no valid PE signature PE00'
+            return
+
+        # Read PE file header
+        ByteArray = array.array('B')
+        ByteArray.fromfile(PeObject, 0x14)
+        ByteList = ByteArray.tolist()
+        SecNumber = self._ByteListToInt(ByteList[0x2:0x4])
+        if SecNumber == 0:
+            self.ErrorInfo = self.FileName + ' has no section header'
+            return
+
+        # Read PE optional header
+        OptionalHeaderSize = self._ByteListToInt(ByteArray[0x10:0x12])
+        ByteArray = array.array('B')
+        ByteArray.fromfile(PeObject, OptionalHeaderSize)
+        ByteList = ByteArray.tolist()
+        self.EntryPoint       = self._ByteListToInt(ByteList[0x10:0x14])
+        self.SectionAlignment = self._ByteListToInt(ByteList[0x20:0x24])
+        self.Size             = self._ByteListToInt(ByteList[0x38:0x3C])
+
+        # Read each Section Header
+        for Index in range(SecNumber):
+            ByteArray = array.array('B')
+            ByteArray.fromfile(PeObject, 0x28)
+            ByteList = ByteArray.tolist()
+            SecName  = self._ByteListToStr(ByteList[0:8])
+            SecVirtualSize = self._ByteListToInt(ByteList[8:12])
+            SecRawAddress  = self._ByteListToInt(ByteList[20:24])
+            SecVirtualAddress = self._ByteListToInt(ByteList[12:16])
+            self.SectionHeaderList.append((SecName, SecVirtualAddress, SecRawAddress, SecVirtualSize))
+        self.IsValid = True
+        PeObject.close()
+
+    def _ByteListToStr(self, ByteList):
+        String = ''
+        for index in range(len(ByteList)):
+            if ByteList[index] == 0: 
+                break
+            String += chr(ByteList[index])
+        return String
+
+    def _ByteListToInt(self, ByteList):
+        Value = 0
+        for index in range(len(ByteList) - 1, -1, -1):
+            Value = (Value << 8) | int(ByteList[index])
+        return Value
+        
 ##
 #
 # This acts like the main() function for the script, unless it is 'import'ed into another