<rdar://problem/10103468>

I started work on being able to add symbol files after a debug session
had started with a new "target symfile add" command and quickly ran into
problems with stale Address objects in breakpoint locations that had 
lldb_private::Section pointers into modules that had been removed or 
replaced. This also let to grabbing stale modules from those sections. 
So I needed to thread harded the Address, Section and related objects.

To do this I modified the ModuleChild class to now require a ModuleSP
on initialization so that a weak reference can created. I also changed
all places that were handing out "Section *" to have them hand out SectionSP.
All ObjectFile, SymbolFile and SymbolVendors were inheriting from ModuleChild
so all of the find plug-in, static creation function and constructors now
require ModuleSP references instead of Module *. 

Address objects now have weak references to their sections which can
safely go stale when a module gets destructed. 

This checkin doesn't complete the "target symfile add" command, but it
does get us a lot clioser to being able to do such things without a high
risk of crashing or memory corruption.

llvm-svn: 151336
diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp
index dd2556a..f1f4dc1 100644
--- a/lldb/source/Core/Section.cpp
+++ b/lldb/source/Core/Section.cpp
@@ -15,23 +15,19 @@
 using namespace lldb;
 using namespace lldb_private;
 
-Section::Section
-(
-    Section *parent,
-    Module* module,
-    user_id_t sect_id,
-    const ConstString &name,
-    SectionType sect_type,
-    addr_t file_addr,
-    addr_t byte_size,
-    uint64_t file_offset,
-    uint64_t file_size,
-    uint32_t flags
-) :
-    ModuleChild     (module),
+Section::Section (const ModuleSP &module_sp,
+                  user_id_t sect_id,
+                  const ConstString &name,
+                  SectionType sect_type,
+                  addr_t file_addr,
+                  addr_t byte_size,
+                  uint64_t file_offset,
+                  uint64_t file_size,
+                  uint32_t flags) :
+    ModuleChild     (module_sp),
     UserID          (sect_id),
     Flags           (flags),
-    m_parent        (parent),
+    m_parent_wp     (),
     m_name          (name),
     m_type          (sect_type),
     m_file_addr     (file_addr),
@@ -40,73 +36,92 @@
     m_file_size     (file_size),
     m_children      (),
     m_fake          (false),
-    m_linked_section(NULL),
+    m_linked_section_wp(),
     m_linked_offset (0)
 {
+//    printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16llx, addr=[0x%16.16llx - 0x%16.16llx), file [0x%16.16llx - 0x%16.16llx), flags = 0x%8.8x, name = %s\n",
+//            this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, name.GetCString());
+}
+
+Section::Section (const lldb::SectionSP &parent_section_sp,
+                  const ModuleSP &module_sp,
+                  user_id_t sect_id,
+                  const ConstString &name,
+                  SectionType sect_type,
+                  addr_t file_addr,
+                  addr_t byte_size,
+                  uint64_t file_offset,
+                  uint64_t file_size,
+                  uint32_t flags) :
+    ModuleChild     (module_sp),
+    UserID          (sect_id),
+    Flags           (flags),
+    m_parent_wp     (),
+    m_name          (name),
+    m_type          (sect_type),
+    m_file_addr     (file_addr),
+    m_byte_size     (byte_size),
+    m_file_offset   (file_offset),
+    m_file_size     (file_size),
+    m_children      (),
+    m_fake          (false),
+    m_linked_section_wp(),
+    m_linked_offset (0)
+{
+//    printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16llx, addr=[0x%16.16llx - 0x%16.16llx), file [0x%16.16llx - 0x%16.16llx), flags = 0x%8.8x, name = %s.%s\n",
+//            this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, parent_section_sp->GetName().GetCString(), name.GetCString());
+    if (parent_section_sp)
+        m_parent_wp = parent_section_sp;
 }
 
 Section::~Section()
 {
-}
-
-
-// Get a valid shared pointer to this section object
-SectionSP
-Section::GetSharedPointer() const
-{
-    SectionSP this_sp;
-    if (m_parent)
-        this_sp = m_parent->GetChildren().GetSharedPointer (this, false);
-    else
-    {
-        ObjectFile *objfile = m_module->GetObjectFile();
-        if (objfile)
-        {
-            SectionList *section_list = objfile->GetSectionList();
-            if (section_list)
-                this_sp = section_list->GetSharedPointer (this, false);
-        }
-    }
-    return this_sp;
-}
-
-
-
-ConstString&
-Section::GetName()
-{
-    if (m_linked_section)
-        return const_cast<Section *>(m_linked_section)->GetName();
-    return m_name;
+//    printf ("Section::~Section(%p)\n", this);
 }
 
 const ConstString&
 Section::GetName() const
 {
-    if (m_linked_section)
-        return m_linked_section->GetName();
+    SectionSP linked_section_sp (m_linked_section_wp.lock());
+    if (linked_section_sp)
+        return linked_section_sp->GetName();
     return m_name;
 }
 
 addr_t
 Section::GetFileAddress () const
 {
-    if (m_parent)
+    SectionSP parent_sp (GetParent ());
+    if (parent_sp)
     {
         // This section has a parent which means m_file_addr is an offset into
         // the parent section, so the file address for this section is the file
         // address of the parent plus the offset
-        return m_parent->GetFileAddress() + m_file_addr;
+        return parent_sp->GetFileAddress() + m_file_addr;
     }
     // This section has no parent, so m_file_addr is the file base address
     return m_file_addr;
 }
 
