mirror of
https://github.com/apache/nuttx.git
synced 2026-05-26 10:46:28 +08:00
gdbserver.py: use lief inside of pyelftools to improve load speed
test: an elf have 273MB, load symbol 32s to 2s Signed-off-by: anjiahao <anjiahao@xiaomi.com>
This commit is contained in:
+47
-65
@@ -32,8 +32,11 @@ import subprocess
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
import elftools
|
||||
from elftools.elf.elffile import ELFFile
|
||||
try:
|
||||
import lief
|
||||
except ImportError:
|
||||
print("Please install lief package: pip3 install lief")
|
||||
sys.exit(1)
|
||||
|
||||
# ELF section flags
|
||||
SHF_WRITE = 0x1
|
||||
@@ -301,28 +304,21 @@ class DumpELFFile:
|
||||
|
||||
def parse(self, load_symbol: bool):
|
||||
self.__memories = []
|
||||
elf = ELFFile.load_from_path(self.elffile)
|
||||
self.__arch = elf.get_machine_arch().lower().replace("-", "")
|
||||
self.__xlen = elf.elfclass
|
||||
elf = lief.parse(self.elffile)
|
||||
self.__arch = elf.header.machine_type.name.lower().replace("-", "")
|
||||
if elf.header.identity_class == lief.ELF.Header.CLASS.ELF32:
|
||||
self.__xlen = 32
|
||||
else:
|
||||
self.__xlen = 64
|
||||
|
||||
for section in elf.iter_sections():
|
||||
# REALLY NEED to match exact type as all other sections
|
||||
# (debug, text, etc.) are descendants where
|
||||
# isinstance() would match.
|
||||
if (
|
||||
type(section) is not elftools.elf.sections.Section
|
||||
): # pylint: disable=unidiomatic-typecheck
|
||||
continue
|
||||
|
||||
size = section["sh_size"]
|
||||
flags = section["sh_flags"]
|
||||
start = section["sh_addr"]
|
||||
for section in elf.sections:
|
||||
size = section.size
|
||||
flags = section.flags
|
||||
start = section.virtual_address
|
||||
end = start + size - 1
|
||||
|
||||
store = False
|
||||
desc = "?"
|
||||
|
||||
if section["sh_type"] == "SHT_PROGBITS":
|
||||
if section.type == lief.ELF.Section.TYPE.PROGBITS:
|
||||
if (flags & SHF_ALLOC_EXEC) == SHF_ALLOC_EXEC:
|
||||
# Text section
|
||||
store = True
|
||||
@@ -335,41 +331,35 @@ class DumpELFFile:
|
||||
# Read only data section
|
||||
store = True
|
||||
desc = "read-only data"
|
||||
|
||||
if store:
|
||||
memory = pack_memory(start, end, section.data())
|
||||
memory = pack_memory(start, end, bytes(section.content))
|
||||
logger.debug(
|
||||
f"ELF Section: {hex(memory['start'])} to {hex(memory['end'])} of size {len(memory['data'])} ({desc})"
|
||||
)
|
||||
|
||||
self.__memories.append(memory)
|
||||
|
||||
# record first text segment address
|
||||
for segment in elf.iter_segments():
|
||||
if segment.header.p_flags & 1 and not self.__text:
|
||||
for segment in elf.segments:
|
||||
if segment.flags == 0x1 and not self.__text:
|
||||
self.__text = segment.header.p_vaddr
|
||||
|
||||
self.load_symbol = load_symbol
|
||||
if load_symbol:
|
||||
symtab = elf.get_section_by_name(".symtab")
|
||||
self.symbol = {}
|
||||
for symbol in symtab.iter_symbols():
|
||||
if symbol["st_info"]["type"] != "STT_OBJECT":
|
||||
continue
|
||||
|
||||
if symbol.name in (
|
||||
"g_tcbinfo",
|
||||
"g_pidhash",
|
||||
"g_npidhash",
|
||||
"g_last_regs",
|
||||
"g_running_tasks",
|
||||
):
|
||||
self.symbol[symbol.name] = symbol
|
||||
logger.debug(
|
||||
f"name:{symbol.name} size:{symbol['st_size']} value:{hex(symbol['st_value'])}"
|
||||
)
|
||||
|
||||
elf.close()
|
||||
for symbol in elf.symbols:
|
||||
if symbol.name in (
|
||||
"g_tcbinfo",
|
||||
"g_pidhash",
|
||||
"g_npidhash",
|
||||
"g_last_regs",
|
||||
"g_running_tasks",
|
||||
):
|
||||
self.symbol[symbol.name] = {}
|
||||
self.symbol[symbol.name]["st_size"] = symbol.size
|
||||
self.symbol[symbol.name]["st_value"] = symbol.value
|
||||
logger.debug(
|
||||
f"name:{symbol.name} size:{symbol.size} value:{hex(symbol.value)}"
|
||||
)
|
||||
return True
|
||||
|
||||
def merge(self, other):
|
||||
@@ -520,28 +510,23 @@ class CoreDumpFile:
|
||||
if coredump is None:
|
||||
return
|
||||
|
||||
with open(coredump, "rb") as f:
|
||||
elffile = ELFFile(f)
|
||||
for segment in elffile.iter_segments():
|
||||
if segment["p_type"] != "PT_LOAD":
|
||||
continue
|
||||
logger.debug(f"Segment Flags: {segment['p_flags']}")
|
||||
elf = lief.parse(coredump)
|
||||
for segment in elf.segments:
|
||||
if segment.type == lief.ELF.Segment.TYPE.LOAD:
|
||||
logger.debug(
|
||||
f"Segment Offset: {segment['p_offset']}",
|
||||
f"Segment Offset: {segment.file_offset}",
|
||||
)
|
||||
logger.debug(f"Segment Virtual Address: {hex(segment['p_vaddr'])}")
|
||||
logger.debug(f"Segment Physical Address: {hex(segment['p_paddr'])}")
|
||||
logger.debug(f"Segment File Size:{segment['p_filesz']}")
|
||||
logger.debug(f"Segment Memory Size:{segment['p_memsz']}")
|
||||
logger.debug(f"Segment Alignment:{segment['p_align']}")
|
||||
logger.debug(f"Segment Virtual Address: {hex(segment.virtual_address)}")
|
||||
logger.debug(
|
||||
f"Segment Physical Address: {hex(segment.physical_address)}"
|
||||
)
|
||||
logger.debug(f"Segment File Size:{segment.physical_size}")
|
||||
logger.debug(f"Segment Alignment:{segment.alignment}")
|
||||
logger.debug("=" * 40)
|
||||
f.seek(segment["p_offset"], 0)
|
||||
data = f.read(segment["p_filesz"])
|
||||
self.__memories.append(
|
||||
pack_memory(
|
||||
segment["p_vaddr"], segment["p_vaddr"] + len(data), data
|
||||
)
|
||||
)
|
||||
start = segment.virtual_address
|
||||
end = start + segment.virtual_size
|
||||
data = bytes(segment.content)
|
||||
self.__memories.append(pack_memory(start, end, data))
|
||||
|
||||
def get_memories(self):
|
||||
return self.__memories
|
||||
@@ -672,7 +657,6 @@ class GDBStub:
|
||||
self.put_gdb_packet(pkt)
|
||||
|
||||
def handle_register_group_read_packet(self):
|
||||
|
||||
def put_register_packet(regs):
|
||||
reg_fmt = self.reg_fmt
|
||||
pkt = b""
|
||||
@@ -703,7 +687,6 @@ class GDBStub:
|
||||
logger.debug(f"pkt: {pkt}")
|
||||
|
||||
def put_one_register_packet(regs):
|
||||
|
||||
reg = int(pkt[1:].decode("utf8"), 16)
|
||||
regval = None
|
||||
|
||||
@@ -971,7 +954,6 @@ class GDBStub:
|
||||
|
||||
for thread in self.threadinfo:
|
||||
if thread["tcb"]["pid"] == pid:
|
||||
|
||||
pkt_str = "Name: %s, State: %d, Pri: %d, Stack: %x, Size: %d" % (
|
||||
thread["tcb"]["name"],
|
||||
thread["tcb"]["state"],
|
||||
|
||||
Reference in New Issue
Block a user