blob: b6aeae24c29a5d6f2b7f2f52d909e376ff608da1 [file] [log] [blame]
#!/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())