forked from OSchip/llvm-project
Add support for reading ARM ELF build attributes.
Build attribute sections can now be read if they exist via ELFObjectFile, and the llvm-readobj tool has been extended with an option to dump this information if requested. Regression tests are also included which exercise these features. Also update the docs with a fixed ARM ABI link and a new link to the Addenda which provides the build attributes specification. llvm-svn: 181009
This commit is contained in:
parent
affdc8b54a
commit
2f54d9fe10
|
@ -18,7 +18,9 @@ ARM
|
|||
|
||||
* `ARM documentation <http://www.arm.com/documentation/>`_ (`Processor Cores <http://www.arm.com/documentation/ARMProcessor_Cores/>`_ Cores)
|
||||
|
||||
* `ABI <http://www.arm.com/products/DevTools/ABI.html>`_
|
||||
* `ELF ABI <http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044e/IHI0044E_aaelf.pdf>`_
|
||||
|
||||
* `Addenda to the ARM ABI <http://infocenter.arm.com/help/topic/com.arm.doc.ihi0045d/IHI0045D_ABI_addenda.pdf>`_
|
||||
|
||||
* `ARM C Language Extensions <http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053a/IHI0053A_acle.pdf>`_
|
||||
|
||||
|
|
|
@ -19,11 +19,13 @@
|
|||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Object/ELF_ARM.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/ELF.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/LEB128.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
|
@ -601,6 +603,7 @@ private:
|
|||
const Elf_Shdr *dot_gnu_version_sec; // .gnu.version
|
||||
const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r
|
||||
const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d
|
||||
const Elf_Shdr *dot_arm_attributes_sec; // .ARM.attributes
|
||||
|
||||
// Pointer to SONAME entry in dynamic string table
|
||||
// This is set the first time getLoadName is called.
|
||||
|
@ -643,6 +646,11 @@ private:
|
|||
const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
|
||||
return getSection(Rel.w.b);
|
||||
}
|
||||
// Helper to read a single ARM attribute at the given pointer and return the
|
||||
// read pointer moved forward to the next attribute location.
|
||||
uintptr_t readARMSingleAttribute(uintptr_t ReadPtr,
|
||||
ARMBuildAttrs::ARMGenericBuildAttrInfo &Attrs,
|
||||
SmallVector<unsigned, 16> &TagSet) const;
|
||||
|
||||
public:
|
||||
bool isRelocationHasAddend(DataRefImpl Rel) const;
|
||||
|
@ -838,6 +846,18 @@ public:
|
|||
return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
|
||||
ELFT::Is64Bits);
|
||||
}
|
||||
|
||||
/// \brief Read the ARM build attributes of this object file.
|
||||
/// \param Attrs The attributes container to put the attribute values.
|
||||
/// \param TagsSet A list of attribute tags that were read.
|
||||
error_code readARMBuildAttributes(
|
||||
ARMBuildAttrs::ARMGenericBuildAttrInfo &Attrs,
|
||||
SmallVector<unsigned, 16> &TagsSet) const;
|
||||
|
||||
/// \brief Checks if an ARM build attributes section exists.
|
||||
bool hasARMBuildAttributes() const {
|
||||
return dot_arm_attributes_sec ? true : false;
|
||||
}
|
||||
};
|
||||
|
||||
// Iterate through the version definitions, and place each Elf_Verdef
|
||||
|
@ -2330,6 +2350,7 @@ ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec)
|
|||
, dot_gnu_version_sec(0)
|
||||
, dot_gnu_version_r_sec(0)
|
||||
, dot_gnu_version_d_sec(0)
|
||||
, dot_arm_attributes_sec(0)
|
||||
, dt_soname(0)
|
||||
{
|
||||
|
||||
|
@ -2421,6 +2442,13 @@ ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec)
|
|||
dot_gnu_version_r_sec = sh;
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_ARM_ATTRIBUTES: {
|
||||
if (dot_arm_attributes_sec != NULL)
|
||||
// FIXME: Proper error handling.
|
||||
report_fatal_error("More than one .arm.attributes section!");
|
||||
dot_arm_attributes_sec = sh;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++sh;
|
||||
}
|
||||
|
@ -2970,6 +2998,164 @@ static inline error_code GetELFSymbolVersion(const ObjectFile *Obj,
|
|||
llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF");
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
error_code ELFObjectFile<ELFT>::readARMBuildAttributes(
|
||||
ARMBuildAttrs::ARMGenericBuildAttrInfo &Attrs,
|
||||
SmallVector<unsigned, 16> &TagsSet) const {
|
||||
if (getArch() != Triple::arm)
|
||||
return object_error::invalid_file_type;
|
||||
if (!dot_arm_attributes_sec)
|
||||
return object_error::parse_failed;
|
||||
|
||||
const char *SecStart = (const char*)base() +
|
||||
dot_arm_attributes_sec->sh_offset;
|
||||
const char *SecEnd = SecStart + dot_arm_attributes_sec->sh_size;
|
||||
char format_version = *SecStart;
|
||||
if (format_version != ARMBuildAttrs::Format_Version)
|
||||
return object_error::parse_failed;
|
||||
|
||||
uintptr_t SSectionPtr = (uintptr_t)SecStart + 1;
|
||||
uintptr_t ReadPtr = SSectionPtr;
|
||||
// Begin reading section after format-version byte
|
||||
while (ReadPtr < (uintptr_t)SecEnd) {
|
||||
// Read a subsection, starting with: <section-length> "vendor-name"
|
||||
// For now, we only care about the "aeabi" pseudo-vendor subsection.
|
||||
uint32_t SSectionLen = *(Elf_Word*)ReadPtr;
|
||||
ReadPtr += sizeof(uint32_t);
|
||||
StringRef Vendor((char*)(ReadPtr));
|
||||
ReadPtr += Vendor.size() + 1; // Vendor string + NUL byte
|
||||
|
||||
if (Vendor != "aeabi") {
|
||||
SSectionPtr += SSectionLen;
|
||||
ReadPtr = SSectionPtr;
|
||||
continue; //skip to the next sub-section
|
||||
}
|
||||
|
||||
bool FoundFileTag = false;
|
||||
uintptr_t SSSectionPtr = ReadPtr;
|
||||
uint32_t SSSectionLen = *(Elf_Word*)ReadPtr;
|
||||
// Found aeabi subsection, now find the File scope tag.
|
||||
while (ReadPtr < SSectionPtr + SSectionLen) {
|
||||
unsigned n = 0;
|
||||
uint64_t Tag = decodeULEB128((uint8_t*)ReadPtr, &n);
|
||||
ReadPtr += n;
|
||||
SSSectionLen = *(Elf_Word*)ReadPtr;
|
||||
if (Tag == ARMBuildAttrs::File) {
|
||||
FoundFileTag = true;
|
||||
break;
|
||||
}
|
||||
// We only handle File scope attributes, skip ahead to the next
|
||||
// sub-subsection.
|
||||
SSSectionPtr += SSSectionLen;
|
||||
ReadPtr = SSSectionPtr;
|
||||
}
|
||||
|
||||
if (!FoundFileTag)
|
||||
return object_error::parse_failed;
|
||||
|
||||
ReadPtr += sizeof(uint32_t);
|
||||
while (ReadPtr < SSSectionPtr + SSSectionLen) {
|
||||
// Read any number of attributes.
|
||||
// Attributes are pairs of <uleb128, uleb128> or <uleb128, NTBS>.
|
||||
ReadPtr = readARMSingleAttribute(ReadPtr, Attrs, TagsSet);
|
||||
}
|
||||
Attrs.setValid(true);
|
||||
}
|
||||
return object_error::success;
|
||||
}
|
||||
|
||||
#define SWITCH_ARM_ATTR_READ_ULEB(X) case ARMBuildAttrs::X: \
|
||||
UlebValue = decodeULEB128((uint8_t*)ReadPtr, &n); \
|
||||
ReadPtr += n; \
|
||||
Attrs.Tag_##X = UlebValue; \
|
||||
TagsSet.push_back(tag); \
|
||||
break;
|
||||
|
||||
template<class ELFT>
|
||||
uintptr_t ELFObjectFile<ELFT>::readARMSingleAttribute(uintptr_t ReadPtr,
|
||||
ARMBuildAttrs::ARMGenericBuildAttrInfo &Attrs,
|
||||
SmallVector<unsigned, 16> &TagsSet) const {
|
||||
// The ABI says that tags in the range 0-63 must be handled by tools.
|
||||
unsigned n = 0;
|
||||
uint64_t tagInt = decodeULEB128((uint8_t*)ReadPtr, &n);
|
||||
ARMBuildAttrs::AttrType tag = (ARMBuildAttrs::AttrType)tagInt;
|
||||
ReadPtr += n;
|
||||
uint64_t UlebValue = 0;
|
||||
StringRef StrValue;
|
||||
switch (tag) {
|
||||
case ARMBuildAttrs::CPU_arch: // uleb128
|
||||
UlebValue = decodeULEB128((uint8_t*)ReadPtr, &n);
|
||||
ReadPtr += n;
|
||||
Attrs.Tag_CPU_arch = (ARMBuildAttrs::CPUArch)UlebValue;
|
||||
TagsSet.push_back(tag);
|
||||
break;
|
||||
case ARMBuildAttrs::CPU_raw_name: // NTBS
|
||||
StrValue = (char*)ReadPtr;
|
||||
Attrs.Tag_CPU_raw_name = StrValue;
|
||||
TagsSet.push_back(ARMBuildAttrs::CPU_raw_name);
|
||||
ReadPtr += StrValue.size() + 1;
|
||||
break;
|
||||
case ARMBuildAttrs::CPU_name: //NTBS
|
||||
StrValue = (char*)ReadPtr;
|
||||
Attrs.Tag_CPU_name = StrValue;
|
||||
TagsSet.push_back(ARMBuildAttrs::CPU_name);
|
||||
ReadPtr += StrValue.size() + 1;
|
||||
break;
|
||||
case ARMBuildAttrs::CPU_arch_profile: // uleb128
|
||||
UlebValue = decodeULEB128((uint8_t*)ReadPtr, &n);
|
||||
ReadPtr += n;
|
||||
Attrs.Tag_CPU_arch_profile =
|
||||
(ARMBuildAttrs::CPUArchProfile)UlebValue;
|
||||
TagsSet.push_back(tag);
|
||||
break;
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ARM_ISA_use)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(THUMB_ISA_use)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(FP_arch)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(WMMX_arch)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(Advanced_SIMD_arch)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(FP_HP_extension)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(CPU_unaligned_access)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(MPextension_use)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(DIV_use)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(T2EE_use)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(Virtualization_use)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_optimization_goals)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_FP_optimization_goals)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(PCS_config)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_PCS_R9_use)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_PCS_RW_data)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_PCS_RO_data)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_PCS_GOT_use)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_PCS_wchar_t)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_enum_size)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_align8_needed)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_align8_preserved)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_FP_rounding)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_FP_denormal)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_FP_number_model)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_FP_exceptions)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_FP_user_exceptions)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_HardFP_use)
|
||||
SWITCH_ARM_ATTR_READ_ULEB(ABI_VFP_args)
|
||||
default:
|
||||
// Unhandled build attribute tag, according to the spec we should be able
|
||||
// to infer the type of the value from (tag % 2) and skip over it.
|
||||
if (tag & 0x1) {
|
||||
// Value should be a null terminated byte string
|
||||
StrValue = (char*)ReadPtr;
|
||||
ReadPtr += StrValue.size() + 1;
|
||||
} else {
|
||||
// Value should be a uleb128
|
||||
UlebValue = decodeULEB128((uint8_t*)ReadPtr, &n);
|
||||
ReadPtr += n;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ReadPtr;
|
||||
}
|
||||
#undef SWITCH_ARM_ATTR_READ_ULEB
|
||||
|
||||
|
||||
/// This function returns the hash value for a symbol in the .dynsym section
|
||||
/// Name of the API remains consistent as specified in the libelf
|
||||
/// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
|
||||
|
|
|
@ -0,0 +1,339 @@
|
|||
//===-- ELF_ARM.h - ARM ELF ABI ---------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains enumerations and support routines for ARM build attributes
|
||||
// as defined in ARM ABI addenda document (ABI release 2.08).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_OBJECT_ELF_ARM_H
|
||||
#define LLVM_OBJECT_ELF_ARM_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace ARMBuildAttrs {
|
||||
enum SpecialAttr {
|
||||
// This is for the .cpu asm attr. It translates into one or more
|
||||
// AttrType (below) entries in the .ARM.attributes section in the ELF.
|
||||
SEL_CPU
|
||||
};
|
||||
|
||||
enum AttrType {
|
||||
// Rest correspond to ELF/.ARM.attributes
|
||||
File = 1,
|
||||
Section = 2,
|
||||
Symbol = 3,
|
||||
CPU_raw_name = 4,
|
||||
CPU_name = 5,
|
||||
CPU_arch = 6,
|
||||
CPU_arch_profile = 7,
|
||||
ARM_ISA_use = 8,
|
||||
THUMB_ISA_use = 9,
|
||||
FP_arch = 10,
|
||||
WMMX_arch = 11,
|
||||
Advanced_SIMD_arch = 12,
|
||||
PCS_config = 13,
|
||||
ABI_PCS_R9_use = 14,
|
||||
ABI_PCS_RW_data = 15,
|
||||
ABI_PCS_RO_data = 16,
|
||||
ABI_PCS_GOT_use = 17,
|
||||
ABI_PCS_wchar_t = 18,
|
||||
ABI_FP_rounding = 19,
|
||||
ABI_FP_denormal = 20,
|
||||
ABI_FP_exceptions = 21,
|
||||
ABI_FP_user_exceptions = 22,
|
||||
ABI_FP_number_model = 23,
|
||||
ABI_align8_needed = 24,
|
||||
ABI_align8_preserved = 25,
|
||||
ABI_enum_size = 26,
|
||||
ABI_HardFP_use = 27,
|
||||
ABI_VFP_args = 28,
|
||||
ABI_WMMX_args = 29,
|
||||
ABI_optimization_goals = 30,
|
||||
ABI_FP_optimization_goals = 31,
|
||||
compatibility = 32,
|
||||
CPU_unaligned_access = 34,
|
||||
FP_HP_extension = 36,
|
||||
ABI_FP_16bit_format = 38,
|
||||
MPextension_use = 42, // was 70, 2.08 ABI
|
||||
DIV_use = 44,
|
||||
nodefaults = 64,
|
||||
also_compatible_with = 65,
|
||||
T2EE_use = 66,
|
||||
conformance = 67,
|
||||
Virtualization_use = 68,
|
||||
MPextension_use_old = 70
|
||||
};
|
||||
|
||||
// Magic numbers for .ARM.attributes
|
||||
enum AttrMagic {
|
||||
Format_Version = 0x41
|
||||
};
|
||||
|
||||
// Legal Values for CPU_arch, (=6), uleb128
|
||||
enum CPUArch {
|
||||
Pre_v4 = 0,
|
||||
v4 = 1, // e.g. SA110
|
||||
v4T = 2, // e.g. ARM7TDMI
|
||||
v5T = 3, // e.g. ARM9TDMI
|
||||
v5TE = 4, // e.g. ARM946E_S
|
||||
v5TEJ = 5, // e.g. ARM926EJ_S
|
||||
v6 = 6, // e.g. ARM1136J_S
|
||||
v6KZ = 7, // e.g. ARM1176JZ_S
|
||||
v6T2 = 8, // e.g. ARM1156T2F_S
|
||||
v6K = 9, // e.g. ARM1136J_S
|
||||
v7 = 10, // e.g. Cortex A8, Cortex M3
|
||||
v6_M = 11, // e.g. Cortex M1
|
||||
v6S_M = 12, // v6_M with the System extensions
|
||||
v7E_M = 13, // v7_M with DSP extensions
|
||||
v8
|
||||
};
|
||||
|
||||
enum CPUArchProfile { // (=7), uleb128
|
||||
Not_Applicable = 0, // pre v7, or cross-profile code
|
||||
ApplicationProfile = (0x41), // 'A' (e.g. for Cortex A8)
|
||||
RealTimeProfile = (0x52), // 'R' (e.g. for Cortex R4)
|
||||
MicroControllerProfile = (0x4D), // 'M' (e.g. for Cortex M3)
|
||||
SystemProfile = (0x53) // 'S' Application or real-time profile
|
||||
};
|
||||
|
||||
// The following have a lot of common use cases
|
||||
enum {
|
||||
//ARMISAUse (=8), uleb128 and THUMBISAUse (=9), uleb128
|
||||
Not_Allowed = 0,
|
||||
Allowed = 1
|
||||
};
|
||||
|
||||
enum {
|
||||
// FP_arch (=10), uleb128 (formerly Tag_VFP_arch = 10)
|
||||
AllowFPv2 = 2, // v2 FP ISA permitted (implies use of the v1 FP ISA)
|
||||
AllowFPv3A = 3, // v3 FP ISA permitted (implies use of the v2 FP ISA)
|
||||
AllowFPv3B = 4, // v3 FP ISA permitted, but only D0-D15, S0-S31
|
||||
AllowFPv4A = 5, // v4 FP ISA permitted (implies use of v3 FP ISA)
|
||||
AllowFPv4B = 6, // v4 FP ISA was permitted, but only D0-D15, S0-S31
|
||||
AllowV8FP = 7, // ARMv8-A FP ISA permitted
|
||||
AllowV8FPB = 8 // ARMv8-A FP ISA permitted, but only D0-D15, S0-D31
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_THUMB_ISA_use, (=9), uleb128
|
||||
AllowThumb32 = 2 // 32-bit Thumb (implies 16-bit instructions)
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_WMMX_arch, (=11), uleb128
|
||||
AllowWMMXv1 = 1, // The user permitted this entity to use WMMX v1
|
||||
AllowWMMXv2 = 2 // The user permitted this entity to use WMMX v2
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_ABI_FP_denormal, (=20), uleb128
|
||||
MightFlushToZero = 0, // Denormal numbers might be flushed to (+) zero
|
||||
IEEE754Denormal = 1 , // Depends on IEEE 754 denormal numbers
|
||||
PreserveFPSign = 2 // Sign when flushed-to-zero is preserved
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_ABI_FP_number_model, (=23), uleb128
|
||||
AllowNormal = 1, // Use IEEE 754 format normal numbers only
|
||||
AllowRTABI = 2, // numbers, infinities, and one quiet NaN (see [RTABI])
|
||||
AllowIEE754 = 3 // this code to use all the IEEE 754-defined FP encodings
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_ABI_FP_rounding, (=19), uleb128
|
||||
FPRoundingNearest = 0, // Use the IEEE 754 round to nearest rounding mode
|
||||
FPRoundingRuntime = 1 // Choose the IEEE 754 rounding mode at run time
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_DIV_use, (=44), uleb128
|
||||
AllowDIVThumb = 0, // Allow SDIV, UDIV on Thumb ISA, e.g. Cortex R4 or M3
|
||||
NotAllowedDIV = 1, // Disallow SDIV and UDIV
|
||||
AllowDIVv7a = 2 // Allow SDIV, UDIV on v7-a with integer div extension
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_Virtualization_use, (=42), uleb128
|
||||
TrustZone = 1, // Use of the TrustZone extension was permitted
|
||||
VirtExts = 2, // Use of virtualization extensions (HVC, ERET) permitted
|
||||
TrustZoneVirtExts = 3 // TrustZone and virtualization extensions permitted
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_PCS_config, (=13), uleb128
|
||||
PCS_none = 0, // No standard configuration used, or no information recorded
|
||||
PCS_bare = 1, // Bare platform configuration
|
||||
PCS_linux = 2, // Linux application configuration
|
||||
PCS_linux_dso = 3, // Linux DSO configuration
|
||||
PCS_palm_2004 = 4, // Palm OS 2004 configuration
|
||||
PCS_palm_future = 5, // Reserved to future Palm OS configuration
|
||||
PCS_symbian_2004 = 6, // Symbian OS 2004 configuration
|
||||
PCS_symbian_future = 7 // Reserved to future Symbian OS configuration
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_ABI_PCS_R9_use, (=14), uleb128
|
||||
PCS_R9_normal = 0, // R9 used as V6 (just another callee-saved register,
|
||||
// implied by omitting the tag)
|
||||
PCS_R9_SB = 1, // R9 used as SB, a global Static Base register
|
||||
PCS_R9_TLS = 2, // R9 used as a Thread Local Storage (TLS) pointer
|
||||
PCS_R9_none = 3 // R9 not used at all by code associated with
|
||||
// the attributed entity.
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_ABI_PCS_RW_data, (=15), uleb128
|
||||
PCS_RW_data_abs = 0, // RW static data permitted to be addressed absolutely
|
||||
PCS_RW_data_pcrel = 1, // RW static data was only permitted to be
|
||||
// addressed PC-relative.
|
||||
PCS_RW_data_sbrel = 2, // RW static data was only permitted to be addressed
|
||||
// SB-relative.
|
||||
PCS_RW_data_none = 3 // No permission to use RW static data
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_ABI_PCS_RO_data, (=16), uleb128
|
||||
PCS_RO_data_abs = 0, // RO static data permitted to be addressed absolutely
|
||||
PCS_RO_data_pcrel = 1, // RO static data was only permitted to be
|
||||
// addressed PC-relative.
|
||||
PCS_RO_data_none = 2 // No permission to use RO static data
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_ABI_PCS_GOT_use, (=17), uleb128
|
||||
PCS_GOT_none = 0, // No permission to import static data
|
||||
PCS_GOT_direct = 1, // Permission to address imported data directly
|
||||
PCS_GOT_indirect = 2 // The user permitted this entity to address imported
|
||||
// data indirectly (e.g. via a GOT)
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_ABI_PCS_wchar_t, (=18), uleb128
|
||||
PCS_wchar_t_disallowed = 0, // The user prohibited the use of wchar_t
|
||||
PCS_wchar_t_2 = 2, // The user intended the size of wchar_t to be 2
|
||||
PCS_wchar_t_4 = 4 // The user intended the size of wchar_t to be 4
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_ABI_enum_size, (=26), uleb128
|
||||
PCS_enum_size = 1, // Enum values occupy the smallest container big enough
|
||||
// to hold all their values.
|
||||
PCS_enum_size_32 = 2, // The user intended Enum containers to be 32-bit
|
||||
PCS_enum_size_abi32 = 3 // The user intended that every enumeration visible
|
||||
// across an ABI-complying interface contains a value needing 32 bits to
|
||||
// encode it; other enums can be containerized.
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_ABI_align_needed, (=24), uleb128
|
||||
PCS_Align_needed_disallowed = 0, // The user did not permit code to depend
|
||||
// the alignment of 8-byte data or data with extended (>8-byte) alignment.
|
||||
PCS_Align_needed_8 = 1, // Code was permitted to depend on the 8-byte
|
||||
// alignment of 8-byte data items.
|
||||
PCS_Align_needed_4 = 2, // Code was permitted to depend on the 4-byte
|
||||
// alignment of 8-byte data items.
|
||||
PCS_Align_needed_res = 3 // Reserved
|
||||
// OR: n (in 4..12) Code was permitted to depend on the 8-byte alignment of
|
||||
// 8-byte data items and the alignment of data items having up to 2^n byte
|
||||
// extended alignment.
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_ABI_align_preserved, (=25), uleb128
|
||||
PCS_Align_preserved_none = 0, // The user did not require code to preserve
|
||||
// 8-byte alignment of 8-byte data objects.
|
||||
PCS_Align_preserved_8 = 1, // Code was required to preserve 8-byte alignment
|
||||
// of 8-byte data objects.
|
||||
PCS_Align_preserved_8sp = 2, // Code was required to preserve 8-byte
|
||||
// alignment of 8-byte data objects and to ensure (SP MOD 8) = 0 at all
|
||||
// instruction boundaries (not just at function calls).
|
||||
PCS_Align_preserved_res = 3 // Reserved
|
||||
// OR: n (in 4..12) Code was required to preserve the alignments of case 2
|
||||
// and the alignment of data items having up to 2^n byte extended alignment
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_ABI_HardFP_use, (=27), uleb128
|
||||
HardFPImplied = 0, // FP use should be implied by Tag_FP_arch
|
||||
HardFP_SP_VFP = 1, // Use only SP FP instructions
|
||||
HardFP_Reserved = 2, // Reserved
|
||||
HardFP_ImpliedDup = 3 // Deprecated duplicate of the default HardFPImplied
|
||||
};
|
||||
|
||||
enum {
|
||||
// Tag_ABI_VFP_args, (=28), uleb128
|
||||
VFPArgs_base = 0, // FP parameter/result passing using AAPCS, base variant
|
||||
VFPArgs_VFP = 1, // FP parameter/result passing using AAPCS, VFP variant
|
||||
VFPArgs_toolchain = 2, // FP parameter/result passing to conform to tool
|
||||
// chain-specific conventions
|
||||
VFPArgs_baseVFP = 3 // FP parameter/result passing using both base and VFP
|
||||
//variants. Did not permit non-variadic functions to pass FP params/results.
|
||||
};
|
||||
|
||||
/// Contains build ARM aeabi attribute values.
|
||||
class ARMGenericBuildAttrInfo {
|
||||
public:
|
||||
ARMGenericBuildAttrInfo()
|
||||
: Valid(false) {}
|
||||
|
||||
CPUArch Tag_CPU_arch;
|
||||
CPUArchProfile Tag_CPU_arch_profile;
|
||||
std::string Tag_CPU_raw_name;
|
||||
std::string Tag_CPU_name;
|
||||
unsigned Tag_ARM_ISA_use;
|
||||
unsigned Tag_THUMB_ISA_use;
|
||||
unsigned Tag_FP_arch;
|
||||
unsigned Tag_WMMX_arch;
|
||||
unsigned Tag_Advanced_SIMD_arch;
|
||||
unsigned Tag_FP_HP_extension;
|
||||
unsigned Tag_CPU_unaligned_access;
|
||||
unsigned Tag_MPextension_use;
|
||||
unsigned Tag_DIV_use;
|
||||
unsigned Tag_T2EE_use;
|
||||
unsigned Tag_Virtualization_use;
|
||||
unsigned Tag_ABI_optimization_goals;
|
||||
unsigned Tag_ABI_FP_optimization_goals;
|
||||
|
||||
//PCS/ABI attributes
|
||||
unsigned Tag_PCS_config;
|
||||
unsigned Tag_ABI_PCS_R9_use;
|
||||
unsigned Tag_ABI_PCS_RW_data;
|
||||
unsigned Tag_ABI_PCS_RO_data;
|
||||
unsigned Tag_ABI_PCS_GOT_use;
|
||||
unsigned Tag_ABI_PCS_wchar_t;
|
||||
unsigned Tag_ABI_enum_size;
|
||||
unsigned Tag_ABI_align8_needed;
|
||||
unsigned Tag_ABI_align8_preserved;
|
||||
|
||||
//FP
|
||||
unsigned Tag_ABI_FP_rounding;
|
||||
unsigned Tag_ABI_FP_denormal;
|
||||
unsigned Tag_ABI_FP_number_model;
|
||||
unsigned Tag_ABI_FP_exceptions;
|
||||
unsigned Tag_ABI_FP_user_exceptions;
|
||||
unsigned Tag_ABI_HardFP_use;
|
||||
unsigned Tag_ABI_VFP_args;
|
||||
|
||||
private:
|
||||
bool Valid;
|
||||
|
||||
public:
|
||||
/// Indicates whether this instance contains valid or default values.
|
||||
bool isValid() { return Valid; }
|
||||
void setValid(bool v) { Valid = v; }
|
||||
};
|
||||
|
||||
}
|
||||
} // llvm
|
||||
|
||||
#endif // LLVM_OBJECT_ELF_ARM_H
|
|
@ -15,7 +15,6 @@
|
|||
#define DEBUG_TYPE "asm-printer"
|
||||
#include "ARMAsmPrinter.h"
|
||||
#include "ARM.h"
|
||||
#include "ARMBuildAttrs.h"
|
||||
#include "ARMConstantPoolValue.h"
|
||||
#include "ARMMachineFunctionInfo.h"
|
||||
#include "ARMTargetMachine.h"
|
||||
|
@ -44,6 +43,7 @@
|
|||
#include "llvm/MC/MCSectionMachO.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Object/ELF_ARM.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ELF.h"
|
||||
|
@ -90,7 +90,7 @@ namespace {
|
|||
break;
|
||||
/* GAS requires .fpu to be emitted regardless of EABI attribute */
|
||||
case ARMBuildAttrs::Advanced_SIMD_arch:
|
||||
case ARMBuildAttrs::VFP_arch:
|
||||
case ARMBuildAttrs::FP_arch:
|
||||
Streamer.EmitRawText(StringRef("\t.fpu ") + String.lower());
|
||||
break;
|
||||
}
|
||||
|
@ -798,24 +798,24 @@ void ARMAsmPrinter::emitAttributes() {
|
|||
|
||||
/* VFPv4 + .fpu */
|
||||
if (Subtarget->hasVFP4()) {
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::FP_arch,
|
||||
ARMBuildAttrs::AllowFPv4A);
|
||||
if (emitFPU)
|
||||
AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv4");
|
||||
AttrEmitter->EmitTextAttribute(ARMBuildAttrs::FP_arch, "vfpv4");
|
||||
|
||||
/* VFPv3 + .fpu */
|
||||
} else if (Subtarget->hasVFP3()) {
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::FP_arch,
|
||||
ARMBuildAttrs::AllowFPv3A);
|
||||
if (emitFPU)
|
||||
AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv3");
|
||||
AttrEmitter->EmitTextAttribute(ARMBuildAttrs::FP_arch, "vfpv3");
|
||||
|
||||
/* VFPv2 + .fpu */
|
||||
} else if (Subtarget->hasVFP2()) {
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
|
||||
AttrEmitter->EmitAttribute(ARMBuildAttrs::FP_arch,
|
||||
ARMBuildAttrs::AllowFPv2);
|
||||
if (emitFPU)
|
||||
AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv2");
|
||||
AttrEmitter->EmitTextAttribute(ARMBuildAttrs::FP_arch, "vfpv2");
|
||||
}
|
||||
|
||||
/* TODO: ARMBuildAttrs::Allowed is not completely accurate,
|
||||
|
|
|
@ -1,131 +0,0 @@
|
|||
//===-- ARMBuildAttrs.h - ARM Build Attributes ------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains enumerations and support routines for ARM build attributes
|
||||
// as defined in ARM ABI addenda document (ABI release 2.08).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef __TARGET_ARMBUILDATTRS_H__
|
||||
#define __TARGET_ARMBUILDATTRS_H__
|
||||
|
||||
namespace ARMBuildAttrs {
|
||||
enum SpecialAttr {
|
||||
// This is for the .cpu asm attr. It translates into one or more
|
||||
// AttrType (below) entries in the .ARM.attributes section in the ELF.
|
||||
SEL_CPU
|
||||
};
|
||||
|
||||
enum AttrType {
|
||||
// Rest correspond to ELF/.ARM.attributes
|
||||
File = 1,
|
||||
Section = 2,
|
||||
Symbol = 3,
|
||||
CPU_raw_name = 4,
|
||||
CPU_name = 5,
|
||||
CPU_arch = 6,
|
||||
CPU_arch_profile = 7,
|
||||
ARM_ISA_use = 8,
|
||||
THUMB_ISA_use = 9,
|
||||
VFP_arch = 10,
|
||||
WMMX_arch = 11,
|
||||
Advanced_SIMD_arch = 12,
|
||||
PCS_config = 13,
|
||||
ABI_PCS_R9_use = 14,
|
||||
ABI_PCS_RW_data = 15,
|
||||
ABI_PCS_RO_data = 16,
|
||||
ABI_PCS_GOT_use = 17,
|
||||
ABI_PCS_wchar_t = 18,
|
||||
ABI_FP_rounding = 19,
|
||||
ABI_FP_denormal = 20,
|
||||
ABI_FP_exceptions = 21,
|
||||
ABI_FP_user_exceptions = 22,
|
||||
ABI_FP_number_model = 23,
|
||||
ABI_align8_needed = 24,
|
||||
ABI_align8_preserved = 25,
|
||||
ABI_enum_size = 26,
|
||||
ABI_HardFP_use = 27,
|
||||
ABI_VFP_args = 28,
|
||||
ABI_WMMX_args = 29,
|
||||
ABI_optimization_goals = 30,
|
||||
ABI_FP_optimization_goals = 31,
|
||||
compatibility = 32,
|
||||
CPU_unaligned_access = 34,
|
||||
VFP_HP_extension = 36,
|
||||
ABI_FP_16bit_format = 38,
|
||||
MPextension_use = 42, // was 70, 2.08 ABI
|
||||
DIV_use = 44,
|
||||
nodefaults = 64,
|
||||
also_compatible_with = 65,
|
||||
T2EE_use = 66,
|
||||
conformance = 67,
|
||||
Virtualization_use = 68,
|
||||
MPextension_use_old = 70
|
||||
};
|
||||
|
||||
// Magic numbers for .ARM.attributes
|
||||
enum AttrMagic {
|
||||
Format_Version = 0x41
|
||||
};
|
||||
|
||||
// Legal Values for CPU_arch, (=6), uleb128
|
||||
enum CPUArch {
|
||||
Pre_v4 = 0,
|
||||
v4 = 1, // e.g. SA110
|
||||
v4T = 2, // e.g. ARM7TDMI
|
||||
v5T = 3, // e.g. ARM9TDMI
|
||||
v5TE = 4, // e.g. ARM946E_S
|
||||
v5TEJ = 5, // e.g. ARM926EJ_S
|
||||
v6 = 6, // e.g. ARM1136J_S
|
||||
v6KZ = 7, // e.g. ARM1176JZ_S
|
||||
v6T2 = 8, // e.g. ARM1156T2F_S
|
||||
v6K = 9, // e.g. ARM1136J_S
|
||||
v7 = 10, // e.g. Cortex A8, Cortex M3
|
||||
v6_M = 11, // e.g. Cortex M1
|
||||
v6S_M = 12, // v6_M with the System extensions
|
||||
v7E_M = 13 // v7_M with DSP extensions
|
||||
};
|
||||
|
||||
enum CPUArchProfile { // (=7), uleb128
|
||||
Not_Applicable = 0, // pre v7, or cross-profile code
|
||||
ApplicationProfile = (0x41), // 'A' (e.g. for Cortex A8)
|
||||
RealTimeProfile = (0x52), // 'R' (e.g. for Cortex R4)
|
||||
MicroControllerProfile = (0x4D), // 'M' (e.g. for Cortex M3)
|
||||
SystemProfile = (0x53) // 'S' Application or real-time profile
|
||||
};
|
||||
|
||||
// The following have a lot of common use cases
|
||||
enum {
|
||||
//ARMISAUse (=8), uleb128 and THUMBISAUse (=9), uleb128
|
||||
Not_Allowed = 0,
|
||||
Allowed = 1,
|
||||
|
||||
// FP_arch (=10), uleb128 (formerly Tag_VFP_arch = 10)
|
||||
AllowFPv2 = 2, // v2 FP ISA permitted (implies use of the v1 FP ISA)
|
||||
AllowFPv3A = 3, // v3 FP ISA permitted (implies use of the v2 FP ISA)
|
||||
AllowFPv3B = 4, // v3 FP ISA permitted, but only D0-D15, S0-S31
|
||||
AllowFPv4A = 5, // v4 FP ISA permitted (implies use of v3 FP ISA)
|
||||
AllowFPv4B = 6, // v4 FP ISA was permitted, but only D0-D15, S0-S31
|
||||
|
||||
// Tag_WMMX_arch, (=11), uleb128
|
||||
AllowThumb32 = 2, // 32-bit Thumb (implies 16-bit instructions)
|
||||
|
||||
// Tag_WMMX_arch, (=11), uleb128
|
||||
AllowWMMXv1 = 2, // The user permitted this entity to use WMMX v2
|
||||
|
||||
// Tag_ABI_FP_denormal, (=20), uleb128
|
||||
PreserveFPSign = 2, // sign when flushed-to-zero is preserved
|
||||
|
||||
// Tag_ABI_FP_number_model, (=23), uleb128
|
||||
AllowRTABI = 2, // numbers, infinities, and one quiet NaN (see [RTABI])
|
||||
AllowIEE754 = 3 // this code to use all the IEEE 754-defined FP encodings
|
||||
};
|
||||
}
|
||||
|
||||
#endif // __TARGET_ARMBUILDATTRS_H__
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,46 @@
|
|||
RUN: llvm-readobj -arm-buildattrs %p/Inputs/trivial-object-test.elf-arm \
|
||||
RUN: | FileCheck %s -check-prefix=SMALL
|
||||
RUN: llvm-readobj -arm-buildattrs %p/Inputs/arm-attributes.elf-arm \
|
||||
RUN: | FileCheck %s -check-prefix=LARGE
|
||||
|
||||
SMALL: ARMBuildAttributes {
|
||||
SMALL: Tag_CPU_name: Cortex-A8
|
||||
SMALL: Tag_CPU_arch: 10
|
||||
SMALL: Tag_ARM_ISA_use: 1
|
||||
SMALL: Tag_THUMB_ISA_use: 2
|
||||
SMALL: Tag_FP_arch: 3
|
||||
SMALL: Tag_Advanced_SIMD_arch: 1
|
||||
SMALL: Tag_ABI_FP_denormal: 1
|
||||
SMALL: Tag_ABI_FP_exceptions: 1
|
||||
SMALL: Tag_ABI_FP_number_model: 3
|
||||
SMALL: Tag_ABI_align8_needed: 1
|
||||
SMALL: Tag_ABI_align8_preserved: 1
|
||||
SMALL: Tag_ABI_HardFP_use: 3
|
||||
SMALL: Tag_ABI_VFP_args: 1
|
||||
SMALL: Tag_DIV_use: 1
|
||||
SMALL: Tag_Virtualization_use: 1
|
||||
|
||||
LARGE: ARMBuildAttributes {
|
||||
LARGE: Tag_CPU_name: iwmmxt2
|
||||
LARGE: Tag_CPU_arch: 4
|
||||
LARGE: Tag_ARM_ISA_use: 1
|
||||
LARGE: Tag_THUMB_ISA_use: 1
|
||||
LARGE: Tag_WMMX_arch: 2
|
||||
LARGE: Tag_Advanced_SIMD_arch: 1
|
||||
LARGE: Tag_ABI_PCS_RW_data: 3
|
||||
LARGE: Tag_ABI_PCS_GOT_use: 2
|
||||
LARGE: Tag_ABI_PCS_wchar_t: 4
|
||||
LARGE: Tag_ABI_FP_rounding: 1
|
||||
LARGE: Tag_ABI_FP_denormal: 1
|
||||
LARGE: Tag_ABI_FP_exceptions: 1
|
||||
LARGE: Tag_ABI_FP_number_model: 3
|
||||
LARGE: Tag_ABI_align8_needed: 1
|
||||
LARGE: Tag_ABI_align8_preserved: 1
|
||||
LARGE: Tag_ABI_enum_size: 2
|
||||
LARGE: Tag_ABI_HardFP_use: 3
|
||||
LARGE: Tag_ABI_VFP_args: 1
|
||||
LARGE: Tag_ABI_optimization_goals: 1
|
||||
LARGE: Tag_CPU_unaligned_access: 1
|
||||
LARGE: Tag_FP_HP_extension: 1
|
||||
LARGE: Tag_DIV_use: 1
|
||||
LARGE: Tag_T2EE_use: 1
|
|
@ -51,6 +51,7 @@ public:
|
|||
virtual void printDynamicTable() LLVM_OVERRIDE;
|
||||
virtual void printNeededLibraries() LLVM_OVERRIDE;
|
||||
virtual void printProgramHeaders() LLVM_OVERRIDE;
|
||||
virtual void printARMBuildAttributes() LLVM_OVERRIDE;
|
||||
|
||||
private:
|
||||
typedef ELFObjectFile<ELFT> ELFO;
|
||||
|
@ -858,3 +859,65 @@ void ELFDumper<ELFT>::printProgramHeaders() {
|
|||
W.printNumber("Alignment", PI->p_align);
|
||||
}
|
||||
}
|
||||
|
||||
#define LLVM_READOBJ_ARMATTR_NUMCASE(X) case ARMBuildAttrs::X: \
|
||||
W.printNumber(" Tag_" #X, BuildAttrs.Tag_##X); \
|
||||
break; \
|
||||
|
||||
#define LLVM_READOBJ_ARMATTR_STRCASE(X) case ARMBuildAttrs::X: \
|
||||
W.printString(" Tag_" #X, BuildAttrs.Tag_##X); \
|
||||
break; \
|
||||
|
||||
template<class ELFT>
|
||||
void ELFDumper<ELFT>::printARMBuildAttributes() {
|
||||
if (Obj->getArch() != Triple::arm || !Obj->hasARMBuildAttributes())
|
||||
return;
|
||||
ARMBuildAttrs::ARMGenericBuildAttrInfo BuildAttrs;
|
||||
SmallVector<unsigned, 16> AttrsRead;
|
||||
error_code EC = Obj->readARMBuildAttributes(BuildAttrs, AttrsRead);
|
||||
if (error(EC))
|
||||
return;
|
||||
|
||||
DictScope D(W, "ARMBuildAttributes");
|
||||
|
||||
for (SmallVector<unsigned, 16>::iterator I = AttrsRead.begin(),
|
||||
E = AttrsRead.end(); I != E; ++I) {
|
||||
switch (*I) {
|
||||
LLVM_READOBJ_ARMATTR_STRCASE(CPU_name)
|
||||
LLVM_READOBJ_ARMATTR_STRCASE(CPU_raw_name)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(CPU_arch)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(CPU_arch_profile)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ARM_ISA_use)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(THUMB_ISA_use)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(FP_arch)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(WMMX_arch)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(Advanced_SIMD_arch)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(PCS_config)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_R9_use)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_RW_data)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_RO_data)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_GOT_use)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_wchar_t)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_rounding)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_denormal)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_exceptions)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_user_exceptions)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_number_model)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_align8_needed)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_align8_preserved)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_enum_size)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_HardFP_use)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_VFP_args)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(CPU_unaligned_access)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(FP_HP_extension)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(MPextension_use)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(DIV_use)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(T2EE_use)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(Virtualization_use)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_optimization_goals)
|
||||
LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_optimization_goals)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
virtual void printDynamicTable() { }
|
||||
virtual void printNeededLibraries() { }
|
||||
virtual void printProgramHeaders() { }
|
||||
virtual void printARMBuildAttributes() { }
|
||||
|
||||
protected:
|
||||
StreamWriter& W;
|
||||
|
|
|
@ -128,6 +128,10 @@ namespace opts {
|
|||
// -expand-relocs
|
||||
cl::opt<bool> ExpandRelocs("expand-relocs",
|
||||
cl::desc("Expand each shown relocation to multiple lines"));
|
||||
|
||||
// -arm-buildattrs
|
||||
cl::opt<bool> ArmBuildAttrs("arm-buildattrs",
|
||||
cl::desc("Display ARM ELF build attributes"));
|
||||
} // namespace opts
|
||||
|
||||
namespace llvm {
|
||||
|
@ -221,6 +225,8 @@ static void dumpObject(const ObjectFile *Obj) {
|
|||
Dumper->printNeededLibraries();
|
||||
if (opts::ProgramHeaders)
|
||||
Dumper->printProgramHeaders();
|
||||
if (opts::ArmBuildAttrs)
|
||||
Dumper->printARMBuildAttributes();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue