fxconv: alignment parameter in fxconv.ptr() (default 4)

This commit is contained in:
Lephenixnoir 2023-08-20 10:41:53 +02:00
parent 11e3b614c2
commit be8c1f0d94
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495

View file

@ -174,14 +174,14 @@ def u16(x):
def u32(x): def u32(x):
return bytes([ (x >> 24) & 255, (x >> 16) & 255, (x >> 8) & 255, x & 255 ]) return bytes([ (x >> 24) & 255, (x >> 16) & 255, (x >> 8) & 255, x & 255 ])
def ref(base, offset=None, padding=None, prefix_underscore=True): def ref(base, offset=None, padding=None, prefix_underscore=True, align=None):
if isinstance(base, bytes) or isinstance(base, bytearray): if isinstance(base, bytes) or isinstance(base, bytearray):
base = bytes(base) base = bytes(base)
if offset is not None: if offset is not None:
raise FxconvError(f"reference to bytes does not allow offset") raise FxconvError(f"reference to bytes does not allow offset")
if padding and len(base) % padding != 0: if padding and len(base) % padding != 0:
base += bytes(padding - len(base) % padding) base += bytes(padding - len(base) % padding)
return Ref("bytes", base) return Ref("bytes", base, align or 4)
elif isinstance(base, str): elif isinstance(base, str):
if padding is not None: if padding is not None:
@ -191,19 +191,24 @@ def ref(base, offset=None, padding=None, prefix_underscore=True):
if offset is not None: if offset is not None:
offset = int(offset) offset = int(offset)
base = f"{base} + {offset}" base = f"{base} + {offset}"
return Ref("name", base) return Ref("name", base, align or 4)
elif isinstance(base, ObjectData): elif isinstance(base, ObjectData):
if offset is not None or padding is not None: if offset is not None:
raise FxconvError("reference to structure does not allow offset " + raise FxconvError("reference to structure does not allow offset")
"or padding") if padding is not None:
return Ref("struct", base) raise FxconvError("reference to structure does not allow padding")
# Allow over-aligning the structure (but not more than 4)
align = max(base.alignment, align or 4)
if align > 4:
raise FxconvError(f"align {align} > 4 will not be honored (yet)")
return Ref("struct", base, align)
else: else:
raise FxconvError(f"invalid type {type(base)} for ref()") raise FxconvError(f"invalid type {type(base)} for ref()")
def ptr(base): def ptr(*args, **kwargs):
return ref(base) return ref(*args, **kwargs)
def chars(text, length, require_final_nul=True): def chars(text, length, require_final_nul=True):
btext = bytes(text, 'utf-8') btext = bytes(text, 'utf-8')
@ -221,7 +226,7 @@ def sym(name):
# "bytes" -> target is a bytes(), we point to that data # "bytes" -> target is a bytes(), we point to that data
# "name" -> target is an str like "_sym+2", we point to that # "name" -> target is an str like "_sym+2", we point to that
# "struct" -> target is an ObjectData # "struct" -> target is an ObjectData
Ref = collections.namedtuple("Ref", ["kind", "target"]) Ref = collections.namedtuple("Ref", ["kind", "target", "align"])
Sym = collections.namedtuple("Sym", ["name"]) Sym = collections.namedtuple("Sym", ["name"])
@ -282,13 +287,14 @@ class ObjectData:
# end of the structure # end of the structure
for el in inner: for el in inner:
if isinstance(el, Ref) and el.kind == "bytes": if isinstance(el, Ref) and el.kind == "bytes":
elements.append(Ref("name", f"{symbol} + {size}")) size += self.align(size, el.align, outer)
elements.append(Ref("name", f"{symbol} + {size}", None))
outer.append(el.target) outer.append(el.target)
size += self.element_size(el.target) size += self.element_size(el.target)
elif isinstance(el, Ref) and el.kind == "struct": elif isinstance(el, Ref) and el.kind == "struct":
size += self.align(size, el.target.alignment, outer) size += self.align(size, el.target.alignment, outer)
elements.append(Ref("name", f"{symbol} + {size}")) elements.append(Ref("name", f"{symbol} + {size}", None))
code, code_size = el.target.link(f"{symbol} + {size}") code, code_size = el.target.link(f"{symbol} + {size}")
outer.append((code, code_size)) outer.append((code, code_size))
size += code_size size += code_size