• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- ARMELFAttributeData.h ----------------------------------------------===//
2 //
3 //                     The MCLinker Project
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #include "ARMELFAttributeData.h"
10 
11 #include "mcld/LinkerConfig.h"
12 #include "mcld/MC/Input.h"
13 #include "mcld/Support/LEB128.h"
14 #include "mcld/Support/MsgHandling.h"
15 #include <llvm/ADT/STLExtras.h>
16 
17 namespace mcld {
18 
getAttributeValue(TagType pTag) const19 const ELFAttributeValue* ARMELFAttributeData::getAttributeValue(
20     TagType pTag) const {
21   if (pTag <= Tag_Max) {
22     const ELFAttributeValue& attr_value = m_Attrs[pTag];
23 
24     if (attr_value.isInitialized()) {
25       return &attr_value;
26     } else {
27       // Don't return uninitialized attribute value.
28       return NULL;
29     }
30   } else {
31     UnknownAttrsMap::const_iterator attr_it = m_UnknownAttrs.find(pTag);
32 
33     if (attr_it == m_UnknownAttrs.end()) {
34       return NULL;
35     } else {
36       return &attr_it->second;
37     }
38   }
39 }
40 
41 std::pair<ELFAttributeValue*, bool>
getOrCreateAttributeValue(TagType pTag)42 ARMELFAttributeData::getOrCreateAttributeValue(TagType pTag) {
43   ELFAttributeValue* attr_value = NULL;
44 
45   if (pTag <= Tag_Max) {
46     attr_value = &m_Attrs[pTag];
47   } else {
48     // An unknown tag encounterred.
49     attr_value = &m_UnknownAttrs[pTag];
50   }
51 
52   assert(attr_value != NULL);
53 
54   // Setup the value type.
55   if (!attr_value->isUninitialized()) {
56     return std::make_pair(attr_value, false);
57   } else {
58     attr_value->setType(GetAttributeValueType(pTag));
59     return std::make_pair(attr_value, true);
60   }
61 }
62 
GetAttributeValueType(TagType pTag)63 unsigned int ARMELFAttributeData::GetAttributeValueType(TagType pTag) {
64   // See ARM [ABI-addenda], 2.2.6.
65   switch (pTag) {
66     case Tag_compatibility: {
67       return (ELFAttributeValue::Int | ELFAttributeValue::String);
68     }
69     case Tag_nodefaults: {
70       return (ELFAttributeValue::Int | ELFAttributeValue::NoDefault);
71     }
72     case Tag_CPU_raw_name:
73     case Tag_CPU_name: {
74       return ELFAttributeValue::String;
75     }
76     default: {
77       if (pTag < 32)
78         return ELFAttributeValue::Int;
79       else
80         return ((pTag & 1) ? ELFAttributeValue::String
81                            : ELFAttributeValue::Int);
82     }
83   }
84   // unreachable
85 }
86 
87 //===--------------------------------------------------------------------===//
88 // Helper Functions for merge()
89 //===--------------------------------------------------------------------===//
90 
91 namespace {
92 
93 /*
94  * Helper function to decode value in Tag_also_compatible_with.
95  *
96  * @ref ARM [ABI-addenda], 2.3.7.3
97  */
decode_secondary_compatibility_attribute(const ELFAttributeValue & pValue)98 static int decode_secondary_compatibility_attribute(
99     const ELFAttributeValue& pValue) {
100   // The encoding of Tag_also_compatible_with is:
101   //
102   // Tag_also_compatible_with (=65), NTSB: data
103   //
104   // The data can be either an ULEB128-encoded number followed by a NULL byte or
105   // a NULL-terminated string. Currently, only the following byte sequence in
106   // data are currently defined:
107   //
108   // Tag_CPU_arch (=6) [The arch] 0
109   assert((pValue.type() == ELFAttributeValue::String) &&
110          "Value of Tag_also_compatible_with must be a string!");
111 
112   const std::string& data = pValue.getStringValue();
113 
114   // Though the integer is in LEB128 format, but they occupy only 1 byte in
115   // currently defined value.
116   if (data.length() < 2)
117     // Must have a byte for Tag_CPU_arch (=6)
118     //           a byte for specifying the CPU architecture (CPU_Arch_ARM_*)
119     //
120     // Currently, the 2nd byte can only be v4T (=2) or v6-M (=11).
121     return -1;
122 
123   if ((static_cast<uint8_t>(data[0]) == ARMELFAttributeData::Tag_CPU_arch) &&
124       ((data[1] == ARMELFAttributeData::CPU_Arch_ARM_V4T) ||
125        (data[1] == ARMELFAttributeData::CPU_Arch_ARM_V6_M)))
126     return static_cast<uint32_t>(data[1]);
127 
128   // Tag_also_compatible_with can be safely ignored.
129   return -1;
130 }
131 
132 /*
133  * This helper array keeps the ordering of the values in attributes such as
134  * Tag_ABI_align_needed which are sored as 1 > 2 > 0.
135  */
136 static const int value_ordering_120[] = {0, 2, 1};
137 
138 }  // anonymous namespace
139 
140 //===--------------------------------------------------------------------===//
141 // End Helper Functions for merge()
142 //===--------------------------------------------------------------------===//
143 
merge(const LinkerConfig & pConfig,const Input & pInput,TagType pTag,const ELFAttributeValue & pInAttr)144 bool ARMELFAttributeData::merge(const LinkerConfig& pConfig,
145                                 const Input& pInput,
146                                 TagType pTag,
147                                 const ELFAttributeValue& pInAttr) {
148   // Pre-condition
149   //  1. The out_attr must be initailized and has value of the same type as
150   //     pInAttr.
151   //  2. The value helf by out_attr and pInAttr must be different.
152   ELFAttributeValue& out_attr = m_Attrs[pTag];
153 
154   // Attribute in the output must have value assigned.
155   assert(out_attr.isInitialized() && "No output attribute to be merged!");
156 
157   switch (pTag) {
158     case Tag_CPU_arch: {
159       // Need value of Tag_also_compatible_with in the input for merge.
160       if (pInAttr.getIntValue() <= CPU_Arch_Max) {
161         m_CPUArch = pInAttr.getIntValue();
162       } else {
163         error(diag::error_unknown_cpu_arch) << pInput.name();
164         return false;
165       }
166       break;
167     }
168     case Tag_CPU_name: {
169       // need value of Tag_CPU_arch in the input for merge
170       m_CPUName = pInAttr.getStringValue();
171       break;
172     }
173     case Tag_CPU_raw_name: {
174       // need value of Tag_CPU_arch in the input for merge
175       m_CPURawName = pInAttr.getStringValue();
176       break;
177     }
178     case Tag_FP_arch: {
179       // need value of Tag_HardFP_use in the input for merge
180       m_FPArch = pInAttr.getIntValue();
181       break;
182     }
183     case Tag_ABI_HardFP_use: {
184       // need value of Tag_FP_arch in the input for merge
185       m_HardFPUse = pInAttr.getIntValue();
186       break;
187     }
188     case Tag_also_compatible_with: {
189       // need value of Tag_CPU_arch in the input for merge
190       m_SecondaryCPUArch = decode_secondary_compatibility_attribute(pInAttr);
191       break;
192     }
193     case Tag_ABI_VFP_args: {
194       // need value of Tag_ABI_FP_number_model in the input for merge
195       m_VFPArgs = pInAttr.getIntValue();
196       break;
197     }
198     // The value of these tags are integers and after merge, only the greatest
199     // value held by pInAttr and out_attr goes into output.
200     case Tag_ARM_ISA_use:
201     case Tag_THUMB_ISA_use:
202     case Tag_WMMX_arch:
203     case Tag_Advanced_SIMD_arch:
204     case Tag_ABI_FP_rounding:
205     case Tag_ABI_FP_exceptions:
206     case Tag_ABI_FP_user_exceptions:
207     case Tag_ABI_FP_number_model:
208     case Tag_FP_HP_extension:
209     case Tag_CPU_unaligned_access:
210     case Tag_T2EE_use: {
211       assert((out_attr.type() == ELFAttributeValue::Int) &&
212              (pInAttr.type() == ELFAttributeValue::Int) &&
213              "should have integer parameeter!");
214       if (pInAttr.getIntValue() > out_attr.getIntValue())
215         out_attr.setIntValue(pInAttr.getIntValue());
216       break;
217     }
218     // The value of these tags are integers and after merge, only the smallest
219     // value held by pInAttr and out_attr goes into output.
220     case Tag_ABI_align_preserved:
221     case Tag_ABI_PCS_RO_data: {
222       assert((out_attr.type() == ELFAttributeValue::Int) &&
223              (pInAttr.type() == ELFAttributeValue::Int) &&
224              "should have integer parameeter!");
225       if (pInAttr.getIntValue() < out_attr.getIntValue())
226         out_attr.setIntValue(pInAttr.getIntValue());
227       break;
228     }
229     // The values of these attributes are sorted as 1 > 2 > 0. And the greater
230     // value becomes output.
231     case Tag_ABI_align_needed:
232     case Tag_ABI_FP_denormal:
233     case Tag_ABI_PCS_GOT_use: {
234       const int in_val = pInAttr.getIntValue();
235       const int out_val = out_attr.getIntValue();
236 
237       if (in_val <= 2) {
238         if (out_val <= 2) {
239           // Use value_ordering_120 to determine the ordering.
240           if (value_ordering_120[in_val] > value_ordering_120[out_val]) {
241             out_attr.setIntValue(in_val);
242           }
243         }
244       } else {
245         // input value > 2, for future-proofing
246         if (in_val > out_val) {
247           out_attr.setIntValue(in_val);
248         }
249       }
250       break;
251     }
252     // These tags use the first value ever seen.
253     case Tag_ABI_optimization_goals:
254     case Tag_ABI_FP_optimization_goals: {
255       break;
256     }
257     // Tag_CPU_arch_profile
258     case Tag_CPU_arch_profile: {
259       if (pInAttr.getIntValue() == Arch_Profile_None)
260         return true;
261 
262       switch (out_attr.getIntValue()) {
263         case Arch_Profile_None: {
264           out_attr.setIntValue(pInAttr.getIntValue());
265           break;
266         }
267         case Arch_Profile_RealOrApp: {
268           if (pInAttr.getIntValue() != Arch_Profile_Microcontroller)
269             out_attr.setIntValue(pInAttr.getIntValue());
270           else
271             warning(diag::warn_mismatch_cpu_arch_profile)
272                 << pInAttr.getIntValue() << pInput.name();
273           break;
274         }
275         default: {
276           // out_attr is Arch_Profile_Application or Arch_Profile_Realtime or
277           // Arch_Profile_Microcontroller.
278           if ((pInAttr.getIntValue() == Arch_Profile_RealOrApp) &&
279               (out_attr.getIntValue() != Arch_Profile_Microcontroller)) {
280             // do nothing
281           } else {
282             if (pConfig.options().warnMismatch())
283               warning(diag::warn_mismatch_cpu_arch_profile)
284                   << pInAttr.getIntValue() << pInput.name();
285           }
286           break;
287         }
288       }
289       break;
290     }
291     // Tag_MPextension_use and Tag_MPextension_use_legacy
292     case Tag_MPextension_use:
293     case Tag_MPextension_use_legacy: {
294       if (m_MPextensionUse < 0) {
295         m_MPextensionUse = pInAttr.getIntValue();
296       } else {
297         if (static_cast<unsigned>(m_MPextensionUse) != pInAttr.getIntValue()) {
298           warning(diag::error_mismatch_mpextension_use) << pInput.name();
299         }
300       }
301       break;
302     }
303     // Tag_DIV_use
304     case Tag_DIV_use: {
305       if (pInAttr.getIntValue() == 2) {
306         // 2 means the code was permitted to use SDIV/UDIV in anyway.
307         out_attr.setIntValue(2);
308       } else {
309         // Merge until settling down Tag_CPU_arch.
310         m_DIVUse = pInAttr.getIntValue();
311       }
312       break;
313     }
314     // Tag_ABI_enum_size
315     case Tag_ABI_enum_size: {
316       if ((out_attr.getIntValue() == Enum_Unused) ||
317           (out_attr.getIntValue() == Enum_Containerized_As_Possible))
318         out_attr.setIntValue(pInAttr.getIntValue());
319       else if (pInAttr.getIntValue() != Enum_Containerized_As_Possible &&
320                pConfig.options().warnMismatch())
321         warning(diag::warn_mismatch_enum_size)
322             << pInput.name() << pInAttr.getIntValue() << out_attr.getIntValue();
323       break;
324     }
325     // Tag_ABI_FP_16bit_format
326     case Tag_ABI_FP_16bit_format: {
327       // 0: doesn't use any 16-bit FP number
328       // 1: use IEEE 754 format 16-bit FP number
329       // 2: use VFPv3/Advanced SIMD "alternative format" 16-bit FP number
330       if (pInAttr.getIntValue() != 0) {
331         if (out_attr.getIntValue() == 0) {
332           out_attr.setIntValue(pInAttr.getIntValue());
333         } else {
334           if (pConfig.options().warnMismatch())
335             warning(diag::warn_mismatch_fp16_format) << pInput.name();
336         }
337       }
338       break;
339     }
340     // Tag_nodefaults
341     case Tag_nodefaults: {
342       // There's nothing to do for this tag. It doesn't have an actual value.
343       break;
344     }
345     // Tag_conformance
346     case Tag_conformance: {
347       // Throw away the value if the attribute value doesn't match.
348       if (out_attr.getStringValue() != pInAttr.getStringValue())
349         out_attr.setStringValue("");
350       break;
351     }
352     // Tag_Virtualization_use
353     case Tag_Virtualization_use: {
354       // 0: No use of any virtualization extension
355       // 1: TrustZone
356       // 2: Virtualization extension such as HVC and ERET
357       // 3: TrustZone and virtualization extension are permitted
358       if (pInAttr.getIntValue() != 0) {
359         if (out_attr.getIntValue() == 0) {
360           out_attr.setIntValue(pInAttr.getIntValue());
361         } else {
362           if ((out_attr.getIntValue() <= 3) && (pInAttr.getIntValue() <= 3)) {
363             // Promote to 3
364             out_attr.setIntValue(3);
365           } else {
366             warning(diag::warn_unrecognized_virtualization_use)
367                 << pInput.name() << pInAttr.getIntValue();
368           }
369         }
370       }
371       break;
372     }
373     // Tag_ABI_WMMX_args
374     case Tag_ABI_WMMX_args: {
375       // There's no way to merge this value (i.e., objects contain different
376       // value in this tag are definitely incompatible.)
377       if (pConfig.options().warnMismatch())
378         warning(diag::warn_mismatch_abi_wmmx_args) << pInput.name();
379       break;
380     }
381     // Tag_PCS_config
382     case Tag_PCS_config: {
383       // 0 means no standard configuration used or no information recorded.
384       if (pInAttr.getIntValue() != 0) {
385         if (out_attr.getIntValue() == 0)
386           out_attr.setIntValue(pInAttr.getIntValue());
387         else {
388           // Different values in these attribute are conflict
389           if (pConfig.options().warnMismatch())
390             warning(diag::warn_mismatch_pcs_config) << pInput.name();
391         }
392       }
393       break;
394     }
395     // Tag_ABI_PCS_R9_use
396     case Tag_ABI_PCS_R9_use: {
397       if (pInAttr.getIntValue() != R9_Unused) {
398         if (out_attr.getIntValue() == R9_Unused)
399           out_attr.setIntValue(pInAttr.getIntValue());
400         else {
401           if (pConfig.options().warnMismatch())
402             warning(diag::warn_mismatch_r9_use) << pInput.name();
403         }
404       }
405       break;
406     }
407     // Tag_ABI_PCS_RW_data
408     case Tag_ABI_PCS_RW_data: {
409       if (pInAttr.getIntValue() == RW_data_SB_Relative) {
410         // Require using R9 as SB (global Static Base register).
411         if ((out_attr.getIntValue() != R9_Unused) &&
412             (out_attr.getIntValue() != R9_SB) &&
413             pConfig.options().warnMismatch())
414           warning(diag::warn_mismatch_r9_use) << pInput.name();
415       }
416       // Choose the smaller value
417       if (pInAttr.getIntValue() < out_attr.getIntValue())
418         out_attr.setIntValue(pInAttr.getIntValue());
419       break;
420     }
421     // Tag_ABI_PCS_wchar_t
422     case Tag_ABI_PCS_wchar_t: {
423       // 0: no use of wchar_t
424       // 2: sizeof(wchar_t) = 2
425       // 4: sizeof(wchar_t) = 4
426       if (pInAttr.getIntValue() != 0) {
427         if (out_attr.getIntValue() == 0)
428           out_attr.setIntValue(pInAttr.getIntValue());
429         else {
430           if (pConfig.options().warnMismatch())
431             warning(diag::warn_mismatch_wchar_size) << pInput.name()
432                                                     << pInAttr.getIntValue()
433                                                     << out_attr.getIntValue();
434         }
435       }
436       break;
437     }
438     default: {
439       // Handle unknown attributes:
440       //
441       // Since we don't know how to merge the value of unknown attribute, we
442       // have to ignore it. There're two rules related to the processing (See
443       // ARM [ABI-addenda] 2.2.6, Coding extensibility and compatibility.):
444       //
445       // 1. For tag N where N >= 128, tag N has the same properties as
446       //    tag N % 128.
447       // 2. Tag 64-127 can be safely ignored.
448       // 3. Tag 0-63 must be comprehended, therefore we cannot ignore.
449       if (pConfig.options().warnMismatch()) {
450         if ((pTag & 127) < 64) {
451           warning(diag::warn_unknown_mandatory_attribute) << pTag
452                                                           << pInput.name();
453         } else {
454           warning(diag::warn_unknown_attribute) << pTag << pInput.name();
455         }
456       }
457       break;
458     }
459   }
460   return true;
461 }
462 
463 //===--------------------------------------------------------------------===//
464 // Helper Functions for postMerge()
465 //===--------------------------------------------------------------------===//
466 
467 namespace {
468 
469 /*
470  * Helper function to encode value in Tag_also_compatible_with.
471  *
472  * @ref ARM [ABI-addenda], 2.3.7.3
473  */
encode_secondary_compatibility_attribute(ELFAttributeValue & pValue,int pArch)474 static void encode_secondary_compatibility_attribute(ELFAttributeValue& pValue,
475                                                      int pArch) {
476   if ((pArch < 0) || (pArch > ARMELFAttributeData::CPU_Arch_Max)) {
477     pValue.setStringValue("");
478   } else {
479     char new_value[] = {
480         ARMELFAttributeData::Tag_CPU_arch, static_cast<char>(pArch), 0};
481     pValue.setStringValue(std::string(new_value, sizeof(new_value)));
482   }
483   return;
484 }
485 
486 /*
487  * Combine the main and secondary CPU arch value
488  */
calculate_cpu_arch(int cpu_arch,int secondary_arch)489 static int calculate_cpu_arch(int cpu_arch, int secondary_arch) {
490   // short-circuit
491   if ((secondary_arch < 0) ||
492       ((cpu_arch + secondary_arch) != (ARMELFAttributeData::CPU_Arch_ARM_V4T +
493                                        ARMELFAttributeData::CPU_Arch_ARM_V6_M)))
494     return cpu_arch;
495 
496   if ((cpu_arch == ARMELFAttributeData::CPU_Arch_ARM_V4T) &&
497       (secondary_arch == ARMELFAttributeData::CPU_Arch_ARM_V6_M))
498     return ARMELFAttributeData::CPU_Arch_ARM_V4T_Plus_V6_M;
499   else if ((cpu_arch == ARMELFAttributeData::CPU_Arch_ARM_V6_M) &&
500            (secondary_arch == ARMELFAttributeData::CPU_Arch_ARM_V4T))
501     return ARMELFAttributeData::CPU_Arch_ARM_V4T_Plus_V6_M;
502   else
503     return cpu_arch;
504 }
505 
506 /*
507  * Given a CPU arch X and a CPU arch Y in which Y is newer than X, the value in
508  * cpu_compatibility_table[X][Y] is the CPU arch required to run ISA both from X
509  * and Y. 0 in the table means unreachable and -1 means conflict architecture
510  * profile.
511  */
512 #define CPU(C)  ARMELFAttributeData::CPU_Arch_ARM_ ## C
513 static const int cpu_compatibility_table[][CPU(V4T_Plus_V6_M) + 1] = {
514     /* old\new          ARM v6T2    ARM v6K   ARM v7   ARM v6-M   ARM v6S-M   ARM v7E-M    ARMv8, ARM v4t + v6-M     */  // NOLINT
515     /* Pre v4     */ { CPU(V6T2),  CPU(V6K), CPU(V7),        -1,         -1,         -1,      -1,       -1           },  // NOLINT
516     /* ARM v4     */ { CPU(V6T2),  CPU(V6K), CPU(V7),        -1,         -1,         -1,      -1,       -1           },  // NOLINT
517     /* ARM v4T    */ { CPU(V6T2),  CPU(V6K), CPU(V7),  CPU(V6K),   CPU(V6K), CPU(V7E_M), CPU(V8), CPU(V4T)           },  // NOLINT
518     /* ARM v5T    */ { CPU(V6T2),  CPU(V6K), CPU(V7),  CPU(V6K),   CPU(V6K), CPU(V7E_M), CPU(V8), CPU(V5T)           },  // NOLINT
519     /* ARM v5TE   */ { CPU(V6T2),  CPU(V6K), CPU(V7),  CPU(V6K),   CPU(V6K), CPU(V7E_M), CPU(V8), CPU(V5TE)          },  // NOLINT
520     /* ARM v5TEJ  */ { CPU(V6T2),  CPU(V6K), CPU(V7),  CPU(V6K),   CPU(V6K), CPU(V7E_M), CPU(V8), CPU(V5TEJ)         },  // NOLINT
521     /* ARM v6     */ { CPU(V6T2),  CPU(V6K), CPU(V7),  CPU(V6K),   CPU(V6K), CPU(V7E_M), CPU(V8), CPU(V6)            },  // NOLINT
522     /* ARM v6KZ   */ {   CPU(V7), CPU(V6KZ), CPU(V7), CPU(V6KZ),  CPU(V6KZ), CPU(V7E_M), CPU(V8), CPU(V6KZ)          },  // NOLINT
523     /* ARM v6T2   */ { CPU(V6T2),   CPU(V7), CPU(V7),   CPU(V7),    CPU(V7), CPU(V7E_M), CPU(V8), CPU(V6T2)          },  // NOLINT
524     /* ARM v6K    */ {         0,  CPU(V6K), CPU(V7),  CPU(V6K),   CPU(V6K), CPU(V7E_M), CPU(V8), CPU(V6K)           },  // NOLINT
525     /* ARM v7     */ {         0,         0, CPU(V7),   CPU(V7),    CPU(V7), CPU(V7E_M), CPU(V8), CPU(V7)            },  // NOLINT
526     /* ARM v6-M   */ {         0,         0,       0, CPU(V6_M), CPU(V6S_M), CPU(V7E_M), CPU(V8), CPU(V6_M)          },  // NOLINT
527     /* ARM v6S-M  */ {         0,         0,       0,         0, CPU(V6S_M), CPU(V7E_M), CPU(V8), CPU(V6S_M)         },  // NOLINT
528     /* ARM v7E-M  */ {         0,         0,       0,         0,          0, CPU(V7E_M), CPU(V8), CPU(V7E_M)         },  // NOLINT
529     /* ARM v8     */ {         0,         0,       0,         0,          0,          0, CPU(V8), CPU(V8)            },  // NOLINT
530     /* v4T + v6-M */ {         0,         0,       0,         0,          0,          0,       0, CPU(V4T_Plus_V6_M) }   // NOLINT
531 };
532 
533 /*
534  * Helper function to determine the merge of two different CPU arch.
535  */
merge_cpu_arch(int out_cpu_arch,int in_cpu_arch)536 static int merge_cpu_arch(int out_cpu_arch, int in_cpu_arch) {
537   if (out_cpu_arch > CPU(V4T_Plus_V6_M))
538     return in_cpu_arch;
539 
540   int new_cpu_arch, old_cpu_arch;
541   if (out_cpu_arch > in_cpu_arch) {
542     new_cpu_arch = out_cpu_arch;
543     old_cpu_arch = in_cpu_arch;
544   } else {
545     new_cpu_arch = in_cpu_arch;
546     old_cpu_arch = out_cpu_arch;
547   }
548 
549   // No need to check the compatibility since the CPU architectures before
550   // V6KZ add features monotonically.
551   if (new_cpu_arch <= CPU(V6KZ))
552     return new_cpu_arch;
553 
554   return cpu_compatibility_table[old_cpu_arch][new_cpu_arch - CPU(V6T2)];
555 }
556 #undef CPU
557 
558 /*
559  * Generic CPU name is used when Tag_CPU_name is unable to guess during the
560  * merge of Tag_CPU_arch.
561  */
562 static const char* generic_cpu_name_table[] = {
563     /* Pre v4    */ "Pre v4",
564     /* Pre v4    */ "ARM v4",
565     /* ARM v4T   */ "ARM v4T",
566     /* ARM v5T   */ "ARM v5T",
567     /* ARM v5TE  */ "ARM v5TE",
568     /* ARM v5TEJ */ "ARM v5TEJ",
569     /* ARM v6    */ "ARM v6",
570     /* ARM v6KZ  */ "ARM v6KZ",
571     /* ARM v6T2  */ "ARM v6T2",
572     /* ARM v6K   */ "ARM v6K",
573     /* ARM v7    */ "ARM v7",
574     /* ARM v6-M  */ "ARM v6-M",
575     /* ARM v6S-M */ "ARM v6S-M",
576     /* ARM v7E-M */ "ARM v7E-M",
577     /* ARM v8    */ "ARM v8",
578 };
579 
get_generic_cpu_name(int cpu_arch)580 static const char* get_generic_cpu_name(int cpu_arch) {
581   assert(static_cast<size_t>(cpu_arch) <
582          (sizeof(generic_cpu_name_table) / sizeof(generic_cpu_name_table[0])));
583   return generic_cpu_name_table[cpu_arch];
584 }
585 
586 /*
587  * Helper functions & data used in the merge of two different FP arch.
588  */
589 static const struct fp_config_data {
590   int version;
591   int regs;
592 } fp_configs[] = {
593       {0, 0},
594       {1, 16},
595       {2, 16},
596       {3, 32},
597       {3, 16},
598       {4, 32},
599       {4, 16},
600       {8, 32},
601       {8, 16},
602 };
603 
604 static const size_t num_fp_configs =
605     sizeof(fp_configs) / sizeof(fp_config_data);
606 
607 // Given h(x, y) = (x * (y >> 4) + (y >> 5))
608 //
609 // fp_config_hash_table[ h(0, 0)  =  0 ] = 0
610 // fp_config_hash_table[ h(1, 16) =  1 ] = 1
611 // fp_config_hash_table[ h(2, 16) =  2 ] = 2
612 // fp_config_hash_table[ h(3, 32) =  7 ] = 3
613 // fp_config_hash_table[ h(3, 16) =  3 ] = 4
614 // fp_config_hash_table[ h(4, 32) =  9 ] = 5
615 // fp_config_hash_table[ h(4, 16) =  4 ] = 6
616 // fp_config_hash_table[ h(8, 32) = 17 ] = 7
617 // fp_config_hash_table[ h(8, 16) =  8 ] = 8
618 //
619 // h(0, 0) = 0
620 static const uint8_t fp_config_hash_table[] = {
621 #define UND static_cast<uint8_t>(-1)
622     /*  0 */ 0,
623     /*  1 */ 1,
624     /*  2 */ 2,
625     /*  3 */ 4,
626     /*  4 */ 6,
627     /*  5 */ UND,
628     /*  6 */ UND,
629     /*  7 */ 3,
630     /*  8 */ 8,
631     /*  9 */ 5,
632     /* 10 */ UND,
633     /* 11 */ UND,
634     /* 12 */ UND,
635     /* 13 */ UND,
636     /* 14 */ UND,
637     /* 15 */ UND,
638     /* 16 */ UND,
639     /* 17 */ 7,
640 #undef UND
641 };
642 
calculate_fp_config_hash(const struct fp_config_data & pConfig)643 static int calculate_fp_config_hash(const struct fp_config_data& pConfig) {
644   int x = pConfig.version;
645   int y = pConfig.regs;
646   return (x * (y >> 4) + (y >> 5));
647 }
648 
get_fp_arch_of_config(const struct fp_config_data & pConfig)649 static int get_fp_arch_of_config(const struct fp_config_data& pConfig) {
650   int hash = calculate_fp_config_hash(pConfig);
651   assert(static_cast<size_t>(hash) <
652          llvm::array_lengthof(fp_config_hash_table));
653   return fp_config_hash_table[hash];
654 }
655 
is_allowed_use_of_div(int cpu_arch,int cpu_arch_profile,int div_use)656 static bool is_allowed_use_of_div(int cpu_arch,
657                                   int cpu_arch_profile,
658                                   int div_use) {
659   // 0: The code was permitted to use SDIV and UDIV in the Thumb ISA on v7-R or
660   //    v7-M.
661   // 1: The code was not permitted to use SDIV and UDIV.
662   // 2: The code was explicitly permitted to use SDIV and UDIV.
663   switch (div_use) {
664     case 0: {
665       if ((cpu_arch == ARMELFAttributeData::CPU_Arch_ARM_V7) &&
666           ((cpu_arch_profile == 'R') || (cpu_arch_profile == 'M'))) {
667         return true;
668       } else {
669         return (cpu_arch >= ARMELFAttributeData::CPU_Arch_ARM_V7E_M);
670       }
671     }
672     case 1: {
673       return false;
674     }
675     case 2:
676     // For future proofing
677     default: { return true; }
678   }
679 }
680 
681 }  // anonymous namespace
682 
683 //===--------------------------------------------------------------------===//
684 // End Helper Functions for postMerge()
685 //===--------------------------------------------------------------------===//
686 
postMerge(const LinkerConfig & pConfig,const Input & pInput)687 bool ARMELFAttributeData::postMerge(const LinkerConfig& pConfig,
688                                     const Input& pInput) {
689   // Process Tag_CPU_arch, Tag_CPU_name, Tag_CPU_raw_name, and
690   // Tag_also_compatible_with.
691   ELFAttributeValue& out_cpu_arch_attr = m_Attrs[Tag_CPU_arch];
692   ELFAttributeValue& out_secondary_compatibility_attr =
693       m_Attrs[Tag_also_compatible_with];
694 
695   if ((m_CurrentCPUArch < 0) && out_cpu_arch_attr.isInitialized()) {
696     // Current input initializes the value of Tag_CPU_arch. Validate it.
697     int out_cpu_arch = out_cpu_arch_attr.getIntValue();
698 
699     if (out_cpu_arch > CPU_Arch_Max) {
700       error(diag::error_unknown_cpu_arch) << pInput.name();
701       return false;
702     }
703 
704     // Initialize m_CurrentCPUArch.
705     int out_secondary_arch = -1;
706     if (out_secondary_compatibility_attr.isInitialized())
707       out_secondary_arch = decode_secondary_compatibility_attribute(
708           out_secondary_compatibility_attr);
709 
710     m_CurrentCPUArch = calculate_cpu_arch(out_cpu_arch, out_secondary_arch);
711   }
712 
713   if (m_CPUArch >= 0) {
714     assert(out_cpu_arch_attr.isInitialized() && "CPU arch has never set!");
715     assert(m_CurrentCPUArch >= 0);
716 
717     int in_cpu_arch = calculate_cpu_arch(m_CPUArch, m_SecondaryCPUArch);
718     int result_cpu_arch = merge_cpu_arch(m_CurrentCPUArch, in_cpu_arch);
719 
720     if (result_cpu_arch < 0) {
721       warning(diag::warn_mismatch_cpu_arch_profile) << in_cpu_arch
722                                                     << pInput.name();
723     } else {
724       if (result_cpu_arch != m_CurrentCPUArch) {
725         // Value of Tag_CPU_arch are going to changea.
726         m_CurrentCPUArch = result_cpu_arch;
727 
728         // Write the result value to the output.
729         if (result_cpu_arch == CPU_Arch_ARM_V4T_Plus_V6_M) {
730           out_cpu_arch_attr.setIntValue(CPU_Arch_ARM_V4T);
731           encode_secondary_compatibility_attribute(
732               out_secondary_compatibility_attr, CPU_Arch_ARM_V6_M);
733         } else {
734           out_cpu_arch_attr.setIntValue(result_cpu_arch);
735           encode_secondary_compatibility_attribute(
736               out_secondary_compatibility_attr, -1);
737         }
738 
739         ELFAttributeValue& out_cpu_name = m_Attrs[Tag_CPU_name];
740         ELFAttributeValue& out_cpu_raw_name = m_Attrs[Tag_CPU_raw_name];
741 
742         if (m_CurrentCPUArch != in_cpu_arch) {
743           // Unable to guess the Tag_CPU_name. Use the generic name.
744           if (out_cpu_name.isInitialized()) {
745             out_cpu_name.setStringValue(get_generic_cpu_name(m_CurrentCPUArch));
746           }
747 
748           // Tag_CPU_raw_name becomes unknown. Set to default value to disable
749           // it.
750           out_cpu_raw_name.setStringValue("");
751         } else {
752           // Use the value of Tag_CPU_name and Tag_CPU_raw_name from the input.
753           if (!m_CPUName.empty()) {
754             ELFAttributeValue& out_cpu_name = m_Attrs[Tag_CPU_name];
755             assert(out_cpu_name.isInitialized() && "CPU name has never set!");
756             out_cpu_name.setStringValue(m_CPUName);
757           }
758 
759           if (!m_CPURawName.empty()) {
760             ELFAttributeValue& out_cpu_raw_name = m_Attrs[Tag_CPU_raw_name];
761             assert(out_cpu_raw_name.isInitialized() &&
762                    "CPU raw name has never set!");
763             out_cpu_raw_name.setStringValue(m_CPURawName);
764           }
765         }
766       }
767     }
768   }  // (m_CPUArch >= 0)
769 
770   // Process Tag_ABI_VFP_args.
771   if (m_VFPArgs >= 0) {
772     ELFAttributeValue& out_attr = m_Attrs[Tag_ABI_VFP_args];
773     ELFAttributeValue& out_float_number_model_attr =
774         m_Attrs[Tag_ABI_FP_number_model];
775 
776     assert(out_attr.isInitialized() && "VFP args has never set!");
777 
778     // If the output is not permitted to use floating number, this attribute
779     // is ignored (migrate the value from input directly.)
780     if (out_float_number_model_attr.isUninitialized() ||
781         (out_float_number_model_attr.getIntValue() == 0)) {
782       // Inherit requirement from input.
783       out_attr.setIntValue(m_VFPArgs);
784     } else {
785       if (pConfig.options().warnMismatch())
786         warning(diag::warn_mismatch_vfp_args) << pInput.name();
787     }
788   }
789 
790   // Process Tag_FP_arch.
791   ELFAttributeValue& out_fp_arch_attr = m_Attrs[Tag_FP_arch];
792   if (m_FPArch >= 0) {
793     assert(out_fp_arch_attr.isInitialized() && "FP arch has never set!");
794 
795     // Tag_FP_arch
796     //  0: instructions requiring FP hardware are not permitted
797     //  1: VFP1
798     //  2: VFP2
799     //  3: VFP3 D32
800     //  4: VFP3 D16
801     //  5: VFP4 D32
802     //  6: VFP4 D16
803     //  7: ARM v8-A D32
804     //  8: ARM v8-A D16
805     if (out_fp_arch_attr.getIntValue() == 0) {
806       // Output has no constraints on FP hardware. Copy the requirement from
807       // input.
808       out_fp_arch_attr.setIntValue(m_FPArch);
809     } else if (m_FPArch == 0) {
810       // Input has no constraints on FP hardware. Do nothing.
811     } else {
812       // If here, both output and input contain non-zero value of Tag_FP_arch.
813 
814       // Version greater than num_fp_configs is not defined. Choose the greater
815       // one for future-proofing.
816       if (static_cast<unsigned>(m_FPArch) > num_fp_configs) {
817         if (static_cast<unsigned>(m_FPArch) > out_fp_arch_attr.getIntValue()) {
818           out_fp_arch_attr.setIntValue(m_FPArch);
819         }
820       } else {
821         if (out_fp_arch_attr.getIntValue() < num_fp_configs) {
822           const struct fp_config_data& input_fp_config = fp_configs[m_FPArch];
823 
824           const struct fp_config_data& output_fp_config =
825               fp_configs[out_fp_arch_attr.getIntValue()];
826 
827           const struct fp_config_data result_fp_config = {
828               /*version*/ ((output_fp_config.version > input_fp_config.version)
829                                ? output_fp_config.version
830                                : input_fp_config.version),
831               /* regs */ ((output_fp_config.regs > input_fp_config.regs)
832                               ? output_fp_config.regs
833                               : input_fp_config.regs),
834           };
835           // Find the attribute value corresponding the result_fp_config
836           out_fp_arch_attr.setIntValue(get_fp_arch_of_config(result_fp_config));
837         }
838       }
839     }
840   }  // (m_FPArch >= 0)
841 
842   // Process Tag_ABI_HardFP_use.
843   ELFAttributeValue& out_hardfp_use_attr = m_Attrs[Tag_ABI_HardFP_use];
844 
845   if (!m_HardFPUseInitialized && out_hardfp_use_attr.isInitialized()) {
846     m_HardFPUse = out_hardfp_use_attr.getIntValue();
847     m_HardFPUseInitialized = true;
848   }
849 
850   if (m_HardFPUse >= 0) {
851     // Tag_ABI_HardFP_use depends on the meaning of Tag_FP_arch when it's 0.
852     assert(out_hardfp_use_attr.isInitialized() && "HardFP use has never set!");
853 
854     if (out_fp_arch_attr.isUninitialized() ||
855         (out_fp_arch_attr.getIntValue() == 0)) {
856       // Has no constraints on FP hardware.
857       out_hardfp_use_attr.setIntValue(m_HardFPUse);
858     } else {
859       // Both output and input contain non-zero value of Tag_FP_arch and we have
860       // different Tag_ABI_HaedFP_Use settings other than 0.
861       if ((out_fp_arch_attr.getIntValue() > 0) && (m_HardFPUse > 0))
862         // Promote to 3 (The user permitted this entity to use both SP and DP
863         // VFP instruction.)
864         out_hardfp_use_attr.setIntValue(3);
865     }
866   }
867 
868   // Move the value of Tag_MPextension_use_legacy to Tag_MPextension_use.
869   ELFAttributeValue& out_mpextension_use_legacy =
870       m_Attrs[Tag_MPextension_use_legacy];
871 
872   ELFAttributeValue& out_mpextension_use = m_Attrs[Tag_MPextension_use];
873 
874   // If Tag_MPextension_use_legacy has value, it must be introduced by current
875   // input since it is reset every time after the merge completed.
876   if (out_mpextension_use_legacy.isInitialized()) {
877     if (out_mpextension_use.isInitialized()) {
878       if (m_MPextensionUse < 0) {
879         // The value of Tag_MPextension_use is introduced by the current input.
880         // Check whether it is consistent with the one set in legacy.
881         m_MPextensionUse = out_mpextension_use.getIntValue();
882       } else {
883         // Current input introduces value of Tag_MPextension_use in
884         // m_MPextensionUse.
885       }
886 
887       // Check the consistency between m_MPextensionUse and the value of
888       // Tag_MPextension_use_legacy.
889       if (static_cast<unsigned>(m_MPextensionUse) !=
890           out_mpextension_use_legacy.getIntValue()) {
891         error(diag::error_mismatch_mpextension_use) << pInput.name();
892         return false;
893       }
894     } else {
895       if (m_MPextensionUse < 0) {
896         // Tag_MPextension_use is not set. Initialize it and move the value.
897         out_mpextension_use.setType(ELFAttributeValue::Int);
898         out_mpextension_use.setIntValue(out_mpextension_use.getIntValue());
899       } else {
900         // Unreachable case since the value to unitialized attribute is directly
901         // assigned in ELFAttribute::Subsection::merge().
902         assert(false && "Tag_MPextension_use is uninitialized but have value?");
903       }
904     }
905 
906     // Reset the attribute to uninitialized so it won't be included in the
907     // output.
908     out_mpextension_use_legacy.setType(ELFAttributeValue::Uninitialized);
909   }
910 
911   // Process Tag_MPextension_use.
912   if (m_MPextensionUse > 0) {
913     assert(out_mpextension_use.isInitialized());
914 
915     if (static_cast<unsigned>(m_MPextensionUse) >
916         out_mpextension_use.getIntValue()) {
917       out_mpextension_use.setIntValue(m_MPextensionUse);
918     }
919   }
920 
921   // Process Tag_DIV_use.
922   ELFAttributeValue& out_div_use_attr = m_Attrs[Tag_DIV_use];
923 
924   if (!m_DIVUseInitialized && out_div_use_attr.isInitialized()) {
925     // Perform the merge by reverting value of Tag_DIV_use and setup m_DIVUse.
926     m_DIVUse = out_div_use_attr.getIntValue();
927     out_div_use_attr.setIntValue(0);
928     m_DIVUseInitialized = true;
929   }
930 
931   if (m_DIVUse >= 0) {
932     assert(out_div_use_attr.isInitialized());
933 
934     const ELFAttributeValue& out_cpu_arch_profile_attr =
935         m_Attrs[Tag_CPU_arch_profile];
936 
937     int out_cpu_arch_profile = Arch_Profile_None;
938     if (out_cpu_arch_profile_attr.isInitialized()) {
939       out_cpu_arch_profile = out_cpu_arch_profile_attr.getIntValue();
940     }
941 
942     if (m_DIVUse == 1) {
943       // Input (=1) was not permitted to use SDIV and UDIV. See whether current
944       // output was explicitly permitted the use.
945       if (!is_allowed_use_of_div(m_CurrentCPUArch,
946                                  out_cpu_arch_profile,
947                                  out_div_use_attr.getIntValue())) {
948         out_div_use_attr.setIntValue(1);
949       }
950     } else {
951       if (out_div_use_attr.getIntValue() != 1) {
952         // Output does not explicitly forbid the use of SDIV/UDIV. See whether
953         // the input attribute can allow it under current CPU architecture
954         // profile.
955         if (is_allowed_use_of_div(
956                 m_CurrentCPUArch, out_cpu_arch_profile, m_DIVUse)) {
957           out_div_use_attr.setIntValue(m_DIVUse);
958         }
959       }
960     }
961   }
962 
963   return true;
964 }
965 
sizeOutput() const966 size_t ARMELFAttributeData::sizeOutput() const {
967   size_t result = 0;
968 
969   // Size contributed by known attributes
970   for (unsigned i = 0; i <= Tag_Max; ++i) {
971     TagType tag = static_cast<TagType>(i);
972     const ELFAttributeValue& value = m_Attrs[tag];
973 
974     if (value.shouldEmit()) {
975       result += leb128::size(static_cast<uint32_t>(tag));
976       result += value.getSize();
977     }
978   }
979 
980   // Size contributed by unknown attributes
981   for (UnknownAttrsMap::const_iterator unknown_attr_it = m_UnknownAttrs.begin(),
982                                        unknown_attr_end = m_UnknownAttrs.end();
983        unknown_attr_it != unknown_attr_end;
984        ++unknown_attr_it) {
985     TagType tag = unknown_attr_it->first;
986     const ELFAttributeValue& value = unknown_attr_it->second;
987 
988     if (value.shouldEmit()) {
989       result += leb128::size(static_cast<uint32_t>(tag));
990       result += value.getSize();
991     }
992   }
993 
994   return result;
995 }
996 
emit(char * pBuf) const997 size_t ARMELFAttributeData::emit(char* pBuf) const {
998   char* buffer = pBuf;
999 
1000   // Tag_conformance "should be emitted first in a file-scope sub-subsection of
1001   // the first public subsection of the attribute section."
1002   //
1003   // See ARM [ABI-addenda], 2.3.7.4 Conformance tag
1004   const ELFAttributeValue& attr_conformance = m_Attrs[Tag_conformance];
1005 
1006   if (attr_conformance.shouldEmit()) {
1007     if (!ELFAttributeData::WriteAttribute(
1008             Tag_conformance, attr_conformance, buffer)) {
1009       return 0;
1010     }
1011   }
1012 
1013   // Tag_nodefaults "should be emitted before any other tag in an attribute
1014   // subsection other that the conformance tag"
1015   //
1016   // See ARM [ABI-addenda], 2.3.7.5 No defaults tag
1017   const ELFAttributeValue& attr_nodefaults = m_Attrs[Tag_nodefaults];
1018 
1019   if (attr_nodefaults.shouldEmit()) {
1020     if (!ELFAttributeData::WriteAttribute(
1021             Tag_nodefaults, attr_nodefaults, buffer)) {
1022       return 0;
1023     }
1024   }
1025 
1026   // Tag_conformance (=67)
1027   // Tag_nodefaults (=64)
1028   for (unsigned i = 0; i < Tag_nodefaults; ++i) {
1029     TagType tag = static_cast<TagType>(i);
1030     const ELFAttributeValue& value = m_Attrs[tag];
1031 
1032     if (value.shouldEmit() &&
1033         !ELFAttributeData::WriteAttribute(tag, value, buffer)) {
1034       return 0;
1035     }
1036   }
1037 
1038   for (unsigned i = (Tag_nodefaults + 1); i <= Tag_Max; ++i) {
1039     TagType tag = static_cast<TagType>(i);
1040     const ELFAttributeValue& value = m_Attrs[tag];
1041 
1042     if (value.shouldEmit() && (i != Tag_conformance) &&
1043         !ELFAttributeData::WriteAttribute(tag, value, buffer)) {
1044       return 0;
1045     }
1046   }
1047 
1048   for (UnknownAttrsMap::const_iterator unknown_attr_it = m_UnknownAttrs.begin(),
1049                                        unknown_attr_end = m_UnknownAttrs.end();
1050        unknown_attr_it != unknown_attr_end;
1051        ++unknown_attr_it) {
1052     TagType tag = unknown_attr_it->first;
1053     const ELFAttributeValue& value = unknown_attr_it->second;
1054 
1055     if (value.shouldEmit() &&
1056         !ELFAttributeData::WriteAttribute(tag, value, buffer)) {
1057       return 0;
1058     }
1059   }
1060 
1061   return (buffer - pBuf);
1062 }
1063 
usingThumb() const1064 bool ARMELFAttributeData::usingThumb() const {
1065   int arch = m_Attrs[Tag_CPU_arch].getIntValue();
1066   if ((arch == CPU_Arch_ARM_V6_M) || (arch == CPU_Arch_ARM_V6S_M))
1067     return true;
1068   if ((arch != CPU_Arch_ARM_V7) && (arch != CPU_Arch_ARM_V7E_M))
1069     return false;
1070 
1071   arch = m_Attrs[Tag_CPU_arch_profile].getIntValue();
1072   return arch == Arch_Profile_Microcontroller;
1073 }
1074 
usingThumb2() const1075 bool ARMELFAttributeData::usingThumb2() const {
1076   int arch = m_Attrs[Tag_CPU_arch].getIntValue();
1077   return (arch == CPU_Arch_ARM_V6T2) || (arch == CPU_Arch_ARM_V7);
1078 }
1079 
1080 }  // namespace mcld
1081