| 562 | |
| 563 | template <class Types> |
| 564 | cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString( |
| 565 | unsigned int tag) |
| 566 | { |
| 567 | // Short-circuit if already checked. |
| 568 | auto dssi = this->DynamicSectionStrings.find(tag); |
| 569 | if (dssi != this->DynamicSectionStrings.end()) { |
| 570 | if (dssi->second.Position > 0) { |
| 571 | return &dssi->second; |
| 572 | } |
| 573 | return nullptr; |
| 574 | } |
| 575 | |
| 576 | // Create an entry for this tag. Assume it is missing until found. |
| 577 | StringEntry& se = this->DynamicSectionStrings[tag]; |
| 578 | se.Position = 0; |
| 579 | se.Size = 0; |
| 580 | se.IndexInSection = -1; |
| 581 | |
| 582 | // Try reading the dynamic section. |
| 583 | if (!this->LoadDynamicSection()) { |
| 584 | return nullptr; |
| 585 | } |
| 586 | |
| 587 | // Get the string table referenced by the DYNAMIC section. |
| 588 | ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex]; |
| 589 | if (sec.sh_link >= this->SectionHeaders.size()) { |
| 590 | this->SetErrorMessage("Section DYNAMIC has invalid string table index."); |
| 591 | return nullptr; |
| 592 | } |
| 593 | ELF_Shdr const& strtab = this->SectionHeaders[sec.sh_link]; |
| 594 | |
| 595 | // Look for the requested entry. |
| 596 | for (auto di = this->DynamicSectionEntries.begin(); |
| 597 | di != this->DynamicSectionEntries.end(); ++di) { |
| 598 | ELF_Dyn& dyn = *di; |
| 599 | if (static_cast<tagtype>(dyn.d_tag) == static_cast<tagtype>(tag)) { |
| 600 | // We found the tag requested. |
| 601 | // Make sure the position given is within the string section. |
| 602 | if (dyn.d_un.d_val >= strtab.sh_size) { |
| 603 | this->SetErrorMessage("Section DYNAMIC references string beyond " |
| 604 | "the end of its string section."); |
| 605 | return nullptr; |
| 606 | } |
| 607 | |
| 608 | // Seek to the position reported by the entry. |
| 609 | unsigned long first = static_cast<unsigned long>(dyn.d_un.d_val); |
| 610 | unsigned long last = first; |
| 611 | unsigned long end = static_cast<unsigned long>(strtab.sh_size); |
| 612 | this->Stream->seekg(strtab.sh_offset + first); |
| 613 | |
| 614 | // Read the string. It may be followed by more than one NULL |
| 615 | // terminator. Count the total size of the region allocated to |
| 616 | // the string. This assumes that the next string in the table |
| 617 | // is non-empty, but the "chrpath" tool makes the same |
| 618 | // assumption. |
| 619 | bool terminated = false; |
| 620 | char c; |
| 621 | while (last != end && this->Stream->get(c) && !(terminated && c)) { |
no test coverage detected