[RISCV] ELF attribute section for RISC-V.
Leverage ARM ELF build attribute section to create ELF attribute section
for RISC-V. Extract the common part of parsing logic for this section
into ELFAttributeParser.[cpp|h] and ELFAttributes.[cpp|h].
Differential Revision: https://reviews.llvm.org/D74023
diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp
index d1bf469..e58d623 100644
--- a/llvm/lib/Object/ELF.cpp
+++ b/llvm/lib/Object/ELF.cpp
@@ -223,6 +223,9 @@
STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);
}
break;
+ case ELF::EM_RISCV:
+ switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_RISCV_ATTRIBUTES); }
+ break;
default:
break;
}
diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp
index 855e032..8627d1b 100644
--- a/llvm/lib/Object/ELFObjectFile.cpp
+++ b/llvm/lib/Object/ELFObjectFile.cpp
@@ -23,6 +23,8 @@
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/RISCVAttributeParser.h"
+#include "llvm/Support/RISCVAttributes.h"
#include "llvm/Support/TargetRegistry.h"
#include <algorithm>
#include <cstddef>
@@ -164,12 +166,14 @@
// both ARMv7-M and R have to support thumb hardware div
bool isV7 = false;
- if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch))
- isV7 = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)
- == ARMBuildAttrs::v7;
+ Optional<unsigned> Attr =
+ Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
+ if (Attr.hasValue())
+ isV7 = Attr.getValue() == ARMBuildAttrs::v7;
- if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch_profile)) {
- switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile)) {
+ Attr = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);
+ if (Attr.hasValue()) {
+ switch (Attr.getValue()) {
case ARMBuildAttrs::ApplicationProfile:
Features.AddFeature("aclass");
break;
@@ -186,8 +190,9 @@
}
}
- if (Attributes.hasAttribute(ARMBuildAttrs::THUMB_ISA_use)) {
- switch(Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use)) {
+ Attr = Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use);
+ if (Attr.hasValue()) {
+ switch (Attr.getValue()) {
default:
break;
case ARMBuildAttrs::Not_Allowed:
@@ -200,8 +205,9 @@
}
}
- if (Attributes.hasAttribute(ARMBuildAttrs::FP_arch)) {
- switch(Attributes.getAttributeValue(ARMBuildAttrs::FP_arch)) {
+ Attr = Attributes.getAttributeValue(ARMBuildAttrs::FP_arch);
+ if (Attr.hasValue()) {
+ switch (Attr.getValue()) {
default:
break;
case ARMBuildAttrs::Not_Allowed:
@@ -223,8 +229,9 @@
}
}
- if (Attributes.hasAttribute(ARMBuildAttrs::Advanced_SIMD_arch)) {
- switch(Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch)) {
+ Attr = Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch);
+ if (Attr.hasValue()) {
+ switch (Attr.getValue()) {
default:
break;
case ARMBuildAttrs::Not_Allowed:
@@ -241,8 +248,9 @@
}
}
- if (Attributes.hasAttribute(ARMBuildAttrs::MVE_arch)) {
- switch(Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch)) {
+ Attr = Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch);
+ if (Attr.hasValue()) {
+ switch (Attr.getValue()) {
default:
break;
case ARMBuildAttrs::Not_Allowed:
@@ -259,8 +267,9 @@
}
}
- if (Attributes.hasAttribute(ARMBuildAttrs::DIV_use)) {
- switch(Attributes.getAttributeValue(ARMBuildAttrs::DIV_use)) {
+ Attr = Attributes.getAttributeValue(ARMBuildAttrs::DIV_use);
+ if (Attr.hasValue()) {
+ switch (Attr.getValue()) {
default:
break;
case ARMBuildAttrs::DisallowDIV:
@@ -285,6 +294,48 @@
Features.AddFeature("c");
}
+ // Add features according to the ELF attribute section.
+ // If there are any unrecognized features, ignore them.
+ RISCVAttributeParser Attributes;
+ if (Error E = getBuildAttributes(Attributes))
+ return Features; // Keep "c" feature if there is one in PlatformFlags.
+
+ Optional<StringRef> Attr = Attributes.getAttributeString(RISCVAttrs::ARCH);
+ if (Attr.hasValue()) {
+ // The Arch pattern is [rv32|rv64][i|e]version(_[m|a|f|d|c]version)*
+ // Version string pattern is (major)p(minor). Major and minor are optional.
+ // For example, a version number could be 2p0, 2, or p92.
+ StringRef Arch = Attr.getValue();
+ if (Arch.consume_front("rv32"))
+ Features.AddFeature("64bit", false);
+ else if (Arch.consume_front("rv64"))
+ Features.AddFeature("64bit");
+
+ while (!Arch.empty()) {
+ switch (Arch[0]) {
+ default:
+ break; // Ignore unexpected features.
+ case 'i':
+ Features.AddFeature("e", false);
+ break;
+ case 'd':
+ Features.AddFeature("f"); // D-ext will imply F-ext.
+ LLVM_FALLTHROUGH;
+ case 'e':
+ case 'm':
+ case 'a':
+ case 'f':
+ case 'c':
+ Features.AddFeature(Arch.take_front());
+ break;
+ }
+
+ // FIXME: Handle version numbers.
+ Arch = Arch.drop_until([](char c) { return c == '_' || c == '\0'; });
+ Arch = Arch.drop_while([](char c) { return c == '_'; });
+ }
+ }
+
return Features;
}
@@ -320,8 +371,10 @@
else
Triple = "arm";
- if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) {
- switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) {
+ Optional<unsigned> Attr =
+ Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
+ if (Attr.hasValue()) {
+ switch (Attr.getValue()) {
case ARMBuildAttrs::v4:
Triple += "v4";
break;