forked from OSchip/llvm-project
[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
This commit is contained in:
parent
807b8cb06c
commit
08c6840f25
|
@ -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)
|
||||
|
|
|
@ -344,6 +344,10 @@ public:
|
|||
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 @@ private:
|
|||
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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue