tberghammer created this revision.
tberghammer added reviewers: ovyalov, clayborg.
tberghammer added a subscriber: lldb-commits.

Add support for handling absolute symbols in ELF

Most address represented in lldb as section plus offset and handling of
absolute addresses is problematic in several location because of lack
of necessary information (e.g. Target) or because of performance issues.

This CL change the way ObjectFileELF handle the absolute symbols with
creating a pseudo section for each symbol. With this change all existing
code designed to work with addresses in the form of section plus offset
will work with absolute symbols as well.

http://reviews.llvm.org/D17450

Files:
  include/lldb/lldb-enumerations.h
  source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
  source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
  source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
  source/Symbol/ObjectFile.cpp
  source/Utility/ConvertEnum.cpp

Index: source/Utility/ConvertEnum.cpp
===================================================================
--- source/Utility/ConvertEnum.cpp
+++ source/Utility/ConvertEnum.cpp
@@ -115,6 +115,8 @@
             return "compact-unwind";
         case eSectionTypeGoSymtab:
             return "go-symtab";
+        case eSectionTypeAbsoluteAddress:
+            return "absolute";
         case eSectionTypeOther:
             return "regular";
     }
Index: source/Symbol/ObjectFile.cpp
===================================================================
--- source/Symbol/ObjectFile.cpp
+++ source/Symbol/ObjectFile.cpp
@@ -379,6 +379,7 @@
                     case eSectionTypeARMextab:
                     case eSectionTypeCompactUnwind:
                         return eAddressClassRuntime;
+                    case eSectionTypeAbsoluteAddress:
                     case eSectionTypeELFSymbolTable:
                     case eSectionTypeELFDynamicSymbols:
                     case eSectionTypeELFRelocationEntries:
Index: source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
===================================================================
--- source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -1388,6 +1388,7 @@
                     case eSectionTypeCompactUnwind:
                         return eAddressClassRuntime;
 
+                    case eSectionTypeAbsoluteAddress:
                     case eSectionTypeELFSymbolTable:
                     case eSectionTypeELFDynamicSymbols:
                     case eSectionTypeELFRelocationEntries:
Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
===================================================================
--- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -921,10 +921,14 @@
                 // Iterate through the object file sections to find all
                 // of the sections that have SHF_ALLOC in their flag bits.
                 SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
-                // if (section_sp && !section_sp->IsThreadSpecific())
                 if (section_sp && section_sp->Test(SHF_ALLOC))
                 {
-                    lldb::addr_t load_addr = section_sp->GetFileAddress() + value;
+                    lldb::addr_t load_addr = section_sp->GetFileAddress();
+                    // We don't want to update the load address of a section with type
+                    // eSectionTypeAbsoluteAddress as they already have the absolute load address
+                    // already specified
+                    if (section_sp->GetType() != eSectionTypeAbsoluteAddress)
+                        load_addr += value;
 
                     // On 32-bit systems the load address have to fit into 4 bytes. The rest of
                     // the bytes are the overflow from the addition.
@@ -2058,6 +2062,8 @@
 
     ArchSpec arch;
     GetArchitecture(arch);
+    ModuleSP module_sp(GetModule());
+    SectionList* module_section_list = module_sp ? module_sp->GetSectionList() : nullptr;
 
     // Local cache to avoid doing a FindSectionByName for each symbol. The "const char*" key must
     // came from a ConstString object so they can be compared by pointer
@@ -2278,30 +2284,44 @@
             }
         }
 
-        // symbol_value_offset may contain 0 for ARM symbols or -1 for
-        // THUMB symbols. See above for more details.
+        // symbol_value_offset may contain 0 for ARM symbols or -1 for THUMB symbols. See above for
+        // more details.
         uint64_t symbol_value = symbol.st_value + symbol_value_offset;
+
+        if (symbol_section_sp == nullptr && symbol.st_size != 0)
+        {
+            // We don't have a section for a symbol with non-zero size. Create a new section for it
+            // so the address range covered by the symbol is also covered by the module (represented
+            // through the section list). It is needed so module lookup for the addresses covered
+            // by this symbol will be successfull. This case happens for absolute symbols.
+            ConstString fake_section_name(std::string(".absolute.") + symbol_name);
+            symbol_section_sp = std::make_shared<Section>(module_sp,
+                                                          this,
+                                                          SHN_ABS,
+                                                          fake_section_name,
+                                                          eSectionTypeAbsoluteAddress,
+                                                          symbol_value,
+                                                          symbol.st_size,
+                                                          0, 0, 0,
+                                                          SHF_ALLOC);
+
+            module_section_list->AddSection(symbol_section_sp);
+            section_list->AddSection(symbol_section_sp);
+        }
+
         if (symbol_section_sp && CalculateType() != ObjectFile::Type::eTypeObjectFile)
             symbol_value -= symbol_section_sp->GetFileAddress();
 
-        if (symbol_section_sp)
+        if (symbol_section_sp && module_section_list && module_section_list != section_list)
         {
-            ModuleSP module_sp(GetModule());
-            if (module_sp)
-            {
-                SectionList *module_section_list = module_sp->GetSectionList();
-                if (module_section_list && module_section_list != section_list)
-                {
-                    const ConstString &sect_name = symbol_section_sp->GetName();
-                    auto section_it = section_name_to_section.find(sect_name.GetCString());
-                    if (section_it == section_name_to_section.end())
-                        section_it = section_name_to_section.emplace(
-                            sect_name.GetCString(),
-                            module_section_list->FindSectionByName (sect_name)).first;
-                    if (section_it->second && section_it->second->GetFileSize())
-                        symbol_section_sp = section_it->second;
-                }
-            }
+            const ConstString &sect_name = symbol_section_sp->GetName();
+            auto section_it = section_name_to_section.find(sect_name.GetCString());
+            if (section_it == section_name_to_section.end())
+                section_it = section_name_to_section.emplace(
+                    sect_name.GetCString(),
+                    module_section_list->FindSectionByName (sect_name)).first;
+            if (section_it->second && section_it->second->GetFileSize())
+                symbol_section_sp = section_it->second;
         }
 
         bool is_global = symbol.getBinding() == STB_GLOBAL;
Index: source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
===================================================================
--- source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
+++ source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
@@ -340,7 +340,9 @@
 
             if (module_sp && module_sp->GetObjectFile())
             {
-                bool changed;
+                // load the symbol table right away
+                module_sp->GetObjectFile()->GetSymtab();
+
                 m_jit_objects.insert(std::make_pair(symbolfile_addr, module_sp));
                 if (module_sp->GetObjectFile()->GetPluginName() == ConstString("mach-o"))
                 {
@@ -360,12 +362,10 @@
                 }
                 else
                 {
+                    bool changed = false;
                     module_sp->SetLoadAddress(target, 0, true, changed);
                 }
 
-                // load the symbol table right away
-                module_sp->GetObjectFile()->GetSymtab();
-
                 module_list.AppendIfNeeded(module_sp);
 
                 ModuleList module_list;
Index: include/lldb/lldb-enumerations.h
===================================================================
--- include/lldb/lldb-enumerations.h
+++ include/lldb/lldb-enumerations.h
@@ -622,6 +622,7 @@
         eSectionTypeARMextab,
         eSectionTypeCompactUnwind,        // compact unwind section in Mach-O, __TEXT,__unwind_info
         eSectionTypeGoSymtab,
+        eSectionTypeAbsoluteAddress,      // Dummy section for symbols with absolute address
         eSectionTypeOther
     };
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to