import argparse
import os
import shutil
import gdb
from . import autocompeletion, mm, utils
def create_file_with_size(filename, size):
with open(filename, "wb") as f:
f.write(b"\0" * size)
@autocompeletion.complete
class NXGcore(gdb.Command):
__doc__ = "Generate a core file with specified memory range."
def get_argparser(self):
parser = argparse.ArgumentParser(description=self.__doc__)
parser.add_argument("-o", "--output", metavar="file", help="Gcore output file")
parser.add_argument(
"-p",
"--prefix",
help="Prefix for objcopy tool",
default="",
type=str,
)
parser.add_argument(
"--trust-readonly",
help="Trust readonly section from elf, bypass read from device.",
action="store_true",
default=True,
)
parser.add_argument(
"--no-trust-readonly",
help="Do not trust readonly section from elf, read from device.",
action="store_false",
dest="trust_readonly",
)
parser.add_argument(
"-r",
"--memrange",
type=str,
)
return parser
def __init__(self):
self.tempfile = utils.import_check(
"tempfile",
errmsg="No tempfile module found, please try gdb-multiarch instead.\n",
)
if not self.tempfile:
return
super().__init__("nxgcore", gdb.COMMAND_USER)
self.parser = self.get_argparser()
@utils.dont_repeat_decorator
def invoke(self, args, from_tty):
try:
args = self.parser.parse_args(gdb.string_to_argv(args))
except SystemExit:
return
objfile = gdb.current_progspace().objfiles()[0]
elffile = objfile.filename
tmpfile = self.tempfile.NamedTemporaryFile(suffix=".elf")
shutil.copy(elffile, tmpfile.name)
if args.output:
corefile = args.output
else:
corefile = elffile + ".core"
memrange = mm.get_memrange(args.memrange)
for i, (start, end) in enumerate(memrange):
section = tmpfile.name + f"{i // 3}"
create_file_with_size(section, end - start)
gdb.write(f"Using objcopy: {args.prefix}objcopy")
os.system(
f"{args.prefix}objcopy --add-section {section}={section} "
f"--set-section-flags {section}=noload,alloc {tmpfile.name}"
)
os.system(
f"{args.prefix}objcopy --change-section-address "
f"{section}={hex(start)} {tmpfile.name}"
)
os.remove(section)
gdb.execute(f"file {tmpfile.name}")
if args.trust_readonly:
gdb.execute("set trust-readonly-sections on")
gdb.execute(f"gcore {corefile}")
if args.trust_readonly:
gdb.execute("set trust-readonly-sections off")
gdb.execute(f'file "{elffile}"')
tmpfile.close()
print(f"Please run gdbserver.py to parse {corefile}")