brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.1 KiB · 43a1173 Raw
502 lines · cpp
1//===- ARMAttributeParser.cpp - ARM Attribute Information Printer ---------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Support/ARMAttributeParser.h"10#include "llvm/ADT/StringExtras.h"11#include "llvm/Support/ARMBuildAttributes.h"12#include "llvm/Support/Errc.h"13#include "llvm/Support/ScopedPrinter.h"14#include <optional>15 16using namespace llvm;17using namespace llvm::ARMBuildAttrs;18 19#define ATTRIBUTE_HANDLER(attr)                                                \20  { ARMBuildAttrs::attr, &ARMAttributeParser::attr }21 22const ARMAttributeParser::DisplayHandler ARMAttributeParser::displayRoutines[] =23    {24        {ARMBuildAttrs::CPU_raw_name, &ARMAttributeParser::stringAttribute},25        {ARMBuildAttrs::CPU_name, &ARMAttributeParser::stringAttribute},26        ATTRIBUTE_HANDLER(CPU_arch),27        ATTRIBUTE_HANDLER(CPU_arch_profile),28        ATTRIBUTE_HANDLER(ARM_ISA_use),29        ATTRIBUTE_HANDLER(THUMB_ISA_use),30        ATTRIBUTE_HANDLER(FP_arch),31        ATTRIBUTE_HANDLER(WMMX_arch),32        ATTRIBUTE_HANDLER(Advanced_SIMD_arch),33        ATTRIBUTE_HANDLER(MVE_arch),34        ATTRIBUTE_HANDLER(PCS_config),35        ATTRIBUTE_HANDLER(ABI_PCS_R9_use),36        ATTRIBUTE_HANDLER(ABI_PCS_RW_data),37        ATTRIBUTE_HANDLER(ABI_PCS_RO_data),38        ATTRIBUTE_HANDLER(ABI_PCS_GOT_use),39        ATTRIBUTE_HANDLER(ABI_PCS_wchar_t),40        ATTRIBUTE_HANDLER(ABI_FP_rounding),41        ATTRIBUTE_HANDLER(ABI_FP_denormal),42        ATTRIBUTE_HANDLER(ABI_FP_exceptions),43        ATTRIBUTE_HANDLER(ABI_FP_user_exceptions),44        ATTRIBUTE_HANDLER(ABI_FP_number_model),45        ATTRIBUTE_HANDLER(ABI_align_needed),46        ATTRIBUTE_HANDLER(ABI_align_preserved),47        ATTRIBUTE_HANDLER(ABI_enum_size),48        ATTRIBUTE_HANDLER(ABI_HardFP_use),49        ATTRIBUTE_HANDLER(ABI_VFP_args),50        ATTRIBUTE_HANDLER(ABI_WMMX_args),51        ATTRIBUTE_HANDLER(ABI_optimization_goals),52        ATTRIBUTE_HANDLER(ABI_FP_optimization_goals),53        ATTRIBUTE_HANDLER(compatibility),54        ATTRIBUTE_HANDLER(CPU_unaligned_access),55        ATTRIBUTE_HANDLER(FP_HP_extension),56        ATTRIBUTE_HANDLER(ABI_FP_16bit_format),57        ATTRIBUTE_HANDLER(MPextension_use),58        ATTRIBUTE_HANDLER(DIV_use),59        ATTRIBUTE_HANDLER(DSP_extension),60        ATTRIBUTE_HANDLER(T2EE_use),61        ATTRIBUTE_HANDLER(Virtualization_use),62        ATTRIBUTE_HANDLER(PAC_extension),63        ATTRIBUTE_HANDLER(BTI_extension),64        ATTRIBUTE_HANDLER(PACRET_use),65        ATTRIBUTE_HANDLER(BTI_use),66        ATTRIBUTE_HANDLER(nodefaults),67        ATTRIBUTE_HANDLER(also_compatible_with),68};69 70#undef ATTRIBUTE_HANDLER71 72Error ARMAttributeParser::stringAttribute(AttrType tag) {73  StringRef tagName =74      ELFAttrs::attrTypeAsString(tag, tagToStringMap, /*hasTagPrefix=*/false);75  StringRef desc = de.getCStrRef(cursor);76 77  if (sw) {78    DictScope scope(*sw, "Attribute");79    sw->printNumber("Tag", tag);80    if (!tagName.empty())81      sw->printString("TagName", tagName);82    sw->printString("Value", desc);83  }84  return Error::success();85}86 87static const char *const CPU_arch_strings[] = {"Pre-v4",88                                               "ARM v4",89                                               "ARM v4T",90                                               "ARM v5T",91                                               "ARM v5TE",92                                               "ARM v5TEJ",93                                               "ARM v6",94                                               "ARM v6KZ",95                                               "ARM v6T2",96                                               "ARM v6K",97                                               "ARM v7",98                                               "ARM v6-M",99                                               "ARM v6S-M",100                                               "ARM v7E-M",101                                               "ARM v8-A",102                                               "ARM v8-R",103                                               "ARM v8-M Baseline",104                                               "ARM v8-M Mainline",105                                               nullptr,106                                               nullptr,107                                               nullptr,108                                               "ARM v8.1-M Mainline",109                                               "ARM v9-A"};110 111Error ARMAttributeParser::CPU_arch(AttrType tag) {112  return parseStringAttribute("CPU_arch", tag, ArrayRef(CPU_arch_strings));113}114 115Error ARMAttributeParser::CPU_arch_profile(AttrType tag) {116  uint64_t value = de.getULEB128(cursor);117 118  StringRef profile;119  switch (value) {120  default: profile = "Unknown"; break;121  case 'A': profile = "Application"; break;122  case 'R': profile = "Real-time"; break;123  case 'M': profile = "Microcontroller"; break;124  case 'S': profile = "Classic"; break;125  case 0: profile = "None"; break;126  }127 128  printAttribute(tag, value, profile);129  return Error::success();130}131 132Error ARMAttributeParser::ARM_ISA_use(AttrType tag) {133  static const char *const strings[] = {"Not Permitted", "Permitted"};134  return parseStringAttribute("ARM_ISA_use", tag, ArrayRef(strings));135}136 137Error ARMAttributeParser::THUMB_ISA_use(AttrType tag) {138  static const char *const strings[] = {"Not Permitted", "Thumb-1", "Thumb-2",139                                        "Permitted"};140  return parseStringAttribute("THUMB_ISA_use", tag, ArrayRef(strings));141}142 143Error ARMAttributeParser::FP_arch(AttrType tag) {144  static const char *const strings[] = {145      "Not Permitted", "VFPv1",     "VFPv2",      "VFPv3",         "VFPv3-D16",146      "VFPv4",         "VFPv4-D16", "ARMv8-a FP", "ARMv8-a FP-D16"};147  return parseStringAttribute("FP_arch", tag, ArrayRef(strings));148}149 150Error ARMAttributeParser::WMMX_arch(AttrType tag) {151  static const char *const strings[] = {"Not Permitted", "WMMXv1", "WMMXv2"};152  return parseStringAttribute("WMMX_arch", tag, ArrayRef(strings));153}154 155Error ARMAttributeParser::Advanced_SIMD_arch(AttrType tag) {156  static const char *const strings[] = {"Not Permitted", "NEONv1", "NEONv2+FMA",157                                        "ARMv8-a NEON", "ARMv8.1-a NEON"};158  return parseStringAttribute("Advanced_SIMD_arch", tag, ArrayRef(strings));159}160 161Error ARMAttributeParser::MVE_arch(AttrType tag) {162  static const char *const strings[] = {"Not Permitted", "MVE integer",163                                        "MVE integer and float"};164  return parseStringAttribute("MVE_arch", tag, ArrayRef(strings));165}166 167Error ARMAttributeParser::PCS_config(AttrType tag) {168  static const char *const strings[] = {"None",169                                        "Bare Platform",170                                        "Linux Application",171                                        "Linux DSO",172                                        "Palm OS 2004",173                                        "Reserved (Palm OS)",174                                        "Symbian OS 2004",175                                        "Reserved (Symbian OS)"};176  return parseStringAttribute("PCS_config", tag, ArrayRef(strings));177}178 179Error ARMAttributeParser::ABI_PCS_R9_use(AttrType tag) {180  static const char *const strings[] = {"v6", "Static Base", "TLS", "Unused"};181  return parseStringAttribute("ABI_PCS_R9_use", tag, ArrayRef(strings));182}183 184Error ARMAttributeParser::ABI_PCS_RW_data(AttrType tag) {185  static const char *const strings[] = {"Absolute", "PC-relative",186                                        "SB-relative", "Not Permitted"};187  return parseStringAttribute("ABI_PCS_RW_data", tag, ArrayRef(strings));188}189 190Error ARMAttributeParser::ABI_PCS_RO_data(AttrType tag) {191  static const char *const strings[] = {"Absolute", "PC-relative",192                                        "Not Permitted"};193  return parseStringAttribute("ABI_PCS_RO_data", tag, ArrayRef(strings));194}195 196Error ARMAttributeParser::ABI_PCS_GOT_use(AttrType tag) {197  static const char *const strings[] = {"Not Permitted", "Direct",198                                        "GOT-Indirect"};199  return parseStringAttribute("ABI_PCS_GOT_use", tag, ArrayRef(strings));200}201 202Error ARMAttributeParser::ABI_PCS_wchar_t(AttrType tag) {203  static const char *const strings[] = {"Not Permitted", "Unknown", "2-byte",204                                        "Unknown", "4-byte"};205  return parseStringAttribute("ABI_PCS_wchar_t", tag, ArrayRef(strings));206}207 208Error ARMAttributeParser::ABI_FP_rounding(AttrType tag) {209  static const char *const strings[] = {"IEEE-754", "Runtime"};210  return parseStringAttribute("ABI_FP_rounding", tag, ArrayRef(strings));211}212 213Error ARMAttributeParser::ABI_FP_denormal(AttrType tag) {214  static const char *const strings[] = {"Unsupported", "IEEE-754", "Sign Only"};215  return parseStringAttribute("ABI_FP_denormal", tag, ArrayRef(strings));216}217 218Error ARMAttributeParser::ABI_FP_exceptions(AttrType tag) {219  static const char *const strings[] = {"Not Permitted", "IEEE-754"};220  return parseStringAttribute("ABI_FP_exceptions", tag, ArrayRef(strings));221}222Error ARMAttributeParser::ABI_FP_user_exceptions(AttrType tag) {223  static const char *const strings[] = {"Not Permitted", "IEEE-754"};224  return parseStringAttribute("ABI_FP_user_exceptions", tag, ArrayRef(strings));225}226 227Error ARMAttributeParser::ABI_FP_number_model(AttrType tag) {228  static const char *const strings[] = {"Not Permitted", "Finite Only", "RTABI",229                                        "IEEE-754"};230  return parseStringAttribute("ABI_FP_number_model", tag, ArrayRef(strings));231}232 233Error ARMAttributeParser::ABI_align_needed(AttrType tag) {234  static const char *const strings[] = {"Not Permitted", "8-byte alignment",235                                        "4-byte alignment", "Reserved"};236 237  uint64_t value = de.getULEB128(cursor);238 239  std::string description;240  if (value < std::size(strings))241    description = strings[value];242  else if (value <= 12)243    description = "8-byte alignment, " + utostr(1ULL << value) +244                  "-byte extended alignment";245  else246    description = "Invalid";247 248  printAttribute(tag, value, description);249  return Error::success();250}251 252Error ARMAttributeParser::ABI_align_preserved(AttrType tag) {253  static const char *strings[] = {"Not Required", "8-byte data alignment",254                                  "8-byte data and code alignment", "Reserved"};255 256  uint64_t value = de.getULEB128(cursor);257 258  std::string description;259  if (value < std::size(strings))260    description = std::string(strings[value]);261  else if (value <= 12)262    description = std::string("8-byte stack alignment, ") +263                  utostr(1ULL << value) + std::string("-byte data alignment");264  else265    description = "Invalid";266 267  printAttribute(tag, value, description);268  return Error::success();269}270 271Error ARMAttributeParser::ABI_enum_size(AttrType tag) {272  static const char *const strings[] = {"Not Permitted", "Packed", "Int32",273                                        "External Int32"};274  return parseStringAttribute("ABI_enum_size", tag, ArrayRef(strings));275}276 277Error ARMAttributeParser::ABI_HardFP_use(AttrType tag) {278  static const char *const strings[] = {"Tag_FP_arch", "Single-Precision",279                                        "Reserved", "Tag_FP_arch (deprecated)"};280  return parseStringAttribute("ABI_HardFP_use", tag, ArrayRef(strings));281}282 283Error ARMAttributeParser::ABI_VFP_args(AttrType tag) {284  static const char *const strings[] = {"AAPCS", "AAPCS VFP", "Custom",285                                        "Not Permitted"};286  return parseStringAttribute("ABI_VFP_args", tag, ArrayRef(strings));287}288 289Error ARMAttributeParser::ABI_WMMX_args(AttrType tag) {290  static const char *const strings[] = {"AAPCS", "iWMMX", "Custom"};291  return parseStringAttribute("ABI_WMMX_args", tag, ArrayRef(strings));292}293 294Error ARMAttributeParser::ABI_optimization_goals(AttrType tag) {295  static const char *const strings[] = {296      "None",          "Speed",           "Aggressive Speed",297      "Size",          "Aggressive Size", "Debugging",298      "Best Debugging"};299  return parseStringAttribute("ABI_optimization_goals", tag, ArrayRef(strings));300}301 302Error ARMAttributeParser::ABI_FP_optimization_goals(AttrType tag) {303  static const char *const strings[] = {304      "None",     "Speed",        "Aggressive Speed", "Size", "Aggressive Size",305      "Accuracy", "Best Accuracy"};306  return parseStringAttribute("ABI_FP_optimization_goals", tag,307                              ArrayRef(strings));308}309 310Error ARMAttributeParser::compatibility(AttrType tag) {311  uint64_t integer = de.getULEB128(cursor);312  StringRef string = de.getCStrRef(cursor);313 314  if (sw) {315    DictScope scope(*sw, "Attribute");316    sw->printNumber("Tag", tag);317    sw->startLine() << "Value: " << integer << ", " << string << '\n';318    sw->printString("TagName",319                    ELFAttrs::attrTypeAsString(tag, tagToStringMap,320                                               /*hasTagPrefix=*/false));321    switch (integer) {322    case 0:323      sw->printString("Description", StringRef("No Specific Requirements"));324      break;325    case 1:326      sw->printString("Description", StringRef("AEABI Conformant"));327      break;328    default:329      sw->printString("Description", StringRef("AEABI Non-Conformant"));330      break;331    }332  }333  return Error::success();334}335 336Error ARMAttributeParser::CPU_unaligned_access(AttrType tag) {337  static const char *const strings[] = {"Not Permitted", "v6-style"};338  return parseStringAttribute("CPU_unaligned_access", tag, ArrayRef(strings));339}340 341Error ARMAttributeParser::FP_HP_extension(AttrType tag) {342  static const char *const strings[] = {"If Available", "Permitted"};343  return parseStringAttribute("FP_HP_extension", tag, ArrayRef(strings));344}345 346Error ARMAttributeParser::ABI_FP_16bit_format(AttrType tag) {347  static const char *const strings[] = {"Not Permitted", "IEEE-754", "VFPv3"};348  return parseStringAttribute("ABI_FP_16bit_format", tag, ArrayRef(strings));349}350 351Error ARMAttributeParser::MPextension_use(AttrType tag) {352  static const char *const strings[] = {"Not Permitted", "Permitted"};353  return parseStringAttribute("MPextension_use", tag, ArrayRef(strings));354}355 356Error ARMAttributeParser::DIV_use(AttrType tag) {357  static const char *const strings[] = {"If Available", "Not Permitted",358                                        "Permitted"};359  return parseStringAttribute("DIV_use", tag, ArrayRef(strings));360}361 362Error ARMAttributeParser::DSP_extension(AttrType tag) {363  static const char *const strings[] = {"Not Permitted", "Permitted"};364  return parseStringAttribute("DSP_extension", tag, ArrayRef(strings));365}366 367Error ARMAttributeParser::T2EE_use(AttrType tag) {368  static const char *const strings[] = {"Not Permitted", "Permitted"};369  return parseStringAttribute("T2EE_use", tag, ArrayRef(strings));370}371 372Error ARMAttributeParser::Virtualization_use(AttrType tag) {373  static const char *const strings[] = {374      "Not Permitted", "TrustZone", "Virtualization Extensions",375      "TrustZone + Virtualization Extensions"};376  return parseStringAttribute("Virtualization_use", tag, ArrayRef(strings));377}378 379Error ARMAttributeParser::PAC_extension(ARMBuildAttrs::AttrType tag) {380  static const char *const strings[] = {"Not Permitted",381                                        "Permitted in NOP space", "Permitted"};382  return parseStringAttribute("PAC_extension", tag, ArrayRef(strings));383}384 385Error ARMAttributeParser::BTI_extension(ARMBuildAttrs::AttrType tag) {386  static const char *const strings[] = {"Not Permitted",387                                        "Permitted in NOP space", "Permitted"};388  return parseStringAttribute("BTI_extension", tag, ArrayRef(strings));389}390 391Error ARMAttributeParser::PACRET_use(ARMBuildAttrs::AttrType tag) {392  static const char *const strings[] = {"Not Used", "Used"};393  return parseStringAttribute("PACRET_use", tag, ArrayRef(strings));394}395 396Error ARMAttributeParser::BTI_use(ARMBuildAttrs::AttrType tag) {397  static const char *const strings[] = {"Not Used", "Used"};398  return parseStringAttribute("BTI_use", tag, ArrayRef(strings));399}400 401Error ARMAttributeParser::nodefaults(AttrType tag) {402  uint64_t value = de.getULEB128(cursor);403  printAttribute(tag, value, "Unspecified Tags UNDEFINED");404  return Error::success();405}406 407Error ARMAttributeParser::also_compatible_with(AttrType tag) {408  // Parse value as a C string first in order to print it in escaped form later.409  // Then, parse it again to catch errors or to pretty print if Tag_CPU_arch.410  std::optional<Error> returnValue;411 412  SmallString<8> Description;413  raw_svector_ostream DescStream(Description);414 415  uint64_t InitialOffset = cursor.tell();416  StringRef RawStringValue = de.getCStrRef(cursor);417  uint64_t FinalOffset = cursor.tell();418  cursor.seek(InitialOffset);419  uint64_t InnerTag = de.getULEB128(cursor);420 421  bool ValidInnerTag =422      any_of(tagToStringMap, [InnerTag](const TagNameItem &Item) {423        return Item.attr == InnerTag;424      });425 426  if (!ValidInnerTag) {427    returnValue =428        createStringError(errc::argument_out_of_domain,429                          Twine(InnerTag) + " is not a valid tag number");430  } else {431    switch (InnerTag) {432    case ARMBuildAttrs::CPU_arch: {433      uint64_t InnerValue = de.getULEB128(cursor);434      auto strings = ArrayRef(CPU_arch_strings);435      if (InnerValue >= strings.size()) {436        returnValue = createStringError(437            errc::argument_out_of_domain,438            Twine(InnerValue) + " is not a valid " +439                ELFAttrs::attrTypeAsString(InnerTag, tagToStringMap) +440                " value");441      } else {442        DescStream << ELFAttrs::attrTypeAsString(InnerTag, tagToStringMap)443                   << " = " << InnerValue;444        if (strings[InnerValue])445          DescStream << " (" << strings[InnerValue] << ')';446      }447      break;448    }449    case ARMBuildAttrs::also_compatible_with:450      returnValue = createStringError(451          errc::invalid_argument,452          ELFAttrs::attrTypeAsString(InnerTag, tagToStringMap) +453              " cannot be recursively defined");454      break;455    case ARMBuildAttrs::CPU_raw_name:456    case ARMBuildAttrs::CPU_name:457    case ARMBuildAttrs::compatibility:458    case ARMBuildAttrs::conformance: {459      StringRef InnerValue = de.getCStrRef(cursor);460      DescStream << ELFAttrs::attrTypeAsString(InnerTag, tagToStringMap)461                 << " = " << InnerValue;462      break;463    }464    default: {465      uint64_t InnerValue = de.getULEB128(cursor);466      DescStream << ELFAttrs::attrTypeAsString(InnerTag, tagToStringMap)467                 << " = " << InnerValue;468    }469    }470  }471 472  setAttributeString(tag, RawStringValue);473  if (sw) {474    DictScope scope(*sw, "Attribute");475    sw->printNumber("Tag", tag);476    sw->printString("TagName",477                    ELFAttrs::attrTypeAsString(tag, tagToStringMap, false));478    sw->printStringEscaped("Value", RawStringValue);479    if (!Description.empty()) {480      sw->printString("Description", Description);481    }482  }483 484  cursor.seek(FinalOffset);485 486  return returnValue ? std::move(*returnValue) : Error::success();487}488 489Error ARMAttributeParser::handler(uint64_t tag, bool &handled) {490  handled = false;491  for (const auto &AH : displayRoutines) {492    if (uint64_t(AH.attribute) == tag) {493      if (Error e = (this->*AH.routine)(static_cast<AttrType>(tag)))494        return e;495      handled = true;496      break;497    }498  }499 500  return Error::success();501}502