[llvm] 08c6840 - [ARM] Parse Tag_also_compatible_with attribute

Victor Campos via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 16 03:23:01 PDT 2022


Author: Victor Campos
Date: 2022-08-16T11:22:56+01:00
New Revision: 08c6840f254ccc1d93da2e1f79d398d30f8b3862

URL: https://github.com/llvm/llvm-project/commit/08c6840f254ccc1d93da2e1f79d398d30f8b3862
DIFF: https://github.com/llvm/llvm-project/commit/08c6840f254ccc1d93da2e1f79d398d30f8b3862.diff

LOG: [ARM] Parse Tag_also_compatible_with attribute

The ARM Attribute Parser used to parse the value of also_compatible_with
as it is, disregarding the way it is encoded.

This patch does a context aware parsing of the also_compatible_with
attribute. Additionally, some error handling is also done for incorrect
cases.

Reviewed By: pratlucas

Differential Revision: https://reviews.llvm.org/D130913

Added: 
    llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-integer.s
    llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-invalid_arch.s
    llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-invalid_tag.s
    llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-recursive.s
    llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-string.s

Modified: 
    llvm/include/llvm/Support/ARMAttributeParser.h
    llvm/include/llvm/Support/ScopedPrinter.h
    llvm/lib/Support/ARMAttributeParser.cpp
    llvm/test/MC/ARM/directive-eabi_attribute.s

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Support/ARMAttributeParser.h b/llvm/include/llvm/Support/ARMAttributeParser.h
index cbb5701540e14..d1d953120ae7e 100644
--- a/llvm/include/llvm/Support/ARMAttributeParser.h
+++ b/llvm/include/llvm/Support/ARMAttributeParser.h
@@ -70,6 +70,7 @@ class ARMAttributeParser : public ELFAttributeParser {
   Error PACRET_use(ARMBuildAttrs::AttrType tag);
   Error BTI_use(ARMBuildAttrs::AttrType tag);
   Error nodefaults(ARMBuildAttrs::AttrType tag);
+  Error also_compatible_with(ARMBuildAttrs::AttrType tag);
 
 public:
   ARMAttributeParser(ScopedPrinter *sw)

diff  --git a/llvm/include/llvm/Support/ScopedPrinter.h b/llvm/include/llvm/Support/ScopedPrinter.h
index c9eabfb3788c0..40af8dc6521a9 100644
--- a/llvm/include/llvm/Support/ScopedPrinter.h
+++ b/llvm/include/llvm/Support/ScopedPrinter.h
@@ -344,6 +344,10 @@ class ScopedPrinter {
     startLine() << Label << ": " << Value << "\n";
   }
 
+  void printStringEscaped(StringRef Label, StringRef Value) {
+    printStringEscapedImpl(Label, Value);
+  }
+
   void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
     printBinaryImpl(Label, Str, Value, false);
   }
@@ -478,6 +482,12 @@ class ScopedPrinter {
     startLine() << Label << ": " << Str << " (" << Value << ")\n";
   }
 
+  virtual void printStringEscapedImpl(StringRef Label, StringRef Value) {
+    startLine() << Label << ": ";
+    OS.write_escaped(Value);
+    OS << '\n';
+  }
+
   void scopedBegin(char Symbol) {
     startLine() << Symbol << '\n';
     indent();

diff  --git a/llvm/lib/Support/ARMAttributeParser.cpp b/llvm/lib/Support/ARMAttributeParser.cpp
index 03c0c7aac4235..69a969fdce0b8 100644
--- a/llvm/lib/Support/ARMAttributeParser.cpp
+++ b/llvm/lib/Support/ARMAttributeParser.cpp
@@ -9,6 +9,8 @@
 #include "llvm/Support/ARMAttributeParser.h"
 #include "llvm/ADT/STLArrayExtras.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/ARMBuildAttributes.h"
+#include "llvm/Support/Errc.h"
 #include "llvm/Support/ScopedPrinter.h"
 
 using namespace llvm;
@@ -62,6 +64,7 @@ const ARMAttributeParser::DisplayHandler ARMAttributeParser::displayRoutines[] =
         ATTRIBUTE_HANDLER(PACRET_use),
         ATTRIBUTE_HANDLER(BTI_use),
         ATTRIBUTE_HANDLER(nodefaults),
+        ATTRIBUTE_HANDLER(also_compatible_with),
 };
 
 #undef ATTRIBUTE_HANDLER
@@ -81,15 +84,15 @@ Error ARMAttributeParser::stringAttribute(AttrType tag) {
   return Error::success();
 }
 
