From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mx.groups.io with SMTP id smtpd.web10.2358.1682493461906983700 for ; Wed, 26 Apr 2023 00:17:42 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=INY40nRr; spf=pass (domain: intel.com, ip: 134.134.136.100, mailfrom: gua.guo@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1682493461; x=1714029461; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=43qtjbIdL4kGZ4toLEhk05xq83wSQIsqssxqH3F2MDY=; b=INY40nRrk7+QwThctSFEXnT0jseQQ6j1MK11E/DTaukrR+bp7sIKCZu2 D61y/RF1AkbeUYyPEPJ0jrW29kZpM4+5Sj3KCLn35+r28346UOASMegRL M6qKeQjWneQUnqNVBRvm1bRblNXuwYF1g7wLXIl1lVpgajQnpLpNAX9NB 46bA+l0Ki2+NPpHe5FOL53CdVjFA18xxFHDJL4K9PKnye8V3QrFh2MLzl 8etS0fmQGIiyUA18fjDHi2pO8z7dbYgUy4QrauJ+8MwYJkt5baiFcSWCU L3vZ5wu59IblURazyfZEAb6nnFYTxmufULxf5ciAdvGCKSQCcwssQ1zAu A==; X-IronPort-AV: E=McAfee;i="6600,9927,10691"; a="412330671" X-IronPort-AV: E=Sophos;i="5.99,227,1677571200"; d="scan'208";a="412330671" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Apr 2023 00:17:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10691"; a="837785020" X-IronPort-AV: E=Sophos;i="5.99,227,1677571200"; d="scan'208";a="837785020" Received: from fmsmsx603.amr.corp.intel.com ([10.18.126.83]) by fmsmga001.fm.intel.com with ESMTP; 26 Apr 2023 00:17:40 -0700 Received: from fmsmsx610.amr.corp.intel.com (10.18.126.90) by fmsmsx603.amr.corp.intel.com (10.18.126.83) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.23; Wed, 26 Apr 2023 00:17:40 -0700 Received: from fmsmsx610.amr.corp.intel.com (10.18.126.90) by fmsmsx610.amr.corp.intel.com (10.18.126.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.23; Wed, 26 Apr 2023 00:17:39 -0700 Received: from fmsedg602.ED.cps.intel.com (10.1.192.136) by fmsmsx610.amr.corp.intel.com (10.18.126.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.23 via Frontend Transport; Wed, 26 Apr 2023 00:17:39 -0700 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (104.47.59.173) by edgegateway.intel.com (192.55.55.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.23; Wed, 26 Apr 2023 00:17:38 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=mDfXQnQL/MoMRlvAMf22z9LMMUZbM3xt7hfU+cbDkhjLwIvv/rwQOUJiWUTTtXcA32ZDUErY+ShRCvsJ3kV7GLBXLVLSVaOLQOwW8X6WsMV4e+gh794UOyX5ES74d5jJCxYNvNX4RtF3hhnDLPDS3QBDYvbB1GEHpEAUCBzxkVR9Ci3QIWKxK+UES8mJEm0Io9YsU8YQxHASsw4rFPoP2q3ILu6QWR/DflKJJ9k+hvxWI6N527+DlmLN6ojYCcRbL8GA/OR7dZrWWqMNbCLGQR7AMtYAUXLmX+cAQUZBAmc9Rm2tkvqsQe74CNTTiDLg9M+Sj5C1iN6nNdi5ls2Gvw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=QBRZxQaywf9DFR4+Bgomsg5CA1DzuLM9di20OgmDqrU=; b=g4ufOh+3mEvHiVoCUF5z2WK1URfkNBT4QvHR0ks+Ujh2WfsXji7CFAEPHwA7pcXyM4hgLVDzeaZ0z5aeie+aktOaP8+7UvVhsxxuiHJUO3Ff8ZK+DZuA9iuBpGY+VvTwA4fas27s+zkbDqujf936g56nBAyLxkBCQMifCLxVZizBtfOu0qxud4O3PWDtSxa3iyzLJ03ttAXwD4eoeG+kps2cJofj9durH29q85zT/sRAnF1smAijHe+QmZXFJWNLCR9Kp2qcCiaQLmVqJhmqk069J3Lkpk5hqaVA8QT/YVUD3YTiFbHwNn+794so2PTgneFy9F/mQmanGL+7rJglTA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Received: from BL1PR11MB5478.namprd11.prod.outlook.com (2603:10b6:208:31d::12) by MW4PR11MB6886.namprd11.prod.outlook.com (2603:10b6:303:224::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6319.32; Wed, 26 Apr 2023 07:17:30 +0000 Received: from BL1PR11MB5478.namprd11.prod.outlook.com ([fe80::c7e7:7b20:9a8b:aa59]) by BL1PR11MB5478.namprd11.prod.outlook.com ([fe80::c7e7:7b20:9a8b:aa59%5]) with mapi id 15.20.6319.034; Wed, 26 Apr 2023 07:17:30 +0000 From: "Guo, Gua" To: "Wang, BruceX" , "devel@edk2.groups.io" CC: "Dong, Guo" , "Ni, Ray" , "Rhodes, Sean" , "Lu, James" Subject: Re: [PATCH] * UefiPayloadPkg: Clang dependency removal Thread-Topic: [PATCH] * UefiPayloadPkg: Clang dependency removal Thread-Index: AQHZeA5lDkht/VPTg0qJD+E6O/je5K89LfAA Date: Wed, 26 Apr 2023 07:17:29 +0000 Message-ID: References: <0b1c996e78cddfa3a272187bd783f0c8b8e33492.1682492500.git.brucex.wang@intel.com> In-Reply-To: <0b1c996e78cddfa3a272187bd783f0c8b8e33492.1682492500.git.brucex.wang@intel.com> Accept-Language: en-US X-Mentions: brucex.wang@intel.com X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: BL1PR11MB5478:EE_|MW4PR11MB6886:EE_ x-ms-office365-filtering-correlation-id: 0d905ef3-3b32-4fca-0c26-08db46264bd3 x-ld-processed: 46c98d88-e344-4ed4-8496-4ed7712e255d,ExtAddr x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: akOSS/lrhv/AV61i43TufmmvBMfN7qAyYaTbRsF92w9TIAjDfqxLGdMqkXmsL7b/c28y40UpQWV4RE/Hbq2nBZTj3c7jZvj52tQDg5ak3wRM4cYXZm22oQGV9vToiz12FB9kdWJaIlceLl2rzY3Fg+T52LaB7X3uqKpQMOWJdfqU5kyoenDH2HMSkLOf/XSNdEoZfbeBtDjclyJ3nuDv7fZz8jca7MnsxbejuJomANY6SUsiJGs0fUrYzuWF//m7Fk5WX8HPxeo0dP1ktXL/5dsVaL0E3r4mjTVSdtxJzeK0pfdqiWrNaTJDQzlhf4o93kwOXvcEE9kla/LZ78Niu4O224iWz4fiAKpNCNmTedfJaCe7m48GQiq/OdsFfbzLC3X0jHGrEJ5fr22/NY8X3oDgpuB+QhvhdmEZGW4mN5EeaemEAW8JrBaNECXzPjM2Pv+F0BnKm9FeOKdG0DAHRCkVw1044RxB/E1CvG6RhsC9jBXlyHdaPDXeSJdhq6e+9yIe03EubSJnBhbKp8HwU93XAEEGnWaN26Q8ExqbXBAu7/CeskhS7sXIYp4CWSh9xIttOuvBwXj8B4vW9N4jdOCKLXaTH4BknGjXFsyoUllVbay+Lf4qIgT0vx4XhD27 x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BL1PR11MB5478.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230028)(346002)(39860400002)(136003)(396003)(366004)(376002)(451199021)(186003)(2906002)(30864003)(9686003)(41300700001)(110136005)(6506007)(53546011)(26005)(38070700005)(107886003)(83380400001)(86362001)(33656002)(54906003)(71200400001)(966005)(52536014)(7696005)(66556008)(8676002)(8936002)(5660300002)(82960400001)(316002)(122000001)(478600001)(19627235002)(38100700002)(55016003)(76116006)(66946007)(66476007)(4326008)(66446008)(64756008)(21314003)(579004)(559001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?0zixvuZFUlYUdYl0vSegrObuXL3OpBn0fS4QbFCvVXPpqIqZ/pkKA0tl+D1n?= =?us-ascii?Q?Umwubf8Uy8j163uXDjPfI8PZTwGZ/3CsbQ7MnqZgw1gNqolodg/baXNqcFWi?= =?us-ascii?Q?YXa+wnk5OBqhkYhnQ95DTLTojp2FyGbX0xxY38UTneAEPH+YREDnZNZ5qS3p?= =?us-ascii?Q?iHHVLros030RSJ+UjaAPskQYbxV97cWPUmcCEqxjEJI9YWzsVdbURj8DTnXx?= =?us-ascii?Q?kFoUmTpAAxzUHQgI3lF9TX/4TJwGkI+kb3rTLlDQ9jwLdcd6PE9fo3P4/yun?= =?us-ascii?Q?9eIlOz4zg424W5GEALo13Kv3fEVScokducp/cHzRjJuN03HLrFaopcIdcWhm?= =?us-ascii?Q?7eHvLWvL7xcG37CqTJGHubzgFr/doCUMg229yG1TCDeTCUldac7AElW1+5kK?= =?us-ascii?Q?FGiCMJwDzjgYSYBfT7Y/YcOz8P6xcSkbjemdLymBlL7KkvTcKBfnXMQdupqU?= =?us-ascii?Q?GwVq7Ygyj+q5UQbbF7DbhyzD1lzq+2rMtGBLORYNAQlcoDSWivJRSRVLbsHJ?= =?us-ascii?Q?tZncIVamNPzN29JKM78p1yKndosrFBHAA0CzVpJOqp7bxdWBosDjPWDlQW2V?= =?us-ascii?Q?72plMLFfl4bak/LpSe3Rn1Z5gdpojE0jyTeRfpGJZ3UtODyozIJPisKARVw7?= =?us-ascii?Q?/x/cfrdFBkWrgxRmH+jLz4z3baHj4IBk5A1OOoURK53ONhPPgvYL88Ve4yiv?= =?us-ascii?Q?I57X5fgMsjKw3I3m5CpVw4jNUl3xNwEru9LvlsopF3XW4E0Qw2sGo1kNgFMb?= =?us-ascii?Q?ZQUjANwKOXKIIpi2S7fE9lSUrNsywuJvhGK6r9T1uVt+4ZfT4IP3bEkcmS4z?= =?us-ascii?Q?8iejmMYvmA7a5HJQ1bFG/L6ZDUw20RUeK8drod0IgdyfQMHa08E/vp9Hk4Ts?= =?us-ascii?Q?jrXZfkq5wBfwxJwMxNtkH+bhHvG4l+eFpXHnY9ANU58GieA7aUp9BBJF45JF?= =?us-ascii?Q?AewyTxRd0vAGZeGA+fS+5wd7QoeQgCYsUDtCJ6AhwxieCABJIvtMl7W9Scbo?= =?us-ascii?Q?1PAJAF0jiOLWYWv4qjHbwV5mxfEjS6Zxw8/b5g+wXlo3qgibJbkKYDi3Z1mk?= =?us-ascii?Q?ntcVz7vLDqjnNzKX9GtCeAULosaKJFCkp2gWe+mIelf2mYXSmV6TNZ9+FQBk?= =?us-ascii?Q?JIWJgg3cECKehfRcwt0t0ms4bCd+oZWgLc819KxyrEpJ8754ZgowxsUFuvUq?= =?us-ascii?Q?hJltWDb0Mvnv1AnU9NZG4A2y0ZRYVHcM5XLbhsm7b1xcBQ+NfJFwTenHv/jx?= =?us-ascii?Q?TXASSyTr2EEXDXZ6gcw0UVkQkQZLjIxuaYXgZcaGpiCDS57CkePRo1WRkWcL?= =?us-ascii?Q?1wAK/KU9HeqLirKyKngPmvb9QKgPpsw1HG79DeuCBSIA0VhtybAQ+XI4+LS1?= =?us-ascii?Q?Rm5J+rpDy4j2hs67aDbrnN0Oqepaq3KBVJkiCp42SwS2sK4Q/MvCG82IjPBG?= =?us-ascii?Q?32D6tehoyZ49Gb0qrPDW9BGIQlJz8QF3x57iL8ANPMAWS+AMJexLCJsgw20C?= =?us-ascii?Q?nYSviAOD7WjmReZx7mTnYBMbreKMHjYYeiCIQWiBbKbBqoeB0FvSRFGD4xuZ?= =?us-ascii?Q?cqvBgBjSlV8KUCT1i/U=3D?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: BL1PR11MB5478.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0d905ef3-3b32-4fca-0c26-08db46264bd3 X-MS-Exchange-CrossTenant-originalarrivaltime: 26 Apr 2023 07:17:29.7824 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: crpY2NAEMi4hUQuF9HqencmwvvuHte4X6xKqpe22+pcmhc/tXlC5+4AyQna6gy8f8PMjjdkHPozas83m5zb3nQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW4PR11MB6886 Return-Path: gua.guo@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable @Wang, BruceX Bugzilla please fill this link https://bugzilla.tianocore.org/show_bug.cgi?= id=3D4426 Reviewed-by: Gua Guo -----Original Message----- From: Wang, BruceX =20 Sent: Wednesday, April 26, 2023 3:12 PM To: devel@edk2.groups.io Cc: Wang, BruceX ; Dong, Guo ; N= i, Ray ; Rhodes, Sean ; Lu, James = ; Guo, Gua Subject: [PATCH] * UefiPayloadPkg: Clang dependency removal From: BruceX Wang REF: TBD Use Python to replace llvm-objcopy in UniversalPayloadBuild.py. 1. AddSection32() and AddSection64(): Make a section named
with the contents of . 2. RemoveSection32() and RemoveSection64(): Remove
. 3. ReplaceFv (): remove the section before add the section if the file exists. Cc: Guo Dong Cc: Ray Ni Cc: Sean Rhodes Cc: James Lu Cc: Gua Guo Signed-off-by: BruceX Wang --- UefiPayloadPkg/Tools/ElfFv.py | 809 ++++++++++++++++++++++++ UefiPayloadPkg/Tools/__init__.py | 19 + UefiPayloadPkg/UniversalPayloadBuild.py | 232 ++++--- 3 files changed, 935 insertions(+), 125 deletions(-) create mode 100644 UefiPayloadPkg/Tools/ElfFv.py create mode 100644 UefiPayloadPkg/Tools/__init__.py diff --git a/UefiPayloadPkg/Tools/ElfFv.py b/UefiPayloadPkg/Tools/ElfFv.py new file mode 100644 index 0000000000..a3d5bf08b9 --- /dev/null +++ b/UefiPayloadPkg/Tools/ElfFv.py @@ -0,0 +1,809 @@ +## @file +# OBJCOPY parser, it's used to replace FV +# +# Copyright (c) 2023, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +import argparse +from ctypes import * +import struct + +class ElfSectionHeader64: + def __init__(self, sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_= size, sh_link, sh_info, sh_addralign, sh_entsize): + self.sh_name =3D sh_name + self.sh_type =3D sh_type + self.sh_flags =3D sh_flags + self.sh_addr =3D sh_addr + self.sh_offset =3D sh_offset + self.sh_size =3D sh_size + self.sh_link =3D sh_link + self.sh_info =3D sh_info + self.sh_addralign =3D sh_addralign + self.sh_entsize =3D sh_entsize + + def pack(self): + return struct.pack(' RemoveNameOffset): + unpacked_header.sh_name -=3D RemoveNameOffset + # Modify size of name string section entry in section entry. + if (Index =3D=3D StringIndexNumber): + unpacked_header.sh_size -=3D len (SectionName) + # added section + else : + if (Index =3D=3D StringIndexNumber): + unpacked_header.sh_size +=3D len (SectionName) + NewSHentry =3D ElfSectionHeader64 ( + unpacked_header.sh_name, + unpacked_header.sh_type, + unpacked_header.sh_flags, + unpacked_header.sh_addr, + unpacked_header.sh_offset, + unpacked_header.sh_size, + unpacked_header.sh_link, + unpacked_header.sh_info, + unpacked_header.sh_addralign, + unpacked_header.sh_entsize).pack() + return NewSHentry + +def AddSectionHeader32(SHentry, NewUPLEntrylen, SectionHeaderEntrySize, In= dex, RemoveNameOffset, SectionName, StringIndexNumber): + SHentry =3D bytearray(SHentry) + unpacked_header =3D ElfSectionHeader32.unpack(SHentry[(Index * Section= HeaderEntrySize):((Index * SectionHeaderEntrySize) + SectionHeaderEntrySize= )]) + if (Index !=3D 0): + NewSHentry =3D SHentry[(Index * SectionHeaderEntrySize):((Index * = SectionHeaderEntrySize) + SectionHeaderEntrySize)] + unpacked_header.sh_offset =3D NewUPLEntrylen + # Modify offset of name in section entry + # if RemoveNameOffset !=3D 0 that is remove function. + if (RemoveNameOffset !=3D 0): + if (unpacked_header.sh_name > RemoveNameOffset): + unpacked_header.sh_name -=3D RemoveNameOffset + # Modify size of name string section entry in section entry. + if (Index =3D=3D StringIndexNumber): + unpacked_header.sh_size -=3D len (SectionName) + # added section + else : + if (Index =3D=3D StringIndexNumber): + unpacked_header.sh_size +=3D len (SectionName) + NewSHentry =3D ElfSectionHeader32 ( + unpacked_header.sh_name, + unpacked_header.sh_type, + unpacked_header.sh_flags, + unpacked_header.sh_addr, + unpacked_header.sh_offset, + unpacked_header.sh_size, + unpacked_header.sh_link, + unpacked_header.sh_info, + unpacked_header.sh_addralign, + unpacked_header.sh_entsize).pack() + return NewSHentry + +def ModifyPHSegmentOffset64(NewUPLEntry, ElfHeaderOffset, PHSegmentName): + # Modify offset and address of program header tables. + elf_header =3D ElfHeader64(NewUPLEntry[:64]) + SHentry =3D NewUPLEntry[ElfHeaderOffset:] + # Elf program header tables start from 0x40 in 64-bits objects + PHentry =3D NewUPLEntry[64: 64 + (elf_header.e_phnum * elf_header.e_ph= entsize)] + PHdrs =3D [] + SHdrs =3D [] + for i in range(elf_header.e_shnum): + SHData =3D SHentry[(i * elf_header.e_shentsize): (i * elf_header.e= _shentsize) + elf_header.e_shentsize] + unpacked_SectionHeader =3D ElfSectionHeader64.unpack(SHData) + SHdrs.append(unpacked_SectionHeader) + for i in range(elf_header.e_phnum): + PHData =3D PHentry[(i * elf_header.e_phentsize): (i * elf_header.e= _phentsize) + elf_header.e_phentsize] + unpacked_ProgramHeader =3D Elf64_Phdr(PHData) + PHdrs.append(unpacked_ProgramHeader) + if (PHSegmentName =3D=3D '.text'): + PHdrs[0].p_offset =3D SHdrs[1].sh_offset + PHdrs[0].p_paddr =3D SHdrs[1].sh_addr + PHdrs[4].p_offset =3D SHdrs[1].sh_offset + PHdrs[4].p_paddr =3D SHdrs[1].sh_addr + elif (PHSegmentName =3D=3D '.dynamic'): + PHdrs[1].p_offset =3D SHdrs[2].sh_offset + PHdrs[1].p_paddr =3D SHdrs[2].sh_addr + PHdrs[3].p_offset =3D SHdrs[2].sh_offset + PHdrs[3].p_paddr =3D SHdrs[2].sh_addr + elif (PHSegmentName =3D=3D '.data'): + PHdrs[2].p_offset =3D SHdrs[3].sh_offset + PHdrs[2].p_paddr =3D SHdrs[3].sh_addr + packed_PHData =3D b'' + for phdr in PHdrs: + packed_PHData +=3D phdr.pack() + NewUPLEntry =3D bytearray(NewUPLEntry) + NewUPLEntry[64: 64 + (elf_header.e_phnum * elf_header.e_phentsize)] = =3D packed_PHData + return NewUPLEntry + +def ModifyPHSegmentOffset32(NewUPLEntry, ElfHeaderOffset, PHSegmentName): + # Modify offset and address of program header tables. + # Elf header is stored at 0x0-0x34 in 32-bits objects + elf_header =3D ElfHeader32(NewUPLEntry[:52]) + SHentry =3D NewUPLEntry[ElfHeaderOffset:] + # Elf program header tables start from 0x34 in 32-bits objects + PHentry =3D NewUPLEntry[52: 52 + (elf_header.e_phnum * elf_header.e_ph= entsize)] + PHdrs =3D [] + SHdrs =3D [] + for i in range(elf_header.e_shnum): + SHData =3D SHentry[(i * elf_header.e_shentsize): (i * elf_header.e= _shentsize) + elf_header.e_shentsize] + unpacked_SectionHeader =3D ElfSectionHeader32.unpack(SHData) + SHdrs.append(unpacked_SectionHeader) + for i in range(elf_header.e_phnum): + PHData =3D PHentry[(i * elf_header.e_phentsize): (i * elf_header.e= _phentsize) + elf_header.e_phentsize] + unpacked_ProgramHeader =3D Elf32_Phdr(PHData) + PHdrs.append(unpacked_ProgramHeader) + if (PHSegmentName =3D=3D '.text'): + PHdrs[0].p_offset =3D SHdrs[1].sh_offset + PHdrs[0].p_paddr =3D SHdrs[1].sh_addr + PHdrs[0].p_vaddr =3D SHdrs[1].sh_addr + PHdrs[2].p_offset =3D SHdrs[1].sh_offset + PHdrs[2].p_paddr =3D SHdrs[1].sh_addr + PHdrs[0].p_vaddr =3D SHdrs[1].sh_addr + elif (PHSegmentName =3D=3D '.data'): + PHdrs[1].p_offset =3D SHdrs[2].sh_offset + PHdrs[1].p_paddr =3D SHdrs[2].sh_addr + PHdrs[1].p_vaddr =3D SHdrs[2].sh_addr + packed_PHData =3D b'' + for phdr in PHdrs: + packed_PHData +=3D phdr.pack() + NewUPLEntry =3D bytearray(NewUPLEntry) + NewUPLEntry[52: 52 + (elf_header.e_phnum * elf_header.e_phentsize)] = =3D packed_PHData + return NewUPLEntry + +def RemoveSection64(UniversalPayloadEntry, RemoveSectionName): + # If elf is 64-bit objects. + # Get offsets as follows: + # 1. Section name which will remove in section na= me string. + # 2. Section which will remove. + # 3. Section header which will remove. + with open(UniversalPayloadEntry,'rb') as f: + UPLEntry =3D f.read() + RemoveSectionNameOffset, ElfHeaderOffset, SectionHeaderEntrySize, = SectionHeaderEntryNumber, _, StringIndexNumber, _ =3D FindSection(UPLEntry,= RemoveSectionName) + if (RemoveSectionNameOffset =3D=3D -1): + raise argparse.ArgumentTypeError ('Section: {} not found.'.for= mat (RemoveSectionNameOffset)) + # Read section header entry + SHentry =3D UPLEntry[ElfHeaderOffset:] + # find deleted fv section offset. + # Elf header is stored at 0x0-0x40 in 64-bits objects + elf_header =3D ElfHeader64(UPLEntry[:64]) + Counter =3D 0 + RemoveIndex =3D 0 + RemoveNameOffset =3D 0 + for Index in range(0, elf_header.e_shnum): + # Read Index of section header. + unpacked_SectionHeader =3D ElfSectionHeader64.unpack(SHentry[(= Index * elf_header.e_shentsize):((Index * elf_header.e_shentsize) + elf_hea= der.e_shentsize)]) + # Find offset of section name which is removed. + if (unpacked_SectionHeader.sh_name =3D=3D RemoveSectionNameOff= set): + RemoveIndex =3D Counter + Counter +=3D 1 + else: + Counter +=3D 1 + # Elf header is recombined. + # Elf header and program header table in front of first section ar= e reserved. + # Elf header size is 0x40 with 64-bit object. + ElfHeaderSize =3D 64 + ElfHandPH =3D ElfHeaderSize + (elf_header.e_phnum * elf_header.e_p= hentsize) + NewUPLEntry =3D UPLEntry[:ElfHandPH] + # Keep Section header and program header table, RemoveSection64() = only recombined section and section header. + NewUPLEntry =3D bytearray(NewUPLEntry) + # Sections is recombined. + # 1. name of deleted section is removed in name string section. + # 2. deleted section is removed in dll file. + # 3. re-align sections before and after deleted section. + NewUPLEntrylen =3D [] + for Index in range(0, (SectionHeaderEntryNumber)): + unpacked_SectionHeader =3D ElfSectionHeader64.unpack(SHentry[(= Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + Section= HeaderEntrySize)]) + NewUPLEntrylen.append(len(NewUPLEntry)) + if (Index =3D=3D 0): + # Address alignment, section will align with alignment of = next section. + AlignmentIndex =3D 8 + if (SectionHeaderEntryNumber > 2): + unpacked_NextSectionHeader =3D ElfSectionHeader64.unpac= k(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHea= derEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign) + # Section in front of removed section + elif (Index + 1 =3D=3D RemoveIndex): + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Read section address alignment + # If section that will be removed in .dll is not first and= last one . + # Address alignment, section will align with alignment of = section after deleted section. + # Check next and the section after next are not end of sec= tion. + if ((Index + 2) < (SectionHeaderEntryNumber - 1)): + unpacked_Next2SectionHeader =3D ElfSectionHeader64.unp= ack(SHentry[((Index + 2) * SectionHeaderEntrySize):(((Index + 2) * SectionH= eaderEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _Next2SectionHeader.sh_addralign) + else: + # It is align 8 bytes if next section or the section a= fter next is last one. + AlignmentIndex =3D 8 + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignmen= tIndex) + # section is Deleted section + elif (Index =3D=3D RemoveIndex): + # Don't add removed section to elf. + # Find offset of section name. + RemoveNameOffset =3D unpacked_SectionHeader.sh_name + # section is name string section. + elif (Index =3D=3D StringIndexNumber): + # StringIndex is String Index section + StringIndex =3D UPLEntry[unpacked_SectionHeader.sh_offset:= (unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Remove name of removed section in name string section. + # Section header isn't exist if RemoveSectionNameOffset eq= ual to -1. + StringIndex =3D bytearray(StringIndex) + RemoveSectionName =3D bytearray(RemoveSectionName, encodin= g=3D'utf-8') + RemoveSectionName =3D RemoveSectionName + bytes('\0', enco= ding=3D'utf-8') + StringIndex =3D StringIndex.replace(RemoveSectionName,b'') + NewUPLEntry +=3D StringIndex + # other sections. + else: + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Address alignment, section will align with alignment of = next section. + if (Index < (SectionHeaderEntryNumber - 1)): + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _NextSectionHeader.sh_addralign) + else: + # If section is last one. + AlignmentIndex =3D 8 + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignmen= tIndex) + SectionHeaderOffset =3D len(NewUPLEntry) + # Add section header + for Number in range(0, (SectionHeaderEntryNumber)): + if (Number !=3D RemoveIndex): + NewSHentry =3D AddSectionHeader64(SHentry, NewUPLEntrylen[= Number], SectionHeaderEntrySize, Number, RemoveNameOffset, RemoveSectionNam= e, StringIndexNumber) + NewUPLEntry +=3D NewSHentry + # Modify number of sections and offset of section header in Elf he= ader. + elf_header.e_shoff =3D SectionHeaderOffset + elf_header.e_shnum -=3D 1 + NewUPLEntry =3D elf_header.pack() + NewUPLEntry[64:] + # write to Elf. + with open(UniversalPayloadEntry,'wb') as f: + f.write(NewUPLEntry) + +def RemoveSection32(UniversalPayloadEntry, RemoveSectionName): + # If elf is 32-bit objects. + # Get offsets as follows: + # 1. Section name which will remove in section na= me string. + # 2. Section which will remove. + # 3. Section header which will remove. + with open(UniversalPayloadEntry,'rb') as f: + UPLEntry =3D f.read() + RemoveSectionNameOffset, ElfHeaderOffset, SectionHeaderEntrySize, = SectionHeaderEntryNumber, _, StringIndexNumber, EI_CLASS =3D FindSection(UP= LEntry, RemoveSectionName) + if (RemoveSectionNameOffset =3D=3D -1): + raise argparse.ArgumentTypeError ('Section: {} not found.'.for= mat (RemoveSectionNameOffset)) + # Read section header entry + SHentry =3D UPLEntry[ElfHeaderOffset:] + # find deleted fv section offset. + # Elf header is stored at 0x0-0x34 in 32-bits objects + elf_header =3D ElfHeader32(UPLEntry[:52]) + Counter =3D 0 + RemoveIndex =3D 0 + RemoveNameOffset =3D 0 + for Index in range(0, elf_header.e_shnum): + # Read Index of section header. + unpacked_SectionHeader =3D ElfSectionHeader32.unpack(SHentry[(= Index * elf_header.e_shentsize):((Index * elf_header.e_shentsize) + elf_hea= der.e_shentsize)]) + # Find offset of section name which is removed. + if (unpacked_SectionHeader.sh_name =3D=3D RemoveSectionNameOff= set): + RemoveIndex =3D Counter + Counter +=3D 1 + else: + Counter +=3D 1 + # Elf header is recombined. + # Elf header and program header table in front of first section ar= e reserved. + # Elf header size is 0x34 with 32-bit object. + ElfHeaderSize =3D 52 + ElfHandPH =3D ElfHeaderSize + (elf_header.e_phnum * elf_header.e_p= hentsize) + NewUPLEntry =3D UPLEntry[:ElfHandPH] + # Keep Section header and program header table, RemoveSection32() = only recombined section and section header. + NewUPLEntry =3D bytearray(NewUPLEntry) + # Sections is recombined. + # 1. name of deleted section is removed in name string section. + # 2. deleted section is removed in dll file. + # 3. re-align sections before and after deleted section. + NewUPLEntrylen =3D [] + for Index in range(0, (SectionHeaderEntryNumber)): + unpacked_SectionHeader =3D ElfSectionHeader32.unpack(SHentry[(= Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + Section= HeaderEntrySize)]) + NewUPLEntrylen.append(len(NewUPLEntry)) + if (Index =3D=3D 0): + # Address alignment, section will align with alignment of = next section. + AlignmentIndex =3D 8 + if (SectionHeaderEntryNumber > 2): + unpacked_NextSectionHeader =3D ElfSectionHeader32.unpac= k(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHea= derEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign) + # Section in front of removed section + elif (Index + 1 =3D=3D RemoveIndex): + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Read section address alignment + # If section that will be removed in .dll is not first and= last one . + # Address alignment, section will align with alignment of = section after deleted section. + # Check next and the section after next are not end of sec= tion. + if ((Index + 2) < (SectionHeaderEntryNumber - 1)): + unpacked_Next2SectionHeader =3D ElfSectionHeader32.unp= ack(SHentry[((Index + 2) * SectionHeaderEntrySize):(((Index + 2) * SectionH= eaderEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _Next2SectionHeader.sh_addralign) + else: + # It is align 8 bytes if next section or the section a= fter next is last one. + AlignmentIndex =3D 8 + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignmen= tIndex) + # section is Deleted section + elif (Index =3D=3D RemoveIndex): + # Don't add removed section to elf. + # Find offset of section name. + RemoveNameOffset =3D unpacked_SectionHeader.sh_name + # section is name string section. + elif (Index =3D=3D StringIndexNumber): + # StringIndex is String Index section + StringIndex =3D UPLEntry[unpacked_SectionHeader.sh_offset:= (unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Remove name of removed section in name string section. + # Section header isn't exist if RemoveSectionNameOffset eq= ual to -1. + StringIndex =3D bytearray(StringIndex) + RemoveSectionName =3D bytearray(RemoveSectionName, encodin= g=3D'utf-8') + RemoveSectionName =3D RemoveSectionName + bytes('\0', enco= ding=3D'utf-8') + StringIndex =3D StringIndex.replace(RemoveSectionName,b'') + NewUPLEntry +=3D StringIndex + # other sections. + else: + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Address alignment, section will align with alignment of = next section. + if (Index < (SectionHeaderEntryNumber - 1)): + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _NextSectionHeader.sh_addralign) + else: + # If section is last one. + AlignmentIndex =3D 8 + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignmen= tIndex) + SectionHeaderOffset =3D len(NewUPLEntry) + # Add section header + for Number in range(0, (SectionHeaderEntryNumber)): + if (Number !=3D RemoveIndex): + NewSHentry =3D AddSectionHeader32(SHentry, NewUPLEntrylen[= Number], SectionHeaderEntrySize, Number, RemoveNameOffset, RemoveSectionNam= e, StringIndexNumber) + NewUPLEntry +=3D NewSHentry + # Modify number of sections and offset of section header in Elf he= ader. + elf_header.e_shoff =3D SectionHeaderOffset + elf_header.e_shnum -=3D 1 + NewUPLEntry =3D elf_header.pack() + NewUPLEntry[52:] + # write to Elf. + with open(UniversalPayloadEntry,'wb') as f: + f.write(NewUPLEntry) + +def AddSection64(UniversalPayloadEntry, AddSectionName, ElfHeaderOffset, S= ectionHeaderEntrySize, SectionHeaderEntryNumber, StringIndexNumber, FileBin= ary, Alignment): + with open(UniversalPayloadEntry,'rb+') as f: + UPLEntry =3D f.read() + fFileBinary =3D open(FileBinary, 'rb') + Binary_File =3D fFileBinary.read() + ElfHeaderOffset, SectionHeaderEntryNumber, StringIndexNumber, _, _= , SectionHeaderEntrySize, _, _ =3D ElfHeaderParser(UPLEntry) + # Read section header entry + SHentry =3D UPLEntry[ElfHeaderOffset:] + # Elf header is recombined. + # Elf header and program header table in front of first section ar= e reserved. + # Elf header is stored at 0x0-0x40 in 64-bits objects + elf_header =3D ElfHeader64(UPLEntry[:64]) + # Elf header size is 0x40 with 64-bit object. + ElfHeaderSize =3D 64 + ElfHandPH =3D ElfHeaderSize + (elf_header.e_phnum * elf_header.e_p= hentsize) + NewUPLEntry =3D UPLEntry[:ElfHandPH] + # Keep Section header and program header table, AddSection64() onl= y recombined section and section header. + NewUPLEntry =3D bytearray(NewUPLEntry) + # Sections is recombined. + # 1. name of added section is added in name string section. + # 2. added section is added in dll file. + # 3. re-align sections before and after added section. + NewUPLEntrylen =3D [] + StringIndexValue =3D 0 + for Index in range(0, SectionHeaderEntryNumber): + NewUPLEntrylen.append(len(NewUPLEntry)) + unpacked_SectionHeader =3D ElfSectionHeader64.unpack(SHentry[(= Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + Section= HeaderEntrySize)]) + # Sections is recombined. + if (Index =3D=3D 0): + # Address alignment, section will align with alignment of = next section. + AlignmentIndex =3D 8 + if (SectionHeaderEntryNumber > 2): + unpacked_NextSectionHeader =3D ElfSectionHeader64.unpa= ck(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHe= aderEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign) + # Section is last one. + elif (Index =3D=3D (SectionHeaderEntryNumber - 1)): + # Add new section at the end. + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignment) + LastUPLEntrylen =3D len(NewUPLEntry) + NewUPLEntry +=3D Binary_File + # Address alignment, section will align with alignment of = next section. + AlignmentIndex =3D 8 + NewUPLEntry =3D SectionAlignment(NewUPLEntry, AlignmentInd= ex) + # section is name string section. + elif (Index =3D=3D StringIndexNumber): + # StringIndex is String Index section + StringIndex =3D UPLEntry[unpacked_SectionHeader.sh_offset:= (unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Read name of added Section after StringIndex is transfor= m into string. + StringIndex =3D bytearray(StringIndex) + StringIndexValue =3D len(StringIndex) + AddSectionName =3D bytearray(AddSectionName, encoding=3D'u= tf-8') + bytes('\0', encoding=3D'utf-8') + StringIndex +=3D AddSectionName + NewUPLEntry +=3D StringIndex + # section after name string section but not last one. + elif ((Index > StringIndexNumber) and (Index < (SectionHeaderE= ntryNumber - 1))): + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Address alignment, section will align with alignment of = next section. + unpacked_NextSectionHeader =3D ElfSectionHeader64.unpack(S= Hentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHeader= EntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign) + # Section before name string section. + else: + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Address alignment, section will align with alignment= of next section. + if (Index < (SectionHeaderEntryNumber - 1)): + unpacked_NextSectionHeader =3D ElfSectionHeader64.unpa= ck(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHe= aderEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _NextSectionHeader.sh_addralign) + SectionHeaderOffset =3D len(NewUPLEntry) + RemoveNameOffset =3D 0 + # Add section header + for Number in range(0, (SectionHeaderEntryNumber)): + NewSHentry =3D AddSectionHeader64(SHentry, NewUPLEntrylen[Numb= er], SectionHeaderEntrySize, Number, RemoveNameOffset, AddSectionName, Stri= ngIndexNumber) + NewUPLEntry +=3D NewSHentry + NewUPLEntry +=3D bytearray(AddNewSectionEntry64(LastUPLEntrylen, S= tringIndexValue, len(Binary_File), Alignment)) + # Modify number of sections and offset of section header in Elf he= ader. + # Modify offset in in Elf header. + elf_header.e_shoff =3D SectionHeaderOffset + elf_header.e_shnum +=3D 1 + elf_header =3D elf_header.pack() + UPLEntryBin =3D elf_header + NewUPLEntry[64:] + # Modify offsets and address of program header table in elf. + PHSegmentName =3D '.text' + _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumb= er, _, StringIndexNumber, _ =3D FindSection(UPLEntryBin, PHSegmentName) + UPLEntryBin =3D ModifyPHSegmentOffset64(UPLEntryBin, ElfHeaderOffs= et, PHSegmentName) + # Modify offsets and address of program header table in elf. + PHSegmentName =3D '.dynamic' + _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumb= er, _, StringIndexNumber, _ =3D FindSection(UPLEntryBin, PHSegmentName) + UPLEntryBin =3D ModifyPHSegmentOffset64(UPLEntryBin, ElfHeaderOffs= et, PHSegmentName) + # Modify offsets and address of program header table in elf. + PHSegmentName =3D '.data' + _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumb= er, _, StringIndexNumber, _ =3D FindSection(UPLEntryBin, PHSegmentName) + UPLEntryBin =3D ModifyPHSegmentOffset64(UPLEntryBin, ElfHeaderOffs= et, PHSegmentName) + fFileBinary.close() + return UPLEntryBin + +def AddSection32(UniversalPayloadEntry, AddSectionName, ElfHeaderOffset, S= ectionHeaderEntrySize, SectionHeaderEntryNumber, StringIndexNumber, FileBin= ary, Alignment): + with open(UniversalPayloadEntry,'rb+') as f: + # Read Elf and binary which will be write to elf. + UPLEntry =3D f.read() + fFileBinary =3D open(FileBinary, 'rb') + Binary_File =3D fFileBinary.read() + ElfHeaderOffset, SectionHeaderEntryNumber, StringIndexNumber, _, _= , SectionHeaderEntrySize, _, _ =3D ElfHeaderParser(UPLEntry) + # Read section header entry + SHentry =3D UPLEntry[ElfHeaderOffset:] + # Elf header is recombined. + # Elf header and program header table in front of first section ar= e reserved. + # Elf header is stored at 0x0-0x34 in 32-bits objects + elf_header =3D ElfHeader32(UPLEntry[:52]) + # Elf header size is 0x34 with 32-bit object. + ElfHeaderSize =3D 52 + ElfHandPH =3D ElfHeaderSize + (elf_header.e_phnum * elf_header.e_p= hentsize) + NewUPLEntry =3D UPLEntry[:ElfHandPH] + # Keep Section header and program header table, AddSection64() onl= y recombined section and section header. + NewUPLEntry =3D bytearray(NewUPLEntry) + # Sections is recombined. + # 1. name of added section is added in name string section. + # 2. added section is added in dll file. + # 3. re-align sections before and after added section. + NewUPLEntrylen =3D [] + StringIndexValue =3D 0 + for Index in range(0, SectionHeaderEntryNumber): + NewUPLEntrylen.append(len(NewUPLEntry)) + unpacked_SectionHeader =3D ElfSectionHeader32.unpack(SHentry[(= Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + Section= HeaderEntrySize)]) + # Sections is recombined. + if (Index =3D=3D 0): + # Address alignment, section will align with alignment of = next section. + AlignmentIndex =3D 8 + if (SectionHeaderEntryNumber > 2): + unpacked_NextSectionHeader =3D ElfSectionHeader32.unpa= ck(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHe= aderEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign) + # Section is last one. + elif (Index =3D=3D (SectionHeaderEntryNumber - 1)): + # Add new section at the end. + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignment) + LastUPLEntrylen =3D len(NewUPLEntry) + NewUPLEntry +=3D Binary_File + # Address alignment, section will align with alignment of = next section. + AlignmentIndex =3D 8 + NewUPLEntry =3D SectionAlignment(NewUPLEntry, AlignmentInd= ex) + # section is name string section. + elif (Index =3D=3D StringIndexNumber): + # StringIndex is String Index section + StringIndex =3D UPLEntry[unpacked_SectionHeader.sh_offset:= (unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Read name of added Section after StringIndex is transfor= m into string. + StringIndex =3D bytearray(StringIndex) + StringIndexValue =3D len(StringIndex) + AddSectionName =3D bytearray(AddSectionName, encoding=3D'u= tf-8') + bytes('\0', encoding=3D'utf-8') + StringIndex +=3D AddSectionName + NewUPLEntry +=3D StringIndex + # section after name string section but not last one. + elif ((Index > StringIndexNumber) and (Index < (SectionHeaderE= ntryNumber - 1))): + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Address alignment, section will align with alignment of = next section. + unpacked_NextSectionHeader =3D ElfSectionHeader32.unpack(S= Hentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHeader= EntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign) + # Section before name string section. + else: + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Address alignment, section will align with alignment= of next section. + if (Index < (SectionHeaderEntryNumber - 1)): + unpacked_NextSectionHeader =3D ElfSectionHeader32.unpa= ck(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHe= aderEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _NextSectionHeader.sh_addralign) + SectionHeaderOffset =3D len(NewUPLEntry) + RemoveNameOffset =3D 0 + # Add section header + for Number in range(0, (SectionHeaderEntryNumber)): + NewSHentry =3D AddSectionHeader32(SHentry, NewUPLEntrylen[Numb= er], SectionHeaderEntrySize, Number, RemoveNameOffset, AddSectionName, Stri= ngIndexNumber) + NewUPLEntry +=3D NewSHentry + NewUPLEntry +=3D bytearray(AddNewSectionEntry32(LastUPLEntrylen, S= tringIndexValue, len(Binary_File), Alignment)) + # Modify number of sections and offset of section header in Elf he= ader. + # Modify offset in in Elf header. + elf_header.e_shoff =3D SectionHeaderOffset + elf_header.e_shnum +=3D 1 + PHTableSize =3D elf_header.e_phentsize + elf_header =3D elf_header.pack() + UPLEntryBin =3D elf_header + NewUPLEntry[52:] + # Modify offsets and address of program header table in elf. + PHSegmentName =3D '.text' + _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumb= er, _, StringIndexNumber, _ =3D FindSection(UPLEntryBin, PHSegmentName) + UPLEntryBin =3D ModifyPHSegmentOffset32(UPLEntryBin, ElfHeaderOffs= et, PHSegmentName) + # Modify offsets and address of program header table in elf. Its a= re stored at 0x08-0x0F and 0x10-0x17 + PHSegmentName =3D '.data' + _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumb= er, _, StringIndexNumber, _ =3D FindSection(UPLEntryBin, PHSegmentName) + UPLEntryBin =3D ModifyPHSegmentOffset32(UPLEntryBin, ElfHeaderOffs= et, PHSegmentName) + fFileBinary.close() + return UPLEntryBin + +def ReplaceFv (UniversalPayloadEntry, FileBinary, AddSectionName, Alignmen= t =3D 16): + with open(UniversalPayloadEntry,'rb+') as f: + UPLEntry =3D f.read() + SectionNameOffset, ElfHeaderOffset, SectionHeaderEntrySize, Sectio= nHeaderEntryNumber, _, StringIndexNumber, EI_CLASS =3D FindSection(UPLEntry= , AddSectionName) + # If elf is 64-bit objects. + if (EI_CLASS =3D=3D 2): + # Remove section if it exists. + if (SectionNameOffset !=3D -1): + RemoveSection64(UniversalPayloadEntry, AddSectionName) + # Add section. + NewUPLEntry =3D AddSection64(UniversalPayloadEntry, AddSectionName= , ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, String= IndexNumber, FileBinary, Alignment) + # If elf is 32-bit objects. + else: + # Remove section if it exists. + if (SectionNameOffset !=3D -1): + RemoveSection32(UniversalPayloadEntry, AddSectionName) + # Add section. + NewUPLEntry =3D AddSection32(UniversalPayloadEntry, AddSectionName= , ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, String= IndexNumber, FileBinary, Alignment) + with open(UniversalPayloadEntry,'wb') as f: + f.write(NewUPLEntry) + return 0 diff --git a/UefiPayloadPkg/Tools/__init__.py b/UefiPayloadPkg/Tools/__init= __.py new file mode 100644 index 0000000000..de57d1b907 --- /dev/null +++ b/UefiPayloadPkg/Tools/__init__.py @@ -0,0 +1,19 @@ +## @file +# Python 'Tools' package initialization file. +# +# @copyright +# INTEL CONFIDENTIAL +# +# Copyright (C) 2023 Intel Corporation +# +# This software and the related documents are Intel copyrighted materials= , and your +# use of them is governed by the express license under which they were pr= ovided to +# you ("License"). Unless the License provides otherwise, you may not use= , modify, +# copy, publish, distribute, disclose or transmit this software or the re= lated +# documents without Intel's prior written permission. +# +# This software and the related documents are provided as is, with no exp= ress or +# implied warranties, other than those that are expressly stated in the L= icense. +# +# @par Specification +## diff --git a/UefiPayloadPkg/UniversalPayloadBuild.py b/UefiPayloadPkg/Unive= rsalPayloadBuild.py index 83e0de95d8..416946a431 100644 --- a/UefiPayloadPkg/UniversalPayloadBuild.py +++ b/UefiPayloadPkg/UniversalPayloadBuild.py @@ -11,7 +11,7 @@ import os import shutil import sys from ctypes import * - +from Tools.ElfFv import ReplaceFv sys.dont_write_bytecode =3D True =20 class UPLD_INFO_HEADER(LittleEndianStructure): @@ -36,106 +36,56 @@ class UPLD_INFO_HEADER(LittleEndianStructure): self.ImageId =3D b'UEFI' self.ProducerId =3D b'INTEL' =20 -def GenSpecRevision (Argument): - try: - (MajorStr, MinorStr) =3D Argument.split('.') - except: - raise argparse.ArgumentTypeError ('{} is not a valid SpecRevision = format (Major[8-bits].Minor[8-bits]).'.format (Argument)) - # - # Spec Revision Bits 15 : 8 - Major Version. Bits 7 : 0 - Minor Versio= n. - # - if len(MinorStr) > 0 and len(MinorStr) < 3: - try: - Minor =3D int(MinorStr, 16) if len(MinorStr) =3D=3D 2 else (in= t(MinorStr, 16) << 4) - except: - raise argparse.ArgumentTypeError ('{} Minor version of SpecRev= ision is not a valid integer value.'.format (Argument)) - else: - raise argparse.ArgumentTypeError ('{} is not a valid SpecRevision = format (Major[8-bits].Minor[8-bits]).'.format (Argument)) +def BuildUniversalPayload(Args): + def RunCommand(cmd): + print(cmd) + p =3D subprocess.Popen(cmd, shell=3DTrue, stdout=3Dsubprocess.PIPE= , stderr=3Dsubprocess.STDOUT,cwd=3Dos.environ['WORKSPACE']) + while True: + line =3D p.stdout.readline() + if not line: + break + print(line.strip().decode(errors=3D'ignore')) + + p.communicate() + if p.returncode !=3D 0: + print("- Failed - error happened when run command: %s"%cmd) + raise Exception("ERROR: when run command: %s"%cmd) =20 - if len(MajorStr) > 0 and len(MajorStr) < 3: - try: - Major =3D int(MajorStr, 16) - except: - raise argparse.ArgumentTypeError ('{} Major version of SpecRev= ision is not a valid integer value.'.format (Argument)) - else: - raise argparse.ArgumentTypeError ('{} is not a valid SpecRevision = format (Major[8-bits].Minor[8-bits]).'.format (Argument)) - - return int('0x{0:02x}{1:02x}'.format(Major, Minor), 0) - -def Validate32BitInteger (Argument): - try: - Value =3D int (Argument, 0) - except: - raise argparse.ArgumentTypeError ('{} is not a valid integer value= .'.format (Argument)) - if Value < 0: - raise argparse.ArgumentTypeError ('{} is a negative value.'.format= (Argument)) - if Value > 0xffffffff: - raise argparse.ArgumentTypeError ('{} is larger than 32-bits.'.for= mat (Argument)) - return Value - -def RunCommand(cmd): - print(cmd) - p =3D subprocess.Popen(cmd, shell=3DTrue, stdout=3Dsubprocess.PIPE, st= derr=3Dsubprocess.STDOUT,cwd=3Dos.environ['WORKSPACE']) - while True: - line =3D p.stdout.readline() - if not line: - break - print(line.strip().decode(errors=3D'ignore')) - - p.communicate() - if p.returncode !=3D 0: - print("- Failed - error happened when run command: %s"%cmd) - raise Exception("ERROR: when run command: %s"%cmd) - -def BuildUniversalPayload(Args, MacroList): BuildTarget =3D Args.Target ToolChain =3D Args.ToolChain Quiet =3D "--quiet" if Args.Quiet else "" ElfToolChain =3D 'CLANGDWARF' BuildDir =3D os.path.join(os.environ['WORKSPACE'], os.path.normpat= h("Build/UefiPayloadPkgX64")) + BuildModule =3D "" + BuildArch =3D "" if Args.Arch =3D=3D 'X64': BuildArch =3D "X64" - ObjCopyFlag =3D "elf64-x86-64" EntryOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ElfToolChain), os.path.normpath("X64/UefiPayloadPkg/UefiPayloadEntry/U= niversalPayloadEntry/DEBUG/UniversalPayloadEntry.dll")) else: BuildArch =3D "IA32 -a X64" - ObjCopyFlag =3D "elf32-i386" EntryOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ElfToolChain), os.path.normpath("IA32/UefiPayloadPkg/UefiPayloadEntry/= UniversalPayloadEntry/DEBUG/UniversalPayloadEntry.dll")) =20 if Args.PreBuildUplBinary is not None: EntryOutputDir =3D os.path.abspath(Args.PreBuildUplBinary) - EntryModuleInf =3D os.path.normpath("UefiPayloadPkg/UefiPayloadEntry/U= niversalPayloadEntry.inf") DscPath =3D os.path.normpath("UefiPayloadPkg/UefiPayloadPkg.dsc") - DxeFvOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTarget,= ToolChain), os.path.normpath("FV/DXEFV.Fv")) - BdsFvOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTarget,= ToolChain), os.path.normpath("FV/BDSFV.Fv")) - NetworkFvOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/NETWORKFV.Fv")) - PayloadReportPath =3D os.path.join(BuildDir, "UefiUniversalPayload.txt= ") ModuleReportPath =3D os.path.join(BuildDir, "UefiUniversalPayloadEntry= .txt") UpldInfoFile =3D os.path.join(BuildDir, "UniversalPayloadInfo.bin") =20 - if "CLANG_BIN" in os.environ: - LlvmObjcopyPath =3D os.path.join(os.environ["CLANG_BIN"], "llvm-ob= jcopy") - else: - LlvmObjcopyPath =3D "llvm-objcopy" - try: - RunCommand('"%s" --version'%LlvmObjcopyPath) - except: - print("- Failed - Please check if LLVM is installed or if CLANG_BI= N is set correctly") - sys.exit(1) - Pcds =3D "" if (Args.pcd !=3D None): for PcdItem in Args.pcd: Pcds +=3D " --pcd {}".format (PcdItem) =20 Defines =3D "" - for key in MacroList: - Defines +=3D" -D {0}=3D{1}".format(key, MacroList[key]) + if (Args.Macro !=3D None): + for MacroItem in Args.Macro: + Defines +=3D " -D {}".format (MacroItem) =20 # # Building DXE core and DXE drivers as DXEFV. # if Args.BuildEntryOnly =3D=3D False: + PayloadReportPath =3D os.path.join(BuildDir, "UefiUniversalPayload= .txt") BuildPayload =3D "build -p {} -b {} -a X64 -t {} -y {} {}".format = (DscPath, BuildTarget, ToolChain, PayloadReportPath, Quiet) BuildPayload +=3D Pcds BuildPayload +=3D Defines @@ -144,6 +94,7 @@ def BuildUniversalPayload(Args, MacroList): # Building Universal Payload entry. # if Args.PreBuildUplBinary is None: + EntryModuleInf =3D os.path.normpath("UefiPayloadPkg/UefiPayloadEnt= ry/UniversalPayloadEntry.inf") BuildModule =3D "build -p {} -b {} -a {} -m {} -t {} -y {} {}".for= mat (DscPath, BuildTarget, BuildArch, EntryModuleInf, ElfToolChain, ModuleR= eportPath, Quiet) BuildModule +=3D Pcds BuildModule +=3D Defines @@ -151,59 +102,80 @@ def BuildUniversalPayload(Args, MacroList): # # Buid Universal Payload Information Section ".upld_info" # - upld_info_hdr =3D UPLD_INFO_HEADER() + upld_info_hdr =3D UPLD_INFO_HEADER() upld_info_hdr.SpecRevision =3D Args.SpecRevision - upld_info_hdr.Revision =3D Args.Revision - upld_info_hdr.ProducerId =3D Args.ProducerId.encode()[:16] - upld_info_hdr.ImageId =3D Args.ImageId.encode()[:16] - upld_info_hdr.Attribute |=3D 1 if BuildTarget =3D=3D "DEBUG" else 0 + upld_info_hdr.Revision =3D Args.Revision + upld_info_hdr.ProducerId =3D Args.ProducerId.encode()[:16] + upld_info_hdr.ImageId =3D Args.ImageId.encode()[:16] + upld_info_hdr.Attribute |=3D 1 if BuildTarget =3D=3D "DEBUG" else 0 fp =3D open(UpldInfoFile, 'wb') fp.write(bytearray(upld_info_hdr)) fp.close() =20 + MultiFvList =3D [] if Args.BuildEntryOnly =3D=3D False: - # - # Copy the DXEFV as a section in elf format Universal Payload entr= y. - # - remove_section =3D '"{}" -I {} -O {} --remove-section .upld_info -= -remove-section .upld.uefi_fv --remove-section .upld.bds_fv {}'.format ( - LlvmObjcopyPath, - ObjCopyFlag, - ObjCopyFlag, - EntryOutputDir - ) - add_section =3D '"{}" -I {} -O {} --add-section .upld_info=3D{}= --add-section .upld.uefi_fv=3D{} --add-section .upld.bds_fv=3D{} {}'.forma= t ( - LlvmObjcopyPath, - ObjCopyFlag, - ObjCopyFlag, - UpldInfoFile, - DxeFvOutputDir, - BdsFvOutputDir, - EntryOutputDir - ) - set_section =3D '"{}" -I {} -O {} --set-section-alignment .upld= _info=3D4 --set-section-alignment .upld.uefi_fv=3D16 --set-section-alignmen= t .upld.bds_fv=3D16 {}'.format ( - LlvmObjcopyPath, - ObjCopyFlag, - ObjCopyFlag, - EntryOutputDir - ) - # - # Append network fv to sections if exists - # - if os.path.isfile(NetworkFvOutputDir): - index =3D remove_section.find(EntryOutputDir) - remove_section =3D remove_section[:index] + '--remove-section = .upld.network_fv ' + remove_section[index:] - index =3D add_section.find(EntryOutputDir) - add_section =3D add_section[:index] + '--add-section .upld.net= work_fv=3D' + NetworkFvOutputDir + ' ' + add_section[index:] - index =3D set_section.find(EntryOutputDir) - set_section =3D set_section[:index] + '--set-section-alignment= .upld.network_fv=3D16 ' + set_section[index:] - - RunCommand(remove_section) - RunCommand(add_section) - RunCommand(set_section) + MultiFvList =3D [ + ['uefi_fv', os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/DXEFV.Fv")) ], + ['bds_fv', os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/BDSFV.Fv")) ], + ['network_fv', os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/NETWORKFV.Fv")) ], + ] + AddSectionName =3D '.upld_info' + ReplaceFv (EntryOutputDir, UpldInfoFile, AddSectionName, Alignment= =3D 4) =20 shutil.copy (EntryOutputDir, os.path.join(BuildDir, 'UniversalPayload.= elf')) =20 + return MultiFvList, os.path.join(BuildDir, 'UniversalPayload.elf') + def main(): + def ValidateSpecRevision (Argument): + try: + (MajorStr, MinorStr) =3D Argument.split('.') + except: + raise argparse.ArgumentTypeError ('{} is not a valid SpecRevis= ion format (Major[8-bits].Minor[8-bits]).'.format (Argument)) + # + # Spec Revision Bits 15 : 8 - Major Version. Bits 7 : 0 - Minor Ve= rsion. + # + if len(MinorStr) > 0 and len(MinorStr) < 3: + try: + Minor =3D int(MinorStr, 16) if len(MinorStr) =3D=3D 2 else= (int(MinorStr, 16) << 4) + except: + raise argparse.ArgumentTypeError ('{} Minor version of Spe= cRevision is not a valid integer value.'.format (Argument)) + else: + raise argparse.ArgumentTypeError ('{} is not a valid SpecRevis= ion format (Major[8-bits].Minor[8-bits]).'.format (Argument)) + + if len(MajorStr) > 0 and len(MajorStr) < 3: + try: + Major =3D int(MajorStr, 16) + except: + raise argparse.ArgumentTypeError ('{} Major version of Spe= cRevision is not a valid integer value.'.format (Argument)) + else: + raise argparse.ArgumentTypeError ('{} is not a valid SpecRevis= ion format (Major[8-bits].Minor[8-bits]).'.format (Argument)) + + return int('0x{0:02x}{1:02x}'.format(Major, Minor), 0) + + def Validate32BitInteger (Argument): + try: + Value =3D int (Argument, 0) + except: + raise argparse.ArgumentTypeError ('{} is not a valid integer v= alue.'.format (Argument)) + if Value < 0: + raise argparse.ArgumentTypeError ('{} is a negative value.'.fo= rmat (Argument)) + if Value > 0xffffffff: + raise argparse.ArgumentTypeError ('{} is larger than 32-bits.'= .format (Argument)) + return Value + + def ValidateAddFv (Argument): + Value =3D Argument.split ("=3D") + if len (Value) !=3D 2: + raise argparse.ArgumentTypeError ('{} is incorrect format with= "xxx_fv=3Dxxx.fv"'.format (Argument)) + if Value[0][-3:] !=3D "_fv": + raise argparse.ArgumentTypeError ('{} is incorrect format with= "xxx_fv=3Dxxx.fv"'.format (Argument)) + if Value[1][-3:].lower () !=3D ".fv": + raise argparse.ArgumentTypeError ('{} is incorrect format with= "xxx_fv=3Dxxx.fv"'.format (Argument)) + if os.path.exists (Value[1]) =3D=3D False: + raise argparse.ArgumentTypeError ('File {} is not found.'.form= at (Value[1])) + return Value + parser =3D argparse.ArgumentParser(description=3D'For building Univers= al Payload') parser.add_argument('-t', '--ToolChain') parser.add_argument('-b', '--Target', default=3D'DEBUG') @@ -212,22 +184,32 @@ def main(): parser.add_argument('-i', '--ImageId', type=3Dstr, help=3D'Specify pay= load ID (16 bytes maximal).', default =3D'UEFI') parser.add_argument('-q', '--Quiet', action=3D'store_true', help=3D'Di= sable all build messages except FATAL ERRORS.') parser.add_argument("-p", "--pcd", action=3D"append") - parser.add_argument("-s", "--SpecRevision", type=3DGenSpecRevision, de= fault =3D'0.7', help=3D'Indicates compliance with a revision of this specif= ication in the BCD format.') + parser.add_argument("-s", "--SpecRevision", type=3DValidateSpecRevisio= n, default =3D'0.7', help=3D'Indicates compliance with a revision of this s= pecification in the BCD format.') parser.add_argument("-r", "--Revision", type=3DValidate32BitInteger, d= efault =3D'0x0000010105', help=3D'Revision of the Payload binary. Major.Min= or.Revision.Build') parser.add_argument("-o", "--ProducerId", default =3D'INTEL', help=3D'= A null-terminated OEM-supplied string that identifies the payload producer = (16 bytes maximal).') parser.add_argument("-e", "--BuildEntryOnly", action=3D'store_true', h= elp=3D'Build UniversalPayload Entry file') parser.add_argument("-pb", "--PreBuildUplBinary", default=3DNone, help= =3D'Specify the UniversalPayload file') - MacroList =3D {} + parser.add_argument("-sk", "--SkipBuild", action=3D'store_true', help= =3D'Skip UniversalPayload build') + parser.add_argument("-af", "--AddFv", type=3DValidateAddFv, action=3D'= append', help=3D'Add or replace specific FV into payload, Ex: uefi_fv=3DXXX= .fv') args =3D parser.parse_args() - if args.Macro is not None: - for Argument in args.Macro: - if Argument.count('=3D') !=3D 1: - print("Unknown variable passed in: %s"%Argument) - raise Exception("ERROR: Unknown variable passed in: %s"%Ar= gument) - tokens =3D Argument.strip().split('=3D') - MacroList[tokens[0].upper()] =3D tokens[1] - BuildUniversalPayload(args, MacroList) - print ("Successfully build Universal Payload") + + MultiFvList =3D [] + UniversalPayloadBinary =3D args.PreBuildUplBinary + if (args.SkipBuild =3D=3D False): + MultiFvList, UniversalPayloadBinary =3D BuildUniversalPayload(args= ) + + if (args.AddFv !=3D None): + for (SectionName, SectionFvFile) in args.AddFv: + MultiFvList.append ([SectionName, SectionFvFile]) + + if (UniversalPayloadBinary !=3D None): + for (SectionName, SectionFvFile) in MultiFvList: + if os.path.exists (SectionFvFile) =3D=3D False: + continue + print ("Patch {}=3D{} into {}".format (SectionName, SectionFvF= ile, UniversalPayloadBinary)) + ReplaceFv (UniversalPayloadBinary, SectionFvFile, '.upld.{}'.f= ormat (SectionName)) + + print ("\nSuccessfully build Universal Payload") =20 if __name__ =3D=3D '__main__': main() --=20 2.39.1.windows.1