summaryrefslogtreecommitdiffstats
path: root/BaseTools
diff options
context:
space:
mode:
authorYuwei Chen <yuwei.chen@intel.com>2023-06-29 11:35:01 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-12-11 10:12:52 +0000
commit59f0d350a9f39fdb1d26295457eaf14306703afb (patch)
tree72b04736a86382c2404df42d1ed7e15958d93c98 /BaseTools
parent96274476257bd8e4e5d9e3b8983382c159972e64 (diff)
downloadedk2-59f0d350a9f39fdb1d26295457eaf14306703afb.tar.gz
edk2-59f0d350a9f39fdb1d26295457eaf14306703afb.tar.bz2
edk2-59f0d350a9f39fdb1d26295457eaf14306703afb.zip
BaseTools: FMMT support ELF UPLD parser
FMMT add new function to support the .elf file parsing. Using '-v' option, the UPLD info will be printed out. ''' - UNIVERSAL_PAYLOAD_INFO - 4 bytes align (BOOLEAN) - Identifier - SpecRevision - Attribute - Revision - Capability - ProducerId - ImageId UPLD Buffer ''' Cc: Rebecca Cran <rebecca@bsdio.com> Cc: Bob Feng <bob.c.feng@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Signed-off-by: Yuwei Chen <yuwei.chen@intel.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn> Reviewed-by: Bob Feng <bob.c.feng@intel.com>
Diffstat (limited to 'BaseTools')
-rw-r--r--BaseTools/Source/Python/FMMT/FMMT.py2
-rw-r--r--BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py36
-rw-r--r--BaseTools/Source/Python/FMMT/core/BiosTree.py48
-rw-r--r--BaseTools/Source/Python/FMMT/core/BiosTreeNode.py56
-rw-r--r--BaseTools/Source/Python/FMMT/core/FMMTParser.py2
-rw-r--r--BaseTools/Source/Python/FirmwareStorageFormat/UPLHeader.py244
6 files changed, 383 insertions, 5 deletions
diff --git a/BaseTools/Source/Python/FMMT/FMMT.py b/BaseTools/Source/Python/FMMT/FMMT.py
index bf580b3843..26fc4c5792 100644
--- a/BaseTools/Source/Python/FMMT/FMMT.py
+++ b/BaseTools/Source/Python/FMMT/FMMT.py
@@ -84,6 +84,8 @@ class FMMT():
ROOT_TYPE = ROOT_FFS_TREE
elif filetype == '.sec':
ROOT_TYPE = ROOT_SECTION_TREE
+ elif filetype == '.elf':
+ ROOT_TYPE = ROOT_ELF_TREE
else:
ROOT_TYPE = ROOT_TREE
ViewFile(inputfile, ROOT_TYPE, layoutfilename, outputfile)
diff --git a/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
index 2d4e6d9276..de174f26ab 100644
--- a/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
+++ b/BaseTools/Source/Python/FMMT/core/BinaryFactoryProduct.py
@@ -15,10 +15,13 @@ from core.GuidTools import GUIDTools
from utils.FmmtLogger import FmmtLogger as logger
ROOT_TREE = 'ROOT'
+ROOT_ELF_TREE = 'ROOT_ELF_TREE'
ROOT_FV_TREE = 'ROOT_FV_TREE'
ROOT_FFS_TREE = 'ROOT_FFS_TREE'
ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
+ELF_TREE = 'ELF'
+ELF_SECTION_TREE = 'ELF_SECTION_TREE'
FV_TREE = 'FV'
DATA_FV_TREE = 'DATA_FV'
FFS_TREE = 'FFS'
@@ -49,6 +52,12 @@ class BinaryProduct():
def ParserData():
pass
+class ElfFactory(BinaryFactory):
+ type = [ROOT_ELF_TREE, ELF_TREE]
+
+ def Create_Product():
+ return ElfProduct()
+
class SectionFactory(BinaryFactory):
type = [SECTION_TREE]
@@ -354,6 +363,30 @@ class FdProduct(BinaryProduct):
tmp_index += 1
return Fd_Struct
+class ElfSectionProduct(BinaryProduct):
+ ## Decompress the compressed section.
+ def ParserData(self, Section_Tree, whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
+ pass
+ def ParserSectionData(self, Section_Tree, whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
+ pass
+ def ParserProgramData(self, Section_Tree, whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
+ pass
+
+class ElfProduct(BinaryProduct):
+
+ def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: int=0) -> None:
+ Elf_Info = ElfNode(Whole_Data)
+ if Elf_Info.Header.ELF_PHOff != 0:
+ Elf_Info.GetProgramList(Whole_Data[Elf_Info.Header.ELF_PHOff:])
+ if Elf_Info.Header.ELF_SHOff != 0:
+ Elf_Info.GetSectionList(Whole_Data[Elf_Info.Header.ELF_SHOff:])
+ Elf_Info.FindUPLDSection(Whole_Data)
+ Elf_Tree = BIOSTREE(Elf_Info.Name)
+ Elf_Tree.type = ELF_TREE
+ Elf_Info.Data = Whole_Data[Elf_Info.HeaderLength:]
+ Elf_Tree.Data = Elf_Info
+ ParTree.insertChild(Elf_Tree)
+
class ParserEntry():
FactoryTable:dict = {
SECTION_TREE: SectionFactory,
@@ -364,6 +397,7 @@ class ParserEntry():
SEC_FV_TREE: FvFactory,
ROOT_FV_TREE: FdFactory,
ROOT_TREE: FdFactory,
+ ROOT_ELF_TREE: ElfFactory,
}
def GetTargetFactory(self, Tree_type: str) -> BinaryFactory:
@@ -377,4 +411,4 @@ class ParserEntry():
def DataParser(self, Tree, Data: bytes, Offset: int) -> None:
TargetFactory = self.GetTargetFactory(Tree.type)
if TargetFactory:
- self.Generate_Product(TargetFactory, Tree, Data, Offset) \ No newline at end of file
+ self.Generate_Product(TargetFactory, Tree, Data, Offset)
diff --git a/BaseTools/Source/Python/FMMT/core/BiosTree.py b/BaseTools/Source/Python/FMMT/core/BiosTree.py
index 137f49748b..c5a7b017f4 100644
--- a/BaseTools/Source/Python/FMMT/core/BiosTree.py
+++ b/BaseTools/Source/Python/FMMT/core/BiosTree.py
@@ -12,6 +12,7 @@ ROOT_TREE = 'ROOT'
ROOT_FV_TREE = 'ROOT_FV_TREE'
ROOT_FFS_TREE = 'ROOT_FFS_TREE'
ROOT_SECTION_TREE = 'ROOT_SECTION_TREE'
+ROOT_ELF_TREE = 'ROOT_ELF_TREE'
FV_TREE = 'FV'
DATA_FV_TREE = 'DATA_FV'
@@ -21,11 +22,13 @@ FFS_FREE_SPACE = 'FFS_FREE_SPACE'
SECTION_TREE = 'SECTION'
SEC_FV_TREE = 'SEC_FV_IMAGE'
BINARY_DATA = 'BINARY'
+ELF_TREE = 'ELF'
RootType = [ROOT_TREE, ROOT_FV_TREE, ROOT_FFS_TREE, ROOT_SECTION_TREE]
FvType = [FV_TREE, SEC_FV_TREE]
FfsType = FFS_TREE
SecType = SECTION_TREE
+ElfType = [ROOT_ELF_TREE, ELF_TREE]
class BIOSTREE:
def __init__(self, NodeName: str) -> None:
@@ -118,6 +121,31 @@ class BIOSTREE:
Info.append("Image File: {}".format(Key))
Info.append("FilesNum: {}".format(TargetDict.get(Key).get('FilesNum')))
Info.append("\n")
+ elif TargetDict[Key]["Type"] == ROOT_ELF_TREE:
+ Info.append("ELF File: {}\n".format(Key))
+ elif TargetDict[Key]["Type"] == ELF_TREE:
+ ProducerId = ""
+ ImageId = ""
+ if TargetDict.get(Key).get('IfExist'):
+ Identifier = TargetDict.get(Key).get('Identifier')
+ for item in TargetDict.get(Key).get('ProducerId'):
+ ProducerId += chr(item)
+ for item in TargetDict.get(Key).get('ImageId'):
+ ImageId += chr(item)
+ Info.append("- UNIVERSAL_PAYLOAD_INFO")
+ Info.append(" - 4 bytes align: {}".format(TargetDict.get(Key).get('Upld_Info_Align')))
+ Info.append(" - Identifier: {} # 0x48444c50--PLDH / 0x444c5055--UPLD".format(hex(Identifier)))
+ Info.append(" - SpecRevision: {}".format(hex(TargetDict.get(Key).get('SpecRevision'))))
+ Info.append(" - Attribute: {}".format(hex(TargetDict.get(Key).get('Attribute'))))
+ Info.append(" - Revision: {}".format(hex(TargetDict.get(Key).get('Revision'))))
+ Info.append(" - Capability: {}".format(hex(TargetDict.get(Key).get('Capability'))))
+ Info.append(" - ProducerId: {}".format(ProducerId))
+ Info.append(" - ImageId: {}".format(ImageId))
+ Info.append("\n")
+ Info.append("- UPLD buffer")
+ Info.append(" Buffer: {}".format(TargetDict.get(Key).get('Upld_Buffer')))
+ else:
+ print("Do not find the Upld Info section!!!\n")
elif TargetDict[Key]["Type"] in FvType:
space += 2
if TargetDict[Key]["Type"] == SEC_FV_TREE:
@@ -146,13 +174,29 @@ class BIOSTREE:
if TreeInfo is None:
TreeInfo =collections.OrderedDict()
- if self.type == ROOT_TREE or self.type == ROOT_FV_TREE or self.type == ROOT_FFS_TREE or self.type == ROOT_SECTION_TREE:
+ if self.type == ROOT_TREE or self.type == ROOT_FV_TREE or self.type == ROOT_FFS_TREE or self.type == ROOT_SECTION_TREE or self.type == ROOT_ELF_TREE:
key = str(self.key)
TreeInfo[self.key] = collections.OrderedDict()
TreeInfo[self.key]["Name"] = key
TreeInfo[self.key]["Type"] = self.type
TreeInfo[self.key]["FilesNum"] = len(self.Child)
- elif self.type == FV_TREE or self.type == SEC_FV_TREE:
+ elif self.type == ELF_TREE:
+ key = str(self.Data.Name)
+ TreeInfo[key] = collections.OrderedDict()
+ TreeInfo[key]["Name"] = key
+ TreeInfo[key]["Type"] = self.type
+ TreeInfo[key]["IfExist"] = self.Data.UpldInfo
+ if self.Data.UpldInfo:
+ TreeInfo[key]["Identifier"] = self.Data.UpldInfo.Identifier
+ TreeInfo[key]["SpecRevision"] = self.Data.UpldInfo.SpecRevision
+ TreeInfo[key]["Attribute"] = self.Data.UpldInfo.Attribute
+ TreeInfo[key]["Revision"] = self.Data.UpldInfo.Revision
+ TreeInfo[key]["Capability"] = self.Data.UpldInfo.Capability
+ TreeInfo[key]["ProducerId"] = self.Data.UpldInfo.ProducerId
+ TreeInfo[key]["ImageId"] = self.Data.UpldInfo.ImageId
+ TreeInfo[key]["Upld_Info_Align"] = self.Data.Upld_Info_Align
+ TreeInfo[key]["Upld_Buffer"] = self.Data.UpldBuffer
+ elif self.type == FV_TREE or self.type == SEC_FV_TREE:
key = str(self.Data.FvId)
TreeInfo[key] = collections.OrderedDict()
TreeInfo[key]["Name"] = key
diff --git a/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
index 20447766c8..5ca4c20dc6 100644
--- a/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
+++ b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
@@ -4,6 +4,7 @@
# Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
+from FirmwareStorageFormat.UPLHeader import *
from FirmwareStorageFormat.FvHeader import *
from FirmwareStorageFormat.FfsFileHeader import *
from FirmwareStorageFormat.SectionHeader import *
@@ -37,6 +38,59 @@ class BinaryNode:
self.HOffset = 0
self.Data = b''
+class ElfNode:
+ def __init__(self, buffer: bytes) -> None:
+ self.Header = ELF_HEADER32.from_buffer_copy(buffer)
+ if self.Header.ELF_Identification[0:4] != b'\x7fELF':
+ logger.error('Invalid Elf Header! Elf Identification {} is not ".ELF".'.format(self.Header.ELF_Identification))
+ raise Exception("Process Failed: Invalid ELF Header Identification!")
+ self.Class = self.Header.ELF_Identification[4]
+ if self.Class == 0x02:
+ self.Header = ELF_HEADER64.from_buffer_copy(buffer)
+ elif self.Class != 0x01:
+ logger.error('Invalid Elf Class! Elf Class {} is not 0x01 or 0x02.'.format(self.Class))
+ raise Exception("Process Failed: Invalid ELF Class!")
+
+ self.ProList = []
+ self.SecList = []
+ self.UpldInfoSection = None
+ self.UpldInfo = None
+ self.UpldBuffer = b''
+ self.Name = "ELF"
+ self.HeaderLength = len(struct2stream(self.Header))
+ self.HOffset = 0
+ self.DOffset = 0
+ self.ROffset = 0
+ self.Data = b''
+ self.PadData = b''
+ self.Upld_Info_Align = False
+
+ def GetProgramList(self, buffer: bytes) -> None:
+ for i in range(self.Header.ELF_PHNum):
+ if self.Class == 0x01:
+ ElfProgramHeader = ELF_PROGRAM_HEADER32.from_buffer_copy(buffer[i*self.Header.ELF_PHEntSize:])
+ elif self.Class == 0x02:
+ ElfProgramHeader = ELF_PROGRAM_HEADER64.from_buffer_copy(buffer[i*self.Header.ELF_PHEntSize:])
+ self.ProList.append(ElfProgramHeader)
+
+ def GetSectionList(self, buffer: bytes) -> None:
+ for i in range(self.Header.ELF_SHNum):
+ if self.Class == 0x01:
+ ElfSectionHeader = ELF_SECTION_HEADER32.from_buffer_copy(buffer[i*self.Header.ELF_SHEntSize:])
+ elif self.Class == 0x02:
+ ElfSectionHeader = ELF_SECTION_HEADER64.from_buffer_copy(buffer[i*self.Header.ELF_SHEntSize:])
+ self.SecList.append(ElfSectionHeader)
+
+ def FindUPLDSection(self, buffer: bytes) -> None:
+ for item in self.SecList:
+ if buffer[item.SH_Offset:item.SH_Offset+4] == b'PLDH' or buffer[item.SH_Offset:item.SH_Offset+4] == b'UPLD':
+ self.UpldInfoSection = item
+ self.UpldInfo = UNIVERSAL_PAYLOAD_INFO.from_buffer_copy(buffer[item.SH_Offset:item.SH_Offset+item.SH_Size])
+ self.UpldBuffer = struct2stream(self.UpldInfo)
+ if (self.UpldInfoSection.SH_Offset) % 4 == 0:
+ # if (self.UpldInfoSection.SH_Offset - self.Header.ELF_Entry) % 4 == 0:
+ self.Upld_Info_Align = True
+
class FvNode:
def __init__(self, name, buffer: bytes) -> None:
self.Header = EFI_FIRMWARE_VOLUME_HEADER.from_buffer_copy(buffer)
@@ -191,4 +245,4 @@ class FreeSpaceNode:
self.HOffset = 0
self.DOffset = 0
self.ROffset = 0
- self.PadData = b'' \ No newline at end of file
+ self.PadData = b''
diff --git a/BaseTools/Source/Python/FMMT/core/FMMTParser.py b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
index e76ac51185..25a2bde799 100644
--- a/BaseTools/Source/Python/FMMT/core/FMMTParser.py
+++ b/BaseTools/Source/Python/FMMT/core/FMMTParser.py
@@ -20,7 +20,7 @@ class FMMTParser:
## Parser the nodes in WholeTree.
def ParserFromRoot(self, WholeFvTree=None, whole_data: bytes=b'', Reloffset: int=0) -> None:
- if WholeFvTree.type == ROOT_TREE or WholeFvTree.type == ROOT_FV_TREE:
+ if WholeFvTree.type == ROOT_TREE or WholeFvTree.type == ROOT_FV_TREE or WholeFvTree.type == ROOT_ELF_TREE:
ParserEntry().DataParser(self.WholeFvTree, whole_data, Reloffset)
else:
ParserEntry().DataParser(WholeFvTree, whole_data, Reloffset)
diff --git a/BaseTools/Source/Python/FirmwareStorageFormat/UPLHeader.py b/BaseTools/Source/Python/FirmwareStorageFormat/UPLHeader.py
new file mode 100644
index 0000000000..fd4da939f9
--- /dev/null
+++ b/BaseTools/Source/Python/FirmwareStorageFormat/UPLHeader.py
@@ -0,0 +1,244 @@
+## @file
+# This file is used to define the UPL Header C Struct.
+#
+# Copyright (c) 2023-, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+from struct import *
+from ctypes import *
+from FirmwareStorageFormat.Common import *
+
+EFI_COMMON_SECTION_HEADER_LEN = 4
+EFI_COMMON_SECTION_HEADER2_LEN = 8
+
+# ELF header.
+class ELF_HEADER32(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('ELF_Identification', ARRAY(c_char, 16)), # /* File identification. */
+ ('ELF_Type', c_uint16), # Elf32_Half /* File type. */
+ ('ELF_Machine', c_uint16), # Elf32_Half /* Machine architecture. */
+ ('ELF_Version', c_uint32), # Elf32_Word /* ELF format version. */
+ ('ELF_Entry', c_uint32), # Elf32_Addr /* Entry point. */
+ ('ELF_PHOff', c_uint32), # Elf32_Off /* Program header file offset. */
+ ('ELF_SHOff', c_uint32), # Elf32_Off /* Section header file offset. */
+ ('ELF_Flags', c_uint32), # Elf32_Word /* Architecture-specific flags. */
+ ('ELF_EFSize', c_uint16), # Elf32_Half /* Size of ELF header in bytes. */
+ ('ELF_PHEntSize', c_uint16), # Elf32_Half /* Size of program header entry. */
+ ('ELF_PHNum', c_uint16), # Elf32_Half /* Number of program header entries. */
+ ('ELF_SHEntSize', c_uint16), # Elf32_Half /* Size of section header entry. */
+ ('ELF_SHNum', c_uint16), # Elf32_Half /* Number of section header entries. */
+ ('ELF_SNStr', c_uint16), # Elf32_Half /* Section name strings section. */
+ ]
+
+class ELF_HEADER64(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('ELF_Identification', ARRAY(c_char, 16)), # /* File identification. */
+ ('ELF_Type', c_uint16), # Elf64_Half /* File type. */
+ ('ELF_Machine', c_uint16), # Elf64_Half /* Machine architecture. */
+ ('ELF_Version', c_uint32), # Elf64_Word /* ELF format version. */
+ ('ELF_Entry', c_uint64), # Elf64_Addr /* Entry point. */
+ ('ELF_PHOff', c_uint64), # Elf64_Off /* Program header file offset. */
+ ('ELF_SHOff', c_uint64), # Elf64_Off /* Section header file offset. */
+ ('ELF_Flags', c_uint32), # Elf64_Word /* Architecture-specific flags. */
+ ('ELF_EFSize', c_uint16), # Elf64_Half /* Size of ELF header in bytes. */
+ ('ELF_PHEntSize', c_uint16), # Elf64_Half /* Size of program header entry. */
+ ('ELF_PHNum', c_uint16), # Elf64_Half /* Number of program header entries. */
+ ('ELF_SHEntSize', c_uint16), # Elf64_Half /* Size of section header entry. */
+ ('ELF_SHNum', c_uint16), # Elf64_Half /* Number of section header entries. */
+ ('ELF_SNStr', c_uint16), # Elf64_Half /* Section name strings section. */
+ ]
+
+# Section header.
+class ELF_SECTION_HEADER32(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('SH_Name', c_uint32), # Elf32_Word /* Section name (index into the section header string table). */
+ ('SH_Type', c_uint32), # Elf32_Word /* Section type. */
+ ('SH_Flags', c_uint32), # Elf32_Word /* Section flags. */
+ ('SH_ADDR', c_uint32), # Elf32_Addr /* Address in memory image. */
+ ('SH_Offset', c_uint32), # Elf32_Off /* Offset in file. */
+ ('SH_Size', c_uint32), # Elf32_Word /* Size in bytes. */
+ ('SH_Link', c_uint32), # Elf32_Word /* Index of a related section. */
+ ('SH_Info', c_uint32), # Elf32_Word /* Depends on section type. */
+ ('SH_AddrAlign', c_uint32), # Elf32_Word /* Alignment in bytes. */
+ ('SH_EntSize', c_uint32), # Elf32_Word /* Size of each entry in section. */
+ ]
+
+class ELF_SECTION_HEADER64(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('SH_Name', c_uint32), # Elf32_Word /* Section name (index into the section header string table). */
+ ('SH_Type', c_uint32), # Elf32_Word /* Section type. */
+ ('SH_Flags', c_uint64), # Elf32_XWord /* Section flags. */
+ ('SH_ADDR', c_uint64), # Elf32_Addr /* Address in memory image. */
+ ('SH_Offset', c_uint64), # Elf32_Off /* Offset in file. */
+ ('SH_Size', c_uint64), # Elf32_XWord /* Size in bytes. */
+ ('SH_Link', c_uint32), # Elf32_Word /* Index of a related section. */
+ ('SH_Info', c_uint32), # Elf32_Word /* Depends on section type. */
+ ('SH_AddrAlign', c_uint64), # Elf32_XWord /* Alignment in bytes. */
+ ('SH_EntSize', c_uint64), # Elf32_XWord /* Size of each entry in section. */
+ ]
+
+# Program header.
+class ELF_PROGRAM_HEADER32(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('PH_Type', c_uint32), # Elf32_Word /* Entry type. */
+ ('PH_Offset', c_uint32), # Elf32_Off /* File offset of contents. */
+ ('PH_VirAddr', c_uint32), # Elf32_Addr /* Virtual address in memory image. */
+ ('PH_PhyAddr', c_uint32), # Elf32_Addr /* Physical address (not used). */
+ ('PH_FileSize', c_uint32), # Elf32_Word /* Size of contents in file. */
+ ('PH_MemorySize', c_uint32), # Elf32_Word /* Size of contents in memory. */
+ ('PH_Flags', c_uint32), # Elf32_Word /* Access permission flags. */
+ ('PH_Align', c_uint32), # Elf32_Word /* Alignment in memory and file. */
+ ]
+
+class ELF_PROGRAM_HEADER64(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('PH_Type', c_uint32), # Elf32_Word /* Entry type. */
+ ('PH_Flags', c_uint32), # Elf32_Word /* Access permission flags. */
+ ('PH_Offset', c_uint64), # Elf32_Off /* File offset of contents. */
+ ('PH_VirAddr', c_uint64), # Elf32_Addr /* Virtual address in memory image. */
+ ('PH_PhyAddr', c_uint64), # Elf32_Addr /* Physical address (not used). */
+ ('PH_FileSize', c_uint64), # Elf32_XWord /* Size of contents in file. */
+ ('PH_MemorySize', c_uint64), # Elf32_XWord /* Size of contents in memory. */
+ ('PH_Align', c_uint64), # Elf32_XWord /* Alignment in memory and file. */
+ ]
+
+# Dynamic union.
+class ELF_DYNAMIC_UNION(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('ELF_Dynamic_Val', c_uint32), # Elf32_Word /* Integer value. */
+ ('ELF_Dynamic_Ptr', c_uint32), # Elf32_Addr /* Address value. */
+ ]
+
+
+# Dynamic structure. The ".dynamic" section contains an array of them.
+class ELF_DYNAMIC_STRUCTURE(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('ELF_Dynamic_Tag', c_int32), # Elf32_Sword /* Entry type. */
+ ('ELF_Dynamic_Union', ELF_DYNAMIC_UNION), # Elf32_Off /* Section type. */
+ ]
+
+## Relocation entries.
+
+# /* Relocations that don't need an addend field. */
+class ELF_RELOCATION(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('ELF_ReOffset', c_uint32), # Elf32_Addr /* Location to be relocated. */
+ ('ELF_ReInfo', c_uint32), # Elf32_Word /* Relocation type and symbol index. */
+ ]
+
+# /* Relocations that need an addend field. */
+class ELF_RELOCATION(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('ELF_ReOffset', c_uint32), # Elf32_Addr /* Location to be relocated. */
+ ('ELF_ReInfo', c_uint32), # Elf32_Word /* Relocation type and symbol index. */
+ ('ELF_ReAddend', c_int32), # Elf32_SWord /* Addend. */
+ ]
+
+# Move Entry
+class ELF_MOVE(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('ELF_MValue', c_uint64), # Elf32_Lword /* symbol value */
+ ('ELF_MInfo', c_uint32), # Elf32_Word /* size + index */
+ ('ELF_MPOffset', c_int32), # Elf32_Word /* symbol offset */
+ ('ELF_MRepeat', c_uint16), # Elf32_Half /* repeat count */
+ ('ELF_MStride', c_uint16), # Elf32_Half /* stride info */
+ ]
+
+## Hardware/Software capabilities entry
+class ELF_CAPA_UNION(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('ELF_Capa_Val', c_uint32), # Elf32_Word /* Integer value. */
+ ('ELF_Capa_Ptr', c_uint32), # Elf32_Addr /* Address value. */
+ ]
+
+class ELF_CAPABILITY(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('ELF_Capa_Tag', c_uint32), # Elf32_Word /* how to interpret value */
+ ('ELF_Capa_Union', ELF_CAPA_UNION), # ELF_CAPA_UNION
+ ]
+
+# Symbol table entries.
+class ELF_SYMBOL(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('ELF_ST_Name', c_uint32), # Elf32_Word /* String table index of name. */
+ ('ELF_ST_Value', c_uint32), # Elf32_Addr /* Symbol value. */
+ ('ELF_ST_Size', c_uint32), # Elf32_Word /* Size of associated object. */
+ ('ELF_ST_Info', c_char), # /* Type and binding information. */
+ ('ELF_ST_Other', c_char), # /* Reserved (not used). */
+ ('ELF_ST_Shndx', c_uint16), # Elf32_Half /* Section index of symbol. */
+ ]
+
+# Structures used by Sun & GNU symbol versioning.
+class ELF_VERDEF(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('ELF_VD_Version', c_uint16), # Elf32_Half
+ ('ELF_VD_Flags', c_uint16), # Elf32_Half
+ ('ELF_VD_Ndx', c_uint16), # Elf32_Half
+ ('ELF_VD_Cnt', c_uint16), # Elf32_Half
+ ('ELF_VD_Hash', c_uint32), # Elf32_Word
+ ('ELF_VD_Aux', c_uint32), # Elf32_Word
+ ('ELF_VD_Next', c_uint32), # Elf32_Word
+ ]
+
+class ELF_VERDAUX(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('ELF_VDA_Name', c_uint32), # Elf32_Word
+ ('ELF_VDA_Next', c_uint32), # Elf32_Word
+ ]
+
+class ELF_VERNEED(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('ELF_VN_Version', c_uint16), # Elf32_Half
+ ('ELF_VN_Cnt', c_uint16), # Elf32_Half
+ ('ELF_VN_File', c_uint32), # Elf32_Word
+ ('ELF_VN_Aux', c_uint32), # Elf32_Word
+ ('ELF_VN_Next', c_uint32), # Elf32_Word
+ ]
+
+class ELF_VERNAUX(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('ELF_VNA_Hash', c_uint32), # Elf32_Word
+ ('ELF_VNA_Flags', c_uint16), # Elf32_Half
+ ('ELF_VNA_Other', c_uint16), # Elf32_Half
+ ('ELF_VNA_Name', c_uint32), # Elf32_Word
+ ('ELF_VNA_Next', c_uint32), # Elf32_Word
+ ]
+
+class ELF_SYMINFO(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('ELF_SI_BoundTo', c_uint16), # Elf32_Half /* direct bindings - symbol bound to */
+ ('ELF_SI_Flags', c_uint16), # Elf32_Half /* per symbol flags */
+ ]
+
+class UNIVERSAL_PAYLOAD_INFO(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ('Identifier', c_uint32), # ?PLDH? Identifier for the unverial payload info. 0x504c4448
+ ('HeaderLength', c_uint32), # Length of the structure in bytes.
+ ('SpecRevision', c_uint16), # Indicates compliance with a revision of this specification in the BCD format. 7 : 0 - Minor Version / 15 : 8 - Major Version For revision v0.75 the value will be 0x0075.
+ ('Reserved', c_uint16), # Reserved for future use.
+ ('Revision', c_uint32), # Revision of the Payload binary. Major.Minor .Revision.Build . The ImageRevision can be decoded as follows: 7 : 0 - Build Number / 15 :8 - Revision / 23 :16 - Minor Version / 31 :24 - Major Version
+ ('Attribute', c_uint32), # Length of the structure in bytes.
+ ('Capability', c_uint32), # Length of the structure in bytes.
+ ('ProducerId', ARRAY(c_uint8, 16)), # Length of the structure in bytes.
+ ('ImageId', ARRAY(c_uint8, 16)), # Length of the structure in bytes.
+ ]