| 496 | } |
| 497 | |
| 498 | void BinaryAnnotator::BuildTable(const uint64_t table_offset, |
| 499 | const BinarySectionType type, |
| 500 | const reflection::Object *const table) { |
| 501 | if (ContainsSection(table_offset)) { return; } |
| 502 | |
| 503 | BinaryRegionComment vtable_offset_comment; |
| 504 | vtable_offset_comment.type = BinaryRegionCommentType::TableVTableOffset; |
| 505 | |
| 506 | const auto vtable_soffset = ReadScalar<int32_t>(table_offset); |
| 507 | |
| 508 | if (!vtable_soffset.has_value()) { |
| 509 | const uint64_t remaining = RemainingBytes(table_offset); |
| 510 | SetError(vtable_offset_comment, BinaryRegionStatus::ERROR_INCOMPLETE_BINARY, |
| 511 | "4"); |
| 512 | |
| 513 | AddSection( |
| 514 | table_offset, |
| 515 | MakeSingleRegionBinarySection( |
| 516 | table->name()->str(), type, |
| 517 | MakeBinaryRegion(table_offset, remaining, BinaryRegionType::Unknown, |
| 518 | remaining, 0, vtable_offset_comment))); |
| 519 | |
| 520 | // If there aren't enough bytes left to read the vtable offset, there is |
| 521 | // nothing we can do. |
| 522 | return; |
| 523 | } |
| 524 | |
| 525 | // Tables start with the vtable |
| 526 | const uint64_t vtable_offset = table_offset - vtable_soffset.value(); |
| 527 | |
| 528 | if (!IsValidOffset(vtable_offset)) { |
| 529 | SetError(vtable_offset_comment, |
| 530 | BinaryRegionStatus::ERROR_OFFSET_OUT_OF_BINARY); |
| 531 | |
| 532 | AddSection(table_offset, |
| 533 | MakeSingleRegionBinarySection( |
| 534 | table->name()->str(), type, |
| 535 | MakeBinaryRegion(table_offset, sizeof(int32_t), |
| 536 | BinaryRegionType::SOffset, 0, vtable_offset, |
| 537 | vtable_offset_comment))); |
| 538 | |
| 539 | // There isn't much to do with an invalid vtable offset, as we won't be able |
| 540 | // to intepret the rest of the table fields. |
| 541 | return; |
| 542 | } |
| 543 | |
| 544 | std::vector<BinaryRegion> regions; |
| 545 | regions.push_back(MakeBinaryRegion(table_offset, sizeof(int32_t), |
| 546 | BinaryRegionType::SOffset, 0, |
| 547 | vtable_offset, vtable_offset_comment)); |
| 548 | |
| 549 | // Parse the vtable first so we know what the rest of the fields in the table |
| 550 | // are. |
| 551 | const VTable *const vtable = |
| 552 | GetOrBuildVTable(vtable_offset, table, table_offset); |
| 553 | |
| 554 | if (vtable == nullptr) { |
| 555 | // There is no valid vtable for this table, so we cannot process the rest of |
nothing calls this directly
no test coverage detected