| #!/usr/bin/env python |
| # Strip unnecessary data from a core dump to reduce its size. |
| # |
| # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| # See https://llvm.org/LICENSE.txt for license information. |
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| import argparse |
| import os.path |
| import sys |
| import tempfile |
| |
| from elftools.elf.elffile import ELFFile |
| |
| |
| def strip_non_notes(elf, inf, outf): |
| next_segment_offset = min(x.header.p_offset for x in elf.iter_segments()) |
| copy_segments = filter(lambda x: x.header.p_type == "PT_NOTE", elf.iter_segments()) |
| |
| # first copy the headers |
| inf.seek(0) |
| outf.write(inf.read(next_segment_offset)) |
| |
| for seg in copy_segments: |
| assert seg.header.p_filesz > 0 |
| |
| inf.seek(seg.header.p_offset) |
| # fill the area between last write and new offset with zeros |
| outf.seek(seg.header.p_offset) |
| |
| # now copy the segment |
| outf.write(inf.read(seg.header.p_filesz)) |
| |
| |
| def main(): |
| argp = argparse.ArgumentParser() |
| action = argp.add_mutually_exclusive_group(required=True) |
| action.add_argument( |
| "--strip-non-notes", |
| action="store_const", |
| const=strip_non_notes, |
| dest="action", |
| help="Strip all segments except for notes", |
| ) |
| argp.add_argument("elf", help="ELF file to strip (in place)", nargs="+") |
| args = argp.parse_args() |
| |
| for path in args.elf: |
| with open(path, "rb") as f: |
| elf = ELFFile(f) |
| # we do not support copying the section table now |
| assert elf.num_sections() == 0 |
| |
| tmpf = tempfile.NamedTemporaryFile(dir=os.path.dirname(path), delete=False) |
| try: |
| args.action(elf, f, tmpf) |
| except: |
| os.unlink(tmpf.name) |
| raise |
| else: |
| os.rename(tmpf.name, path) |
| |
| return 0 |
| |
| |
| if __name__ == "__main__": |
| sys.exit(main()) |