summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2016-04-23 16:00:15 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2016-04-23 16:00:15 +0000
commitd2d1504805f9bf2a9925dd4f09bfe5329f819030 (patch)
treebd1c584fc825171c4b0fffcf2760975f005e7900 /lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
parent66b0a87ae8d6e148e089e7cd6d45d50887e0ea63 (diff)
downloadbcm5719-llvm-d2d1504805f9bf2a9925dd4f09bfe5329f819030.tar.gz
bcm5719-llvm-d2d1504805f9bf2a9925dd4f09bfe5329f819030.zip
ObjectFile: parse EABI Attributes
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. llvm-svn: 267291
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp')
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp100
1 files changed, 100 insertions, 0 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index bb388d45e36..76416843fd5 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/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,93 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l
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:
+ 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);
+
+ break;
+ }
+ 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 +1736,18 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
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;
OpenPOWER on IntegriCloud