From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mx.groups.io with SMTP id smtpd.web10.36349.1675067066549700999 for ; Mon, 30 Jan 2023 00:24:26 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=dbPy/rSV; spf=pass (domain: intel.com, ip: 192.55.52.120, mailfrom: yuwei.chen@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1675067066; x=1706603066; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=0gddIdBJOpjpED8KrNrjsZqxtBi7Q1/rITp8yuJtknI=; b=dbPy/rSVV/+8Tan6JwdOKpxXXSnNUXZYttHurHeqLInEtuGbv2znUKX7 rtzEkVj0CmS5knU3jDX1U817+m7oNLgcNrQz2ncl4nZVHXb3aaQ6b4gwt M2HC216GXqJ6yVTx75Q3wUBRV5T/QdEcGgCMjOD434hpYrBHJCDMqHQsq zPpQHZJAldJcWyy7zOew2gg2ko3nxpxIDd77p1o7wc1l19rLMB+KTWDYY prLHu4ibDhFW3EIoHUk0E+W/0f05ZF7Zwft6Xm0W0N+7QafWTkPVAj+zO 4W/UC9yfV1plJvvgpgexR9IZbSNp6xV8fknxOveZo8unmD2yWE/E9kOLZ g==; X-IronPort-AV: E=McAfee;i="6500,9779,10605"; a="326170685" X-IronPort-AV: E=Sophos;i="5.97,257,1669104000"; d="scan'208";a="326170685" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Jan 2023 00:24:24 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10605"; a="752729579" X-IronPort-AV: E=Sophos;i="5.97,257,1669104000"; d="scan'208";a="752729579" Received: from yuweipc.ccr.corp.intel.com ([10.239.158.38]) by FMSMGA003.fm.intel.com with ESMTP; 30 Jan 2023 00:24:22 -0800 From: "Yuwei Chen" To: devel@edk2.groups.io Cc: Bob Feng , Liming Gao Subject: [Patch V1 2/2] BaseTools: FMMT support ELF UPLD parser Date: Mon, 30 Jan 2023 16:24:20 +0800 Message-Id: <20230130082420.1643-1-yuwei.chen@intel.com> X-Mailer: git-send-email 2.27.0.windows.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable 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: Bob Feng Cc: Liming Gao Signed-off-by: Yuwei Chen --- edk2basetools/FMMT/FMMT.py | 2 ++ edk2basetools/FMMT/core/BinaryFactoryProduct.py | 36 +++++++++++++++++++= ++++++++++++++++- edk2basetools/FMMT/core/BiosTree.py | 49 +++++++++++++++++++= ++++++++++++++++++++++++++++-- edk2basetools/FMMT/core/BiosTreeNode.py | 56 +++++++++++++++++++= ++++++++++++++++++++++++++++++++++++- edk2basetools/FMMT/core/FMMTParser.py | 2 +- edk2basetools/FirmwareStorageFormat/UPLHeader.py | 244 +++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 384 insertions(+), 5 deletions(-) diff --git a/edk2basetools/FMMT/FMMT.py b/edk2basetools/FMMT/FMMT.py index 5f2c8eb9f3..29aec65f35 100644 --- a/edk2basetools/FMMT/FMMT.py +++ b/edk2basetools/FMMT/FMMT.py @@ -84,6 +84,8 @@ def View(self, inputfile: str, layoutfilename: str=3DNone= , outputfile: str=3DNone) - ROOT_TYPE =3D ROOT_FFS_TREE elif filetype =3D=3D '.sec': ROOT_TYPE =3D ROOT_SECTION_TREE + elif filetype =3D=3D '.elf': + ROOT_TYPE =3D ROOT_ELF_TREE else: ROOT_TYPE =3D ROOT_TREE ViewFile(inputfile, ROOT_TYPE, layoutfilename, outputfile) diff --git a/edk2basetools/FMMT/core/BinaryFactoryProduct.py b/edk2basetool= s/FMMT/core/BinaryFactoryProduct.py index ecae1ca94a..dde1f3b64e 100644 --- a/edk2basetools/FMMT/core/BinaryFactoryProduct.py +++ b/edk2basetools/FMMT/core/BinaryFactoryProduct.py @@ -15,10 +15,13 @@ from utils.FmmtLogger import FmmtLogger as logger =20 ROOT_TREE =3D 'ROOT' +ROOT_ELF_TREE =3D 'ROOT_ELF_TREE' ROOT_FV_TREE =3D 'ROOT_FV_TREE' ROOT_FFS_TREE =3D 'ROOT_FFS_TREE' ROOT_SECTION_TREE =3D 'ROOT_SECTION_TREE' =20 +ELF_TREE =3D 'ELF' +ELF_SECTION_TREE =3D 'ELF_SECTION_TREE' FV_TREE =3D 'FV' DATA_FV_TREE =3D 'DATA_FV' FFS_TREE =3D 'FFS' @@ -73,6 +76,12 @@ class FdFactory(BinaryFactory): def Create_Product(): return FdProduct() =20 +class ElfFactory(BinaryFactory): + type =3D [ROOT_ELF_TREE, ELF_TREE] + + def Create_Product(): + return ElfProduct() + class SectionProduct(BinaryProduct): ## Decompress the compressed section. def ParserData(self, Section_Tree, whole_Data: bytes, Rel_Whole_Offset= : int=3D0) -> None: @@ -354,6 +363,30 @@ def GetFvFromFd(self, whole_data: bytes=3Db'') -> list: tmp_index +=3D 1 return Fd_Struct =20 +class ElfSectionProduct(BinaryProduct): + ## Decompress the compressed section. + def ParserData(self, Section_Tree, whole_Data: bytes, Rel_Whole_Offset= : int=3D0) -> None: + pass + def ParserSectionData(self, Section_Tree, whole_Data: bytes, Rel_Whole= _Offset: int=3D0) -> None: + pass + def ParserProgramData(self, Section_Tree, whole_Data: bytes, Rel_Whole= _Offset: int=3D0) -> None: + pass + +class ElfProduct(BinaryProduct): + + def ParserData(self, ParTree, Whole_Data: bytes, Rel_Whole_Offset: int= =3D0) -> None: + Elf_Info =3D ElfNode(Whole_Data) + if Elf_Info.Header.ELF_PHOff !=3D 0: + Elf_Info.GetProgramList(Whole_Data[Elf_Info.Header.ELF_PHOff:]) + if Elf_Info.Header.ELF_SHOff !=3D 0: + Elf_Info.GetSectionList(Whole_Data[Elf_Info.Header.ELF_SHOff:]) + Elf_Info.FindUPLDSection(Whole_Data) + Elf_Tree =3D BIOSTREE(Elf_Info.Name) + Elf_Tree.type =3D ELF_TREE + Elf_Info.Data =3D Whole_Data[Elf_Info.HeaderLength:] + Elf_Tree.Data =3D Elf_Info + ParTree.insertChild(Elf_Tree) + class ParserEntry(): FactoryTable:dict =3D { SECTION_TREE: SectionFactory, @@ -364,6 +397,7 @@ class ParserEntry(): SEC_FV_TREE: FvFactory, ROOT_FV_TREE: FdFactory, ROOT_TREE: FdFactory, + ROOT_ELF_TREE: ElfFactory, } =20 def GetTargetFactory(self, Tree_type: str) -> BinaryFactory: @@ -377,4 +411,4 @@ def Generate_Product(self, TargetFactory: BinaryFactory= , Tree, Data: bytes, Offs def DataParser(self, Tree, Data: bytes, Offset: int) -> None: TargetFactory =3D self.GetTargetFactory(Tree.type) if TargetFactory: - self.Generate_Product(TargetFactory, Tree, Data, Offset)=0D \ No newline at end of file + self.Generate_Product(TargetFactory, Tree, Data, Offset) diff --git a/edk2basetools/FMMT/core/BiosTree.py b/edk2basetools/FMMT/core/= BiosTree.py index 14fb007b14..bed9533cb1 100644 --- a/edk2basetools/FMMT/core/BiosTree.py +++ b/edk2basetools/FMMT/core/BiosTree.py @@ -12,6 +12,7 @@ ROOT_FV_TREE =3D 'ROOT_FV_TREE' ROOT_FFS_TREE =3D 'ROOT_FFS_TREE' ROOT_SECTION_TREE =3D 'ROOT_SECTION_TREE' +ROOT_ELF_TREE =3D 'ROOT_ELF_TREE' =20 FV_TREE =3D 'FV' DATA_FV_TREE =3D 'DATA_FV' @@ -21,11 +22,13 @@ SECTION_TREE =3D 'SECTION' SEC_FV_TREE =3D 'SEC_FV_IMAGE' BINARY_DATA =3D 'BINARY' +ELF_TREE =3D 'ELF' =20 RootType =3D [ROOT_TREE, ROOT_FV_TREE, ROOT_FFS_TREE, ROOT_SECTION_TREE] FvType =3D [FV_TREE, SEC_FV_TREE] FfsType =3D FFS_TREE SecType =3D SECTION_TREE +ElfType =3D [ROOT_ELF_TREE, ELF_TREE] =20 class BIOSTREE: def __init__(self, NodeName: str) -> None: @@ -118,6 +121,32 @@ def parserTree(self, TargetDict: dict=3DNone, Info: li= st=3DNone, space: int=3D0, ParFv Info.append("Image File: {}".format(Key)) Info.append("FilesNum: {}".format(TargetDict.get(Key).get('Fil= esNum'))) Info.append("\n") + elif TargetDict[Key]["Type"] =3D=3D ROOT_ELF_TREE: + Info.append("ELF File: {}\n".format(Key)) + elif TargetDict[Key]["Type"] =3D=3D ELF_TREE: + ProducerId =3D "" + ImageId =3D "" + if TargetDict.get(Key).get('IfExist'): + Identifier =3D TargetDict.get(Key).get('Identifier') + for item in TargetDict.get(Key).get('ProducerId'): + ProducerId +=3D chr(item) + for item in TargetDict.get(Key).get('ImageId'): + ImageId +=3D 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 / 0x= 444c5055--UPLD".format(hex(Identifier))) + Info.append(" - SpecRevision: {}".format(hex(TargetDict= .get(Key).get('SpecRevision')))) + Info.append(" - Attribute: {}".format(hex(TargetDict.ge= t(Key).get('Attribute')))) + Info.append(" - Revision: {}".format(hex(TargetDict.get= (Key).get('Revision')))) + Info.append(" - Capability: {}".format(hex(TargetDict.g= et(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 +=3D 2 if TargetDict[Key]["Type"] =3D=3D SEC_FV_TREE: @@ -146,13 +175,29 @@ def ExportTree(self,TreeInfo: dict=3DNone) -> dict: if TreeInfo is None: TreeInfo =3Dcollections.OrderedDict() =20 - if self.type =3D=3D ROOT_TREE or self.type =3D=3D ROOT_FV_TREE or = self.type =3D=3D ROOT_FFS_TREE or self.type =3D=3D ROOT_SECTION_TREE: + if self.type =3D=3D ROOT_TREE or self.type =3D=3D ROOT_FV_TREE or = self.type =3D=3D ROOT_FFS_TREE or self.type =3D=3D ROOT_SECTION_TREE or sel= f.type =3D=3D ROOT_ELF_TREE: key =3D str(self.key) TreeInfo[self.key] =3D collections.OrderedDict() TreeInfo[self.key]["Name"] =3D key TreeInfo[self.key]["Type"] =3D self.type TreeInfo[self.key]["FilesNum"] =3D len(self.Child) - elif self.type =3D=3D FV_TREE or self.type =3D=3D SEC_FV_TREE: + elif self.type =3D=3D ELF_TREE: + key =3D str(self.Data.Name) + TreeInfo[key] =3D collections.OrderedDict() + TreeInfo[key]["Name"] =3D key + TreeInfo[key]["Type"] =3D self.type + TreeInfo[key]["IfExist"] =3D self.Data.UpldInfo + if self.Data.UpldInfo: + TreeInfo[key]["Identifier"] =3D self.Data.UpldInfo.Identif= ier + TreeInfo[key]["SpecRevision"] =3D self.Data.UpldInfo.SpecR= evision + TreeInfo[key]["Attribute"] =3D self.Data.UpldInfo.Attribute + TreeInfo[key]["Revision"] =3D self.Data.UpldInfo.Revision + TreeInfo[key]["Capability"] =3D self.Data.UpldInfo.Capabil= ity + TreeInfo[key]["ProducerId"] =3D self.Data.UpldInfo.Produce= rId + TreeInfo[key]["ImageId"] =3D self.Data.UpldInfo.ImageId + TreeInfo[key]["Upld_Info_Align"] =3D self.Data.Upld_Info_A= lign + TreeInfo[key]["Upld_Buffer"] =3D self.Data.UpldBuffer + elif self.type =3D=3D FV_TREE or self.type =3D=3D SEC_FV_TREE: key =3D str(self.Data.FvId) TreeInfo[key] =3D collections.OrderedDict() TreeInfo[key]["Name"] =3D key diff --git a/edk2basetools/FMMT/core/BiosTreeNode.py b/edk2basetools/FMMT/c= ore/BiosTreeNode.py index 670c7d799c..ba6a027c40 100644 --- a/edk2basetools/FMMT/core/BiosTreeNode.py +++ b/edk2basetools/FMMT/core/BiosTreeNode.py @@ -4,6 +4,7 @@ # Copyright (c) 2021-, Intel Corporation. All rights reserved.
# 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 @@ def __init__(self, name: str) -> None: self.HOffset =3D 0 self.Data =3D b'' =20 +class ElfNode: + def __init__(self, buffer: bytes) -> None: + self.Header =3D ELF_HEADER32.from_buffer_copy(buffer) + if self.Header.ELF_Identification[0:4] !=3D b'\x7fELF': + logger.error('Invalid Elf Header! Elf Identification {} is not= ".ELF".'.format(self.Header.ELF_Identification)) + raise Exception("Process Failed: Invalid ELF Header Identifica= tion!") + self.Class =3D self.Header.ELF_Identification[4] + if self.Class =3D=3D 0x02: + self.Header =3D ELF_HEADER64.from_buffer_copy(buffer) + elif self.Class !=3D 0x01: + logger.error('Invalid Elf Class! Elf Class {} is not 0x01 or 0= x02.'.format(self.Class)) + raise Exception("Process Failed: Invalid ELF Class!") + + self.ProList =3D [] + self.SecList =3D [] + self.UpldInfoSection =3D None + self.UpldInfo =3D None + self.UpldBuffer =3D b'' + self.Name =3D "ELF" + self.HeaderLength =3D len(struct2stream(self.Header)) + self.HOffset =3D 0 + self.DOffset =3D 0 + self.ROffset =3D 0 + self.Data =3D b'' + self.PadData =3D b'' + self.Upld_Info_Align =3D False + + def GetProgramList(self, buffer: bytes) -> None: + for i in range(self.Header.ELF_PHNum): + if self.Class =3D=3D 0x01: + ElfProgramHeader =3D ELF_PROGRAM_HEADER32.from_buffer_copy= (buffer[i*self.Header.ELF_PHEntSize:]) + elif self.Class =3D=3D 0x02: + ElfProgramHeader =3D 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 =3D=3D 0x01: + ElfSectionHeader =3D ELF_SECTION_HEADER32.from_buffer_copy= (buffer[i*self.Header.ELF_SHEntSize:]) + elif self.Class =3D=3D 0x02: + ElfSectionHeader =3D 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] =3D=3D b'PLDH' or b= uffer[item.SH_Offset:item.SH_Offset+4] =3D=3D b'UPLD': + self.UpldInfoSection =3D item + self.UpldInfo =3D UNIVERSAL_PAYLOAD_INFO.from_buffer_copy(= buffer[item.SH_Offset:item.SH_Offset+item.SH_Size]) + self.UpldBuffer =3D struct2stream(self.UpldInfo) + if (self.UpldInfoSection.SH_Offset) % 4 =3D=3D 0: + # if (self.UpldInfoSection.SH_Offset - self.Header.ELF_Ent= ry) % 4 =3D=3D 0: + self.Upld_Info_Align =3D True + class FvNode: def __init__(self, name, buffer: bytes) -> None: self.Header =3D EFI_FIRMWARE_VOLUME_HEADER.from_buffer_copy(buffer) @@ -191,4 +245,4 @@ def __init__(self, buffer: bytes) -> None: self.HOffset =3D 0 self.DOffset =3D 0 self.ROffset =3D 0 - self.PadData =3D b''=0D \ No newline at end of file + self.PadData =3D b'' diff --git a/edk2basetools/FMMT/core/FMMTParser.py b/edk2basetools/FMMT/cor= e/FMMTParser.py index dd71cf3fdc..18de96c08e 100644 --- a/edk2basetools/FMMT/core/FMMTParser.py +++ b/edk2basetools/FMMT/core/FMMTParser.py @@ -20,7 +20,7 @@ def __init__(self, name: str, TYPE: str) -> None: =20 ## Parser the nodes in WholeTree. def ParserFromRoot(self, WholeFvTree=3DNone, whole_data: bytes=3Db'', = Reloffset: int=3D0) -> None: - if WholeFvTree.type =3D=3D ROOT_TREE or WholeFvTree.type =3D=3D RO= OT_FV_TREE: + if WholeFvTree.type =3D=3D ROOT_TREE or WholeFvTree.type =3D=3D RO= OT_FV_TREE or WholeFvTree.type =3D=3D ROOT_ELF_TREE: ParserEntry().DataParser(self.WholeFvTree, whole_data, Reloffs= et) else: ParserEntry().DataParser(WholeFvTree, whole_data, Reloffset) diff --git a/edk2basetools/FirmwareStorageFormat/UPLHeader.py b/edk2basetoo= ls/FirmwareStorageFormat/UPLHeader.py new file mode 100644 index 0000000000..06e73a114a --- /dev/null +++ b/edk2basetools/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.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## +from struct import * +from ctypes import * +from FirmwareStorageFormat.Common import * + +EFI_COMMON_SECTION_HEADER_LEN =3D 4 +EFI_COMMON_SECTION_HEADER2_LEN =3D 8 + +# ELF header. +class ELF_HEADER32(Structure): + _pack_ =3D 1 + _fields_ =3D [ + ('ELF_Identification', ARRAY(c_char, 16)), # /* File ident= ification. */ + ('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_ =3D 1 + _fields_ =3D [ + ('ELF_Identification', ARRAY(c_char, 16)), # /* File ident= ification. */ + ('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_ =3D 1 + _fields_ =3D [ + ('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_ =3D 1 + _fields_ =3D [ + ('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_ =3D 1 + _fields_ =3D [ + ('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_ =3D 1 + _fields_ =3D [ + ('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_ =3D 1 + _fields_ =3D [ + ('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_ =3D 1 + _fields_ =3D [ + ('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_ =3D 1 + _fields_ =3D [ + ('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_ =3D 1 + _fields_ =3D [ + ('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_ =3D 1 + _fields_ =3D [ + ('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_ =3D 1 + _fields_ =3D [ + ('ELF_Capa_Val', c_uint32), # Elf32_Word = /* Integer value. */ + ('ELF_Capa_Ptr', c_uint32), # Elf32_Addr = /* Address value. */ + ] + +class ELF_CAPABILITY(Structure): + _pack_ =3D 1 + _fields_ =3D [ + ('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_ =3D 1 + _fields_ =3D [ + ('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 b= inding 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_ =3D 1 + _fields_ =3D [ + ('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_ =3D 1 + _fields_ =3D [ + ('ELF_VDA_Name', c_uint32), # Elf32_Word + ('ELF_VDA_Next', c_uint32), # Elf32_Word + ] + +class ELF_VERNEED(Structure): + _pack_ =3D 1 + _fields_ =3D [ + ('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_ =3D 1 + _fields_ =3D [ + ('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_ =3D 1 + _fields_ =3D [ + ('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_ =3D 1 + _fields_ =3D [ + ('Identifier', c_uint32), # =E2=80=98PLDH= =E2=80=99 Identifier for the unverial payload info. 0x504c4448 + ('HeaderLength', c_uint32), # Length of the= structure in bytes. + ('SpecRevision', c_uint16), # Indicates com= pliance with a revision of this specification in the BCD format. 7 : 0 - Mi= nor Version / 15 : 8 - Major Version For revision v0.75 the value will be 0= x0075. + ('Reserved', c_uint16), # Reserved for = future use. + ('Revision', c_uint32), # Revision of t= he Payload binary. Major.Minor .Revision.Build . The ImageRevision can be d= ecoded as follows: 7 : 0 - Build Number / 15 :8 - Revision / 23 :16 - Min= or 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. + ] --=20 2.27.0.windows.1