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.cpp55
1 files changed, 19 insertions, 36 deletions
diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp
index 6b29703..c293fdd 100644
--- a/llvm/lib/Object/ELFObjectFile.cpp
+++ b/llvm/lib/Object/ELFObjectFile.cpp
@@ -25,6 +25,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/RISCVAttributeParser.h"
#include "llvm/Support/RISCVAttributes.h"
+#include "llvm/Support/RISCVISAInfo.h"
#include <algorithm>
#include <cstddef>
#include <cstdint>
@@ -286,7 +287,7 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
return Features;
}
-SubtargetFeatures ELFObjectFileBase::getRISCVFeatures() const {
+Expected<SubtargetFeatures> ELFObjectFileBase::getRISCVFeatures() const {
SubtargetFeatures Features;
unsigned PlatformFlags = getPlatformFlags();
@@ -294,50 +295,32 @@ 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.
+ return E;
}
std::optional<StringRef> Attr =
Attributes.getAttributeString(RISCVAttrs::ARCH);
if (Attr) {
- // 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;
- if (Arch.consume_front("rv32"))
+ // Suppress version checking for experimental extensions to prevent erroring
+ // when getting any unknown version of experimental extension.
+ auto ParseResult = RISCVISAInfo::parseArchString(
+ *Attr, /*EnableExperimentalExtension=*/true,
+ /*ExperimentalExtensionVersionCheck=*/false,
+ /*IgnoreUnknown=*/true);
+ if (!ParseResult)
+ return ParseResult.takeError();
+ auto &ISAInfo = *ParseResult;
+
+ if (ISAInfo->getXLen() == 32)
Features.AddFeature("64bit", false);
- else if (Arch.consume_front("rv64"))
+ else if (ISAInfo->getXLen() == 64)
Features.AddFeature("64bit");
+ else
+ llvm_unreachable("XLEN should be 32 or 64.");
- 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.
- [[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 == '_'; });
- }
+ Features.addFeaturesVector(ISAInfo->toFeatureVector());
}
return Features;
@@ -361,7 +344,7 @@ SubtargetFeatures ELFObjectFileBase::getLoongArchFeatures() const {
return Features;
}
-SubtargetFeatures ELFObjectFileBase::getFeatures() const {
+Expected<SubtargetFeatures> ELFObjectFileBase::getFeatures() const {
switch (getEMachine()) {
case ELF::EM_MIPS:
return getMIPSFeatures();