compnerd created this revision.
compnerd added a reviewer: clayborg.
compnerd added a subscriber: lldb-commits.
compnerd set the repository for this revision to rL LLVM.

This adds basic parsing of the EABI attributes section.  This section contains
additional information about the target for which the file was built.  Attempt
to infer additional architecture information from that section.

This is still relatively light in terms of inferred information.  However, this 
lays the groundwork for inferring more information in the future.

Suggestions for testing this welcome.

Repository:
  rL LLVM

http://reviews.llvm.org/D19446

Files:
  source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
  source/Plugins/ObjectFile/ELF/ObjectFileELF.h

Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.h
===================================================================
--- source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -298,6 +298,10 @@
     size_t
     ParseSectionHeaders();
 
+    static void
+    ParseARMAttributes(lldb_private::DataExtractor &data, uint64_t length,
+                       lldb_private::ArchSpec &arch_spec);
+
     /// Parses the elf section headers and returns the uuid, debug link name, crc, archspec.
     static size_t
     GetSectionHeaderInfo(SectionHeaderColl &section_headers,
Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
===================================================================
--- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -31,6 +31,7 @@
 
 #include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ARMBuildAttributes.h"
 #include "llvm/Support/MathExtras.h"
 
 #define CASE_AND_STREAM(s, def, width)                  \
@@ -1516,6 +1517,90 @@
     return error;
 }
 
+void
+ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length, ArchSpec &arch_spec)
+{
+    lldb::offset_t Offset = 0;
+
+    uint8_t FormatVersion = data.GetU8(&Offset);
+    if (FormatVersion != llvm::ARMBuildAttrs::Format_Version)
+      return;
+
+    Offset = Offset + sizeof(uint32_t); // Section Length
+    llvm::StringRef VendorName = data.GetCStr(&Offset);
+
+    if (VendorName != "aeabi")
+      return;
+
+    if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment)
+        arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);
+
+    while (Offset < length)
+    {
+        uint8_t Tag = data.GetU8(&Offset);
+        uint32_t Size = data.GetU32(&Offset);
+
+        if (Tag != llvm::ARMBuildAttrs::File || Size == 0)
+            continue;
+
+        while (Offset < length)
+        {
+            uint64_t Tag = data.GetULEB128(&Offset);
+            switch (Tag)
+            {
+                default:
+                    // TODO: log error for unhandled AEABI attribute
+                    if (Tag < 32)
+                        data.GetULEB128(&Offset);
+                    else if (Tag % 2 == 0)
+                        data.GetULEB128(&Offset);
+                    else
+                        data.GetCStr(&Offset);
+                    break;
+
+                case llvm::ARMBuildAttrs::CPU_raw_name:
+                case llvm::ARMBuildAttrs::CPU_name:
+                    data.GetCStr(&Offset);
+                    break;
+
+                case llvm::ARMBuildAttrs::THUMB_ISA_use:
+                {
+                    uint64_t ThumbISA = data.GetULEB128(&Offset);
+
+                    // NOTE: ignore ThumbISA == llvm::ARMBuildAttrs::AllowThumbDerived
+                    // since that derives it based on the architecutre/profile
+                    if (ThumbISA == llvm::ARMBuildAttrs::AllowThumb32)
+                        if (arch_spec.GetTriple().getArch() == llvm::Triple::UnknownArch ||
+                            arch_spec.GetTriple().getArch() == llvm::Triple::arm)
+                            arch_spec.GetTriple().setArch(llvm::Triple::thumb);
+                }
+                case llvm::ARMBuildAttrs::ABI_VFP_args:
+                {
+                    uint64_t VFPArgs = data.GetULEB128(&Offset);
+
+                    if (VFPArgs == llvm::ARMBuildAttrs::BaseAAPCS)
+                    {
+                        if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment ||
+                            arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABIHF)
+                            arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);
+
+                        arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float);
+                    }
+                    else if (VFPArgs == llvm::ARMBuildAttrs::HardFPAAPCS)
+                    {
+                        if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment ||
+                            arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABI)
+                            arch_spec.GetTriple().setEnvironment(llvm::Triple::EABIHF);
+
+                        arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);
+                    }
+
+                    break;
+                }
+            }
+        }
+    }
+}
 
 //----------------------------------------------------------------------
 // GetSectionHeaderInfo
@@ -1648,6 +1733,18 @@
                     arch_spec.SetFlags (arch_flags);
                 }
 
+                if (arch_spec.GetMachine() == llvm::Triple::arm || arch_spec.GetMachine() == llvm::Triple::thumb)
+                {
+                    DataExtractor data;
+
+                    if (sheader.sh_type != SHT_ARM_ATTRIBUTES)
+                        continue;
+                    if (section_size == 0 || set_data(data, sheader.sh_offset, section_size) != section_size)
+                        continue;
+
+                    ParseARMAttributes(data, section_size, arch_spec);
+                }
+
                 if (name == g_sect_name_gnu_debuglink)
                 {
                     DataExtractor data;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to