[clang] [llvm] [LLVM][Clang][AArch64] Implement AArch64 build attributes (PR #118771)
Oliver Stannard via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 13 03:26:55 PST 2025
================
@@ -7806,6 +7815,261 @@ bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L, bool Paired,
return false;
}
+bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
+ // Expecting 3 AsmToken::Identifier after '.aeabi_subsection', a name and 2
+ // parameters, e.g.: .aeabi_subsection (1)aeabi_feature_and_bits, (2)optional,
+ // (3)uleb128 separated by 2 commas.
+ MCAsmParser &Parser = getParser();
+
+ bool HasActiveSubsection = true;
+ std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
+ getTargetStreamer().getActiveAtributesSubsection();
+ if (nullptr == ActiveSubsection) {
+ HasActiveSubsection = false;
+ }
+
+ // Consume the name (subsection name)
+ StringRef SubsectionName;
+ AArch64BuildAttributes::VendorID SubsectionNameID;
+ if (Parser.getTok().is(AsmToken::Identifier)) {
+ SubsectionName = Parser.getTok().getIdentifier();
+ SubsectionNameID = AArch64BuildAttributes::getVendorID(SubsectionName);
+ } else {
+ Error(Parser.getTok().getLoc(), "Expecting subsection name");
+ return true;
+ }
+ Parser.Lex();
+ // consume a comma
+ // parseComma() return *false* on success, and call Lex(), no need to call
+ // Lex() again.
+ if (Parser.parseComma()) {
+ return true;
+ }
+
+ // Consume the first parameter (optionality parameter)
+ AArch64BuildAttributes::SubsectionOptional IsOptional;
+ // options: optional/required
+ if (Parser.getTok().is(AsmToken::Identifier)) {
+ StringRef Optinality = Parser.getTok().getIdentifier();
+ IsOptional = AArch64BuildAttributes::getOptionalID(Optinality);
+ if (AArch64BuildAttributes::OPTIONAL_NOT_FOUND == IsOptional) {
+ Error(Parser.getTok().getLoc(),
+ AArch64BuildAttributes::getSubsectionOptionalUnknownError() + ": " +
+ Optinality);
+ return true;
+ }
+ if (HasActiveSubsection &&
+ (SubsectionName == ActiveSubsection->VendorName)) {
+ if (IsOptional != ActiveSubsection->IsOptional) {
+ Error(Parser.getTok().getLoc(),
+ "Optinality mismatch! Subsection " + SubsectionName +
+ " allready exists with optinality defined as '" +
+ Twine(ActiveSubsection->IsOptional) + "' and not '" +
+ Twine(IsOptional) + "'! (0: required, 1: optional)");
+ return true;
+ }
+ }
+ } else {
+ Error(
+ Parser.getTok().getLoc(),
+ "Expecitng optionality parameter \n Hint: use 'optional' | 'required'");
+ return true;
+ }
+ // Check for possible IsOptional unaccepted values for known subsections
+ 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 (AArch64BuildAttributes::AEABI_PAUTHABI == SubsectionNameID) {
+ if (AArch64BuildAttributes::OPTIONAL == IsOptional) {
+ Error(Parser.getTok().getLoc(),
+ "aeabi_pauthabi must be marked as required");
+ return true;
+ }
+ }
+ Parser.Lex();
+ // consume a comma
+ if (Parser.parseComma()) {
+ return true;
+ }
+
+ // Consume the second parameter (type parameter)
+ AArch64BuildAttributes::SubsectionType Type;
+ if (Parser.getTok().is(AsmToken::Identifier)) {
+ StringRef Name = Parser.getTok().getIdentifier();
+ Type = AArch64BuildAttributes::getTypeID(Name);
+ if (AArch64BuildAttributes::TYPE_NOT_FOUND == Type) {
+ Error(Parser.getTok().getLoc(),
+ AArch64BuildAttributes::getSubsectionTypeUnknownError() + ": " +
+ Name);
+ return true;
+ }
+ if (HasActiveSubsection &&
+ (SubsectionName == ActiveSubsection->VendorName)) {
+ if (Type != ActiveSubsection->ParameterType) {
+ Error(Parser.getTok().getLoc(),
+ "Type mismatch! Subsection " + SubsectionName +
+ " allready exists with Type defined as '" +
+ Twine(ActiveSubsection->ParameterType) + "' and not '" +
+ Twine(Type) + "'! (0: uleb128, 1: ntbs)");
+ return true;
+ }
+ }
+ } else {
+ Error(Parser.getTok().getLoc(), "Expecitng type parameter");
+ return true;
+ }
+ // Check for possible Type unaccepted values for known subsections
+ 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;
+ }
+ }
+ Parser.Lex();
+ // Parsing finished, check for trailing tokens.
+ if (Parser.getTok().isNot(llvm::AsmToken::EndOfStatement)) {
+ Error(Parser.getTok().getLoc(), "unexpected token for AArch64 build "
+ "attributes subsection header directive");
+ return true;
+ }
+
+ getTargetStreamer().emitAtributesSubsection(SubsectionName, IsOptional, Type);
+
+ return false;
+}
+
+bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
+ // Expecting 2 Tokens: after '.aeabi_attribute', e.g.:
+ // .aeabi_attribute (1)Tag_Feature_BTI, (2)[uleb128|ntbs]
+ // separated by a comma.
+ MCAsmParser &Parser = getParser();
+
+ std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
+ getTargetStreamer().getActiveAtributesSubsection();
+ if (nullptr == ActiveSubsection) {
+ Error(Parser.getTok().getLoc(),
+ "no active subsection, build attribute can not be added");
+ return true;
+ }
+ StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
+ unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
+
+ unsigned ActiveSubsectionID = AArch64BuildAttributes::VENDOR_UNKNOWN;
+ if (AArch64BuildAttributes::VendorName
+ [AArch64BuildAttributes::AEABI_PAUTHABI] == ActiveSubsectionName)
+ ActiveSubsectionID = AArch64BuildAttributes::AEABI_PAUTHABI;
+ if (AArch64BuildAttributes::VendorName
+ [AArch64BuildAttributes::AEABI_FEATURE_AND_BITS] ==
+ ActiveSubsectionName)
+ ActiveSubsectionID = AArch64BuildAttributes::AEABI_FEATURE_AND_BITS;
+
+ StringRef TagStr = "";
+ unsigned Tag;
+ if (Parser.getTok().is(AsmToken::Identifier)) {
+ TagStr = Parser.getTok().getIdentifier();
+ switch (ActiveSubsectionID) {
+ default:
+ assert(0 && "Subsection name error");
+ break;
+ case AArch64BuildAttributes::VENDOR_UNKNOWN:
+ // Private subsection, accept any tag.
+ break;
+ 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 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 +
+ "' \n Hint: options are: Tag_Feature_BTI, Tag_Feature_PAC, "
+ "Tag_Feature_GCS");
+ return true;
+ }
+ break;
+ }
+ } else if (Parser.getTok().is(AsmToken::Integer)) {
+ Tag = getTok().getIntVal();
+ } else {
+ Error(Parser.getTok().getLoc(), "AArch64 build attributes Tag not found");
+ return true;
+ }
+ Parser.Lex();
+ // consume a comma
+ // parseComma() return *false* on success, and call Lex(), no need to call
+ // Lex() again.
+ if (Parser.parseComma()) {
+ return true;
+ }
+
+ // Consume the second parameter (attribute value)
+ unsigned ValueInt = unsigned(-1);
+ std::string ValueStr = "";
+ if (Parser.getTok().is(AsmToken::Integer)) {
+ if (AArch64BuildAttributes::NTBS == ActiveSubsectionType) {
+ Error(
+ Parser.getTok().getLoc(),
+ "active subsection type is NTBS (string), found ULEB128 (unsigned)");
+ return true;
+ }
+ ValueInt = getTok().getIntVal();
+ } else if (Parser.getTok().is(AsmToken::Identifier)) {
+ if (AArch64BuildAttributes::ULEB128 == ActiveSubsectionType) {
+ Error(
+ Parser.getTok().getLoc(),
+ "active subsection type is ULEB128 (unsigned), found NTBS (string)");
+ return true;
+ }
+ ValueStr = Parser.getTok().getIdentifier();
+ } else {
+ Error(Parser.getTok().getLoc(), "AArch64 build attributes Value not found");
+ return true;
+ }
+ // Check for possible unaccepted values for known tags (AEABI_PAUTHABI,
+ // AEABI_FEATURE_AND_BITS)
+ if (!(ActiveSubsectionID == AArch64BuildAttributes::VENDOR_UNKNOWN) &&
+ TagStr != "") { // TagStr was a recognized string
+ if (0 != ValueInt && 1 != ValueInt) {
+ Error(Parser.getTok().getLoc(),
+ "Unknown AArch64 build attributes Value for Tag '" + TagStr +
----------------
ostannard wrote:
Missing test.
https://github.com/llvm/llvm-project/pull/118771
More information about the llvm-commits
mailing list