[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:
@@ -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;
|
||||
|
||||
29
llvm/include/llvm/Support/AArch64AttributeParser.h
Normal file
29
llvm/include/llvm/Support/AArch64AttributeParser.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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") {}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
92
llvm/include/llvm/Support/ELFAttrParserCompact.h
Normal file
92
llvm/include/llvm/Support/ELFAttrParserCompact.h
Normal 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
|
||||
56
llvm/include/llvm/Support/ELFAttrParserExtended.h
Normal file
56
llvm/include/llvm/Support/ELFAttrParserExtended.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
21
llvm/lib/Support/AArch64AttributeParser.cpp
Normal file
21
llvm/lib/Support/AArch64AttributeParser.cpp
Normal 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;
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
187
llvm/lib/Support/ELFAttrParserExtended.cpp
Normal file
187
llvm/lib/Support/ELFAttrParserExtended.cpp
Normal 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();
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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, "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 +
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user