Skip to content

Commit

Permalink
fix pointer arithemtic bug for extra padding in structs
Browse files Browse the repository at this point in the history
  • Loading branch information
robertmuth committed Feb 12, 2024
1 parent f49bcb3 commit d2c565d
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 10 deletions.
10 changes: 8 additions & 2 deletions FrontEnd/cwast.py
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,8 @@ def NodeCommon(cls):
# Typing
############################################################

def align(x, a):
return (x + a - 1) // a * a

@dataclasses.dataclass()
class CanonType:
Expand All @@ -813,7 +815,7 @@ class CanonType:
children: List["CanonType"] = dataclasses.field(default_factory=list)
#
ast_node: Optional[Union["DefRec", "DefEnum"]] = None
#
# will be filled in by type_corpus.
alignment: int = -1
size: int = -1
register_types: Optional[List[Any]] = None
Expand Down Expand Up @@ -928,6 +930,10 @@ def contained_type(self) -> "CanonType":
else:
assert False, f"unexpected type: {self.name}"

def aligned_size(self) -> int:
# somtimes we need to round up. e.g. struct {int32, int8} needs 3 bytes padding
return align(self.size, self.alignment)

def array_dim(self):
assert self.is_array()
return self.dim
Expand Down Expand Up @@ -3005,7 +3011,7 @@ def EliminateEphemeralsRecursively(node):
child = getattr(node, f)
if isinstance(child, EphemeralList):
new_child = _MaybeFlattenEphemeralList([child])
assert len(new_child) == 1
assert len(new_child) == 1, f"{f} {node.__class__} {len(new_child)}"
setattr(node, f, new_child[0])
EliminateEphemeralsRecursively(child)
elif nfd.kind is NFK.LIST:
Expand Down
7 changes: 4 additions & 3 deletions FrontEnd/emit_ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,9 @@ def EmitIRExpr(node, tc: type_corpus.TypeCorpus, id_gen: identifier.IdGenIR) ->
ct: cwast.CanonType = node.expr1.x_type
if node.pointer_expr_kind is cwast.POINTER_EXPR_KIND.INCP:
assert ct.is_pointer()
#print ("@@@@@ ", ct, ct.underlying_pointer_type().size)
offset = OffsetScaleToOffset(
node.expr2, ct.underlying_pointer_type().size, tc, id_gen)
node.expr2, ct.underlying_pointer_type().aligned_size(), tc, id_gen)
kind = tc.get_data_address_reg_type()
print(f"{TAB}lea {res}:{kind} = {base} {offset}")
else:
Expand All @@ -436,7 +437,7 @@ def EmitIRExpr(node, tc: type_corpus.TypeCorpus, id_gen: identifier.IdGenIR) ->
f"{TAB}bitcast {res}:{node.type.x_type.get_single_register_type()} = {expr}")
return res
elif isinstance(node, cwast.ExprUnsafeCast):
return EmitIRExpr(node.expr, tc, id_gen)
return EmitIRExpr(node.expr, tc, id_gen)
elif isinstance(node, cwast.ExprNarrow):
if ct_dst.is_void_or_wrapped_void():
return None
Expand Down Expand Up @@ -761,6 +762,7 @@ def _EmitMem(data, comment) -> int:
assert False
return len(data)


_BYTE_ZERO = b"\0"
_BYTE_UNDEF = b"\0"
_BYTE_PADDING = b"\x6f" # intentioanlly not zero?
Expand Down Expand Up @@ -1036,7 +1038,6 @@ def GetIdGen(fun):
eliminated_nodes.add(cwast.Expr3)
mod_gen.body_mod += constant_pool.GetDefGlobals()


slice_to_struct_map = canonicalize_slice.MakeSliceTypeReplacementMap(
mod_topo_order, tc)
mod_gen.body_mod += [
Expand Down
6 changes: 1 addition & 5 deletions FrontEnd/type_corpus.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,11 +414,7 @@ def _get_size_and_alignment(self, tc: cwast.CanonType):
len_field_size = self._target_arch_config.uint_bitwidth // 8
return ptr_field_size + len_field_size, ptr_field_size
elif tc.node is cwast.TypeArray:
alignment = tc.children[0].alignment
size = tc.children[0].size
# somtimes we need to round up. e.g. struct {int32, int8} needs 3 bytes padding
size = align(size, alignment)
return size * tc.dim, alignment
return tc.children[0].aligned_size() * tc.dim, tc.children[0].alignment
elif tc.node is cwast.TypeUnion:
return _get_size_and_offset_for_sum_type(
tc, self._target_arch_config.typeid_bitwidth // 8,
Expand Down

0 comments on commit d2c565d

Please sign in to comment.