Improve the handling of missing elf symtab and missing symbol sizes

* Generate artificial symbol names from eh_fame during symbol parsing
  so these symbols are already present when we calcualte the size of
  the symbols where 0 is specified.
* Fix symbol size calculation for the last symbol in the file where
  it have to last until the end of the parent section.

This is the re-commit of the original change after fixing some test
failures on OSX.

Differential revision: http://reviews.llvm.org/D16996

llvm-svn: 261205
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 61e5896..2ee2b13 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -2332,11 +2332,11 @@
                 mangled.SetDemangledName( ConstString((demangled_name + suffix).str()) );
         }
 
-        // In ELF all symbol should have a valid size but it is not true for some code symbols
-        // coming from hand written assembly. As none of the code symbol should have 0 size we try
-        // to calculate the size for these symbols in the symtab with saying that their original
+        // In ELF all symbol should have a valid size but it is not true for some function symbols
+        // coming from hand written assembly. As none of the function symbol should have 0 size we
+        // try to calculate the size for these symbols in the symtab with saying that their original
         // size is not valid.
-        bool symbol_size_valid = symbol.st_size != 0 || symbol_type != eSymbolTypeCode;
+        bool symbol_size_valid = symbol.st_size != 0 || symbol.getType() != STT_FUNC;
 
         Symbol dc_symbol(
             i + start_id,       // ID is the original symbol table index.
@@ -2863,6 +2863,14 @@
             }
         }
 
+        DWARFCallFrameInfo* eh_frame = GetUnwindTable().GetEHFrameInfo();
+        if (eh_frame)
+        {
+            if (m_symtab_ap == nullptr)
+                m_symtab_ap.reset(new Symtab(this));
+            ParseUnwindSymbols (m_symtab_ap.get(), eh_frame);
+        }
+
         // If we still don't have any symtab then create an empty instance to avoid do the section
         // lookup next time.
         if (m_symtab_ap == nullptr)
@@ -2892,57 +2900,64 @@
     return m_symtab_ap.get();
 }
 
-Symbol *
-ObjectFileELF::ResolveSymbolForAddress(const Address& so_addr, bool verify_unique)
+void
+ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table, DWARFCallFrameInfo* eh_frame)
 {
-    if (!m_symtab_ap.get())
-        return nullptr; // GetSymtab() should be called first.
-
-    const SectionList *section_list = GetSectionList();
+    SectionList* section_list = GetSectionList();
     if (!section_list)
-        return nullptr;
+        return;
 
-    if (DWARFCallFrameInfo *eh_frame = GetUnwindTable().GetEHFrameInfo())
-    {
-        AddressRange range;
-        if (eh_frame->GetAddressRange (so_addr, range))
+    // First we save the new symbols into a separate list and add them to the symbol table after
+    // we colleced all symbols we want to add. This is neccessary because adding a new symbol
+    // invalidates the internal index of the symtab what causing the next lookup to be slow because
+    // it have to recalculate the index first.
+    std::vector<Symbol> new_symbols;
+
+    eh_frame->ForEachFDEEntries(
+        [this, symbol_table, section_list, &new_symbols](lldb::addr_t file_addr,
+                                                         uint32_t size,
+                                                         dw_offset_t) {
+        Symbol* symbol = symbol_table->FindSymbolAtFileAddress(file_addr);
+        if (symbol)
         {
-            const addr_t file_addr = range.GetBaseAddress().GetFileAddress();
-            Symbol * symbol = verify_unique ? m_symtab_ap->FindSymbolContainingFileAddress(file_addr) : nullptr;
-            if (symbol)
-                return symbol;
-
-            // Note that a (stripped) symbol won't be found by GetSymtab()...
-            lldb::SectionSP eh_sym_section_sp = section_list->FindSectionContainingFileAddress(file_addr);
-            if (eh_sym_section_sp.get())
+            if (!symbol->GetByteSizeIsValid())
             {
-                addr_t section_base = eh_sym_section_sp->GetFileAddress();
-                addr_t offset = file_addr - section_base;
-                uint64_t symbol_id = m_symtab_ap->GetNumSymbols();
-
-                Symbol eh_symbol(
-                        symbol_id,            // Symbol table index.
-                        "???",                // Symbol name.
-                        false,                // Is the symbol name mangled?
-                        eSymbolTypeCode,      // Type of this symbol.
-                        true,                 // Is this globally visible?
-                        false,                // Is this symbol debug info?
-                        false,                // Is this symbol a trampoline?
-                        true,                 // Is this symbol artificial?
-                        eh_sym_section_sp,    // Section in which this symbol is defined or null.
-                        offset,               // Offset in section or symbol value.
-                        range.GetByteSize(),  // Size in bytes of this symbol.
-                        true,                 // Size is valid.
-                        false,                // Contains linker annotations?
-                        0);                   // Symbol flags.
-                if (symbol_id == m_symtab_ap->AddSymbol(eh_symbol))
-                    return m_symtab_ap->SymbolAtIndex(symbol_id);
+                symbol->SetByteSize(size);
+                symbol->SetSizeIsSynthesized(true);
             }
         }
-    }
-    return nullptr;
-}
+        else
+        {
+            SectionSP section_sp = section_list->FindSectionContainingFileAddress(file_addr);
+            if (section_sp)
+            {
+                addr_t offset = file_addr - section_sp->GetFileAddress();
+                const char* symbol_name = GetNextSyntheticSymbolName().GetCString();
+                uint64_t symbol_id = symbol_table->GetNumSymbols();
+                Symbol eh_symbol(
+                        symbol_id,       // Symbol table index.
+                        symbol_name,     // Symbol name.
+                        false,           // Is the symbol name mangled?
+                        eSymbolTypeCode, // Type of this symbol.
+                        true,            // Is this globally visible?
+                        false,           // Is this symbol debug info?
+                        false,           // Is this symbol a trampoline?
+                        true,            // Is this symbol artificial?
+                        section_sp,      // Section in which this symbol is defined or null.
+                        offset,          // Offset in section or symbol value.
+                        0,               // Size:          Don't specify the size as an FDE can
+                        false,           // Size is valid: cover multiple symbols.
+                        false,           // Contains linker annotations?
+                        0);              // Symbol flags.
+                new_symbols.push_back(eh_symbol);
+            }
+        }
+        return true;
+    });
 
