util: bsp-tool: extract bootstrap exec constants and store them in the bsp image

This commit is contained in:
2026-02-19 19:23:28 +00:00
parent 3d28ed2cb8
commit 0e562f6a79
4 changed files with 254 additions and 6 deletions

1
util/lib/__init__.py Normal file
View File

@@ -0,0 +1 @@
from . import *

102
util/lib/elf.py Normal file
View File

@@ -0,0 +1,102 @@
from enum import Enum, Flag
import struct
class ELFPType(Enum):
NULL = 0
LOAD = 1
DYNAMIC = 2
INTERP = 3
NOTE = 4
SHLIB = 5
PHDR = 6
TLS = 7
class ELFPFlag(Flag):
NONE = 0
EXEC = 1
WRITE = 2
READ = 4
class ELFEndian(Enum):
LITTLE = 1
BIG = 2
class ELF64Phdr:
def __init__(self):
self.type = ELFPType.NULL
self.flags = 0
self.offset = 0
self.vaddr = 0
self.paddr = 0
self.filesz = 0
self.memsz = 0
self.align = 0
return
def parse(self, buf, endian):
endian_marker = '>' if endian == ELFEndian.BIG else '<'
entry = struct.unpack('{}IIQQQQQQ'.format(endian_marker), buf)
self.type = ELFPType(entry[0])
self.flags = ELFPFlag.NONE
self.offset = entry[2]
self.vaddr = entry[3]
self.paddr = entry[4]
self.filesz = entry[5]
self.memsz = entry[6]
self.align = entry[7]
if entry[1] & ELFPFlag.READ.value: self.flags |= ELFPFlag.READ
if entry[1] & ELFPFlag.WRITE.value: self.flags |= ELFPFlag.WRITE
if entry[1] & ELFPFlag.EXEC.value: self.flags |= ELFPFlag.EXEC
class ELF64Image:
def __init__(self):
self.ph_list = []
self.text = None
self.data = None
self.entry = None
def load(self, path):
f = open(path, mode='rb')
ident_bytes = f.read(16)
ident = struct.unpack('BBBBBBBBBBBBBBBB', ident_bytes)
if ident[0] != 0x7F or ident[1] != ord('E') or ident[2] != ord('L') or ident[3] != ord('F'):
f.close()
return -1
endian = ELFEndian(ident[5])
endian_marker = '>' if endian == ELFEndian.BIG else '<'
hdr_bytes = f.read(48)
hdr = struct.unpack('{}HHIQQQIHHHHHH'.format(endian_marker), hdr_bytes)
self.entry = hdr[3]
phoff = hdr[4]
phnum = hdr[9]
phentsize = hdr[8]
for i in range(0, phnum):
f.seek(phoff + (i * phentsize))
phdr_bytes = f.read(phentsize)
phdr = ELF64Phdr()
phdr.parse(phdr_bytes, endian)
if phdr.flags == ELFPFlag.READ | ELFPFlag.EXEC:
self.text = phdr
if phdr.flags == ELFPFlag.READ | ELFPFlag.WRITE:
self.data = phdr
self.ph_list.append(phdr)
f.close()
return 0

101
util/lib/manifest.py Normal file
View File

@@ -0,0 +1,101 @@
import json
class Component:
def __init__(self):
self.headers = []
self.binaries = []
return
def add_headers(self, src, dest):
for h in self.headers:
if h['src'] == src and h['dest'] == dest:
return
headers = {}
headers['src'] = src
headers['dest'] = dest
self.headers.append(headers)
def add_binary(self, src, dest):
for b in self.binaries:
if b['src'] == src and b['dest'] == dest:
return
binary = {}
binary['src'] = src
binary['dest'] = dest
self.binaries.append(binary)
def serialise(self):
data = {}
if len(self.headers) > 0:
data['headers'] = self.headers
if len(self.binaries) > 0:
data['binaries'] = self.binaries
return data
def deserialise(self, data):
if 'headers' in data:
self.headers = data['headers']
if 'binaries' in data:
self.binaries = data['binaries']
def get_headers(self):
return self.headers
def get_binaries(self):
return self.binaries
class Manifest:
def __init__(self, path):
self.path = path
self.components = {}
def load(self):
with open(self.path, 'r') as f:
self.data = json.load(f)
if 'components' not in self.data:
return 0
for n, t in self.data['components'].items():
component = Component()
component.deserialise(t)
self.components[n] = component
def save(self):
component_data = {}
for n, t in self.components.items():
d = t.serialise()
component_data[n] = d
self.data['components'] = component_data
with open(self.path, 'w') as f:
json.dump(self.data, f, indent=4)
def reset(self):
self.data = {}
def get_component(self, name):
if name in self.components:
return self.components[name]
component = Component()
self.components[name] = component
return component
def get_all_components(self):
return self.components