Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 97368988 authored by Zach Johnson's avatar Zach Johnson
Browse files

rusty-gd: handle padding in sizes

need to unroll size concatenation, to ensure padding only applies to
size contributions *before* it exists

Bug: 171749953
Tag: #gd-refactor
Test: gd/cert/run --rhost DirectHciTest
Change-Id: If7eabc0b1f499c2168fec6df6c5e294c5672b8e4
parent 569da72a
Loading
Loading
Loading
Loading
+32 −14
Original line number Diff line number Diff line
@@ -650,23 +650,41 @@ void ParentDef::GenSizeRetVal(std::ostream& s) const {
  auto fields = fields_.GetFieldsWithoutTypes({
      BodyField::kFieldType,
  });
  s << "let ret = 0;";
  for (int i = 0; i < fields.size(); i++) {
    size += fields[i]->GetSize().bits();
  }
    auto field = fields[i];
    bool is_padding = field->GetFieldType() == PaddingField::kFieldType;
    bool is_vector = field->GetFieldType() == VectorField::kFieldType;
    if (is_padding || is_vector) {
      if (size > 0) {
        if (size % 8 != 0) {
          ERROR() << "size is not a multiple of 8!\n";
        }
  s << size / 8;
        s << "let ret = ret + " << size / 8 << ";";
        size = 0;
      }

  fields = fields_.GetFieldsWithTypes({
      VectorField::kFieldType,
  });
  for (int i = 0; i < fields.size(); i++) {
    const VectorField* vector = (VectorField*)fields[i];
      if (is_vector) {
        const VectorField* vector = (VectorField*)field;
        if (vector->element_size_.empty() || vector->element_size_.has_dynamic()) {
      s << " + self." << vector->GetName() << ".iter().fold(0, |acc, x| acc + x.get_total_size())";
          s << "let ret = ret + self." << vector->GetName() << ".iter().fold(0, |acc, x| acc + x.get_total_size());";
        } else {
          s << "let ret = ret + (self." << vector->GetName() << ".len() * ((" << vector->element_size_ << ") / 8));";
        }
      } else {
      s << " + (self." << vector->GetName() << ".len() * ((" << vector->element_size_ << ") / 8))";
        auto padded = field->GetSize().bytes();
        s << "let ret = if ret < " << padded << " { " << padded << " } else { ret };";
      }
    } else {
      size += field->GetSize().bits();
    }
  }
  if (size > 0) {
    if (size % 8 != 0) {
      ERROR() << "size is not a multiple of 8!\n";
    }
    s << "let ret = ret + " << size / 8 << ";";
  }

  s << "ret";
}