llvm.org GIT mirror llvm / 5d446e6
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181009 91177308-0d34-0410-b5e6-96231b3b80d8 Amara Emerson 6 years ago
11 changed file(s) with 652 addition(s) and 140 deletion(s). Raw diff Collapse all Expand all
1717
1818 * `ARM documentation `_ (`Processor Cores `_ Cores)
1919
20 * `ABI >`_
20 * `ELF ABI >`_
21
22 * `Addenda to the ARM ABI `_
2123
2224 * `ARM C Language Extensions `_
2325
1818 #include "llvm/ADT/SmallVector.h"
1919 #include "llvm/ADT/StringSwitch.h"
2020 #include "llvm/ADT/Triple.h"
21 #include "llvm/Object/ELF_ARM.h"
2122 #include "llvm/Object/ObjectFile.h"
2223 #include "llvm/Support/Casting.h"
2324 #include "llvm/Support/ELF.h"
2425 #include "llvm/Support/Endian.h"
2526 #include "llvm/Support/ErrorHandling.h"
27 #include "llvm/Support/LEB128.h"
2628 #include "llvm/Support/MemoryBuffer.h"
2729 #include "llvm/Support/raw_ostream.h"
2830 #include
600602 const Elf_Shdr *dot_gnu_version_sec; // .gnu.version
601603 const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r
602604 const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d
605 const Elf_Shdr *dot_arm_attributes_sec; // .ARM.attributes
603606
604607 // Pointer to SONAME entry in dynamic string table
605608 // This is set the first time getLoadName is called.
642645 const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
643646 return getSection(Rel.w.b);
644647 }
648 // Helper to read a single ARM attribute at the given pointer and return the
649 // read pointer moved forward to the next attribute location.
650 uintptr_t readARMSingleAttribute(uintptr_t ReadPtr,
651 ARMBuildAttrs::ARMGenericBuildAttrInfo &Attrs,
652 SmallVector &TagSet) const;
645653
646654 public:
647655 bool isRelocationHasAddend(DataRefImpl Rel) const;
836844 static inline bool classof(const Binary *v) {
837845 return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
838846 ELFT::Is64Bits);
847 }
848
849 /// \brief Read the ARM build attributes of this object file.
850 /// \param Attrs The attributes container to put the attribute values.
851 /// \param TagsSet A list of attribute tags that were read.
852 error_code readARMBuildAttributes(
853 ARMBuildAttrs::ARMGenericBuildAttrInfo &Attrs,
854 SmallVector &TagsSet) const;
855
856 /// \brief Checks if an ARM build attributes section exists.
857 bool hasARMBuildAttributes() const {
858 return dot_arm_attributes_sec ? true : false;
839859 }
840860 };
841861
23292349 , dot_gnu_version_sec(0)
23302350 , dot_gnu_version_r_sec(0)
23312351 , dot_gnu_version_d_sec(0)
2352 , dot_arm_attributes_sec(0)
23322353 , dt_soname(0)
23332354 {
23342355
24182439 // FIXME: Proper error handling.
24192440 report_fatal_error("More than one .gnu.version_r section!");
24202441 dot_gnu_version_r_sec = sh;
2442 break;
2443 }
2444 case ELF::SHT_ARM_ATTRIBUTES: {
2445 if (dot_arm_attributes_sec != NULL)
2446 // FIXME: Proper error handling.
2447 report_fatal_error("More than one .arm.attributes section!");
2448 dot_arm_attributes_sec = sh;
24212449 break;
24222450 }
24232451 }
29692997 llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF");
29702998 }
29712999
3000 template
3001 error_code ELFObjectFile::readARMBuildAttributes(
3002 ARMBuildAttrs::ARMGenericBuildAttrInfo &Attrs,
3003 SmallVector &TagsSet) const {
3004 if (getArch() != Triple::arm)
3005 return object_error::invalid_file_type;
3006 if (!dot_arm_attributes_sec)
3007 return object_error::parse_failed;
3008
3009 const char *SecStart = (const char*)base() +
3010 dot_arm_attributes_sec->sh_offset;
3011 const char *SecEnd = SecStart + dot_arm_attributes_sec->sh_size;
3012 char format_version = *SecStart;
3013 if (format_version != ARMBuildAttrs::Format_Version)
3014 return object_error::parse_failed;
3015
3016 uintptr_t SSectionPtr = (uintptr_t)SecStart + 1;
3017 uintptr_t ReadPtr = SSectionPtr;
3018 // Begin reading section after format-version byte
3019 while (ReadPtr < (uintptr_t)SecEnd) {
3020 // Read a subsection, starting with: "vendor-name"
3021 // For now, we only care about the "aeabi" pseudo-vendor subsection.
3022 uint32_t SSectionLen = *(Elf_Word*)ReadPtr;
3023 ReadPtr += sizeof(uint32_t);
3024 StringRef Vendor((char*)(ReadPtr));
3025 ReadPtr += Vendor.size() + 1; // Vendor string + NUL byte
3026
3027 if (Vendor != "aeabi") {
3028 SSectionPtr += SSectionLen;
3029 ReadPtr = SSectionPtr;
3030 continue; //skip to the next sub-section
3031 }
3032
3033 bool FoundFileTag = false;
3034 uintptr_t SSSectionPtr = ReadPtr;
3035 uint32_t SSSectionLen = *(Elf_Word*)ReadPtr;
3036 // Found aeabi subsection, now find the File scope tag.
3037 while (ReadPtr < SSectionPtr + SSectionLen) {
3038 unsigned n = 0;
3039 uint64_t Tag = decodeULEB128((uint8_t*)ReadPtr, &n);
3040 ReadPtr += n;
3041 SSSectionLen = *(Elf_Word*)ReadPtr;
3042 if (Tag == ARMBuildAttrs::File) {
3043 FoundFileTag = true;
3044 break;
3045 }
3046 // We only handle File scope attributes, skip ahead to the next
3047 // sub-subsection.
3048 SSSectionPtr += SSSectionLen;
3049 ReadPtr = SSSectionPtr;
3050 }
3051
3052 if (!FoundFileTag)
3053 return object_error::parse_failed;
3054
3055 ReadPtr += sizeof(uint32_t);
3056 while (ReadPtr < SSSectionPtr + SSSectionLen) {
3057 // Read any number of attributes.
3058 // Attributes are pairs of or .
3059 ReadPtr = readARMSingleAttribute(ReadPtr, Attrs, TagsSet);
3060 }
3061 Attrs.setValid(true);
3062 }
3063 return object_error::success;
3064 }
3065
3066 #define SWITCH_ARM_ATTR_READ_ULEB(X) case ARMBuildAttrs::X: \
3067 UlebValue = decodeULEB128((uint8_t*)ReadPtr, &n); \
3068 ReadPtr += n; \
3069 Attrs.Tag_##X = UlebValue; \
3070 TagsSet.push_back(tag); \
3071 break;
3072
3073 template
3074 uintptr_t ELFObjectFile::readARMSingleAttribute(uintptr_t ReadPtr,
3075 ARMBuildAttrs::ARMGenericBuildAttrInfo &Attrs,
3076 SmallVector &TagsSet) const {
3077 // The ABI says that tags in the range 0-63 must be handled by tools.
3078 unsigned n = 0;
3079 uint64_t tagInt = decodeULEB128((uint8_t*)ReadPtr, &n);
3080 ARMBuildAttrs::AttrType tag = (ARMBuildAttrs::AttrType)tagInt;
3081 ReadPtr += n;
3082 uint64_t UlebValue = 0;
3083 StringRef StrValue;
3084 switch (tag) {
3085 case ARMBuildAttrs::CPU_arch: // uleb128
3086 UlebValue = decodeULEB128((uint8_t*)ReadPtr, &n);
3087 ReadPtr += n;
3088 Attrs.Tag_CPU_arch = (ARMBuildAttrs::CPUArch)UlebValue;
3089 TagsSet.push_back(tag);
3090 break;
3091 case ARMBuildAttrs::CPU_raw_name: // NTBS
3092 StrValue = (char*)ReadPtr;
3093 Attrs.Tag_CPU_raw_name = StrValue;
3094 TagsSet.push_back(ARMBuildAttrs::CPU_raw_name);
3095 ReadPtr += StrValue.size() + 1;
3096 break;
3097 case ARMBuildAttrs::CPU_name: //NTBS
3098 StrValue = (char*)ReadPtr;
3099 Attrs.Tag_CPU_name = StrValue;
3100 TagsSet.push_back(ARMBuildAttrs::CPU_name);
3101 ReadPtr += StrValue.size() + 1;
3102 break;
3103 case ARMBuildAttrs::CPU_arch_profile: // uleb128
3104 UlebValue = decodeULEB128((uint8_t*)ReadPtr, &n);
3105 ReadPtr += n;
3106 Attrs.Tag_CPU_arch_profile =
3107 (ARMBuildAttrs::CPUArchProfile)UlebValue;
3108 TagsSet.push_back(tag);
3109 break;
3110 SWITCH_ARM_ATTR_READ_ULEB(ARM_ISA_use)
3111 SWITCH_ARM_ATTR_READ_ULEB(THUMB_ISA_use)
3112 SWITCH_ARM_ATTR_READ_ULEB(FP_arch)
3113 SWITCH_ARM_ATTR_READ_ULEB(WMMX_arch)
3114 SWITCH_ARM_ATTR_READ_ULEB(Advanced_SIMD_arch)
3115 SWITCH_ARM_ATTR_READ_ULEB(FP_HP_extension)
3116 SWITCH_ARM_ATTR_READ_ULEB(CPU_unaligned_access)
3117 SWITCH_ARM_ATTR_READ_ULEB(MPextension_use)
3118 SWITCH_ARM_ATTR_READ_ULEB(DIV_use)
3119 SWITCH_ARM_ATTR_READ_ULEB(T2EE_use)
3120 SWITCH_ARM_ATTR_READ_ULEB(Virtualization_use)
3121 SWITCH_ARM_ATTR_READ_ULEB(ABI_optimization_goals)
3122 SWITCH_ARM_ATTR_READ_ULEB(ABI_FP_optimization_goals)
3123 SWITCH_ARM_ATTR_READ_ULEB(PCS_config)
3124 SWITCH_ARM_ATTR_READ_ULEB(ABI_PCS_R9_use)
3125 SWITCH_ARM_ATTR_READ_ULEB(ABI_PCS_RW_data)
3126 SWITCH_ARM_ATTR_READ_ULEB(ABI_PCS_RO_data)
3127 SWITCH_ARM_ATTR_READ_ULEB(ABI_PCS_GOT_use)
3128 SWITCH_ARM_ATTR_READ_ULEB(ABI_PCS_wchar_t)
3129 SWITCH_ARM_ATTR_READ_ULEB(ABI_enum_size)
3130 SWITCH_ARM_ATTR_READ_ULEB(ABI_align8_needed)
3131 SWITCH_ARM_ATTR_READ_ULEB(ABI_align8_preserved)
3132 SWITCH_ARM_ATTR_READ_ULEB(ABI_FP_rounding)
3133 SWITCH_ARM_ATTR_READ_ULEB(ABI_FP_denormal)
3134 SWITCH_ARM_ATTR_READ_ULEB(ABI_FP_number_model)
3135 SWITCH_ARM_ATTR_READ_ULEB(ABI_FP_exceptions)
3136 SWITCH_ARM_ATTR_READ_ULEB(ABI_FP_user_exceptions)
3137 SWITCH_ARM_ATTR_READ_ULEB(ABI_HardFP_use)
3138 SWITCH_ARM_ATTR_READ_ULEB(ABI_VFP_args)
3139 default:
3140 // Unhandled build attribute tag, according to the spec we should be able
3141 // to infer the type of the value from (tag % 2) and skip over it.
3142 if (tag & 0x1) {
3143 // Value should be a null terminated byte string
3144 StrValue = (char*)ReadPtr;
3145 ReadPtr += StrValue.size() + 1;
3146 } else {
3147 // Value should be a uleb128
3148 UlebValue = decodeULEB128((uint8_t*)ReadPtr, &n);
3149 ReadPtr += n;
3150 }
3151 break;
3152 }
3153 return ReadPtr;
3154 }
3155 #undef SWITCH_ARM_ATTR_READ_ULEB
3156
3157
29723158 /// This function returns the hash value for a symbol in the .dynsym section
29733159 /// Name of the API remains consistent as specified in the libelf
29743160 /// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
0 //===-- ELF_ARM.h - ARM ELF ABI ---------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains enumerations and support routines for ARM build attributes
10 // as defined in ARM ABI addenda document (ABI release 2.08).
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_OBJECT_ELF_ARM_H
15 #define LLVM_OBJECT_ELF_ARM_H
16
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/Support/Endian.h"
19
20 namespace llvm {
21
22 namespace ARMBuildAttrs {
23 enum SpecialAttr {
24 // This is for the .cpu asm attr. It translates into one or more
25 // AttrType (below) entries in the .ARM.attributes section in the ELF.
26 SEL_CPU
27 };
28
29 enum AttrType {
30 // Rest correspond to ELF/.ARM.attributes
31 File = 1,
32 Section = 2,
33 Symbol = 3,
34 CPU_raw_name = 4,
35 CPU_name = 5,
36 CPU_arch = 6,
37 CPU_arch_profile = 7,
38 ARM_ISA_use = 8,
39 THUMB_ISA_use = 9,
40 FP_arch = 10,
41 WMMX_arch = 11,
42 Advanced_SIMD_arch = 12,
43 PCS_config = 13,
44 ABI_PCS_R9_use = 14,
45 ABI_PCS_RW_data = 15,
46 ABI_PCS_RO_data = 16,
47 ABI_PCS_GOT_use = 17,
48 ABI_PCS_wchar_t = 18,
49 ABI_FP_rounding = 19,
50 ABI_FP_denormal = 20,
51 ABI_FP_exceptions = 21,
52 ABI_FP_user_exceptions = 22,
53 ABI_FP_number_model = 23,
54 ABI_align8_needed = 24,
55 ABI_align8_preserved = 25,
56 ABI_enum_size = 26,
57 ABI_HardFP_use = 27,
58 ABI_VFP_args = 28,
59 ABI_WMMX_args = 29,
60 ABI_optimization_goals = 30,
61 ABI_FP_optimization_goals = 31,
62 compatibility = 32,
63 CPU_unaligned_access = 34,
64 FP_HP_extension = 36,
65 ABI_FP_16bit_format = 38,
66 MPextension_use = 42, // was 70, 2.08 ABI
67 DIV_use = 44,
68 nodefaults = 64,
69 also_compatible_with = 65,
70 T2EE_use = 66,
71 conformance = 67,
72 Virtualization_use = 68,
73 MPextension_use_old = 70
74 };
75
76 // Magic numbers for .ARM.attributes
77 enum AttrMagic {
78 Format_Version = 0x41
79 };
80
81 // Legal Values for CPU_arch, (=6), uleb128
82 enum CPUArch {
83 Pre_v4 = 0,
84 v4 = 1, // e.g. SA110
85 v4T = 2, // e.g. ARM7TDMI
86 v5T = 3, // e.g. ARM9TDMI
87 v5TE = 4, // e.g. ARM946E_S
88 v5TEJ = 5, // e.g. ARM926EJ_S
89 v6 = 6, // e.g. ARM1136J_S
90 v6KZ = 7, // e.g. ARM1176JZ_S
91 v6T2 = 8, // e.g. ARM1156T2F_S
92 v6K = 9, // e.g. ARM1136J_S
93 v7 = 10, // e.g. Cortex A8, Cortex M3
94 v6_M = 11, // e.g. Cortex M1
95 v6S_M = 12, // v6_M with the System extensions
96 v7E_M = 13, // v7_M with DSP extensions
97 v8
98 };
99
100 enum CPUArchProfile { // (=7), uleb128
101 Not_Applicable = 0, // pre v7, or cross-profile code
102 ApplicationProfile = (0x41), // 'A' (e.g. for Cortex A8)
103 RealTimeProfile = (0x52), // 'R' (e.g. for Cortex R4)
104 MicroControllerProfile = (0x4D), // 'M' (e.g. for Cortex M3)
105 SystemProfile = (0x53) // 'S' Application or real-time profile
106 };
107
108 // The following have a lot of common use cases
109 enum {
110 //ARMISAUse (=8), uleb128 and THUMBISAUse (=9), uleb128
111 Not_Allowed = 0,
112 Allowed = 1
113 };
114
115 enum {
116 // FP_arch (=10), uleb128 (formerly Tag_VFP_arch = 10)
117 AllowFPv2 = 2, // v2 FP ISA permitted (implies use of the v1 FP ISA)
118 AllowFPv3A = 3, // v3 FP ISA permitted (implies use of the v2 FP ISA)
119 AllowFPv3B = 4, // v3 FP ISA permitted, but only D0-D15, S0-S31
120 AllowFPv4A = 5, // v4 FP ISA permitted (implies use of v3 FP ISA)
121 AllowFPv4B = 6, // v4 FP ISA was permitted, but only D0-D15, S0-S31
122 AllowV8FP = 7, // ARMv8-A FP ISA permitted
123 AllowV8FPB = 8 // ARMv8-A FP ISA permitted, but only D0-D15, S0-D31
124 };
125
126 enum {
127 // Tag_THUMB_ISA_use, (=9), uleb128
128 AllowThumb32 = 2 // 32-bit Thumb (implies 16-bit instructions)
129 };
130
131 enum {
132 // Tag_WMMX_arch, (=11), uleb128
133 AllowWMMXv1 = 1, // The user permitted this entity to use WMMX v1
134 AllowWMMXv2 = 2 // The user permitted this entity to use WMMX v2
135 };
136
137 enum {
138 // Tag_ABI_FP_denormal, (=20), uleb128
139 MightFlushToZero = 0, // Denormal numbers might be flushed to (+) zero
140 IEEE754Denormal = 1 , // Depends on IEEE 754 denormal numbers
141 PreserveFPSign = 2 // Sign when flushed-to-zero is preserved
142 };
143
144 enum {
145 // Tag_ABI_FP_number_model, (=23), uleb128
146 AllowNormal = 1, // Use IEEE 754 format normal numbers only
147 AllowRTABI = 2, // numbers, infinities, and one quiet NaN (see [RTABI])
148 AllowIEE754 = 3 // this code to use all the IEEE 754-defined FP encodings
149 };
150
151 enum {
152 // Tag_ABI_FP_rounding, (=19), uleb128
153 FPRoundingNearest = 0, // Use the IEEE 754 round to nearest rounding mode
154 FPRoundingRuntime = 1 // Choose the IEEE 754 rounding mode at run time
155 };
156
157 enum {
158 // Tag_DIV_use, (=44), uleb128
159 AllowDIVThumb = 0, // Allow SDIV, UDIV on Thumb ISA, e.g. Cortex R4 or M3
160 NotAllowedDIV = 1, // Disallow SDIV and UDIV
161 AllowDIVv7a = 2 // Allow SDIV, UDIV on v7-a with integer div extension
162 };
163
164 enum {
165 // Tag_Virtualization_use, (=42), uleb128
166 TrustZone = 1, // Use of the TrustZone extension was permitted
167 VirtExts = 2, // Use of virtualization extensions (HVC, ERET) permitted
168 TrustZoneVirtExts = 3 // TrustZone and virtualization extensions permitted
169 };
170
171 enum {
172 // Tag_PCS_config, (=13), uleb128
173 PCS_none = 0, // No standard configuration used, or no information recorded
174 PCS_bare = 1, // Bare platform configuration
175 PCS_linux = 2, // Linux application configuration
176 PCS_linux_dso = 3, // Linux DSO configuration
177 PCS_palm_2004 = 4, // Palm OS 2004 configuration
178 PCS_palm_future = 5, // Reserved to future Palm OS configuration
179 PCS_symbian_2004 = 6, // Symbian OS 2004 configuration
180 PCS_symbian_future = 7 // Reserved to future Symbian OS configuration
181 };
182
183 enum {
184 // Tag_ABI_PCS_R9_use, (=14), uleb128
185 PCS_R9_normal = 0, // R9 used as V6 (just another callee-saved register,
186 // implied by omitting the tag)
187 PCS_R9_SB = 1, // R9 used as SB, a global Static Base register
188 PCS_R9_TLS = 2, // R9 used as a Thread Local Storage (TLS) pointer
189 PCS_R9_none = 3 // R9 not used at all by code associated with
190 // the attributed entity.
191 };
192
193 enum {
194 // Tag_ABI_PCS_RW_data, (=15), uleb128
195 PCS_RW_data_abs = 0, // RW static data permitted to be addressed absolutely
196 PCS_RW_data_pcrel = 1, // RW static data was only permitted to be
197 // addressed PC-relative.
198 PCS_RW_data_sbrel = 2, // RW static data was only permitted to be addressed
199 // SB-relative.
200 PCS_RW_data_none = 3 // No permission to use RW static data
201 };
202
203 enum {
204 // Tag_ABI_PCS_RO_data, (=16), uleb128
205 PCS_RO_data_abs = 0, // RO static data permitted to be addressed absolutely
206 PCS_RO_data_pcrel = 1, // RO static data was only permitted to be
207 // addressed PC-relative.
208 PCS_RO_data_none = 2 // No permission to use RO static data
209 };
210
211 enum {
212 // Tag_ABI_PCS_GOT_use, (=17), uleb128
213 PCS_GOT_none = 0, // No permission to import static data
214 PCS_GOT_direct = 1, // Permission to address imported data directly
215 PCS_GOT_indirect = 2 // The user permitted this entity to address imported
216 // data indirectly (e.g. via a GOT)
217 };
218
219 enum {
220 // Tag_ABI_PCS_wchar_t, (=18), uleb128
221 PCS_wchar_t_disallowed = 0, // The user prohibited the use of wchar_t
222 PCS_wchar_t_2 = 2, // The user intended the size of wchar_t to be 2
223 PCS_wchar_t_4 = 4 // The user intended the size of wchar_t to be 4
224 };
225
226 enum {
227 // Tag_ABI_enum_size, (=26), uleb128
228 PCS_enum_size = 1, // Enum values occupy the smallest container big enough
229 // to hold all their values.
230 PCS_enum_size_32 = 2, // The user intended Enum containers to be 32-bit
231 PCS_enum_size_abi32 = 3 // The user intended that every enumeration visible
232 // across an ABI-complying interface contains a value needing 32 bits to
233 // encode it; other enums can be containerized.
234 };
235
236 enum {
237 // Tag_ABI_align_needed, (=24), uleb128
238 PCS_Align_needed_disallowed = 0, // The user did not permit code to depend
239 // the alignment of 8-byte data or data with extended (>8-byte) alignment.
240 PCS_Align_needed_8 = 1, // Code was permitted to depend on the 8-byte
241 // alignment of 8-byte data items.
242 PCS_Align_needed_4 = 2, // Code was permitted to depend on the 4-byte
243 // alignment of 8-byte data items.
244 PCS_Align_needed_res = 3 // Reserved
245 // OR: n (in 4..12) Code was permitted to depend on the 8-byte alignment of
246 // 8-byte data items and the alignment of data items having up to 2^n byte
247 // extended alignment.
248 };
249
250 enum {
251 // Tag_ABI_align_preserved, (=25), uleb128
252 PCS_Align_preserved_none = 0, // The user did not require code to preserve
253 // 8-byte alignment of 8-byte data objects.
254 PCS_Align_preserved_8 = 1, // Code was required to preserve 8-byte alignment
255 // of 8-byte data objects.
256 PCS_Align_preserved_8sp = 2, // Code was required to preserve 8-byte
257 // alignment of 8-byte data objects and to ensure (SP MOD 8) = 0 at all
258 // instruction boundaries (not just at function calls).
259 PCS_Align_preserved_res = 3 // Reserved
260 // OR: n (in 4..12) Code was required to preserve the alignments of case 2
261 // and the alignment of data items having up to 2^n byte extended alignment
262 };
263
264 enum {
265 // Tag_ABI_HardFP_use, (=27), uleb128
266 HardFPImplied = 0, // FP use should be implied by Tag_FP_arch
267 HardFP_SP_VFP = 1, // Use only SP FP instructions
268 HardFP_Reserved = 2, // Reserved
269 HardFP_ImpliedDup = 3 // Deprecated duplicate of the default HardFPImplied
270 };
271
272 enum {
273 // Tag_ABI_VFP_args, (=28), uleb128
274 VFPArgs_base = 0, // FP parameter/result passing using AAPCS, base variant
275 VFPArgs_VFP = 1, // FP parameter/result passing using AAPCS, VFP variant
276 VFPArgs_toolchain = 2, // FP parameter/result passing to conform to tool
277 // chain-specific conventions
278 VFPArgs_baseVFP = 3 // FP parameter/result passing using both base and VFP
279 //variants. Did not permit non-variadic functions to pass FP params/results.
280 };
281
282 /// Contains build ARM aeabi attribute values.
283 class ARMGenericBuildAttrInfo {
284 public:
285 ARMGenericBuildAttrInfo()
286 : Valid(false) {}
287
288 CPUArch Tag_CPU_arch;
289 CPUArchProfile Tag_CPU_arch_profile;
290 std::string Tag_CPU_raw_name;
291 std::string Tag_CPU_name;
292 unsigned Tag_ARM_ISA_use;
293 unsigned Tag_THUMB_ISA_use;
294 unsigned Tag_FP_arch;
295 unsigned Tag_WMMX_arch;
296 unsigned Tag_Advanced_SIMD_arch;
297 unsigned Tag_FP_HP_extension;
298 unsigned Tag_CPU_unaligned_access;
299 unsigned Tag_MPextension_use;
300 unsigned Tag_DIV_use;
301 unsigned Tag_T2EE_use;
302 unsigned Tag_Virtualization_use;
303 unsigned Tag_ABI_optimization_goals;
304 unsigned Tag_ABI_FP_optimization_goals;
305
306 //PCS/ABI attributes
307 unsigned Tag_PCS_config;
308 unsigned Tag_ABI_PCS_R9_use;
309 unsigned Tag_ABI_PCS_RW_data;
310 unsigned Tag_ABI_PCS_RO_data;
311 unsigned Tag_ABI_PCS_GOT_use;
312 unsigned Tag_ABI_PCS_wchar_t;
313 unsigned Tag_ABI_enum_size;
314 unsigned Tag_ABI_align8_needed;
315 unsigned Tag_ABI_align8_preserved;
316
317 //FP
318 unsigned Tag_ABI_FP_rounding;
319 unsigned Tag_ABI_FP_denormal;
320 unsigned Tag_ABI_FP_number_model;
321 unsigned Tag_ABI_FP_exceptions;
322 unsigned Tag_ABI_FP_user_exceptions;
323 unsigned Tag_ABI_HardFP_use;
324 unsigned Tag_ABI_VFP_args;
325
326 private:
327 bool Valid;
328
329 public:
330 /// Indicates whether this instance contains valid or default values.
331 bool isValid() { return Valid; }
332 void setValid(bool v) { Valid = v; }
333 };
334
335 }
336 } // llvm
337
338 #endif // LLVM_OBJECT_ELF_ARM_H
1414 #define DEBUG_TYPE "asm-printer"
1515 #include "ARMAsmPrinter.h"
1616 #include "ARM.h"
17 #include "ARMBuildAttrs.h"
1817 #include "ARMConstantPoolValue.h"
1918 #include "ARMMachineFunctionInfo.h"
2019 #include "ARMTargetMachine.h"
4342 #include "llvm/MC/MCSectionMachO.h"
4443 #include "llvm/MC/MCStreamer.h"
4544 #include "llvm/MC/MCSymbol.h"
45 #include "llvm/Object/ELF_ARM.h"
4646 #include "llvm/Support/CommandLine.h"
4747 #include "llvm/Support/Debug.h"
4848 #include "llvm/Support/ELF.h"
8989 break;
9090 /* GAS requires .fpu to be emitted regardless of EABI attribute */
9191 case ARMBuildAttrs::Advanced_SIMD_arch:
92 case ARMBuildAttrs::VFP_arch:
92 case ARMBuildAttrs::FP_arch:
9393 Streamer.EmitRawText(StringRef("\t.fpu ") + String.lower());
9494 break;
9595 }
797797
798798 /* VFPv4 + .fpu */
799799 if (Subtarget->hasVFP4()) {
800 AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
800 AttrEmitter->EmitAttribute(ARMBuildAttrs::FP_arch,
801801 ARMBuildAttrs::AllowFPv4A);
802802 if (emitFPU)
803 AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv4");
803 AttrEmitter->EmitTextAttribute(ARMBuildAttrs::FP_arch, "vfpv4");
804804
805805 /* VFPv3 + .fpu */
806806 } else if (Subtarget->hasVFP3()) {
807 AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
807 AttrEmitter->EmitAttribute(ARMBuildAttrs::FP_arch,
808808 ARMBuildAttrs::AllowFPv3A);
809809 if (emitFPU)
810 AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv3");
810 AttrEmitter->EmitTextAttribute(ARMBuildAttrs::FP_arch, "vfpv3");
811811
812812 /* VFPv2 + .fpu */
813813 } else if (Subtarget->hasVFP2()) {
814 AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
814 AttrEmitter->EmitAttribute(ARMBuildAttrs::FP_arch,
815815 ARMBuildAttrs::AllowFPv2);
816816 if (emitFPU)
817 AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv2");
817 AttrEmitter->EmitTextAttribute(ARMBuildAttrs::FP_arch, "vfpv2");
818818 }
819819
820820 /* TODO: ARMBuildAttrs::Allowed is not completely accurate,
+0
-131
lib/Target/ARM/ARMBuildAttrs.h less more
None //===-- ARMBuildAttrs.h - ARM Build Attributes ------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains enumerations and support routines for ARM build attributes
10 // as defined in ARM ABI addenda document (ABI release 2.08).
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef __TARGET_ARMBUILDATTRS_H__
15 #define __TARGET_ARMBUILDATTRS_H__
16
17 namespace ARMBuildAttrs {
18 enum SpecialAttr {
19 // This is for the .cpu asm attr. It translates into one or more
20 // AttrType (below) entries in the .ARM.attributes section in the ELF.
21 SEL_CPU
22 };
23
24 enum AttrType {
25 // Rest correspond to ELF/.ARM.attributes
26 File = 1,
27 Section = 2,
28 Symbol = 3,
29 CPU_raw_name = 4,
30 CPU_name = 5,
31 CPU_arch = 6,
32 CPU_arch_profile = 7,
33 ARM_ISA_use = 8,
34 THUMB_ISA_use = 9,
35 VFP_arch = 10,
36 WMMX_arch = 11,
37 Advanced_SIMD_arch = 12,
38 PCS_config = 13,
39 ABI_PCS_R9_use = 14,
40 ABI_PCS_RW_data = 15,
41 ABI_PCS_RO_data = 16,
42 ABI_PCS_GOT_use = 17,
43 ABI_PCS_wchar_t = 18,
44 ABI_FP_rounding = 19,
45 ABI_FP_denormal = 20,
46 ABI_FP_exceptions = 21,
47 ABI_FP_user_exceptions = 22,
48 ABI_FP_number_model = 23,
49 ABI_align8_needed = 24,
50 ABI_align8_preserved = 25,
51 ABI_enum_size = 26,
52 ABI_HardFP_use = 27,
53 ABI_VFP_args = 28,
54 ABI_WMMX_args = 29,
55 ABI_optimization_goals = 30,
56 ABI_FP_optimization_goals = 31,
57 compatibility = 32,
58 CPU_unaligned_access = 34,
59 VFP_HP_extension = 36,
60 ABI_FP_16bit_format = 38,
61 MPextension_use = 42, // was 70, 2.08 ABI
62 DIV_use = 44,
63 nodefaults = 64,
64 also_compatible_with = 65,
65 T2EE_use = 66,
66 conformance = 67,
67 Virtualization_use = 68,
68 MPextension_use_old = 70
69 };
70
71 // Magic numbers for .ARM.attributes
72 enum AttrMagic {
73 Format_Version = 0x41
74 };
75
76 // Legal Values for CPU_arch, (=6), uleb128
77 enum CPUArch {
78 Pre_v4 = 0,
79 v4 = 1, // e.g. SA110
80 v4T = 2, // e.g. ARM7TDMI
81 v5T = 3, // e.g. ARM9TDMI
82 v5TE = 4, // e.g. ARM946E_S
83 v5TEJ = 5, // e.g. ARM926EJ_S
84 v6 = 6, // e.g. ARM1136J_S
85 v6KZ = 7, // e.g. ARM1176JZ_S
86 v6T2 = 8, // e.g. ARM1156T2F_S
87 v6K = 9, // e.g. ARM1136J_S
88 v7 = 10, // e.g. Cortex A8, Cortex M3
89 v6_M = 11, // e.g. Cortex M1
90 v6S_M = 12, // v6_M with the System extensions
91 v7E_M = 13 // v7_M with DSP extensions
92 };
93
94 enum CPUArchProfile { // (=7), uleb128
95 Not_Applicable = 0, // pre v7, or cross-profile code
96 ApplicationProfile = (0x41), // 'A' (e.g. for Cortex A8)
97 RealTimeProfile = (0x52), // 'R' (e.g. for Cortex R4)
98 MicroControllerProfile = (0x4D), // 'M' (e.g. for Cortex M3)
99 SystemProfile = (0x53) // 'S' Application or real-time profile
100 };
101
102 // The following have a lot of common use cases
103 enum {
104 //ARMISAUse (=8), uleb128 and THUMBISAUse (=9), uleb128
105 Not_Allowed = 0,
106 Allowed = 1,
107
108 // FP_arch (=10), uleb128 (formerly Tag_VFP_arch = 10)
109 AllowFPv2 = 2, // v2 FP ISA permitted (implies use of the v1 FP ISA)
110 AllowFPv3A = 3, // v3 FP ISA permitted (implies use of the v2 FP ISA)
111 AllowFPv3B = 4, // v3 FP ISA permitted, but only D0-D15, S0-S31
112 AllowFPv4A = 5, // v4 FP ISA permitted (implies use of v3 FP ISA)
113 AllowFPv4B = 6, // v4 FP ISA was permitted, but only D0-D15, S0-S31
114
115 // Tag_WMMX_arch, (=11), uleb128
116 AllowThumb32 = 2, // 32-bit Thumb (implies 16-bit instructions)
117
118 // Tag_WMMX_arch, (=11), uleb128
119 AllowWMMXv1 = 2, // The user permitted this entity to use WMMX v2
120
121 // Tag_ABI_FP_denormal, (=20), uleb128
122 PreserveFPSign = 2, // sign when flushed-to-zero is preserved
123
124 // Tag_ABI_FP_number_model, (=23), uleb128
125 AllowRTABI = 2, // numbers, infinities, and one quiet NaN (see [RTABI])
126 AllowIEE754 = 3 // this code to use all the IEEE 754-defined FP encodings
127 };
128 }
129
130 #endif // __TARGET_ARMBUILDATTRS_H__
0 RUN: llvm-readobj -arm-buildattrs %p/Inputs/trivial-object-test.elf-arm \
1 RUN: | FileCheck %s -check-prefix=SMALL
2 RUN: llvm-readobj -arm-buildattrs %p/Inputs/arm-attributes.elf-arm \
3 RUN: | FileCheck %s -check-prefix=LARGE
4
5 SMALL: ARMBuildAttributes {
6 SMALL: Tag_CPU_name: Cortex-A8
7 SMALL: Tag_CPU_arch: 10
8 SMALL: Tag_ARM_ISA_use: 1
9 SMALL: Tag_THUMB_ISA_use: 2
10 SMALL: Tag_FP_arch: 3
11 SMALL: Tag_Advanced_SIMD_arch: 1
12 SMALL: Tag_ABI_FP_denormal: 1
13 SMALL: Tag_ABI_FP_exceptions: 1
14 SMALL: Tag_ABI_FP_number_model: 3
15 SMALL: Tag_ABI_align8_needed: 1
16 SMALL: Tag_ABI_align8_preserved: 1
17 SMALL: Tag_ABI_HardFP_use: 3
18 SMALL: Tag_ABI_VFP_args: 1
19 SMALL: Tag_DIV_use: 1
20 SMALL: Tag_Virtualization_use: 1
21
22 LARGE: ARMBuildAttributes {
23 LARGE: Tag_CPU_name: iwmmxt2
24 LARGE: Tag_CPU_arch: 4
25 LARGE: Tag_ARM_ISA_use: 1
26 LARGE: Tag_THUMB_ISA_use: 1
27 LARGE: Tag_WMMX_arch: 2
28 LARGE: Tag_Advanced_SIMD_arch: 1
29 LARGE: Tag_ABI_PCS_RW_data: 3
30 LARGE: Tag_ABI_PCS_GOT_use: 2
31 LARGE: Tag_ABI_PCS_wchar_t: 4
32 LARGE: Tag_ABI_FP_rounding: 1
33 LARGE: Tag_ABI_FP_denormal: 1
34 LARGE: Tag_ABI_FP_exceptions: 1
35 LARGE: Tag_ABI_FP_number_model: 3
36 LARGE: Tag_ABI_align8_needed: 1
37 LARGE: Tag_ABI_align8_preserved: 1
38 LARGE: Tag_ABI_enum_size: 2
39 LARGE: Tag_ABI_HardFP_use: 3
40 LARGE: Tag_ABI_VFP_args: 1
41 LARGE: Tag_ABI_optimization_goals: 1
42 LARGE: Tag_CPU_unaligned_access: 1
43 LARGE: Tag_FP_HP_extension: 1
44 LARGE: Tag_DIV_use: 1
45 LARGE: Tag_T2EE_use: 1
5050 virtual void printDynamicTable() LLVM_OVERRIDE;
5151 virtual void printNeededLibraries() LLVM_OVERRIDE;
5252 virtual void printProgramHeaders() LLVM_OVERRIDE;
53 virtual void printARMBuildAttributes() LLVM_OVERRIDE;
5354
5455 private:
5556 typedef ELFObjectFile ELFO;
857858 W.printNumber("Alignment", PI->p_align);
858859 }
859860 }
861
862 #define LLVM_READOBJ_ARMATTR_NUMCASE(X) case ARMBuildAttrs::X: \
863 W.printNumber(" Tag_" #X, BuildAttrs.Tag_##X); \
864 break; \
865
866 #define LLVM_READOBJ_ARMATTR_STRCASE(X) case ARMBuildAttrs::X: \
867 W.printString(" Tag_" #X, BuildAttrs.Tag_##X); \
868 break; \
869
870 template
871 void ELFDumper::printARMBuildAttributes() {
872 if (Obj->getArch() != Triple::arm || !Obj->hasARMBuildAttributes())
873 return;
874 ARMBuildAttrs::ARMGenericBuildAttrInfo BuildAttrs;
875 SmallVector AttrsRead;
876 error_code EC = Obj->readARMBuildAttributes(BuildAttrs, AttrsRead);
877 if (error(EC))
878 return;
879
880 DictScope D(W, "ARMBuildAttributes");
881
882 for (SmallVector::iterator I = AttrsRead.begin(),
883 E = AttrsRead.end(); I != E; ++I) {
884 switch (*I) {
885 LLVM_READOBJ_ARMATTR_STRCASE(CPU_name)
886 LLVM_READOBJ_ARMATTR_STRCASE(CPU_raw_name)
887 LLVM_READOBJ_ARMATTR_NUMCASE(CPU_arch)
888 LLVM_READOBJ_ARMATTR_NUMCASE(CPU_arch_profile)
889 LLVM_READOBJ_ARMATTR_NUMCASE(ARM_ISA_use)
890 LLVM_READOBJ_ARMATTR_NUMCASE(THUMB_ISA_use)
891 LLVM_READOBJ_ARMATTR_NUMCASE(FP_arch)
892 LLVM_READOBJ_ARMATTR_NUMCASE(WMMX_arch)
893 LLVM_READOBJ_ARMATTR_NUMCASE(Advanced_SIMD_arch)
894 LLVM_READOBJ_ARMATTR_NUMCASE(PCS_config)
895 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_R9_use)
896 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_RW_data)
897 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_RO_data)
898 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_GOT_use)
899 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_wchar_t)
900 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_rounding)
901 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_denormal)
902 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_exceptions)
903 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_user_exceptions)
904 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_number_model)
905 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_align8_needed)
906 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_align8_preserved)
907 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_enum_size)
908 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_HardFP_use)
909 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_VFP_args)
910 LLVM_READOBJ_ARMATTR_NUMCASE(CPU_unaligned_access)
911 LLVM_READOBJ_ARMATTR_NUMCASE(FP_HP_extension)
912 LLVM_READOBJ_ARMATTR_NUMCASE(MPextension_use)
913 LLVM_READOBJ_ARMATTR_NUMCASE(DIV_use)
914 LLVM_READOBJ_ARMATTR_NUMCASE(T2EE_use)
915 LLVM_READOBJ_ARMATTR_NUMCASE(Virtualization_use)
916 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_optimization_goals)
917 LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_optimization_goals)
918 default:
919 break;
920 }
921 }
922 }
3838 virtual void printDynamicTable() { }
3939 virtual void printNeededLibraries() { }
4040 virtual void printProgramHeaders() { }
41 virtual void printARMBuildAttributes() { }
4142
4243 protected:
4344 StreamWriter& W;
127127 // -expand-relocs
128128 cl::opt ExpandRelocs("expand-relocs",
129129 cl::desc("Expand each shown relocation to multiple lines"));
130
131 // -arm-buildattrs
132 cl::opt ArmBuildAttrs("arm-buildattrs",
133 cl::desc("Display ARM ELF build attributes"));
130134 } // namespace opts
131135
132136 namespace llvm {
220224 Dumper->printNeededLibraries();
221225 if (opts::ProgramHeaders)
222226 Dumper->printProgramHeaders();
227 if (opts::ArmBuildAttrs)
228 Dumper->printARMBuildAttributes();
223229 }
224230
225231