+static const char *CPU_arch_strings[] = {
+    "Pre-v4", "ARM v4", "ARM v4T", "ARM v5T", "ARM v5TE", "ARM v5TEJ",
+    "ARM v6", "ARM v6KZ", "ARM v6T2", "ARM v6K", "ARM v7", "ARM v6-M",
+    "ARM v6S-M", "ARM v7E-M", "ARM v8-A", "ARM v8-R", "ARM v8-M Baseline",
+    "ARM v8-M Mainline", nullptr, nullptr, nullptr, "ARM v8.1-M Mainline",
+    "ARM v9-A"};
+
 Error ARMAttributeParser::CPU_arch(AttrType tag) {
-  static const char *strings[] = {
-    "Pre-v4", "ARM v4", "ARM v4T", "ARM v5T", "ARM v5TE", "ARM v5TEJ", "ARM v6",
-    "ARM v6KZ", "ARM v6T2", "ARM v6K", "ARM v7", "ARM v6-M", "ARM v6S-M",
-    "ARM v7E-M", "ARM v8-A", "ARM v8-R",
-    "ARM v8-M Baseline", "ARM v8-M Mainline", nullptr, nullptr, nullptr,
-    "ARM v8.1-M Mainline", "ARM v9-A"
-  };
-  return parseStringAttribute("CPU_arch", tag, makeArrayRef(strings));
+  return parseStringAttribute("CPU_arch", tag, makeArrayRef(CPU_arch_strings));
 }
 
 Error ARMAttributeParser::CPU_arch_profile(AttrType tag) {
@@ -380,6 +383,84 @@ Error ARMAttributeParser::nodefaults(AttrType tag) {
   return Error::success();
 }
 
+Error ARMAttributeParser::also_compatible_with(AttrType tag) {
+  // Parse value as a C string first in order to print it in escaped form later.
+  // Then, parse it again to catch errors or to pretty print if Tag_CPU_arch.
+  Optional<Error> returnValue;
+
+  SmallString<8> Description;
+  raw_svector_ostream DescStream(Description);
+
+  uint64_t InitialOffset = cursor.tell();
+  StringRef RawStringValue = de.getCStrRef(cursor);
+  uint64_t FinalOffset = cursor.tell();
+  cursor.seek(InitialOffset);
+  uint64_t InnerTag = de.getULEB128(cursor);
+
+  bool ValidInnerTag =
+      any_of(tagToStringMap, [InnerTag](const TagNameItem &Item) {
+        return Item.attr == InnerTag;
+      });
+
+  if (!ValidInnerTag) {
+    returnValue =
+        createStringError(errc::argument_out_of_domain,
+                          Twine(InnerTag) + " is not a valid tag number");
+  } else {
+    switch (InnerTag) {
+    case ARMBuildAttrs::CPU_arch: {
+      uint64_t InnerValue = de.getULEB128(cursor);
+      auto strings = makeArrayRef(CPU_arch_strings);
+      if (InnerValue >= strings.size()) {
+        returnValue = createStringError(
+            errc::argument_out_of_domain,
+            Twine(InnerValue) + " is not a valid " +
+                ELFAttrs::attrTypeAsString(InnerTag, tagToStringMap) +
+                " value");
+      } else {
+        DescStream << ELFAttrs::attrTypeAsString(InnerTag, tagToStringMap)
+                   << " = " << InnerValue;
+        if (strings[InnerValue])
+          DescStream << " (" << strings[InnerValue] << ')';
+      }
+      break;
+    }
+    case ARMBuildAttrs::also_compatible_with:
+      returnValue = createStringError(
+          errc::invalid_argument,
+          ELFAttrs::attrTypeAsString(InnerTag, tagToStringMap) +
+              " cannot be recursively defined");
+      break;
+    case ARMBuildAttrs::CPU_raw_name:
+    case ARMBuildAttrs::CPU_name:
+    case ARMBuildAttrs::compatibility:
+    case ARMBuildAttrs::conformance: {
+      StringRef InnerValue = de.getCStrRef(cursor);
+      DescStream << ELFAttrs::attrTypeAsString(InnerTag, tagToStringMap)
+                 << " = " << InnerValue;
+      break;
+    }
+    default: {
+      uint64_t InnerValue = de.getULEB128(cursor);
+      DescStream << ELFAttrs::attrTypeAsString(InnerTag, tagToStringMap)
+                 << " = " << InnerValue;
+    }
+    }
+  }
+
+  DictScope scope(*sw, "Attribute");
+  sw->printNumber("Tag", tag);
+  sw->printString("TagName",
+                  ELFAttrs::attrTypeAsString(tag, tagToStringMap, false));
+  sw->printStringEscaped("Value", RawStringValue);
+  if (!Description.empty()) {
+    sw->printString("Description", Description);
+  }
+  cursor.seek(FinalOffset);
+
+  return returnValue ? std::move(*returnValue) : Error::success();
+}
+
 Error ARMAttributeParser::handler(uint64_t tag, bool &handled) {
   handled = false;
   for (unsigned AHI = 0, AHE = array_lengthof(displayRoutines); AHI != AHE;

diff  --git a/llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-integer.s b/llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-integer.s
new file mode 100644
index 0000000000000..afb5a0ca14a75
--- /dev/null
+++ b/llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-integer.s
@@ -0,0 +1,10 @@
+@ RUN: llvm-mc -triple arm -filetype obj -o - %s | \
+@ RUN: llvm-readobj -A - | \
+@ RUN: FileCheck %s
+
+.eabi_attribute Tag_also_compatible_with, "\015\001"
+@ CHECK: Attribute
+@ CHECK: Tag: 65
+@ CHECK: TagName: also_compatible_with
+@ CHECK: Value: \015\001
+@ CHECK: Description: Tag_PCS_config = 1

diff  --git a/llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-invalid_arch.s b/llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-invalid_arch.s
new file mode 100644
index 0000000000000..1bbd0f2463789
--- /dev/null
+++ b/llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-invalid_arch.s
@@ -0,0 +1,6 @@
+@ RUN: llvm-mc -triple arm -filetype obj -o - %s | \
+@ RUN: llvm-readobj -A - 2>&1 | \
+@ RUN: FileCheck %s --check-prefix=CHECK-WARNING
+
+.eabi_attribute Tag_also_compatible_with, "\006\143"
+@ CHECK-WARNING: 99 is not a valid Tag_CPU_arch value

diff  --git a/llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-invalid_tag.s b/llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-invalid_tag.s
new file mode 100644
index 0000000000000..e459701929619
--- /dev/null
+++ b/llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-invalid_tag.s
@@ -0,0 +1,6 @@
+@ RUN: llvm-mc -triple arm -filetype obj -o - %s | \
+@ RUN: llvm-readobj -A - 2>&1 | \
+@ RUN: FileCheck %s --check-prefix=CHECK-WARNING
+
+.eabi_attribute Tag_also_compatible_with, "\074\001"
+@ CHECK-WARNING: 60 is not a valid tag number

diff  --git a/llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-recursive.s b/llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-recursive.s
new file mode 100644
index 0000000000000..fa6174eba9bc4
--- /dev/null
+++ b/llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-recursive.s
@@ -0,0 +1,6 @@
+@ RUN: llvm-mc -triple arm -filetype obj -o - %s | \
+@ RUN: llvm-readobj -A - 2>&1 | \
+@ RUN: FileCheck %s --check-prefix=CHECK-WARNING
+
+.eabi_attribute Tag_also_compatible_with, "\101\006\017"
+@ CHECK-WARNING: Tag_also_compatible_with cannot be recursively defined

diff  --git a/llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-string.s b/llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-string.s
new file mode 100644
index 0000000000000..f5781207e9629
--- /dev/null
+++ b/llvm/test/MC/ARM/directive-eabi_attribute-also_compatible_with-string.s
@@ -0,0 +1,10 @@
+@ RUN: llvm-mc -triple arm -filetype obj -o - %s | \
+@ RUN: llvm-readobj -A - | \
+@ RUN: FileCheck %s
+
+.eabi_attribute Tag_also_compatible_with, "\005Cortex-A7"
+@ CHECK: Attribute
+@ CHECK: Tag: 65
+@ CHECK: TagName: also_compatible_with
+@ CHECK: Value: \005Cortex-A7
+@ CHECK: Description: Tag_CPU_name = Cortex-A7

diff  --git a/llvm/test/MC/ARM/directive-eabi_attribute.s b/llvm/test/MC/ARM/directive-eabi_attribute.s
index fd2719ec9642a..6b3542839b3b6 100644
--- a/llvm/test/MC/ARM/directive-eabi_attribute.s
+++ b/llvm/test/MC/ARM/directive-eabi_attribute.s
@@ -234,13 +234,11 @@
 @ CHECK-OBJ-NEXT:   TagName: nodefaults
 @ CHECK-OBJ-NEXT:   Description: Unspecified Tags UNDEFINED
 	.eabi_attribute Tag_also_compatible_with, "\006\017"
-@ The value for Tag_also_compatible_with should be a pair of a tag (ULEB128) +
-@ a value (ULEB128 + null or NTBS). llvm-readobj doesn't now how to process
-@ this yet, so we use the encoded value explicitly here.
 @ CHECK: .eabi_attribute 65, "\006\017"
 @ CHECK-OBJ:        Tag: 65
 @ CHECK-OBJ-NEXT:   TagName: also_compatible_with
-@ CHECK-OBJ-NEXT:   Value:
+@ CHECK-OBJ-NEXT:   Value: \006\017
+@ CHECK-OBJ-NEXT:   Description: Tag_CPU_arch = 15 (ARM v8-R)
 	.eabi_attribute Tag_T2EE_use, 0
 @ CHECK: .eabi_attribute 66, 0
 @ CHECK-OBJ:        Tag: 66


        


More information about the llvm-commits mailing list