Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /build /extract_partition.py
blob: 5b8267a3f559424f0b55c01600fb8fc69f9bb429 [file] [log] [blame]
Takuto Ikuta3dab32e02023-01-12 18:52:00[diff] [blame]1#!/usr/bin/env python3
Avi Drissman73a09d12022-09-08 20:33:38[diff] [blame]2# Copyright 2019 The Chromium Authors
Christopher Grant3b06acce2019-04-25 18:26:41[diff] [blame]3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5"""Extracts an LLD partition from an ELF file."""
6
7import argparse
Charlie Hua61ff7ca2021-08-03 05:08:26[diff] [blame]8import hashlib
Charlie Hua61ff7ca2021-08-03 05:08:26[diff] [blame]9import os
10import struct
Christopher Grant3b06acce2019-04-25 18:26:41[diff] [blame]11import subprocess
12import sys
Charlie Hua61ff7ca2021-08-03 05:08:26[diff] [blame]13import tempfile
14
15
16def_ComputeNewBuildId(old_build_id, file_path):
17"""
18 Computes the new build-id from old build-id and file_path.
19
20 Args:
21 old_build_id: Original build-id in bytearray.
22 file_path: Path to output ELF file.
23
24 Returns:
25 New build id with the same length as |old_build_id|.
26 """
27 m= hashlib.sha256()
28 m.update(old_build_id)
29 m.update(os.path.basename(file_path).encode('utf-8'))
30 hash_bytes= m.digest()
31# In case build_id is longer than hash computed, repeat the hash
32# to the desired length first.
33 id_size= len(old_build_id)
34 hash_size= len(hash_bytes)
35return(hash_bytes*(id_size// hash_size+1))[:id_size]
36
37
38def_ExtractPartition(objcopy, input_elf, output_elf, partition):
39"""
40 Extracts a partition from an ELF file.
41
42 For partitions other than main partition, we need to rewrite
43 the .note.gnu.build-id section so that the build-id remains
44 unique.
45
46 Note:
47 - `objcopy` does not modify build-id when partitioning the
48 combined ELF file by default.
49 - The new build-id is calculated as hash of original build-id
50 and partitioned ELF file name.
51
52 Args:
53 objcopy: Path to objcopy binary.
54 input_elf: Path to input ELF file.
55 output_elf: Path to output ELF file.
56 partition: Partition to extract from combined ELF file. None when
57 extracting main partition.
58 """
59ifnot partition:# main partition
60# We do not overwrite build-id on main partition to allow the expected
61# partition build ids to be synthesized given a libchrome.so binary,
62# if necessary.
63 subprocess.check_call(
64[objcopy,'--extract-main-partition', input_elf, output_elf])
65return
66
67# partitioned libs
68 build_id_section='.note.gnu.build-id'
69
70with tempfile.TemporaryDirectory()as tempdir:
71 temp_elf= os.path.join(tempdir,'obj_without_id.so')
72 old_build_id_file= os.path.join(tempdir,'old_build_id')
73 new_build_id_file= os.path.join(tempdir,'new_build_id')
74
Charlie Hub4ae21c2024-02-08 19:18:57[diff] [blame]75# Dump out build-id section.
Charlie Hua61ff7ca2021-08-03 05:08:26[diff] [blame]76 subprocess.check_call([
77 objcopy,
78'--extract-partition',
79 partition,
Charlie Hua61ff7ca2021-08-03 05:08:26[diff] [blame]80'--dump-section',
81'{}={}'.format(build_id_section, old_build_id_file),
82 input_elf,
83 temp_elf,
84])
85
86with open(old_build_id_file,'rb')as f:
87 note_content= f.read()
88
89# .note section has following format according to <elf/external.h>
90# typedef struct {
91# unsigned char namesz[4]; /* Size of entry's owner string */
92# unsigned char descsz[4]; /* Size of the note descriptor */
93# unsigned char type[4]; /* Interpretation of the descriptor */
94# char name[1]; /* Start of the name+desc data */
95# } Elf_External_Note;
96# `build-id` rewrite is only required on Android platform,
97# where we have partitioned lib.
98# Android platform uses little-endian.
99# <: little-endian
100# 4x: Skip 4 bytes
101# L: unsigned long, 4 bytes
102 descsz,= struct.Struct('<4xL').unpack_from(note_content)
103 prefix= note_content[:-descsz]
104 build_id= note_content[-descsz:]
105
106with open(new_build_id_file,'wb')as f:
107 f.write(prefix+_ComputeNewBuildId(build_id, output_elf))
108
Charlie Hub4ae21c2024-02-08 19:18:57[diff] [blame]109# Update the build-id section.
Charlie Hua61ff7ca2021-08-03 05:08:26[diff] [blame]110 subprocess.check_call([
111 objcopy,
Charlie Hub4ae21c2024-02-08 19:18:57[diff] [blame]112'--update-section',
Charlie Hua61ff7ca2021-08-03 05:08:26[diff] [blame]113'{}={}'.format(build_id_section, new_build_id_file),
Charlie Hue9c4b8c2024-01-26 19:41:44[diff] [blame]114 temp_elf,
Charlie Hua61ff7ca2021-08-03 05:08:26[diff] [blame]115 output_elf,
116])
Christopher Grant3b06acce2019-04-25 18:26:41[diff] [blame]117
118
119def main():
120 parser= argparse.ArgumentParser(description=__doc__)
121 parser.add_argument(
122'--partition',
123 help='Name of partition if not the main partition',
124 metavar='PART')
125 parser.add_argument(
126'--objcopy',
127 required=True,
128 help='Path to llvm-objcopy binary',
129 metavar='FILE')
130 parser.add_argument(
131'--unstripped-output',
132 required=True,
133 help='Unstripped output file',
134 metavar='FILE')
135 parser.add_argument(
136'--stripped-output',
137 required=True,
138 help='Stripped output file',
139 metavar='FILE')
Andrew Grieved1828005a2021-10-28 16:52:17[diff] [blame]140 parser.add_argument('--split-dwarf', action='store_true')
Christopher Grant3b06acce2019-04-25 18:26:41[diff] [blame]141 parser.add_argument('input', help='Input file')
142 args= parser.parse_args()
143
Charlie Hua61ff7ca2021-08-03 05:08:26[diff] [blame]144_ExtractPartition(args.objcopy, args.input, args.unstripped_output,
145 args.partition)
146 subprocess.check_call([
147 args.objcopy,
148'--strip-all',
149 args.unstripped_output,
150 args.stripped_output,
151])
Christopher Grant3b06acce2019-04-25 18:26:41[diff] [blame]152
Andrew Grieved1828005a2021-10-28 16:52:17[diff] [blame]153# Debug info for partitions is the same as for the main library, so just
154# symlink the .dwp files.
155if args.split_dwarf:
156 dest= args.unstripped_output+'.dwp'
157try:
158 os.unlink(dest)
159exceptOSError:
160pass
161 relpath= os.path.relpath(args.input+'.dwp', os.path.dirname(dest))
162 os.symlink(relpath, dest)
Nelson Billing3ed73012020-08-25 04:39:15[diff] [blame]163
Christopher Grant3b06acce2019-04-25 18:26:41[diff] [blame]164
165if __name__=='__main__':
166 sys.exit(main())

[8]ページ先頭

©2009-2025 Movatter.jp