+lldb::addr_t
+Section::GetOffset () const
+{
+    // This section has a parent which means m_file_addr is an offset.
+    SectionSP parent_sp (GetParent ());
+    if (parent_sp)
+        return m_file_addr;
+    
+    // This section has no parent, so there is no offset to be had
+    return 0;
+}
+
+
 addr_t
 Section::GetLinkedFileAddress () const
 {
-    if (m_linked_section)
-        return m_linked_section->GetFileAddress() + m_linked_offset;
+    SectionSP linked_section_sp (m_linked_section_wp.lock());
+    if (linked_section_sp)
+        return linked_section_sp->GetFileAddress() + m_linked_offset;
     return LLDB_INVALID_ADDRESS;
 }
 
@@ -115,22 +130,26 @@
 Section::GetLoadBaseAddress (Target *target) const
 {
     addr_t load_base_addr = LLDB_INVALID_ADDRESS;
-    if (m_linked_section)
+    SectionSP linked_section_sp (m_linked_section_wp.lock());
+    if (linked_section_sp)
     {
-        load_base_addr = m_linked_section->GetLoadBaseAddress(target);
+        load_base_addr = linked_section_sp->GetLoadBaseAddress(target);
         if (load_base_addr != LLDB_INVALID_ADDRESS)
             load_base_addr += m_linked_offset;
     }
     else
-    if (m_parent)
     {
-        load_base_addr = m_parent->GetLoadBaseAddress (target);
-        if (load_base_addr != LLDB_INVALID_ADDRESS)
-            load_base_addr += GetOffset();
-    }
-    else
-    {
-        load_base_addr = target->GetSectionLoadList().GetSectionLoadAddress (this);
+        SectionSP parent_sp (GetParent ());
+        if (parent_sp)
+        {
+            load_base_addr = parent_sp->GetLoadBaseAddress (target);
+            if (load_base_addr != LLDB_INVALID_ADDRESS)
+                load_base_addr += GetOffset();
+        }
+        else
+        {
+            load_base_addr = target->GetSectionLoadList().GetSectionLoadAddress (this);
+        }
     }
 
     return load_base_addr;
@@ -151,15 +170,16 @@
                 return child_section->ResolveContainedAddress (offset - child_offset, so_addr);
         }
     }
-    if (m_linked_section)
+    SectionSP linked_section_sp (m_linked_section_wp.lock());
+    if (linked_section_sp)
     {
         so_addr.SetOffset(m_linked_offset + offset);
-        so_addr.SetSection(m_linked_section);
+        so_addr.SetSection(linked_section_sp);
     }
     else
     {
         so_addr.SetOffset(offset);
-        so_addr.SetSection(this);
+        so_addr.SetSection(const_cast<Section *>(this)->shared_from_this());
     }
     return true;
 }
@@ -200,9 +220,9 @@
     if (&a == &b)
         return 0;
 