+    for (const Symbol& s : new_symbols)
+        symbol_table->AddSymbol(s);
+}
 
 bool
 ObjectFileELF::IsStripped ()
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 48ae96a..0a1f78e 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -150,9 +150,6 @@
     lldb_private::Symtab *
     GetSymtab() override;
 
-    lldb_private::Symbol *
-    ResolveSymbolForAddress(const lldb_private::Address& so_addr, bool verify_unique) override;
-
     bool
     IsStripped () override;
 
@@ -349,6 +346,10 @@
                            const ELFSectionHeaderInfo *rela_hdr,
                            lldb::user_id_t section_id);
 
+    void
+    ParseUnwindSymbols(lldb_private::Symtab *symbol_table,
+                       lldb_private::DWARFCallFrameInfo* eh_frame);
+
     /// Relocates debug sections
     unsigned
     RelocateDebugSections(const elf::ELFSectionHeader *rel_hdr, lldb::user_id_t rel_id);
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 5d4c217..0b86403 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -4518,7 +4518,6 @@
 
         if (function_starts_count > 0)
         {
-            char synthetic_function_symbol[PATH_MAX];
             uint32_t num_synthetic_function_symbols = 0;
             for (i=0; i<function_starts_count; ++i)
             {
@@ -4533,7 +4532,6 @@
                     num_syms = sym_idx + num_synthetic_function_symbols;
                     sym = symtab->Resize (num_syms);
                 }
-                uint32_t synthetic_function_symbol_idx = 0;
                 for (i=0; i<function_starts_count; ++i)
                 {
                     const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
@@ -4568,13 +4566,8 @@
                                 {
                                     symbol_byte_size = section_end_file_addr - symbol_file_addr;
                                 }
-                                snprintf (synthetic_function_symbol,
-                                          sizeof(synthetic_function_symbol),
-                                          "___lldb_unnamed_function%u$$%s",
-                                          ++synthetic_function_symbol_idx,
-                                          module_sp->GetFileSpec().GetFilename().GetCString());
                                 sym[sym_idx].SetID (synthetic_sym_id++);
-                                sym[sym_idx].GetMangled().SetDemangledName(ConstString(synthetic_function_symbol));
+                                sym[sym_idx].GetMangled().SetDemangledName(GetNextSyntheticSymbolName());
                                 sym[sym_idx].SetType (eSymbolTypeCode);
                                 sym[sym_idx].SetIsSynthetic (true);
                                 sym[sym_idx].GetAddressRef() = symbol_addr;