1#!/usr/bin/env python 2# Strip unnecessary data from a core dump to reduce its size. 3# 4# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5# See https://llvm.org/LICENSE.txt for license information. 6# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 8import argparse 9import os.path 10import sys 11import tempfile 12 13from elftools.elf.elffile import ELFFile 14 15 16def strip_non_notes(elf, inf, outf): 17 next_segment_offset = min(x.header.p_offset for x in elf.iter_segments()) 18 copy_segments = filter(lambda x: x.header.p_type == "PT_NOTE", elf.iter_segments()) 19 20 # first copy the headers 21 inf.seek(0) 22 outf.write(inf.read(next_segment_offset)) 23 24 for seg in copy_segments: 25 assert seg.header.p_filesz > 0 26 27 inf.seek(seg.header.p_offset) 28 # fill the area between last write and new offset with zeros 29 outf.seek(seg.header.p_offset) 30 31 # now copy the segment 32 outf.write(inf.read(seg.header.p_filesz)) 33 34 35def main(): 36 argp = argparse.ArgumentParser() 37 action = argp.add_mutually_exclusive_group(required=True) 38 action.add_argument( 39 "--strip-non-notes", 40 action="store_const", 41 const=strip_non_notes, 42 dest="action", 43 help="Strip all segments except for notes", 44 ) 45 argp.add_argument("elf", help="ELF file to strip (in place)", nargs="+") 46 args = argp.parse_args() 47 48 for path in args.elf: 49 with open(path, "rb") as f: 50 elf = ELFFile(f) 51 # we do not support copying the section table now 52 assert elf.num_sections() == 0 53 54 tmpf = tempfile.NamedTemporaryFile(dir=os.path.dirname(path), delete=False) 55 try: 56 args.action(elf, f, tmpf) 57 except: 58 os.unlink(tmpf.name) 59 raise 60 else: 61 os.rename(tmpf.name, path) 62 63 return 0 64 65 66if __name__ == "__main__": 67 sys.exit(main()) 68