aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/ELFObjectFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Object/ELFObjectFile.cpp')
-rw-r--r--llvm/lib/Object/ELFObjectFile.cpp101
1 files changed, 81 insertions, 20 deletions
diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp
index bf6ffd6c37b9..c919d25855d2 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>
@@ -157,17 +159,21 @@ SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const {
SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
SubtargetFeatures Features;
ARMAttributeParser Attributes;
- if (Error E = getBuildAttributes(Attributes))
+ if (Error E = getBuildAttributes(Attributes)) {
+ consumeError(std::move(E));
return SubtargetFeatures();
+ }
// 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;
-
- if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch_profile)) {
- switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile)) {
+ Optional<unsigned> Attr =
+ Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
+ if (Attr.hasValue())
+ isV7 = Attr.getValue() == ARMBuildAttrs::v7;
+
+ Attr = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);
+ if (Attr.hasValue()) {
+ switch (Attr.getValue()) {
case ARMBuildAttrs::ApplicationProfile:
Features.AddFeature("aclass");
break;
@@ -184,8 +190,9 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
}
- 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:
@@ -198,8 +205,9 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
}
- 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:
@@ -221,8 +229,9 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
}
- 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:
@@ -239,8 +248,9 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
}
- 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:
@@ -257,8 +267,9 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
}
- 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:
@@ -283,6 +294,51 @@ SubtargetFeatures ELFObjectFileBase::getRISCVFeatures() const {
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)) {
+ // TODO Propagate Error.
+ consumeError(std::move(E));
+ 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;
}
@@ -305,8 +361,11 @@ void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
return;
ARMAttributeParser Attributes;
- if (Error E = getBuildAttributes(Attributes))
+ if (Error E = getBuildAttributes(Attributes)) {
+ // TODO Propagate Error.
+ consumeError(std::move(E));
return;
+ }
std::string Triple;
// Default to ARM, but use the triple if it's been set.
@@ -315,8 +374,10 @@ void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
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;