[readobj][Arm][AArch64] Refactor Build Attributes parsing under ELFAtributeParser and add support for AArch64 Build Attributes (#128727)

Refactor readobj to integrate AArch64 Build Attributes under
ELFAttributeParser. ELFAttributeParser now serves as a base class for:
- ELFCompactAttrParser, handling Arm-style attributes with a single
build attribute subsection.
- ELFExtendedAttrParser, handling AArch64-style attributes with multiple
build attribute subsections. This improves code organization and better
aligns with the attribute parsing model.

Add support for parsing AArch64 Build Attributes.
This commit is contained in:
SivanShani-Arm
2025-03-10 09:48:40 +00:00
committed by GitHub
parent 4a59d0c3c8
commit b1ebfac185
31 changed files with 720 additions and 232 deletions

View File

@@ -410,6 +410,9 @@ protected:
case ELF::EM_ARM:
Type = ELF::SHT_ARM_ATTRIBUTES;
break;
case ELF::EM_AARCH64:
Type = ELF::SHT_AARCH64_ATTRIBUTES;
break;
case ELF::EM_RISCV:
Type = ELF::SHT_RISCV_ATTRIBUTES;
break;

View File

@@ -0,0 +1,29 @@
//=== - AArch64AttributeParser.h-AArch64 Attribute Information Printer - ===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===--------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_AARCH64ATTRIBUTEPARSER_H
#define LLVM_SUPPORT_AARCH64ATTRIBUTEPARSER_H
#include "llvm/Support/ELFAttrParserExtended.h"
#include "llvm/Support/ELFAttributes.h"
namespace llvm {
class AArch64AttributeParser : public ELFExtendedAttrParser {
static std::vector<SubsectionAndTagToTagName> &returnTagsNamesMap();
public:
AArch64AttributeParser(ScopedPrinter *Sw)
: ELFExtendedAttrParser(Sw, returnTagsNamesMap()) {}
AArch64AttributeParser()
: ELFExtendedAttrParser(nullptr, returnTagsNamesMap()) {}
};
} // namespace llvm
#endif // LLVM_SUPPORT_AARCH64ATTRIBUTEPARSER_H

View File

@@ -22,7 +22,7 @@
namespace llvm {
namespace AArch64BuildAttrs {
namespace AArch64BuildAttributes {
/// AArch64 build attributes vendors IDs (a.k.a subsection name)
enum VendorID : unsigned {
@@ -69,7 +69,7 @@ enum FeatureAndBitsFlag : unsigned {
Feature_PAC_Flag = 1 << 1,
Feature_GCS_Flag = 1 << 2
};
} // namespace AArch64BuildAttrs
} // namespace AArch64BuildAttributes
} // namespace llvm
#endif // LLVM_SUPPORT_AARCH64BUILDATTRIBUTES_H
#endif // LLVM_SUPPORT_AARCH64BUILDATTRIBUTES_H

View File

@@ -10,15 +10,15 @@
#define LLVM_SUPPORT_ARMATTRIBUTEPARSER_H
#include "ARMBuildAttributes.h"
#include "ELFAttributeParser.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ELFAttrParserCompact.h"
#include "llvm/Support/Error.h"
namespace llvm {
class ScopedPrinter;
class ARMAttributeParser : public ELFAttributeParser {
class ARMAttributeParser : public ELFCompactAttrParser {
struct DisplayHandler {
ARMBuildAttrs::AttrType attribute;
Error (ARMAttributeParser::*routine)(ARMBuildAttrs::AttrType);
@@ -74,9 +74,10 @@ class ARMAttributeParser : public ELFAttributeParser {
public:
ARMAttributeParser(ScopedPrinter *sw)
: ELFAttributeParser(sw, ARMBuildAttrs::getARMAttributeTags(), "aeabi") {}
: ELFCompactAttrParser(sw, ARMBuildAttrs::getARMAttributeTags(),
"aeabi") {}
ARMAttributeParser()
: ELFAttributeParser(ARMBuildAttrs::getARMAttributeTags(), "aeabi") {}
: ELFCompactAttrParser(ARMBuildAttrs::getARMAttributeTags(), "aeabi") {}
};
}

View File

@@ -10,10 +10,10 @@
#define LLVM_SUPPORT_CSKYATTRIBUTEPARSER_H
#include "llvm/Support/CSKYAttributes.h"
#include "llvm/Support/ELFAttributeParser.h"
#include "llvm/Support/ELFAttrParserCompact.h"
namespace llvm {
class CSKYAttributeParser : public ELFAttributeParser {
class CSKYAttributeParser : public ELFCompactAttrParser {
struct DisplayHandler {
CSKYAttrs::AttrType attribute;
Error (CSKYAttributeParser::*routine)(unsigned);
@@ -33,9 +33,9 @@ class CSKYAttributeParser : public ELFAttributeParser {
public:
CSKYAttributeParser(ScopedPrinter *sw)
: ELFAttributeParser(sw, CSKYAttrs::getCSKYAttributeTags(), "csky") {}
: ELFCompactAttrParser(sw, CSKYAttrs::getCSKYAttributeTags(), "csky") {}
CSKYAttributeParser()
: ELFAttributeParser(CSKYAttrs::getCSKYAttributeTags(), "csky") {}
: ELFCompactAttrParser(CSKYAttrs::getCSKYAttributeTags(), "csky") {}
};
} // namespace llvm

View File

@@ -0,0 +1,92 @@
//===- ELF AttributeParser.h - ELF Attribute Parser -------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_ELFCOMPACTATTRPARSER_H
#define LLVM_SUPPORT_ELFCOMPACTATTRPARSER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/ELFAttributeParser.h"
#include "llvm/Support/ELFAttributes.h"
#include "llvm/Support/Error.h"
#include <optional>
#include <unordered_map>
namespace llvm {
class StringRef;
class ScopedPrinter;
class ELFCompactAttrParser : public ELFAttributeParser {
StringRef vendor;
std::unordered_map<unsigned, unsigned> attributes;
std::unordered_map<unsigned, StringRef> attributesStr;
virtual Error handler(uint64_t tag, bool &handled) = 0;
protected:
ScopedPrinter *sw;
TagNameMap tagToStringMap;
DataExtractor de{ArrayRef<uint8_t>{}, true, 0};
DataExtractor::Cursor cursor{0};
void printAttribute(unsigned tag, unsigned value, StringRef valueDesc);
Error parseStringAttribute(const char *name, unsigned tag,
ArrayRef<const char *> strings);
Error parseAttributeList(uint32_t length);
void parseIndexList(SmallVectorImpl<uint8_t> &indexList);
Error parseSubsection(uint32_t length);
void setAttributeString(unsigned tag, StringRef value) {
attributesStr.emplace(tag, value);
}
public:
virtual ~ELFCompactAttrParser() { static_cast<void>(!cursor.takeError()); }
Error integerAttribute(unsigned tag);
Error stringAttribute(unsigned tag);
ELFCompactAttrParser(ScopedPrinter *sw, TagNameMap tagNameMap,
StringRef vendor)
: vendor(vendor), sw(sw), tagToStringMap(tagNameMap) {}
ELFCompactAttrParser(TagNameMap tagNameMap, StringRef vendor)
: vendor(vendor), sw(nullptr), tagToStringMap(tagNameMap) {}
Error parse(ArrayRef<uint8_t> section, llvm::endianness endian) override;
std::optional<unsigned> getAttributeValue(unsigned tag) const override {
auto I = attributes.find(tag);
if (I == attributes.end())
return std::nullopt;
return I->second;
}
std::optional<unsigned>
getAttributeValue(StringRef buildAttributeSubsectionName,
unsigned tag) const override {
assert("" == buildAttributeSubsectionName &&
"buildAttributeSubsectionName must be an empty string");
return getAttributeValue(tag);
}
std::optional<StringRef> getAttributeString(unsigned tag) const override {
auto I = attributesStr.find(tag);
if (I == attributesStr.end())
return std::nullopt;
return I->second;
}
std::optional<StringRef>
getAttributeString(StringRef buildAttributeSubsectionName,
unsigned tag) const override {
assert("" == buildAttributeSubsectionName &&
"buildAttributeSubsectionName must be an empty string");
return getAttributeString(tag);
}
};
} // namespace llvm
#endif // LLVM_SUPPORT_ELFCOMPACTATTRPARSER_H

View File

@@ -0,0 +1,56 @@
//===- ELF AttributeParser.h - ELF Attribute Parser -------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_ELFEXTENDEDATTRPARSER_H
#define LLVM_SUPPORT_ELFEXTENDEDATTRPARSER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/ELFAttributeParser.h"
#include "llvm/Support/ELFAttributes.h"
#include "llvm/Support/Error.h"
#include <optional>
#include <vector>
namespace llvm {
class StringRef;
class ScopedPrinter;
class ELFExtendedAttrParser : public ELFAttributeParser {
protected:
ScopedPrinter *Sw;
DataExtractor De{ArrayRef<uint8_t>{}, true, 0};
DataExtractor::Cursor Cursor{0};
// Data structure for holding Extended ELF Build Attribute subsection
SmallVector<BuildAttributeSubSection, 8> SubSectionVec;
// Maps SubsectionName + Tag to tags names. Required for printing comments.
const std::vector<SubsectionAndTagToTagName> TagsNamesMap;
StringRef getTagName(const StringRef &BuildAttrSubsectionName,
const unsigned Tag);
public:
Error parse(ArrayRef<uint8_t> Section, llvm::endianness Endian) override;
std::optional<unsigned> getAttributeValue(unsigned Tag) const override;
std::optional<unsigned> getAttributeValue(StringRef BuildAttrSubsectionName,
unsigned Tag) const override;
std::optional<StringRef> getAttributeString(unsigned Tag) const override;
std::optional<StringRef> getAttributeString(StringRef BuildAttrSubsectionName,
unsigned Tag) const override;
ELFExtendedAttrParser(
ScopedPrinter *Sw,
const std::vector<SubsectionAndTagToTagName> TagsNamesMap)
: Sw(Sw), TagsNamesMap(TagsNamesMap) {}
ELFExtendedAttrParser(
const std::vector<SubsectionAndTagToTagName> TagsNamesMap)
: Sw(nullptr), TagsNamesMap(TagsNamesMap) {}
};
} // namespace llvm
#endif // LLVM_SUPPORT_ELFEXTENDEDATTRPARSER_H

View File

@@ -9,69 +9,34 @@
#ifndef LLVM_SUPPORT_ELFATTRIBUTEPARSER_H
#define LLVM_SUPPORT_ELFATTRIBUTEPARSER_H
#include "ELFAttributes.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include <optional>
#include <unordered_map>
namespace llvm {
class StringRef;
class ScopedPrinter;
class ELFAttributeParser {
StringRef vendor;
std::unordered_map<unsigned, unsigned> attributes;
std::unordered_map<unsigned, StringRef> attributesStr;
virtual Error handler(uint64_t tag, bool &handled) = 0;
protected:
ScopedPrinter *sw;
TagNameMap tagToStringMap;
DataExtractor de{ArrayRef<uint8_t>{}, true, 0};
DataExtractor::Cursor cursor{0};
void printAttribute(unsigned tag, unsigned value, StringRef valueDesc);
Error parseStringAttribute(const char *name, unsigned tag,
ArrayRef<const char *> strings);
Error parseAttributeList(uint32_t length);
void parseIndexList(SmallVectorImpl<uint8_t> &indexList);
Error parseSubsection(uint32_t length);
void setAttributeString(unsigned tag, StringRef value) {
attributesStr.emplace(tag, value);
}
public:
virtual ~ELFAttributeParser() { static_cast<void>(!cursor.takeError()); }
Error integerAttribute(unsigned tag);
Error stringAttribute(unsigned tag);
virtual ~ELFAttributeParser() {}
ELFAttributeParser(ScopedPrinter *sw, TagNameMap tagNameMap, StringRef vendor)
: vendor(vendor), sw(sw), tagToStringMap(tagNameMap) {}
ELFAttributeParser(TagNameMap tagNameMap, StringRef vendor)
: vendor(vendor), sw(nullptr), tagToStringMap(tagNameMap) {}
Error parse(ArrayRef<uint8_t> section, llvm::endianness endian);
std::optional<unsigned> getAttributeValue(unsigned tag) const {
auto I = attributes.find(tag);
if (I == attributes.end())
return std::nullopt;
return I->second;
virtual Error parse(ArrayRef<uint8_t> Section, llvm::endianness Endian) {
return llvm::Error::success();
}
std::optional<StringRef> getAttributeString(unsigned tag) const {
auto I = attributesStr.find(tag);
if (I == attributesStr.end())
return std::nullopt;
return I->second;
virtual std::optional<unsigned>
getAttributeValue(StringRef BuildAttrSubsectionName, unsigned Tag) const {
return std::nullopt;
}
virtual std::optional<unsigned> getAttributeValue(unsigned Tag) const {
return std::nullopt;
}
virtual std::optional<StringRef>
getAttributeString(StringRef BuildAttrSubsectionName, unsigned Tag) const {
return std::nullopt;
}
virtual std::optional<StringRef> getAttributeString(unsigned Tag) const {
return std::nullopt;
}
};
} // namespace llvm
#endif
#endif // LLVM_SUPPORT_ELFATTRIBUTEPARSER_H

View File

@@ -15,6 +15,7 @@
namespace llvm {
// Tag to string: ELF compact build attribute section
struct TagNameItem {
unsigned attr;
StringRef tagName;
@@ -22,6 +23,34 @@ struct TagNameItem {
using TagNameMap = ArrayRef<TagNameItem>;
// Build Attribute storage for ELF extended attribute section
struct BuildAttributeItem {
enum Types : uint8_t {
NumericAttribute = 0,
TextAttribute,
} Type;
unsigned Tag;
unsigned IntValue;
std::string StringValue;
BuildAttributeItem(Types Ty, unsigned Tg, unsigned IV, std::string SV)
: Type(Ty), Tag(Tg), IntValue(IV), StringValue(std::move(SV)) {}
};
struct BuildAttributeSubSection {
StringRef Name;
unsigned IsOptional;
unsigned ParameterType;
SmallVector<BuildAttributeItem, 64> Content;
};
// Tag to string: ELF extended build attribute section
struct SubsectionAndTagToTagName {
StringRef SubsectionName;
unsigned Tag;
StringRef TagName;
SubsectionAndTagToTagName(StringRef SN, unsigned Tg, StringRef TN)
: SubsectionName(SN), Tag(Tg), TagName(TN) {}
};
namespace ELFAttrs {
enum AttrType : unsigned { File = 1, Section = 2, Symbol = 3 };

View File

@@ -9,11 +9,11 @@
#ifndef LLVM_SUPPORT_HEXAGONATTRIBUTEPARSER_H
#define LLVM_SUPPORT_HEXAGONATTRIBUTEPARSER_H
#include "llvm/Support/ELFAttributeParser.h"
#include "llvm/Support/ELFAttrParserCompact.h"
#include "llvm/Support/HexagonAttributes.h"
namespace llvm {
class HexagonAttributeParser : public ELFAttributeParser {
class HexagonAttributeParser : public ELFCompactAttrParser {
struct DisplayHandler {
HexagonAttrs::AttrType Attribute;
Error (HexagonAttributeParser::*Routine)(unsigned);
@@ -25,11 +25,11 @@ class HexagonAttributeParser : public ELFAttributeParser {
public:
HexagonAttributeParser(ScopedPrinter *SP)
: ELFAttributeParser(SP, HexagonAttrs::getHexagonAttributeTags(),
"hexagon") {}
: ELFCompactAttrParser(SP, HexagonAttrs::getHexagonAttributeTags(),
"hexagon") {}
HexagonAttributeParser()
: ELFAttributeParser(HexagonAttrs::getHexagonAttributeTags(), "hexagon") {
}
: ELFCompactAttrParser(HexagonAttrs::getHexagonAttributeTags(),
"hexagon") {}
};
} // namespace llvm

View File

@@ -14,11 +14,11 @@
#ifndef LLVM_SUPPORT_MSP430ATTRIBUTEPARSER_H
#define LLVM_SUPPORT_MSP430ATTRIBUTEPARSER_H
#include "llvm/Support/ELFAttributeParser.h"
#include "llvm/Support/ELFAttrParserCompact.h"
#include "llvm/Support/MSP430Attributes.h"
namespace llvm {
class MSP430AttributeParser : public ELFAttributeParser {
class MSP430AttributeParser : public ELFCompactAttrParser {
struct DisplayHandler {
MSP430Attrs::AttrType Attribute;
Error (MSP430AttributeParser::*Routine)(MSP430Attrs::AttrType);
@@ -34,10 +34,10 @@ class MSP430AttributeParser : public ELFAttributeParser {
public:
MSP430AttributeParser(ScopedPrinter *SW)
: ELFAttributeParser(SW, MSP430Attrs::getMSP430AttributeTags(),
"mspabi") {}
: ELFCompactAttrParser(SW, MSP430Attrs::getMSP430AttributeTags(),
"mspabi") {}
MSP430AttributeParser()
: ELFAttributeParser(MSP430Attrs::getMSP430AttributeTags(), "mspabi") {}
: ELFCompactAttrParser(MSP430Attrs::getMSP430AttributeTags(), "mspabi") {}
};
} // namespace llvm

View File

@@ -9,11 +9,11 @@
#ifndef LLVM_SUPPORT_RISCVATTRIBUTEPARSER_H
#define LLVM_SUPPORT_RISCVATTRIBUTEPARSER_H
#include "llvm/Support/ELFAttributeParser.h"
#include "llvm/Support/ELFAttrParserCompact.h"
#include "llvm/Support/RISCVAttributes.h"
namespace llvm {
class RISCVAttributeParser : public ELFAttributeParser {
class RISCVAttributeParser : public ELFCompactAttrParser {
struct DisplayHandler {
RISCVAttrs::AttrType attribute;
Error (RISCVAttributeParser::*routine)(unsigned);
@@ -28,9 +28,10 @@ class RISCVAttributeParser : public ELFAttributeParser {
public:
RISCVAttributeParser(ScopedPrinter *sw)
: ELFAttributeParser(sw, RISCVAttrs::getRISCVAttributeTags(), "riscv") {}
: ELFCompactAttrParser(sw, RISCVAttrs::getRISCVAttributeTags(), "riscv") {
}
RISCVAttributeParser()
: ELFAttributeParser(RISCVAttrs::getRISCVAttributeTags(), "riscv") {}
: ELFCompactAttrParser(RISCVAttrs::getRISCVAttributeTags(), "riscv") {}
};
} // namespace llvm

View File

@@ -0,0 +1,21 @@
//===-- AArch64AttributeParser.cpp - AArch64 Build Attributes PArser------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with
// LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===---------------------------------------------------------------------===//
#include "llvm/Support/AArch64AttributeParser.h"
std::vector<llvm::SubsectionAndTagToTagName> &
llvm::AArch64AttributeParser::returnTagsNamesMap() {
static std::vector<SubsectionAndTagToTagName> TagsNamesMap = {
{"aeabi_pauthabi", 1, "Tag_PAuth_Platform"},
{"aeabi_pauthabi", 2, "Tag_PAuth_Schema"},
{"aeabi_feature_and_bits", 0, "Tag_Feature_BTI"},
{"aeabi_feature_and_bits", 1, "Tag_Feature_PAC"},
{"aeabi_feature_and_bits", 2, "Tag_Feature_GCS"}};
return TagsNamesMap;
}

View File

@@ -10,9 +10,9 @@
#include "llvm/ADT/StringSwitch.h"
using namespace llvm;
using namespace llvm::AArch64BuildAttrs;
using namespace llvm::AArch64BuildAttributes;
StringRef AArch64BuildAttrs::getVendorName(unsigned Vendor) {
StringRef AArch64BuildAttributes::getVendorName(unsigned Vendor) {
switch (Vendor) {
case AEABI_FEATURE_AND_BITS:
return "aeabi_feature_and_bits";
@@ -25,14 +25,14 @@ StringRef AArch64BuildAttrs::getVendorName(unsigned Vendor) {
return "";
}
}
VendorID AArch64BuildAttrs::getVendorID(StringRef Vendor) {
VendorID AArch64BuildAttributes::getVendorID(StringRef Vendor) {
return StringSwitch<VendorID>(Vendor)
.Case("aeabi_feature_and_bits", AEABI_FEATURE_AND_BITS)
.Case("aeabi_pauthabi", AEABI_PAUTHABI)
.Default(VENDOR_UNKNOWN);
}
StringRef AArch64BuildAttrs::getOptionalStr(unsigned Optional) {
StringRef AArch64BuildAttributes::getOptionalStr(unsigned Optional) {
switch (Optional) {
case REQUIRED:
return "required";
@@ -43,18 +43,18 @@ StringRef AArch64BuildAttrs::getOptionalStr(unsigned Optional) {
return "";
}
}
SubsectionOptional AArch64BuildAttrs::getOptionalID(StringRef Optional) {
SubsectionOptional AArch64BuildAttributes::getOptionalID(StringRef Optional) {
return StringSwitch<SubsectionOptional>(Optional)
.Case("required", REQUIRED)
.Case("optional", OPTIONAL)
.Default(OPTIONAL_NOT_FOUND);
}
StringRef AArch64BuildAttrs::getSubsectionOptionalUnknownError() {
StringRef AArch64BuildAttributes::getSubsectionOptionalUnknownError() {
return "unknown AArch64 build attributes optionality, expected "
"required|optional";
}
StringRef AArch64BuildAttrs::getTypeStr(unsigned Type) {
StringRef AArch64BuildAttributes::getTypeStr(unsigned Type) {
switch (Type) {
case ULEB128:
return "uleb128";
@@ -65,17 +65,17 @@ StringRef AArch64BuildAttrs::getTypeStr(unsigned Type) {
return "";
}
}
SubsectionType AArch64BuildAttrs::getTypeID(StringRef Type) {
SubsectionType AArch64BuildAttributes::getTypeID(StringRef Type) {
return StringSwitch<SubsectionType>(Type)
.Cases("uleb128", "ULEB128", ULEB128)
.Cases("ntbs", "NTBS", NTBS)
.Default(TYPE_NOT_FOUND);
}
StringRef AArch64BuildAttrs::getSubsectionTypeUnknownError() {
StringRef AArch64BuildAttributes::getSubsectionTypeUnknownError() {
return "unknown AArch64 build attributes type, expected uleb128|ntbs";
}
StringRef AArch64BuildAttrs::getPauthABITagsStr(unsigned PauthABITag) {
StringRef AArch64BuildAttributes::getPauthABITagsStr(unsigned PauthABITag) {
switch (PauthABITag) {
case TAG_PAUTH_PLATFORM:
return "Tag_PAuth_Platform";
@@ -87,7 +87,7 @@ StringRef AArch64BuildAttrs::getPauthABITagsStr(unsigned PauthABITag) {
}
}
PauthABITags AArch64BuildAttrs::getPauthABITagsID(StringRef PauthABITag) {
PauthABITags AArch64BuildAttributes::getPauthABITagsID(StringRef PauthABITag) {
return StringSwitch<PauthABITags>(PauthABITag)
.Case("Tag_PAuth_Platform", TAG_PAUTH_PLATFORM)
.Case("Tag_PAuth_Schema", TAG_PAUTH_SCHEMA)
@@ -95,7 +95,7 @@ PauthABITags AArch64BuildAttrs::getPauthABITagsID(StringRef PauthABITag) {
}
StringRef
AArch64BuildAttrs::getFeatureAndBitsTagsStr(unsigned FeatureAndBitsTag) {
AArch64BuildAttributes::getFeatureAndBitsTagsStr(unsigned FeatureAndBitsTag) {
switch (FeatureAndBitsTag) {
case TAG_FEATURE_BTI:
return "Tag_Feature_BTI";
@@ -110,7 +110,7 @@ AArch64BuildAttrs::getFeatureAndBitsTagsStr(unsigned FeatureAndBitsTag) {
}
FeatureAndBitsTags
AArch64BuildAttrs::getFeatureAndBitsTagsID(StringRef FeatureAndBitsTag) {
AArch64BuildAttributes::getFeatureAndBitsTagsID(StringRef FeatureAndBitsTag) {
return StringSwitch<FeatureAndBitsTags>(FeatureAndBitsTag)
.Case("Tag_Feature_BTI", TAG_FEATURE_BTI)
.Case("Tag_Feature_PAC", TAG_FEATURE_PAC)

View File

@@ -144,6 +144,7 @@ add_llvm_component_library(LLVMSupport
APInt.cpp
APSInt.cpp
ARMBuildAttributes.cpp
AArch64AttributeParser.cpp
AArch64BuildAttributes.cpp
ARMAttributeParser.cpp
ARMWinEH.cpp
@@ -182,8 +183,9 @@ add_llvm_component_library(LLVMSupport
DAGDeltaAlgorithm.cpp
DJB.cpp
DynamicAPInt.cpp
ELFAttributeParser.cpp
ELFAttributes.cpp
ELFAttrParserCompact.cpp
ELFAttrParserExtended.cpp
Error.cpp
ErrorHandling.cpp
ExponentialBackoff.cpp

View File

@@ -16,19 +16,19 @@ const CSKYAttributeParser::DisplayHandler
CSKYAttributeParser::displayRoutines[] = {
{
CSKYAttrs::CSKY_ARCH_NAME,
&ELFAttributeParser::stringAttribute,
&ELFCompactAttrParser::stringAttribute,
},
{
CSKYAttrs::CSKY_CPU_NAME,
&ELFAttributeParser::stringAttribute,
&ELFCompactAttrParser::stringAttribute,
},
{
CSKYAttrs::CSKY_ISA_FLAGS,
&ELFAttributeParser::integerAttribute,
&ELFCompactAttrParser::integerAttribute,
},
{
CSKYAttrs::CSKY_ISA_EXT_FLAGS,
&ELFAttributeParser::integerAttribute,
&ELFCompactAttrParser::integerAttribute,
},
{
CSKYAttrs::CSKY_DSP_VERSION,
@@ -60,7 +60,7 @@ const CSKYAttributeParser::DisplayHandler
},
{
CSKYAttrs::CSKY_FPU_NUMBER_MODULE,
&ELFAttributeParser::stringAttribute,
&ELFCompactAttrParser::stringAttribute,
},
{
CSKYAttrs::CSKY_FPU_HARDFP,

View File

@@ -1,12 +1,15 @@
//===--- ELFAttributeParser.cpp - ELF Attribute Parser --------------------===//
//===--- ELFCompactAttrParser.cpp - ELF Compact Attribute Parser ------ ===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// ELF Compact Attribute Parser parse ELF build atrributes that are held
// in a single Build Attributes Subsection.
//
//===--------------------------------------------------------------------===//
#include "llvm/Support/ELFAttributeParser.h"
#include "llvm/Support/ELFAttrParserCompact.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/ScopedPrinter.h"
@@ -20,8 +23,8 @@ static constexpr EnumEntry<unsigned> tagNames[] = {
{"Tag_Symbol", ELFAttrs::Symbol},
};
Error ELFAttributeParser::parseStringAttribute(const char *name, unsigned tag,
ArrayRef<const char *> strings) {
Error ELFCompactAttrParser::parseStringAttribute(
const char *name, unsigned tag, ArrayRef<const char *> strings) {
uint64_t value = de.getULEB128(cursor);
if (value >= strings.size()) {
printAttribute(tag, value, "");
@@ -33,7 +36,7 @@ Error ELFAttributeParser::parseStringAttribute(const char *name, unsigned tag,
return Error::success();
}
Error ELFAttributeParser::integerAttribute(unsigned tag) {
Error ELFCompactAttrParser::integerAttribute(unsigned tag) {
StringRef tagName =
ELFAttrs::attrTypeAsString(tag, tagToStringMap, /*hasTagPrefix=*/false);
uint64_t value = de.getULEB128(cursor);
@@ -49,7 +52,7 @@ Error ELFAttributeParser::integerAttribute(unsigned tag) {
return Error::success();
}
Error ELFAttributeParser::stringAttribute(unsigned tag) {
Error ELFCompactAttrParser::stringAttribute(unsigned tag) {
StringRef tagName =
ELFAttrs::attrTypeAsString(tag, tagToStringMap, /*hasTagPrefix=*/false);
StringRef desc = de.getCStrRef(cursor);
@@ -65,8 +68,8 @@ Error ELFAttributeParser::stringAttribute(unsigned tag) {
return Error::success();
}
void ELFAttributeParser::printAttribute(unsigned tag, unsigned value,
StringRef valueDesc) {
void ELFCompactAttrParser::printAttribute(unsigned tag, unsigned value,
StringRef valueDesc) {
attributes.insert(std::make_pair(tag, value));
if (sw) {
@@ -82,7 +85,7 @@ void ELFAttributeParser::printAttribute(unsigned tag, unsigned value,
}
}
void ELFAttributeParser::parseIndexList(SmallVectorImpl<uint8_t> &indexList) {
void ELFCompactAttrParser::parseIndexList(SmallVectorImpl<uint8_t> &indexList) {
for (;;) {
uint64_t value = de.getULEB128(cursor);
if (!cursor || !value)
@@ -91,7 +94,7 @@ void ELFAttributeParser::parseIndexList(SmallVectorImpl<uint8_t> &indexList) {
}
}
Error ELFAttributeParser::parseAttributeList(uint32_t length) {
Error ELFCompactAttrParser::parseAttributeList(uint32_t length) {
uint64_t pos;
uint64_t end = cursor.tell() + length;
while ((pos = cursor.tell()) < end) {
@@ -119,7 +122,7 @@ Error ELFAttributeParser::parseAttributeList(uint32_t length) {
return Error::success();
}
Error ELFAttributeParser::parseSubsection(uint32_t length) {
Error ELFCompactAttrParser::parseSubsection(uint32_t length) {
uint64_t end = cursor.tell() - sizeof(length) + length;
StringRef vendorName = de.getCStrRef(cursor);
if (sw) {
@@ -188,8 +191,8 @@ Error ELFAttributeParser::parseSubsection(uint32_t length) {
return Error::success();
}
Error ELFAttributeParser::parse(ArrayRef<uint8_t> section,
llvm::endianness endian) {
Error ELFCompactAttrParser::parse(ArrayRef<uint8_t> section,
llvm::endianness endian) {
unsigned sectionNumber = 0;
de = DataExtractor(section, endian == llvm::endianness::little, 0);

View File

@@ -0,0 +1,187 @@
//===-ELFAttrParserExtended.cpp-ELF Extended Attribute Information Printer-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM
// Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===------------------------------------------------------------------===//
#include "llvm/Support/ELFAttrParserExtended.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/AArch64BuildAttributes.h"
#include "llvm/Support/ELFAttributes.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdint>
using namespace llvm;
using namespace ELFAttrs;
std::optional<unsigned>
ELFExtendedAttrParser::getAttributeValue(unsigned Tag) const {
assert(
0 &&
"use getAttributeValue overloaded version accepting Stringref, unsigned");
return std::nullopt;
}
std::optional<unsigned>
ELFExtendedAttrParser::getAttributeValue(StringRef BuildAttrSubsectionName,
unsigned Tag) const {
for (auto SubSection : SubSectionVec) {
if (BuildAttrSubsectionName == SubSection.Name)
for (auto BAItem : SubSection.Content) {
if (Tag == BAItem.Tag)
return std::optional<unsigned>(BAItem.IntValue);
}
}
return std::nullopt;
}
std::optional<StringRef>
ELFExtendedAttrParser::getAttributeString(unsigned Tag) const {
assert(
0 &&
"use getAttributeValue overloaded version accepting Stringref, unsigned");
return std::nullopt;
}
std::optional<StringRef>
ELFExtendedAttrParser::getAttributeString(StringRef BuildAttrSubsectionName,
unsigned Tag) const {
for (auto SubSection : SubSectionVec) {
if (BuildAttrSubsectionName == SubSection.Name)
for (auto BAItem : SubSection.Content) {
if (Tag == BAItem.Tag)
return std::optional<StringRef>(BAItem.StringValue);
}
}
return std::nullopt;
}
StringRef
ELFExtendedAttrParser::getTagName(const StringRef &BuildAttrSubsectionName,
const unsigned Tag) {
for (const auto &Entry : TagsNamesMap) {
if (BuildAttrSubsectionName == Entry.SubsectionName)
if (Tag == Entry.Tag)
return Entry.TagName;
}
return "";
}
Error ELFExtendedAttrParser::parse(ArrayRef<uint8_t> Section,
llvm::endianness Endian) {
unsigned SectionNumber = 0;
De = DataExtractor(Section, Endian == llvm::endianness::little, 0);
// Early returns have specific errors. Consume the Error in Cursor.
struct ClearCursorError {
DataExtractor::Cursor &Cursor;
~ClearCursorError() { consumeError(Cursor.takeError()); }
} Clear{Cursor};
/*
ELF Extended Build Attributes Layout:
<format-version: A> --> Currently, there is only one version: 'A' (0x41)
[ <uint32: subsection-length> <NTBS: vendor-name> <bytes: vendor-data> ]
--> subsection-length: Offset from the start of this subsection to the
start of the next one.
--> vendor-name: Null-terminated byte string.
--> vendor-data expands to:
[ <uint8: optional> <uint8: parameter type> <attribute>* ]
--> optional: 0 = required, 1 = optional.
--> parameter type: 0 = ULEB128, 1 = NTBS.
--> attribute: <tag, value>* pair. Tag is ULEB128, value is of
<parameter type>.
*/
// Get format-version
uint8_t FormatVersion = De.getU8(Cursor);
if (ELFAttrs::Format_Version != FormatVersion)
return createStringError(errc::invalid_argument,
"unrecognized format-version: 0x" +
utohexstr(FormatVersion));
while (!De.eof(Cursor)) {
uint32_t ExtBASubsectionLength = De.getU32(Cursor);
// Minimal valid Extended Build Attributes subsection header size is at
// least 8: length(4) name(at least a single char + null) optionality(1) and
// type(1)
if (ExtBASubsectionLength < 8)
return createStringError(
errc::invalid_argument,
"invalid Extended Build Attributes subsection size at offset: " +
utohexstr(Cursor.tell() - 4));
StringRef VendorName = De.getCStrRef(Cursor);
uint8_t IsOptional = De.getU8(Cursor);
StringRef IsOptionalStr = IsOptional ? "optional" : "required";
uint8_t Type = De.getU8(Cursor);
StringRef TypeStr = Type ? "ntbs" : "uleb128";
BuildAttributeSubSection BASubSection;
BASubSection.Name = VendorName;
BASubSection.IsOptional = IsOptional;
BASubSection.ParameterType = Type;
if (Sw) {
Sw->startLine() << "Section " << ++SectionNumber << " {\n";
Sw->indent();
Sw->printNumber("SectionLength", ExtBASubsectionLength);
Sw->startLine() << "VendorName" << ": " << VendorName
<< " Optionality: " << IsOptionalStr
<< " Type: " << TypeStr << "\n";
Sw->startLine() << "Attributes {\n";
Sw->indent();
}
// Offset in Section
uint64_t OffsetInSection = Cursor.tell();
// Size: 4 bytes, Vendor Name: VendorName.size() + 1 (null termination),
// optionality: 1, size: 1
uint32_t BytesAllButAttributes = 4 + (VendorName.size() + 1) + 1 + 1;
while (Cursor.tell() <
(OffsetInSection + ExtBASubsectionLength - BytesAllButAttributes)) {
uint64_t Tag = De.getULEB128(Cursor);
StringRef TagName = getTagName(VendorName, Tag);
uint64_t ValueInt = 0;
std::string ValueStr = "";
if (Type) { // type==1 --> ntbs
ValueStr = De.getCStrRef(Cursor);
if (Sw)
Sw->printString("" != TagName ? TagName : utostr(Tag), ValueStr);
} else { // type==0 --> uleb128
ValueInt = De.getULEB128(Cursor);
if (Sw)
Sw->printNumber("" != TagName ? TagName : utostr(Tag), ValueInt);
}
// populate data structure
BuildAttributeItem BAItem(static_cast<BuildAttributeItem::Types>(Type),
Tag, ValueInt, ValueStr);
BASubSection.Content.push_back(BAItem);
}
if (Sw) {
// Close 'Attributes'
Sw->unindent();
Sw->startLine() << "}\n";
// Close 'Section'
Sw->unindent();
Sw->startLine() << "}\n";
}
// populate data structure
SubSectionVec.push_back(BASubSection);
}
return Cursor.takeError();
}

View File

@@ -14,31 +14,31 @@ const HexagonAttributeParser::DisplayHandler
HexagonAttributeParser::DisplayRoutines[] = {
{
HexagonAttrs::ARCH,
&ELFAttributeParser::integerAttribute,
&ELFCompactAttrParser::integerAttribute,
},
{
HexagonAttrs::HVXARCH,
&ELFAttributeParser::integerAttribute,
&ELFCompactAttrParser::integerAttribute,
},
{
HexagonAttrs::HVXIEEEFP,
&ELFAttributeParser::integerAttribute,
&ELFCompactAttrParser::integerAttribute,
},
{
HexagonAttrs::HVXQFLOAT,
&ELFAttributeParser::integerAttribute,
&ELFCompactAttrParser::integerAttribute,
},
{
HexagonAttrs::ZREG,
&ELFAttributeParser::integerAttribute,
&ELFCompactAttrParser::integerAttribute,
},
{
HexagonAttrs::AUDIO,
&ELFAttributeParser::integerAttribute,
&ELFCompactAttrParser::integerAttribute,
},
{
HexagonAttrs::CABAC,
&ELFAttributeParser::integerAttribute,
&ELFCompactAttrParser::integerAttribute,
}};
Error HexagonAttributeParser::handler(uint64_t Tag, bool &Handled) {

View File

@@ -15,19 +15,19 @@ const RISCVAttributeParser::DisplayHandler
RISCVAttributeParser::displayRoutines[] = {
{
RISCVAttrs::ARCH,
&ELFAttributeParser::stringAttribute,
&ELFCompactAttrParser::stringAttribute,
},
{
RISCVAttrs::PRIV_SPEC,
&ELFAttributeParser::integerAttribute,
&ELFCompactAttrParser::integerAttribute,
},
{
RISCVAttrs::PRIV_SPEC_MINOR,
&ELFAttributeParser::integerAttribute,
&ELFCompactAttrParser::integerAttribute,
},
{
RISCVAttrs::PRIV_SPEC_REVISION,
&ELFAttributeParser::integerAttribute,
&ELFCompactAttrParser::integerAttribute,
},
{
RISCVAttrs::STACK_ALIGN,

View File

@@ -361,7 +361,7 @@ void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) {
if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
M.getModuleFlag("branch-target-enforcement"))) {
if (!BTE->isZero()) {
BAFlags |= AArch64BuildAttrs::FeatureAndBitsFlag::Feature_BTI_Flag;
BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_BTI_Flag;
GNUFlags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
}
}
@@ -369,7 +369,7 @@ void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) {
if (const auto *GCS = mdconst::extract_or_null<ConstantInt>(
M.getModuleFlag("guarded-control-stack"))) {
if (!GCS->isZero()) {
BAFlags |= AArch64BuildAttrs::FeatureAndBitsFlag::Feature_GCS_Flag;
BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_GCS_Flag;
GNUFlags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
}
}
@@ -377,7 +377,7 @@ void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) {
if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
M.getModuleFlag("sign-return-address"))) {
if (!Sign->isZero()) {
BAFlags |= AArch64BuildAttrs::FeatureAndBitsFlag::Feature_PAC_Flag;
BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_PAC_Flag;
GNUFlags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
}
}
@@ -480,35 +480,42 @@ void AArch64AsmPrinter::emitAttributes(unsigned Flags,
if (PAuthABIPlatform || PAuthABIVersion) {
TS->emitAtributesSubsection(
AArch64BuildAttrs::getVendorName(AArch64BuildAttrs::AEABI_PAUTHABI),
AArch64BuildAttrs::SubsectionOptional::REQUIRED,
AArch64BuildAttrs::SubsectionType::ULEB128);
TS->emitAttribute(
AArch64BuildAttrs::getVendorName(AArch64BuildAttrs::AEABI_PAUTHABI),
AArch64BuildAttrs::TAG_PAUTH_PLATFORM, PAuthABIPlatform, "");
TS->emitAttribute(
AArch64BuildAttrs::getVendorName(AArch64BuildAttrs::AEABI_PAUTHABI),
AArch64BuildAttrs::TAG_PAUTH_SCHEMA, PAuthABIVersion, "");
AArch64BuildAttributes::getVendorName(
AArch64BuildAttributes::AEABI_PAUTHABI),
AArch64BuildAttributes::SubsectionOptional::REQUIRED,
AArch64BuildAttributes::SubsectionType::ULEB128);
TS->emitAttribute(AArch64BuildAttributes::getVendorName(
AArch64BuildAttributes::AEABI_PAUTHABI),
AArch64BuildAttributes::TAG_PAUTH_PLATFORM,
PAuthABIPlatform, "");
TS->emitAttribute(AArch64BuildAttributes::getVendorName(
AArch64BuildAttributes::AEABI_PAUTHABI),
AArch64BuildAttributes::TAG_PAUTH_SCHEMA, PAuthABIVersion,
"");
}
unsigned BTIValue = (Flags & AArch64BuildAttrs::Feature_BTI_Flag) ? 1 : 0;
unsigned PACValue = (Flags & AArch64BuildAttrs::Feature_PAC_Flag) ? 1 : 0;
unsigned GCSValue = (Flags & AArch64BuildAttrs::Feature_GCS_Flag) ? 1 : 0;
unsigned BTIValue =
(Flags & AArch64BuildAttributes::Feature_BTI_Flag) ? 1 : 0;
unsigned PACValue =
(Flags & AArch64BuildAttributes::Feature_PAC_Flag) ? 1 : 0;
unsigned GCSValue =
(Flags & AArch64BuildAttributes::Feature_GCS_Flag) ? 1 : 0;
if (BTIValue || PACValue || GCSValue) {
TS->emitAtributesSubsection(AArch64BuildAttrs::getVendorName(
AArch64BuildAttrs::AEABI_FEATURE_AND_BITS),
AArch64BuildAttrs::SubsectionOptional::OPTIONAL,
AArch64BuildAttrs::SubsectionType::ULEB128);
TS->emitAttribute(AArch64BuildAttrs::getVendorName(
AArch64BuildAttrs::AEABI_FEATURE_AND_BITS),
AArch64BuildAttrs::TAG_FEATURE_BTI, BTIValue, "");
TS->emitAttribute(AArch64BuildAttrs::getVendorName(
AArch64BuildAttrs::AEABI_FEATURE_AND_BITS),
AArch64BuildAttrs::TAG_FEATURE_PAC, PACValue, "");
TS->emitAttribute(AArch64BuildAttrs::getVendorName(
AArch64BuildAttrs::AEABI_FEATURE_AND_BITS),
AArch64BuildAttrs::TAG_FEATURE_GCS, GCSValue, "");
TS->emitAtributesSubsection(
AArch64BuildAttributes::getVendorName(
AArch64BuildAttributes::AEABI_FEATURE_AND_BITS),
AArch64BuildAttributes::SubsectionOptional::OPTIONAL,
AArch64BuildAttributes::SubsectionType::ULEB128);
TS->emitAttribute(AArch64BuildAttributes::getVendorName(
AArch64BuildAttributes::AEABI_FEATURE_AND_BITS),
AArch64BuildAttributes::TAG_FEATURE_BTI, BTIValue, "");
TS->emitAttribute(AArch64BuildAttributes::getVendorName(
AArch64BuildAttributes::AEABI_FEATURE_AND_BITS),
AArch64BuildAttributes::TAG_FEATURE_PAC, PACValue, "");
TS->emitAttribute(AArch64BuildAttributes::getVendorName(
AArch64BuildAttributes::AEABI_FEATURE_AND_BITS),
AArch64BuildAttributes::TAG_FEATURE_GCS, GCSValue, "");
}
}

View File

@@ -7847,10 +7847,10 @@ bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
// Consume the name (subsection name)
StringRef SubsectionName;
AArch64BuildAttrs::VendorID SubsectionNameID;
AArch64BuildAttributes::VendorID SubsectionNameID;
if (Parser.getTok().is(AsmToken::Identifier)) {
SubsectionName = Parser.getTok().getIdentifier();
SubsectionNameID = AArch64BuildAttrs::getVendorID(SubsectionName);
SubsectionNameID = AArch64BuildAttributes::getVendorID(SubsectionName);
} else {
Error(Parser.getTok().getLoc(), "subsection name not found");
return true;
@@ -7867,14 +7867,14 @@ bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
getTargetStreamer().getAtributesSubsectionByName(SubsectionName);
// Consume the first parameter (optionality parameter)
AArch64BuildAttrs::SubsectionOptional IsOptional;
AArch64BuildAttributes::SubsectionOptional IsOptional;
// options: optional/required
if (Parser.getTok().is(AsmToken::Identifier)) {
StringRef Optionality = Parser.getTok().getIdentifier();
IsOptional = AArch64BuildAttrs::getOptionalID(Optionality);
if (AArch64BuildAttrs::OPTIONAL_NOT_FOUND == IsOptional) {
IsOptional = AArch64BuildAttributes::getOptionalID(Optionality);
if (AArch64BuildAttributes::OPTIONAL_NOT_FOUND == IsOptional) {
Error(Parser.getTok().getLoc(),
AArch64BuildAttrs::getSubsectionOptionalUnknownError());
AArch64BuildAttributes::getSubsectionOptionalUnknownError());
return true;
}
if (SubsectionExists) {
@@ -7882,10 +7882,10 @@ bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
Error(Parser.getTok().getLoc(),
"optionality mismatch! subsection '" + SubsectionName +
"' already exists with optionality defined as '" +
AArch64BuildAttrs::getOptionalStr(
AArch64BuildAttributes::getOptionalStr(
SubsectionExists->IsOptional) +
"' and not '" +
AArch64BuildAttrs::getOptionalStr(IsOptional) + "'");
AArch64BuildAttributes::getOptionalStr(IsOptional) + "'");
return true;
}
}
@@ -7895,15 +7895,15 @@ bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
return true;
}
// Check for possible IsOptional unaccepted values for known subsections
if (AArch64BuildAttrs::AEABI_FEATURE_AND_BITS == SubsectionNameID) {
if (AArch64BuildAttrs::REQUIRED == IsOptional) {
if (AArch64BuildAttributes::AEABI_FEATURE_AND_BITS == SubsectionNameID) {
if (AArch64BuildAttributes::REQUIRED == IsOptional) {
Error(Parser.getTok().getLoc(),
"aeabi_feature_and_bits must be marked as optional");
return true;
}
}
if (AArch64BuildAttrs::AEABI_PAUTHABI == SubsectionNameID) {
if (AArch64BuildAttrs::OPTIONAL == IsOptional) {
if (AArch64BuildAttributes::AEABI_PAUTHABI == SubsectionNameID) {
if (AArch64BuildAttributes::OPTIONAL == IsOptional) {
Error(Parser.getTok().getLoc(),
"aeabi_pauthabi must be marked as required");
return true;
@@ -7916,23 +7916,24 @@ bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
}
// Consume the second parameter (type parameter)
AArch64BuildAttrs::SubsectionType Type;
AArch64BuildAttributes::SubsectionType Type;
if (Parser.getTok().is(AsmToken::Identifier)) {
StringRef Name = Parser.getTok().getIdentifier();
Type = AArch64BuildAttrs::getTypeID(Name);
if (AArch64BuildAttrs::TYPE_NOT_FOUND == Type) {
Type = AArch64BuildAttributes::getTypeID(Name);
if (AArch64BuildAttributes::TYPE_NOT_FOUND == Type) {
Error(Parser.getTok().getLoc(),
AArch64BuildAttrs::getSubsectionTypeUnknownError());
AArch64BuildAttributes::getSubsectionTypeUnknownError());
return true;
}
if (SubsectionExists) {
if (Type != SubsectionExists->ParameterType) {
Error(
Parser.getTok().getLoc(),
"type mismatch! subsection '" + SubsectionName +
"' already exists with type defined as '" +
AArch64BuildAttrs::getTypeStr(SubsectionExists->ParameterType) +
"' and not '" + AArch64BuildAttrs::getTypeStr(Type) + "'");
Error(Parser.getTok().getLoc(),
"type mismatch! subsection '" + SubsectionName +
"' already exists with type defined as '" +
AArch64BuildAttributes::getTypeStr(
SubsectionExists->ParameterType) +
"' and not '" + AArch64BuildAttributes::getTypeStr(Type) +
"'");
return true;
}
}
@@ -7942,9 +7943,9 @@ bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
return true;
}
// Check for possible unaccepted 'type' values for known subsections
if (AArch64BuildAttrs::AEABI_FEATURE_AND_BITS == SubsectionNameID ||
AArch64BuildAttrs::AEABI_PAUTHABI == SubsectionNameID) {
if (AArch64BuildAttrs::NTBS == Type) {
if (AArch64BuildAttributes::AEABI_FEATURE_AND_BITS == SubsectionNameID ||
AArch64BuildAttributes::AEABI_PAUTHABI == SubsectionNameID) {
if (AArch64BuildAttributes::NTBS == Type) {
Error(Parser.getTok().getLoc(),
SubsectionName + " must be marked as ULEB128");
return true;
@@ -7980,13 +7981,14 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
unsigned ActiveSubsectionID = AArch64BuildAttrs::VENDOR_UNKNOWN;
if (AArch64BuildAttrs::getVendorName(AArch64BuildAttrs::AEABI_PAUTHABI) ==
unsigned ActiveSubsectionID = AArch64BuildAttributes::VENDOR_UNKNOWN;
if (AArch64BuildAttributes::getVendorName(
AArch64BuildAttributes::AEABI_PAUTHABI) == ActiveSubsectionName)
ActiveSubsectionID = AArch64BuildAttributes::AEABI_PAUTHABI;
if (AArch64BuildAttributes::getVendorName(
AArch64BuildAttributes::AEABI_FEATURE_AND_BITS) ==
ActiveSubsectionName)
ActiveSubsectionID = AArch64BuildAttrs::AEABI_PAUTHABI;
if (AArch64BuildAttrs::getVendorName(
AArch64BuildAttrs::AEABI_FEATURE_AND_BITS) == ActiveSubsectionName)
ActiveSubsectionID = AArch64BuildAttrs::AEABI_FEATURE_AND_BITS;
ActiveSubsectionID = AArch64BuildAttributes::AEABI_FEATURE_AND_BITS;
StringRef TagStr = "";
unsigned Tag;
@@ -7995,7 +7997,7 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
} else if (Parser.getTok().is(AsmToken::Identifier)) {
TagStr = Parser.getTok().getIdentifier();
switch (ActiveSubsectionID) {
case AArch64BuildAttrs::VENDOR_UNKNOWN:
case AArch64BuildAttributes::VENDOR_UNKNOWN:
// Tag was provided as an unrecognized string instead of an unsigned
// integer
Error(Parser.getTok().getLoc(), "unrecognized Tag: '" + TagStr +
@@ -8003,18 +8005,18 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
"tags have to be an unsigned int.");
return true;
break;
case AArch64BuildAttrs::AEABI_PAUTHABI:
Tag = AArch64BuildAttrs::getPauthABITagsID(TagStr);
if (AArch64BuildAttrs::PAUTHABI_TAG_NOT_FOUND == Tag) {
case AArch64BuildAttributes::AEABI_PAUTHABI:
Tag = AArch64BuildAttributes::getPauthABITagsID(TagStr);
if (AArch64BuildAttributes::PAUTHABI_TAG_NOT_FOUND == Tag) {
Error(Parser.getTok().getLoc(), "unknown AArch64 build attribute '" +
TagStr + "' for subsection '" +
ActiveSubsectionName + "'");
return true;
}
break;
case AArch64BuildAttrs::AEABI_FEATURE_AND_BITS:
Tag = AArch64BuildAttrs::getFeatureAndBitsTagsID(TagStr);
if (AArch64BuildAttrs::FEATURE_AND_BITS_TAG_NOT_FOUND == Tag) {
case AArch64BuildAttributes::AEABI_FEATURE_AND_BITS:
Tag = AArch64BuildAttributes::getFeatureAndBitsTagsID(TagStr);
if (AArch64BuildAttributes::FEATURE_AND_BITS_TAG_NOT_FOUND == Tag) {
Error(Parser.getTok().getLoc(), "unknown AArch64 build attribute '" +
TagStr + "' for subsection '" +
ActiveSubsectionName + "'");
@@ -8038,7 +8040,7 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
unsigned ValueInt = unsigned(-1);
std::string ValueStr = "";
if (Parser.getTok().is(AsmToken::Integer)) {
if (AArch64BuildAttrs::NTBS == ActiveSubsectionType) {
if (AArch64BuildAttributes::NTBS == ActiveSubsectionType) {
Error(
Parser.getTok().getLoc(),
"active subsection type is NTBS (string), found ULEB128 (unsigned)");
@@ -8046,7 +8048,7 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
}
ValueInt = getTok().getIntVal();
} else if (Parser.getTok().is(AsmToken::Identifier)) {
if (AArch64BuildAttrs::ULEB128 == ActiveSubsectionType) {
if (AArch64BuildAttributes::ULEB128 == ActiveSubsectionType) {
Error(
Parser.getTok().getLoc(),
"active subsection type is ULEB128 (unsigned), found NTBS (string)");
@@ -8054,7 +8056,7 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
}
ValueStr = Parser.getTok().getIdentifier();
} else if (Parser.getTok().is(AsmToken::String)) {
if (AArch64BuildAttrs::ULEB128 == ActiveSubsectionType) {
if (AArch64BuildAttributes::ULEB128 == ActiveSubsectionType) {
Error(
Parser.getTok().getLoc(),
"active subsection type is ULEB128 (unsigned), found NTBS (string)");
@@ -8067,7 +8069,7 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
}
// Check for possible unaccepted values for known tags
// (AEABI_FEATURE_AND_BITS)
if (ActiveSubsectionID == AArch64BuildAttrs::AEABI_FEATURE_AND_BITS) {
if (ActiveSubsectionID == AArch64BuildAttributes::AEABI_FEATURE_AND_BITS) {
if (0 != ValueInt && 1 != ValueInt) {
Error(Parser.getTok().getLoc(),
"unknown AArch64 build attributes Value for Tag '" + TagStr +

View File

@@ -161,10 +161,10 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer {
return;
}
unsigned VendorID = AArch64BuildAttrs::getVendorID(VendorName);
unsigned VendorID = AArch64BuildAttributes::getVendorID(VendorName);
switch (VendorID) {
case AArch64BuildAttrs::VENDOR_UNKNOWN:
case AArch64BuildAttributes::VENDOR_UNKNOWN:
if (unsigned(-1) != Value) {
OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value;
AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "");
@@ -176,7 +176,7 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer {
}
break;
// Note: AEABI_FEATURE_AND_BITS takes only unsigned values
case AArch64BuildAttrs::AEABI_FEATURE_AND_BITS:
case AArch64BuildAttributes::AEABI_FEATURE_AND_BITS:
switch (Tag) {
default: // allow emitting any attribute by number
OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value;
@@ -184,17 +184,17 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer {
// (important for llvm-mc asm parsing)
AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "");
break;
case AArch64BuildAttrs::TAG_FEATURE_BTI:
case AArch64BuildAttrs::TAG_FEATURE_GCS:
case AArch64BuildAttrs::TAG_FEATURE_PAC:
case AArch64BuildAttributes::TAG_FEATURE_BTI:
case AArch64BuildAttributes::TAG_FEATURE_GCS:
case AArch64BuildAttributes::TAG_FEATURE_PAC:
OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value << "\t// "
<< AArch64BuildAttrs::getFeatureAndBitsTagsStr(Tag);
<< AArch64BuildAttributes::getFeatureAndBitsTagsStr(Tag);
AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "");
break;
}
break;
// Note: AEABI_PAUTHABI takes only unsigned values
case AArch64BuildAttrs::AEABI_PAUTHABI:
case AArch64BuildAttributes::AEABI_PAUTHABI:
switch (Tag) {
default: // allow emitting any attribute by number
OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value;
@@ -202,10 +202,10 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer {
// (important for llvm-mc asm parsing)
AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "");
break;
case AArch64BuildAttrs::TAG_PAUTH_PLATFORM:
case AArch64BuildAttrs::TAG_PAUTH_SCHEMA:
case AArch64BuildAttributes::TAG_PAUTH_PLATFORM:
case AArch64BuildAttributes::TAG_PAUTH_SCHEMA:
OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value << "\t// "
<< AArch64BuildAttrs::getPauthABITagsStr(Tag);
<< AArch64BuildAttributes::getPauthABITagsStr(Tag);
AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "");
break;
}
@@ -215,42 +215,43 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer {
}
void emitAtributesSubsection(
StringRef SubsectionName, AArch64BuildAttrs::SubsectionOptional Optional,
AArch64BuildAttrs::SubsectionType ParameterType) override {
StringRef SubsectionName,
AArch64BuildAttributes::SubsectionOptional Optional,
AArch64BuildAttributes::SubsectionType ParameterType) override {
// The AArch64 build attributes assembly subsection header format:
// ".aeabi_subsection name, optional, parameter type"
// optional: required (0) optional (1)
// parameter type: uleb128 or ULEB128 (0) ntbs or NTBS (1)
unsigned SubsectionID = AArch64BuildAttrs::getVendorID(SubsectionName);
unsigned SubsectionID = AArch64BuildAttributes::getVendorID(SubsectionName);
assert((0 == Optional || 1 == Optional) &&
AArch64BuildAttrs::getSubsectionOptionalUnknownError().data());
AArch64BuildAttributes::getSubsectionOptionalUnknownError().data());
assert((0 == ParameterType || 1 == ParameterType) &&
AArch64BuildAttrs::getSubsectionTypeUnknownError().data());
AArch64BuildAttributes::getSubsectionTypeUnknownError().data());
std::string SubsectionTag = ".aeabi_subsection";
StringRef OptionalStr = getOptionalStr(Optional);
StringRef ParameterStr = getTypeStr(ParameterType);
switch (SubsectionID) {
case AArch64BuildAttrs::VENDOR_UNKNOWN: {
case AArch64BuildAttributes::VENDOR_UNKNOWN: {
// Private subsection
break;
}
case AArch64BuildAttrs::AEABI_PAUTHABI: {
assert(AArch64BuildAttrs::REQUIRED == Optional &&
case AArch64BuildAttributes::AEABI_PAUTHABI: {
assert(AArch64BuildAttributes::REQUIRED == Optional &&
"subsection .aeabi-pauthabi should be marked as "
"required and not as optional");
assert(AArch64BuildAttrs::ULEB128 == ParameterType &&
assert(AArch64BuildAttributes::ULEB128 == ParameterType &&
"subsection .aeabi-pauthabi should be "
"marked as uleb128 and not as ntbs");
break;
}
case AArch64BuildAttrs::AEABI_FEATURE_AND_BITS: {
assert(AArch64BuildAttrs::OPTIONAL == Optional &&
case AArch64BuildAttributes::AEABI_FEATURE_AND_BITS: {
assert(AArch64BuildAttributes::OPTIONAL == Optional &&
"subsection .aeabi_feature_and_bits should be "
"marked as optional and not as required");
assert(AArch64BuildAttrs::ULEB128 == ParameterType &&
assert(AArch64BuildAttributes::ULEB128 == ParameterType &&
"subsection .aeabi_feature_and_bits should "
"be marked as uleb128 and not as ntbs");
break;
@@ -416,8 +417,8 @@ AArch64ELFStreamer &AArch64TargetELFStreamer::getStreamer() {
}
void AArch64TargetELFStreamer::emitAtributesSubsection(
StringRef VendorName, AArch64BuildAttrs::SubsectionOptional IsOptional,
AArch64BuildAttrs::SubsectionType ParameterType) {
StringRef VendorName, AArch64BuildAttributes::SubsectionOptional IsOptional,
AArch64BuildAttributes::SubsectionType ParameterType) {
AArch64TargetStreamer::emitAtributesSubsection(VendorName, IsOptional,
ParameterType);
}

View File

@@ -154,8 +154,8 @@ MCTargetStreamer *llvm::createAArch64NullTargetStreamer(MCStreamer &S) {
}
void AArch64TargetStreamer::emitAtributesSubsection(
StringRef VendorName, AArch64BuildAttrs::SubsectionOptional IsOptional,
AArch64BuildAttrs::SubsectionType ParameterType) {
StringRef VendorName, AArch64BuildAttributes::SubsectionOptional IsOptional,
AArch64BuildAttributes::SubsectionType ParameterType) {
// If exists, return.
for (MCELFStreamer::AttributeSubSection &SubSection : AttributeSubSections) {

View File

@@ -97,8 +97,8 @@ public:
/// Build attributes implementation
virtual void
emitAtributesSubsection(StringRef VendorName,
AArch64BuildAttrs::SubsectionOptional IsOptional,
AArch64BuildAttrs::SubsectionType ParameterType);
AArch64BuildAttributes::SubsectionOptional IsOptional,
AArch64BuildAttributes::SubsectionType ParameterType);
virtual void emitAttribute(StringRef VendorName, unsigned Tag, unsigned Value,
std::string String);
void activateAtributesSubsection(StringRef VendorName);
@@ -124,8 +124,9 @@ private:
/// Build attributes implementation
void emitAtributesSubsection(
StringRef VendorName, AArch64BuildAttrs::SubsectionOptional IsOptional,
AArch64BuildAttrs::SubsectionType ParameterType) override;
StringRef VendorName,
AArch64BuildAttributes::SubsectionOptional IsOptional,
AArch64BuildAttributes::SubsectionType ParameterType) override;
void emitAttribute(StringRef VendorName, unsigned Tag, unsigned Value,
std::string String) override;
void emitInst(uint32_t Inst) override;

View File

@@ -0,0 +1,81 @@
# RUN: llvm-mc -triple=aarch64-linux -filetype=obj < %s | llvm-readelf --arch-specific - | FileCheck %s --check-prefix=ATTR
# ATTR: BuildAttributes {
# ATTR-NEXT: FormatVersion: 0x41
# ATTR-NEXT: Section 1 {
# ATTR-NEXT: SectionLength: 29
# ATTR-NEXT: VendorName: private_subsection_1 Optionality: optional Type: uleb128
# ATTR-NEXT: Attributes {
# ATTR-NEXT: 1: 1
# ATTR-NEXT: }
# ATTR-NEXT: }
# ATTR-NEXT: Section 2 {
# ATTR-NEXT: SectionLength: 37
# ATTR-NEXT: VendorName: aeabi_feature_and_bits Optionality: optional Type: uleb128
# ATTR-NEXT: Attributes {
# ATTR-NEXT: Tag_Feature_BTI: 1
# ATTR-NEXT: Tag_Feature_PAC: 1
# ATTR-NEXT: Tag_Feature_GCS: 1
# ATTR-NEXT: 3: 1
# ATTR-NEXT: }
# ATTR-NEXT: }
# ATTR-NEXT: Section 3 {
# ATTR-NEXT: SectionLength: 32
# ATTR-NEXT: VendorName: private_subsection_3 Optionality: optional Type: ntbs
# ATTR-NEXT: Attributes {
# ATTR-NEXT: 1: "1"
# ATTR-NEXT: }
# ATTR-NEXT: }
# ATTR-NEXT: Section 4 {
# ATTR-NEXT: SectionLength: 35
# ATTR-NEXT: VendorName: aeabi_pauthabi Optionality: required Type: uleb128
# ATTR-NEXT: Attributes {
# ATTR-NEXT: Tag_PAuth_Schema: 1
# ATTR-NEXT: Tag_PAuth_Platform: 1
# ATTR-NEXT: 5: 1
# ATTR-NEXT: 6: 1
# ATTR-NEXT: 7: 1
# ATTR-NEXT: 8: 1
# ATTR-NEXT: 9: 1
# ATTR-NEXT: }
# ATTR-NEXT: }
# ATTR-NEXT: Section 5 {
# ATTR-NEXT: SectionLength: 32
# ATTR-NEXT: VendorName: private_subsection_4 Optionality: required Type: ntbs
# ATTR-NEXT: Attributes {
# ATTR-NEXT: 1: "1"
# ATTR-NEXT: }
# ATTR-NEXT: }
# ATTR-NEXT: Section 6 {
# ATTR-NEXT: SectionLength: 31
# ATTR-NEXT: VendorName: private_subsection_2 Optionality: required Type: uleb128
# ATTR-NEXT: Attributes {
# ATTR-NEXT: 1: 1
# ATTR-NEXT: 2: 1
# ATTR-NEXT: }
# ATTR-NEXT: }
# ATTR-NEXT: }
.aeabi_subsection private_subsection_1, optional, uleb128
.aeabi_attribute 1, 1
.aeabi_subsection aeabi_feature_and_bits, optional, uleb128
.aeabi_attribute Tag_Feature_BTI, 1
.aeabi_attribute 1, 1
.aeabi_attribute 2, 1
.aeabi_attribute 3, 1
.aeabi_subsection private_subsection_3, optional, ntbs
.aeabi_attribute 1, "1"
.aeabi_subsection aeabi_pauthabi, required, uleb128
.aeabi_attribute Tag_PAuth_Schema, 1
.aeabi_attribute Tag_PAuth_Platform, 1
.aeabi_attribute 5, 1
.aeabi_attribute 6, 1
.aeabi_attribute 7, 1
.aeabi_attribute 8, 1
.aeabi_attribute 9, 1
.aeabi_subsection private_subsection_4, required, ntbs
.aeabi_attribute 1, "1"
.aeabi_subsection private_subsection_2, required, uleb128
.aeabi_attribute 1, 1
.aeabi_attribute 2, 1

View File

@@ -39,6 +39,7 @@
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/RelocationResolver.h"
#include "llvm/Object/StackMapParser.h"
#include "llvm/Support/AArch64AttributeParser.h"
#include "llvm/Support/AMDGPUMetadata.h"
#include "llvm/Support/ARMAttributeParser.h"
#include "llvm/Support/ARMBuildAttributes.h"
@@ -2878,6 +2879,12 @@ template <class ELFT> void ELFDumper<ELFT>::printArchSpecificInfo() {
ELF::SHT_ARM_ATTRIBUTES, std::make_unique<ARMAttributeParser>(&W),
Obj.isLE() ? llvm::endianness::little : llvm::endianness::big);
break;
case EM_AARCH64:
printAttributes(ELF::SHT_AARCH64_ATTRIBUTES,
std::make_unique<AArch64AttributeParser>(&W),
Obj.isLE() ? llvm::endianness::little
: llvm::endianness::big);
break;
case EM_RISCV:
if (Obj.isLE())
printAttributes(ELF::SHT_RISCV_ATTRIBUTES,

View File

@@ -37,7 +37,7 @@ bool testBuildAttr(unsigned Tag, unsigned Value,
ARMAttributeParser Parser;
cantFail(Parser.parse(Bytes, llvm::endianness::little));
std::optional<unsigned> Attr = Parser.getAttributeValue(ExpectedTag);
std::optional<unsigned> Attr = Parser.getAttributeValue("", ExpectedTag);
return Attr && *Attr == ExpectedValue;
}

View File

@@ -83,7 +83,7 @@ static bool testAttributeInt(unsigned Tag, unsigned Value, unsigned ExpectedTag,
CSKYAttributeParser Parser;
cantFail(Parser.parse(Bytes, llvm::endianness::little));
std::optional<unsigned> Attr = Parser.getAttributeValue(ExpectedTag);
std::optional<unsigned> Attr = Parser.getAttributeValue("", ExpectedTag);
return Attr && *Attr == ExpectedValue;
}
@@ -100,7 +100,7 @@ static bool testAttributeString(unsigned Tag, const char *Value,
CSKYAttributeParser Parser;
cantFail(Parser.parse(Bytes, llvm::endianness::little));
std::optional<StringRef> Attr = Parser.getAttributeString(ExpectedTag);
std::optional<StringRef> Attr = Parser.getAttributeString("", ExpectedTag);
return Attr && *Attr == ExpectedValue;
}

View File

@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/ELFAttributeParser.h"
#include "llvm/Support/ELFAttrParserCompact.h"
#include "llvm/Support/ELFAttributes.h"
#include "gtest/gtest.h"
#include <string>
@@ -16,7 +16,7 @@ using namespace llvm;
static const TagNameMap emptyTagNameMap;
// This class is used to test the common part of the ELF attribute section.
class AttributeHeaderParser : public ELFAttributeParser {
class AttributeHeaderParser : public ELFCompactAttrParser {
Error handler(uint64_t tag, bool &handled) override {
// Treat all attributes as handled.
handled = true;
@@ -25,8 +25,8 @@ class AttributeHeaderParser : public ELFAttributeParser {
public:
AttributeHeaderParser(ScopedPrinter *printer)
: ELFAttributeParser(printer, emptyTagNameMap, "test") {}
AttributeHeaderParser() : ELFAttributeParser(emptyTagNameMap, "test") {}
: ELFCompactAttrParser(printer, emptyTagNameMap, "test") {}
AttributeHeaderParser() : ELFCompactAttrParser(emptyTagNameMap, "test") {}
};
static void testParseError(ArrayRef<uint8_t> bytes, const char *msg) {

View File

@@ -44,7 +44,7 @@ static bool testAttribute(unsigned Tag, unsigned Value, unsigned ExpectedTag,
RISCVAttributeParser Parser;
cantFail(Parser.parse(Bytes, llvm::endianness::little));
std::optional<unsigned> Attr = Parser.getAttributeValue(ExpectedTag);
std::optional<unsigned> Attr = Parser.getAttributeValue("", ExpectedTag);
return Attr && *Attr == ExpectedValue;
}