-    const Module* a_module = a.GetModule();
-    const Module* b_module = b.GetModule();
-    if (a_module == b_module)
+    const ModuleSP a_module_sp = a.GetModule();
+    const ModuleSP b_module_sp = b.GetModule();
+    if (a_module_sp == b_module_sp)
     {
         user_id_t a_sect_uid = a.GetID();
         user_id_t b_sect_uid = b.GetID();
@@ -215,7 +235,7 @@
     else
     {
         // The modules are different, just compare the module pointers
-        if (a_module < b_module)
+        if (a_module_sp.get() < b_module_sp.get())
             return -1;
         else
             return 1;   // We already know the modules aren't equal
@@ -232,11 +252,12 @@
     bool resolved = true;
     addr_t addr = LLDB_INVALID_ADDRESS;
 
+    SectionSP linked_section_sp (m_linked_section_wp.lock());
     if (GetByteSize() == 0)
         s->Printf("%39s", "");
     else
     {
-        if (target && m_linked_section == NULL)
+        if (target && linked_section_sp.get() == NULL)
             addr = GetLoadBaseAddress (target);
 
         if (addr == LLDB_INVALID_ADDRESS)
@@ -256,13 +277,13 @@
 
     s->EOL();
 
-    if (m_linked_section)
+    if (linked_section_sp)
     {
         addr = LLDB_INVALID_ADDRESS;
         resolved = true;
         if (target)
         {
-            addr = m_linked_section->GetLoadBaseAddress(target);
+            addr = linked_section_sp->GetLoadBaseAddress(target);
             if (addr != LLDB_INVALID_ADDRESS)
                 addr += m_linked_offset;
         }
@@ -271,7 +292,7 @@
         {
             if (target)
                 resolved = false;
-            addr = m_linked_section->GetFileAddress() + m_linked_offset;
+            addr = linked_section_sp->GetFileAddress() + m_linked_offset;
         }
 
         int indent = 26 + s->GetIndentLevel();
@@ -281,7 +302,7 @@
         indent = 3 * (sizeof(uint32_t) * 2 + 2 + 1) + 1;
         s->Printf("%c%*.*s", resolved ? ' ' : '*', indent, indent, "");
 
-        m_linked_section->DumpName(s);
+        linked_section_sp->DumpName(s);
         s->Printf(" + 0x%llx\n", m_linked_offset);
     }
 
@@ -292,17 +313,22 @@
 void
 Section::DumpName (Stream *s) const
 {
-    if (m_parent == NULL)
+    SectionSP parent_sp (GetParent ());
+    if (parent_sp)
     {
-        // The top most section prints the module basename
-        const char *module_basename = m_module->GetFileSpec().GetFilename().AsCString();
-        if (module_basename && module_basename[0])
-            s->Printf("%s.", module_basename);
+        parent_sp->DumpName (s);
+        s->PutChar('.');
     }
     else
     {
-        m_parent->DumpName (s);
-        s->PutChar('.');
+        // The top most section prints the module basename
+        ModuleSP module_sp (GetModule());
+        if (module_sp)
+        {
+            const char *module_basename = module_sp->GetFileSpec().GetFilename().AsCString();
+            if (module_basename && module_basename[0])
+                s->Printf("%s.", module_basename);
+        }
     }
     m_name.Dump(s);
 }
@@ -312,8 +338,9 @@
 {
     if (this == section)
         return true;
-    if (m_parent)
-        return m_parent->IsDescendant (section);
+    SectionSP parent_sp (GetParent ());
+    if (parent_sp)
+        return parent_sp->IsDescendant (section);
     return false;
 }
 
@@ -336,11 +363,11 @@
 }
 
 void
-Section::SetLinkedLocation (const Section *linked_section, uint64_t linked_offset)
+Section::SetLinkedLocation (const lldb::SectionSP &linked_section_sp, uint64_t linked_offset)
 {
-    if (linked_section)
-        m_module = linked_section->GetModule();
-    m_linked_section = linked_section;
+    if (linked_section_sp)
+        m_module_wp = linked_section_sp->GetModule();
+    m_linked_section_wp = linked_section_sp;
     m_linked_offset  = linked_offset;
 }
 
@@ -357,10 +384,11 @@
 }
 
 uint32_t
-SectionList::AddSection (SectionSP& sect_sp)
+SectionList::AddSection (const lldb::SectionSP& section_sp)
 {
+    assert (section_sp.get());
     uint32_t section_index = m_sections.size();
-    m_sections.push_back(sect_sp);
+    m_sections.push_back(section_sp);
     return section_index;
 }
 
@@ -382,7 +410,7 @@
 }
 
 uint32_t
-SectionList::AddUniqueSection (SectionSP& sect_sp)
+SectionList::AddUniqueSection (const lldb::SectionSP& sect_sp)
 {
     uint32_t sect_idx = FindSectionIndex (sect_sp.get());
     if (sect_idx == UINT32_MAX)
@@ -392,7 +420,7 @@
 
 
 bool
-SectionList::ReplaceSection (user_id_t sect_id, SectionSP& sect_sp, uint32_t depth)
+SectionList::ReplaceSection (user_id_t sect_id, const lldb::SectionSP& sect_sp, uint32_t depth)
 {
     iterator sect_iter, end = m_sections.end();
     for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter)
@@ -441,19 +469,21 @@
 {
     SectionSP sect_sp;
     // Check if we have a valid section string
-    if (section_dstr)
+    if (section_dstr && !m_sections.empty())
     {
         const_iterator sect_iter;
         const_iterator end = m_sections.end();
         for (sect_iter = m_sections.begin(); sect_iter != end && sect_sp.get() == NULL; ++sect_iter)
         {
-            if ((*sect_iter)->GetName() == section_dstr)
+            Section *child_section = sect_iter->get();
+            assert (child_section);
+            if (child_section->GetName() == section_dstr)
             {
                 sect_sp = *sect_iter;
             }
             else
             {
-                sect_sp = (*sect_iter)->GetChildren().FindSectionByName(section_dstr);
+                sect_sp = child_section->GetChildren().FindSectionByName(section_dstr);
             }
         }
     }
@@ -508,32 +538,6 @@
 }
 
 SectionSP
-SectionList::GetSharedPointer (const Section *section, bool check_children) const
-{
-    SectionSP sect_sp;
-    if (section)
-    {
-        const_iterator sect_iter;
-        const_iterator end = m_sections.end();
-        for (sect_iter = m_sections.begin(); sect_iter != end && sect_sp.get() == NULL; ++sect_iter)
-        {
-            if (sect_iter->get() == section)
-            {
-                sect_sp = *sect_iter;
-                break;
-            }
-            else if (check_children)
-            {
-                sect_sp = (*sect_iter)->GetChildren().GetSharedPointer (section, true);
-            }
-        }
-    }
-    return sect_sp;
-}
-
-
-
-SectionSP
 SectionList::FindSectionContainingFileAddress (addr_t vm_addr, uint32_t depth) const
 {
     SectionSP sect_sp;