예제 #1
0
파일: Symtab.cpp 프로젝트: CTSRD-CHERI/lldb
void
Symtab::InitAddressIndexes()
{
    // Protected function, no need to lock mutex...
    if (!m_file_addr_to_index_computed && !m_symbols.empty())
    {
        m_file_addr_to_index_computed = true;

        FileRangeToIndexMap::Entry entry;
        const_iterator begin = m_symbols.begin();
        const_iterator end = m_symbols.end();
        for (const_iterator pos = m_symbols.begin(); pos != end; ++pos)
        {
            if (pos->ValueIsAddress())
            {
                entry.SetRangeBase(pos->GetAddressRef().GetFileAddress());
                entry.SetByteSize(pos->GetByteSize());
                entry.data = std::distance(begin, pos);
                m_file_addr_to_index.Append(entry);
            }
        }
        const size_t num_entries = m_file_addr_to_index.GetSize();
        if (num_entries > 0)
        {
            m_file_addr_to_index.Sort();
            m_file_addr_to_index.CalculateSizesOfZeroByteSizeRanges();

            // Now our last symbols might not have had sizes because there
            // was no subsequent symbol to calculate the size from. If this is
            // the case, then calculate the size by capping it at the end of the
            // section in which the symbol resides
            for (int i = num_entries - 1; i >= 0; --i)
            {
                const FileRangeToIndexMap::Entry &entry = m_file_addr_to_index.GetEntryRef(i);
                // As we iterate backwards, as soon as we find a symbol with a valid
                // byte size, we are done
                if (entry.GetByteSize() > 0)
                    break;

                // Cap the size to the end of the section in which the symbol resides
                SectionSP section_sp (m_objfile->GetSectionList()->FindSectionContainingFileAddress (entry.GetRangeBase()));
                if (section_sp)
                {
                    const lldb::addr_t end_section_file_addr = section_sp->GetFileAddress() + section_sp->GetByteSize();
                    const lldb::addr_t symbol_file_addr = entry.GetRangeBase();
                    if (end_section_file_addr > symbol_file_addr)
                    {
                        Symbol &symbol = m_symbols[entry.data];

                        symbol.SetByteSize(end_section_file_addr - symbol_file_addr);
                        symbol.SetSizeIsSynthesized(true);
                    }
                }
            }
            // Sort again in case the range size changes the ordering
            m_file_addr_to_index.Sort();
        }
    }
}
예제 #2
0
void Symtab::InitAddressIndexes() {
  // Protected function, no need to lock mutex...
  if (!m_file_addr_to_index_computed && !m_symbols.empty()) {
    m_file_addr_to_index_computed = true;

    FileRangeToIndexMap::Entry entry;
    const_iterator begin = m_symbols.begin();
    const_iterator end = m_symbols.end();
    for (const_iterator pos = m_symbols.begin(); pos != end; ++pos) {
      if (pos->ValueIsAddress()) {
        entry.SetRangeBase(pos->GetAddressRef().GetFileAddress());
        entry.SetByteSize(pos->GetByteSize());
        entry.data = std::distance(begin, pos);
        m_file_addr_to_index.Append(entry);
      }
    }
    const size_t num_entries = m_file_addr_to_index.GetSize();
    if (num_entries > 0) {
      m_file_addr_to_index.Sort();

      // Create a RangeVector with the start & size of all the sections for
      // this objfile.  We'll need to check this for any FileRangeToIndexMap
      // entries with an uninitialized size, which could potentially be a
      // large number so reconstituting the weak pointer is busywork when it
      // is invariant information.
      SectionList *sectlist = m_objfile->GetSectionList();
      RangeVector<addr_t, addr_t> section_ranges;
      if (sectlist) {
        AddSectionsToRangeMap(sectlist, section_ranges);
        section_ranges.Sort();
      }

      // Iterate through the FileRangeToIndexMap and fill in the size for any
      // entries that didn't already have a size from the Symbol (e.g. if we
      // have a plain linker symbol with an address only, instead of debug info
      // where we get an address and a size and a type, etc.)
      for (size_t i = 0; i < num_entries; i++) {
        FileRangeToIndexMap::Entry *entry =
            m_file_addr_to_index.GetMutableEntryAtIndex(i);
        if (entry->GetByteSize() == 0) {
          addr_t curr_base_addr = entry->GetRangeBase();
          const RangeVector<addr_t, addr_t>::Entry *containing_section =
              section_ranges.FindEntryThatContains(curr_base_addr);

          // Use the end of the section as the default max size of the symbol
          addr_t sym_size = 0;
          if (containing_section) {
            sym_size =
                containing_section->GetByteSize() -
                (entry->GetRangeBase() - containing_section->GetRangeBase());
          }

          for (size_t j = i; j < num_entries; j++) {
            FileRangeToIndexMap::Entry *next_entry =
                m_file_addr_to_index.GetMutableEntryAtIndex(j);
            addr_t next_base_addr = next_entry->GetRangeBase();
            if (next_base_addr > curr_base_addr) {
              addr_t size_to_next_symbol = next_base_addr - curr_base_addr;

              // Take the difference between this symbol and the next one as its
              // size,
              // if it is less than the size of the section.
              if (sym_size == 0 || size_to_next_symbol < sym_size) {
                sym_size = size_to_next_symbol;
              }
              break;
            }
          }

          if (sym_size > 0) {
            entry->SetByteSize(sym_size);
            Symbol &symbol = m_symbols[entry->data];
            symbol.SetByteSize(sym_size);
            symbol.SetSizeIsSynthesized(true);
          }
        }
      }

      // Sort again in case the range size changes the ordering
      m_file_addr_to_index.Sort();
    }
  }
}