[Lldb-commits] [lldb] r266165 - Update Symtab::InitAddressIndexes so that computed symbol sizes

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Tue Apr 12 21:32:50 PDT 2016


Author: jmolenda
Date: Tue Apr 12 23:32:49 2016
New Revision: 266165

URL: http://llvm.org/viewvc/llvm-project?rev=266165&view=rev
Log:
Update Symtab::InitAddressIndexes so that computed symbol sizes
will not exceed the bounds of their Section.  This is addressing a
problem where a file had a large space between two sections that
were not used by this module - the last symbol in the text section
had an enormous size because the distance between that and the first
symbol in the data section were used to compute the size.

http://reviews.llvm.org/D19004
<rdar://problem/25227945> 

Modified:
    lldb/trunk/include/lldb/Core/RangeMap.h
    lldb/trunk/source/Symbol/Symtab.cpp

Modified: lldb/trunk/include/lldb/Core/RangeMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/RangeMap.h?rev=266165&r1=266164&r2=266165&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/RangeMap.h (original)
+++ lldb/trunk/include/lldb/Core/RangeMap.h Tue Apr 12 23:32:49 2016
@@ -1195,7 +1195,13 @@ namespace lldb_private {
         {
             return ((i < m_entries.size()) ? &m_entries[i] : nullptr);
         }
-        
+
+        Entry *
+        GetMutableEntryAtIndex (size_t i)
+        {
+            return ((i < m_entries.size()) ? &m_entries[i] : nullptr);
+        }
+
         // Clients must ensure that "i" is a valid index prior to calling this function
         const Entry &
         GetEntryRef (size_t i) const

Modified: lldb/trunk/source/Symbol/Symtab.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Symtab.cpp?rev=266165&r1=266164&r2=266165&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Symtab.cpp (original)
+++ lldb/trunk/source/Symbol/Symtab.cpp Tue Apr 12 23:32:49 2016
@@ -894,6 +894,38 @@ typedef struct
     addr_t match_offset;
 } SymbolSearchInfo;
 
+// Add all the section file start address & size to the RangeVector,
+// recusively adding any children sections.  
+static void
+AddSectionsToRangeMap (SectionList *sectlist, RangeVector<addr_t, addr_t> &section_ranges)
+{
+    const int num_sections = sectlist->GetNumSections (0);
+    for (int i = 0; i < num_sections; i++)
+    {
+        SectionSP sect_sp = sectlist->GetSectionAtIndex (i);
+        if (sect_sp)
+        {
+            SectionList &child_sectlist = sect_sp->GetChildren();
+
+            // If this section has children, add the children to the RangeVector.
+            // Else add this section to the RangeVector.
+            if (child_sectlist.GetNumSections (0) > 0)
+            {
+                AddSectionsToRangeMap (&child_sectlist, section_ranges);
+            }
+            else
+            {
+                addr_t base_addr = sect_sp->GetFileAddress();
+                size_t size = sect_sp->GetByteSize();
+                RangeVector<addr_t, addr_t>::Entry entry;
+                entry.SetRangeBase (base_addr);
+                entry.SetByteSize (size);
+                section_ranges.Append (entry);
+            }
+        }
+    }
+}
+
 void
 Symtab::InitAddressIndexes()
 {
@@ -915,26 +947,75 @@ Symtab::InitAddressIndexes()
                 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();
 
-            // Now our last address range 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
-            lldb::addr_t total_size = 0;
-            const FileRangeToIndexMap::Entry* entry = m_file_addr_to_index.Back();
-            if (entry->GetByteSize() == 0)
+            // 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 (int i = 0; i < num_entries; i++)
             {
-                const Address& address = m_symbols[entry->data].GetAddressRef();
-                if (SectionSP section_sp = address.GetSection())
-                    total_size = entry->base + section_sp->GetByteSize() - address.GetOffset();
+                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 (int 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);
+                    }
+                }
             }
 
-            m_file_addr_to_index.CalculateSizesOfZeroByteSizeRanges(total_size);
+            // Sort again in case the range size changes the ordering
+            m_file_addr_to_index.Sort();
         }
     }
 }




More information about the lldb-commits mailing list