1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project 2*7594170eSAndroid Build Coastguard Worker# 3*7594170eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*7594170eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*7594170eSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*7594170eSAndroid Build Coastguard Worker# 7*7594170eSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*7594170eSAndroid Build Coastguard Worker# 9*7594170eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*7594170eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*7594170eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*7594170eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*7594170eSAndroid Build Coastguard Worker# limitations under the License. 14*7594170eSAndroid Build Coastguard Worker 15*7594170eSAndroid Build Coastguard Workerimport argparse 16*7594170eSAndroid Build Coastguard Workerimport os 17*7594170eSAndroid Build Coastguard Workerimport subprocess 18*7594170eSAndroid Build Coastguard Workerimport sys 19*7594170eSAndroid Build Coastguard Workerimport tempfile 20*7594170eSAndroid Build Coastguard Workerimport zipfile 21*7594170eSAndroid Build Coastguard Worker 22*7594170eSAndroid Build Coastguard Workerdef main(): 23*7594170eSAndroid Build Coastguard Worker parser = argparse.ArgumentParser( 24*7594170eSAndroid Build Coastguard Worker description="This program takes an apks file and outputs a text file containing the " + 25*7594170eSAndroid Build Coastguard Worker "name of all the libcutils.so files it found in the apex, and their arches.") 26*7594170eSAndroid Build Coastguard Worker parser.add_argument('--deapexer-path', required=True) 27*7594170eSAndroid Build Coastguard Worker parser.add_argument('--readelf-path', required=True) 28*7594170eSAndroid Build Coastguard Worker parser.add_argument('--debugfs-path', required=True) 29*7594170eSAndroid Build Coastguard Worker parser.add_argument('--fsckerofs-path', required=True) 30*7594170eSAndroid Build Coastguard Worker parser.add_argument('apks') 31*7594170eSAndroid Build Coastguard Worker parser.add_argument('output') 32*7594170eSAndroid Build Coastguard Worker args = parser.parse_args() 33*7594170eSAndroid Build Coastguard Worker 34*7594170eSAndroid Build Coastguard Worker with tempfile.TemporaryDirectory() as d: 35*7594170eSAndroid Build Coastguard Worker with zipfile.ZipFile(args.apks) as zip: 36*7594170eSAndroid Build Coastguard Worker zip.extractall(d) 37*7594170eSAndroid Build Coastguard Worker result = '' 38*7594170eSAndroid Build Coastguard Worker for name in sorted(os.listdir(os.path.join(d, 'standalones'))): 39*7594170eSAndroid Build Coastguard Worker extractedDir = os.path.join(d, 'standalones', name+'_extracted') 40*7594170eSAndroid Build Coastguard Worker subprocess.run([ 41*7594170eSAndroid Build Coastguard Worker args.deapexer_path, 42*7594170eSAndroid Build Coastguard Worker '--debugfs_path', 43*7594170eSAndroid Build Coastguard Worker args.debugfs_path, 44*7594170eSAndroid Build Coastguard Worker '--fsckerofs_path', 45*7594170eSAndroid Build Coastguard Worker args.fsckerofs_path, 46*7594170eSAndroid Build Coastguard Worker 'extract', 47*7594170eSAndroid Build Coastguard Worker os.path.join(d, 'standalones', name), 48*7594170eSAndroid Build Coastguard Worker extractedDir, 49*7594170eSAndroid Build Coastguard Worker ], check=True) 50*7594170eSAndroid Build Coastguard Worker 51*7594170eSAndroid Build Coastguard Worker result += name + ':\n' 52*7594170eSAndroid Build Coastguard Worker all_files = [] 53*7594170eSAndroid Build Coastguard Worker for root, _, files in os.walk(extractedDir): 54*7594170eSAndroid Build Coastguard Worker for f in files: 55*7594170eSAndroid Build Coastguard Worker if f == 'libcutils.so': 56*7594170eSAndroid Build Coastguard Worker all_files.append(os.path.join(root, f)) 57*7594170eSAndroid Build Coastguard Worker all_files.sort() 58*7594170eSAndroid Build Coastguard Worker for f in all_files: 59*7594170eSAndroid Build Coastguard Worker readOutput = subprocess.check_output([ 60*7594170eSAndroid Build Coastguard Worker args.readelf_path, 61*7594170eSAndroid Build Coastguard Worker '-h', 62*7594170eSAndroid Build Coastguard Worker f, 63*7594170eSAndroid Build Coastguard Worker ], text=True) 64*7594170eSAndroid Build Coastguard Worker arch = [x.strip().removeprefix('Machine:').strip() for x in readOutput.split('\n') if x.strip().startswith('Machine:')] 65*7594170eSAndroid Build Coastguard Worker if len(arch) != 1: 66*7594170eSAndroid Build Coastguard Worker sys.exit(f"Expected 1 arch, got {arch}") 67*7594170eSAndroid Build Coastguard Worker rel = os.path.relpath(f, extractedDir) 68*7594170eSAndroid Build Coastguard Worker result += f' {rel}: {arch[0]}\n' 69*7594170eSAndroid Build Coastguard Worker 70*7594170eSAndroid Build Coastguard Worker with open(args.output, 'w') as f: 71*7594170eSAndroid Build Coastguard Worker f.write(result) 72*7594170eSAndroid Build Coastguard Worker 73*7594170eSAndroid Build Coastguard Workerif __name__ == "__main__": 74*7594170eSAndroid Build Coastguard Worker main() 75