diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index 63af5a4cff..b4a9154b4d 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt @@ -701,7 +701,11 @@ else() build_libcrypto(crypto $) endif() -if(NOT ANDROID) +# CMAKE_SYSTEM_NAME is "Generic" for embedded OSes: +# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html#toolchain-files +# +# For now we assume embedded OSes do not have threads. +if(NOT (ANDROID OR CMAKE_SYSTEM_NAME STREQUAL "Generic")) find_package(Threads REQUIRED) target_link_libraries(crypto PUBLIC Threads::Threads) endif() diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c index fdd920f779..f8cd1b8c3d 100644 --- a/crypto/x509/v3_purp.c +++ b/crypto/x509/v3_purp.c @@ -437,6 +437,10 @@ static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, return 0; } if (ca) { + // TODO(davidben): Move the various |check_ca| calls out of the + // |check_purpose| callbacks. Those checks are purpose-independent. They are + // also redundant when called from |X509_verify_cert|, though + // not when |X509_check_purpose| is called directly. return check_ca(x); } // We need to do digital signatures or key agreement @@ -478,8 +482,7 @@ static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca) { - int ret; - ret = check_purpose_ssl_server(xp, x, ca); + int ret = check_purpose_ssl_server(xp, x, ca); if (!ret || ca) { return ret; } @@ -512,8 +515,7 @@ static int purpose_smime(const X509 *x, int ca) { static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca) { - int ret; - ret = purpose_smime(x, ca); + int ret = purpose_smime(x, ca); if (!ret || ca) { return ret; } @@ -525,8 +527,7 @@ static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca) { - int ret; - ret = purpose_smime(x, ca); + int ret = purpose_smime(x, ca); if (!ret || ca) { return ret; } @@ -560,8 +561,6 @@ static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) { static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca) { - int i_ext; - // If ca is true we must return if this is a valid CA certificate. if (ca) { return check_ca(x); @@ -585,9 +584,9 @@ static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, } // Extended Key Usage MUST be critical - i_ext = X509_get_ext_by_NID((X509 *)x, NID_ext_key_usage, -1); + int i_ext = X509_get_ext_by_NID(x, NID_ext_key_usage, -1); if (i_ext >= 0) { - const X509_EXTENSION *ext = X509_get_ext((X509 *)x, i_ext); + const X509_EXTENSION *ext = X509_get_ext(x, i_ext); if (!X509_EXTENSION_get_critical(ext)) { return 0; } diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc index 6d78309855..86482defca 100644 --- a/crypto/x509/x509_test.cc +++ b/crypto/x509/x509_test.cc @@ -2223,6 +2223,46 @@ static bssl::UniquePtr MakeTestCert(const char *issuer, return cert; } +static bool AddExtendedKeyUsage(X509 *x509, const std::vector &eku_nids) { + bssl::UniquePtr objs(sk_ASN1_OBJECT_new_null()); + if (objs == nullptr) { + return false; + } + for (int nid : eku_nids) { + if (!sk_ASN1_OBJECT_push(objs.get(), OBJ_nid2obj(nid))) { + return false; + } + } + return X509_add1_ext_i2d(x509, NID_ext_key_usage, objs.get(), /*crit=*/1, + /*flags=*/0); +} + +enum class KeyUsage : int { + kDigitalSignature = 0, + kNonRepudiation = 1, + kKeyEncipherment = 2, + kDataEncipherment = 3, + kKeyAgreement = 4, + kKeyCertSign = 5, + kCRLSign = 6, + kEncipherOnly = 7, + kDecipherOnly = 8, +}; + +static bool AddKeyUsage(X509 *x509, const std::vector usages) { + bssl::UniquePtr str(ASN1_BIT_STRING_new()); + if (str == nullptr) { + return false; + } + for (KeyUsage usage : usages) { + if (!ASN1_BIT_STRING_set_bit(str.get(), static_cast(usage), 1)) { + return false; + } + } + return X509_add1_ext_i2d(x509, NID_key_usage, str.get(), /*crit=*/1, + /*flags=*/0); +} + TEST(X509Test, NameConstraints) { bssl::UniquePtr key = PrivateKeyFromPEM(kP256Key); ASSERT_TRUE(key); @@ -3295,6 +3335,15 @@ TEST(X509Test, NoBasicConstraintsCertSign) { // basicConstraints. EXPECT_EQ(X509_V_ERR_INVALID_CA, Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, 0)); + + // |X509_check_purpose| with |X509_PURPOSE_ANY| and purpose -1 do not check + // basicConstraints, but other purpose types do. (This is redundant with the + // actual basicConstraints check, but |X509_check_purpose| is public API.) + EXPECT_TRUE(X509_check_purpose(intermediate.get(), -1, /*ca=*/1)); + EXPECT_TRUE( + X509_check_purpose(intermediate.get(), X509_PURPOSE_ANY, /*ca=*/1)); + EXPECT_FALSE(X509_check_purpose(intermediate.get(), X509_PURPOSE_SSL_SERVER, + /*ca=*/1)); } TEST(X509Test, NoBasicConstraintsNetscapeCA) { @@ -7719,3 +7768,360 @@ TEST(X509Test, SPKIPrint) { strlen(expected_certificate_string)); EXPECT_EQ(print, expected_certificate_string); } + +// Tests some unusual behavior in |X509_STORE_CTX_set_purpose| and +// |X509_STORE_CTX_set_trust|. +TEST(X509Test, ContextTrustAndPurpose) { + bssl::UniquePtr store(X509_STORE_new()); + ASSERT_TRUE(store); + bssl::UniquePtr leaf(CertFromPEM(kLeafPEM)); + ASSERT_TRUE(leaf); + + bssl::UniquePtr ctx(X509_STORE_CTX_new()); + ASSERT_TRUE(ctx); + ASSERT_TRUE(X509_STORE_CTX_init(ctx.get(), store.get(), leaf.get(), nullptr)); + + // Initially, neither parameter is set. + EXPECT_EQ(ctx->param->purpose, 0); + EXPECT_EQ(ctx->param->trust, 0); + + // Invalid purpose and trust types fail. + EXPECT_FALSE(X509_STORE_CTX_set_purpose(ctx.get(), 999)); + EXPECT_FALSE(X509_STORE_CTX_set_trust(ctx.get(), 999)); + + // It is not possible to set |X509_PURPOSE_ANY| with this API, because there + // is no corresponding trust. + EXPECT_FALSE(X509_STORE_CTX_set_purpose(ctx.get(), X509_PURPOSE_ANY)); + + // Setting a purpose also sets the corresponding trust. + ASSERT_TRUE(X509_STORE_CTX_set_purpose(ctx.get(), X509_PURPOSE_SSL_SERVER)); + EXPECT_EQ(ctx->param->purpose, X509_PURPOSE_SSL_SERVER); + EXPECT_EQ(ctx->param->trust, X509_TRUST_SSL_SERVER); + + // Once set, the functions silently do nothing. + ASSERT_TRUE(X509_STORE_CTX_set_purpose(ctx.get(), X509_PURPOSE_SSL_CLIENT)); + ASSERT_TRUE(X509_STORE_CTX_set_trust(ctx.get(), X509_TRUST_SSL_CLIENT)); + EXPECT_EQ(ctx->param->purpose, X509_PURPOSE_SSL_SERVER); + EXPECT_EQ(ctx->param->trust, X509_TRUST_SSL_SERVER); + + // Start over. + ctx.reset(X509_STORE_CTX_new()); + ASSERT_TRUE(ctx); + ASSERT_TRUE(X509_STORE_CTX_init(ctx.get(), store.get(), leaf.get(), nullptr)); + EXPECT_EQ(ctx->param->purpose, 0); + EXPECT_EQ(ctx->param->trust, 0); + + // Setting trust leaves purpose unset. + ASSERT_TRUE(X509_STORE_CTX_set_trust(ctx.get(), X509_TRUST_SSL_SERVER)); + EXPECT_EQ(ctx->param->purpose, 0); + EXPECT_EQ(ctx->param->trust, X509_TRUST_SSL_SERVER); + + // If trust is set, but not purpose, |X509_STORE_CTX_set_purpose| only sets + // purpose. + ASSERT_TRUE(X509_STORE_CTX_set_purpose(ctx.get(), X509_PURPOSE_SSL_CLIENT)); + EXPECT_EQ(ctx->param->purpose, X509_PURPOSE_SSL_CLIENT); + EXPECT_EQ(ctx->param->trust, X509_TRUST_SSL_SERVER); + + // Start over. + ctx.reset(X509_STORE_CTX_new()); + ASSERT_TRUE(ctx); + ASSERT_TRUE(X509_STORE_CTX_init(ctx.get(), store.get(), leaf.get(), nullptr)); + EXPECT_EQ(ctx->param->purpose, 0); + EXPECT_EQ(ctx->param->trust, 0); + + // If purpose is set, but not trust, |X509_STORE_CTX_set_purpose| only sets + // trust. + ASSERT_TRUE(X509_VERIFY_PARAM_set_purpose( + X509_STORE_CTX_get0_param(ctx.get()), X509_PURPOSE_SSL_CLIENT)); + EXPECT_EQ(ctx->param->purpose, X509_PURPOSE_SSL_CLIENT); + EXPECT_EQ(ctx->param->trust, 0); + + ASSERT_TRUE(X509_STORE_CTX_set_purpose(ctx.get(), X509_PURPOSE_SSL_SERVER)); + EXPECT_EQ(ctx->param->purpose, X509_PURPOSE_SSL_CLIENT); + EXPECT_EQ(ctx->param->trust, X509_TRUST_SSL_SERVER); +} + +TEST(X509Test, Purpose) { + bssl::UniquePtr key = PrivateKeyFromPEM(kP256Key); + ASSERT_TRUE(key); + + struct { + int purpose; + int eku_nid; + std::vector key_usages; + } kTests[] = { + {X509_PURPOSE_SSL_CLIENT, + NID_client_auth, + {KeyUsage::kDigitalSignature, KeyUsage::kKeyAgreement}}, + {X509_PURPOSE_SSL_SERVER, + NID_server_auth, + {KeyUsage::kDigitalSignature, KeyUsage::kKeyAgreement, + KeyUsage::kKeyEncipherment}}, + {X509_PURPOSE_NS_SSL_SERVER, + NID_server_auth, + {KeyUsage::kKeyEncipherment}}, + {X509_PURPOSE_SMIME_SIGN, + NID_email_protect, + {KeyUsage::kDigitalSignature, KeyUsage::kNonRepudiation}}, + {X509_PURPOSE_SMIME_ENCRYPT, + NID_email_protect, + {KeyUsage::kKeyEncipherment}}, + {X509_PURPOSE_CRL_SIGN, NID_undef, {KeyUsage::kCRLSign}}, + }; + for (const auto &t : kTests) { + SCOPED_TRACE(t.purpose); + + auto configure_callback = [&](X509_STORE_CTX *ctx) { + X509_STORE_CTX_set_purpose(ctx, t.purpose); + }; + + // An unconstrained cert chain is valid. + bssl::UniquePtr root = + MakeTestCert("Root", "Root", key.get(), /*is_ca=*/true); + ASSERT_TRUE(root); + ASSERT_TRUE(X509_sign(root.get(), key.get(), EVP_sha256())); + + bssl::UniquePtr intermediate = + MakeTestCert("Root", "Intermediate", key.get(), /*is_ca=*/true); + ASSERT_TRUE(intermediate); + ASSERT_TRUE(X509_sign(intermediate.get(), key.get(), EVP_sha256())); + + bssl::UniquePtr leaf = + MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false); + ASSERT_TRUE(leaf); + ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256())); + + EXPECT_EQ(X509_V_OK, Verify(leaf.get(), {root.get()}, {intermediate.get()}, + {}, 0, configure_callback)); + + // A leaf and intermediate with compatible constraints is valid. + intermediate = + MakeTestCert("Root", "Intermediate", key.get(), /*is_ca=*/true); + ASSERT_TRUE(intermediate); + ASSERT_TRUE(AddKeyUsage(intermediate.get(), {KeyUsage::kKeyCertSign})); + if (t.eku_nid != NID_undef) { + ASSERT_TRUE(AddExtendedKeyUsage(intermediate.get(), {t.eku_nid})); + } + ASSERT_TRUE(X509_sign(intermediate.get(), key.get(), EVP_sha256())); + + leaf = MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false); + ASSERT_TRUE(leaf); + if (t.eku_nid != NID_undef) { + ASSERT_TRUE(AddExtendedKeyUsage(leaf.get(), {t.eku_nid})); + } + ASSERT_TRUE(AddKeyUsage(leaf.get(), t.key_usages)); + ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256())); + + EXPECT_EQ(X509_V_OK, Verify(leaf.get(), {root.get()}, {intermediate.get()}, + {}, 0, configure_callback)); + + // Each key usage asserted individually is valid. + for (KeyUsage usage : t.key_usages) { + SCOPED_TRACE(static_cast(usage)); + leaf = MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false); + ASSERT_TRUE(leaf); + if (t.eku_nid != NID_undef) { + ASSERT_TRUE(AddExtendedKeyUsage(leaf.get(), {t.eku_nid})); + } + ASSERT_TRUE(AddKeyUsage(leaf.get(), {usage})); + ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256())); + EXPECT_EQ(X509_V_OK, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, 0, + configure_callback)); + } + + // A leaf with the wrong EKU is invalid. + if (t.eku_nid != NID_undef) { + leaf = MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false); + ASSERT_TRUE(leaf); + ASSERT_TRUE(AddExtendedKeyUsage(leaf.get(), {NID_rsaEncryption})); + ASSERT_TRUE(AddKeyUsage(leaf.get(), t.key_usages)); + ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256())); + EXPECT_EQ(X509_V_ERR_INVALID_PURPOSE, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, 0, + configure_callback)); + } + + // A leaf without any of the requested key usages is invalid. + std::vector usages; + for (int i = 0; i < 10; i++) { + auto k = static_cast(i); + if (std::find(t.key_usages.begin(), t.key_usages.end(), k) == + t.key_usages.end()) { + usages.push_back(k); + } + } + leaf = MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false); + ASSERT_TRUE(leaf); + if (t.eku_nid != NID_undef) { + ASSERT_TRUE(AddExtendedKeyUsage(leaf.get(), {t.eku_nid})); + } + ASSERT_TRUE(AddKeyUsage(leaf.get(), usages)); + ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256())); + EXPECT_EQ(X509_V_ERR_INVALID_PURPOSE, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, 0, + configure_callback)); + + // Extra EKUs and key usages are fine. + usages.clear(); + for (int i = 0; i < 10; i++) { + usages.push_back(static_cast(i)); + } + leaf = MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false); + ASSERT_TRUE(leaf); + if (t.eku_nid != NID_undef) { + ASSERT_TRUE( + AddExtendedKeyUsage(leaf.get(), {t.eku_nid, NID_rsaEncryption})); + } + ASSERT_TRUE(AddKeyUsage(leaf.get(), usages)); + ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256())); + EXPECT_EQ(X509_V_OK, Verify(leaf.get(), {root.get()}, {intermediate.get()}, + {}, 0, configure_callback)); + + // anyExtendedKeyUsage is not allowed in place of a concrete EKU. + if (t.eku_nid != NID_undef) { + leaf = MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false); + ASSERT_TRUE(leaf); + ASSERT_TRUE(AddExtendedKeyUsage(leaf.get(), {NID_anyExtendedKeyUsage})); + ASSERT_TRUE(AddKeyUsage(leaf.get(), t.key_usages)); + ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256())); + EXPECT_EQ(X509_V_ERR_INVALID_PURPOSE, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, 0, + configure_callback)); + } + + // Restore |leaf| to a valid option. + leaf = MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false); + ASSERT_TRUE(leaf); + ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256())); + + // The intermediate must have the keyCertSign bit. This bit is checked in + // multiple places. The first place that fails is in looking for candidate + // issuers. + intermediate = + MakeTestCert("Root", "Intermediate", key.get(), /*is_ca=*/true); + ASSERT_TRUE(intermediate); + ASSERT_TRUE(AddKeyUsage(intermediate.get(), {KeyUsage::kDigitalSignature})); + if (t.eku_nid != NID_undef) { + ASSERT_TRUE(AddExtendedKeyUsage(intermediate.get(), {t.eku_nid})); + } + ASSERT_TRUE(X509_sign(intermediate.get(), key.get(), EVP_sha256())); + EXPECT_EQ(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, 0, + configure_callback)); + + // The intermediate must have the EKU asserted. + if (t.eku_nid != NID_undef) { + intermediate = + MakeTestCert("Root", "Intermediate", key.get(), /*is_ca=*/true); + ASSERT_TRUE(intermediate); + ASSERT_TRUE(AddKeyUsage(intermediate.get(), {KeyUsage::kKeyCertSign})); + ASSERT_TRUE(AddExtendedKeyUsage(intermediate.get(), {NID_rsaEncryption})); + ASSERT_TRUE(X509_sign(intermediate.get(), key.get(), EVP_sha256())); + EXPECT_EQ(X509_V_ERR_INVALID_PURPOSE, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, 0, + configure_callback)); + } + } +} + +TEST(X509Test, Trust) { + struct Certs { + bssl::UniquePtr normal = nullptr; + bssl::UniquePtr trusted_server = nullptr, distrusted_server = nullptr; + bssl::UniquePtr trusted_any = nullptr, distrusted_any = nullptr; + }; + auto certs_from_pem = [](const char *pem) -> Certs { + Certs certs; + certs.normal = CertFromPEM(pem); + certs.trusted_server = CertFromPEM(pem); + certs.distrusted_server = CertFromPEM(pem); + certs.trusted_any = CertFromPEM(pem); + certs.distrusted_any = CertFromPEM(pem); + if (certs.normal == nullptr || certs.trusted_server == nullptr || + certs.distrusted_server == nullptr || certs.trusted_any == nullptr || + certs.distrusted_any == nullptr || + !X509_add1_trust_object(certs.trusted_server.get(), + OBJ_nid2obj(NID_server_auth)) || + !X509_add1_reject_object(certs.distrusted_server.get(), + OBJ_nid2obj(NID_server_auth)) || + !X509_add1_trust_object(certs.trusted_any.get(), + OBJ_nid2obj(NID_anyExtendedKeyUsage)) || + !X509_add1_reject_object(certs.distrusted_any.get(), + OBJ_nid2obj(NID_anyExtendedKeyUsage))) { + return Certs{}; + } + return certs; + }; + + Certs root = certs_from_pem(kRootCAPEM); + Certs intermediate = certs_from_pem(kIntermediatePEM); + Certs leaf = certs_from_pem(kLeafPEM); + ASSERT_TRUE(root.normal); + ASSERT_TRUE(intermediate.normal); + ASSERT_TRUE(leaf.normal); + + // By default, trust is determined by a combination of self-signedness and + // NID_anyExtendedKeyUsage. + EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(), {root.normal.get()}, + {intermediate.normal.get()}, {})); + EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(), {root.trusted_any.get()}, + {intermediate.normal.get()}, {})); + EXPECT_EQ(X509_V_ERR_CERT_REJECTED, + Verify(leaf.normal.get(), {root.distrusted_any.get()}, + {intermediate.normal.get()}, {})); + + // Intermediate certificates are not self-signed, so must have an + // NID_anyExtendedKeyUsage trust setting. + EXPECT_EQ(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT, + Verify(leaf.normal.get(), {intermediate.normal.get()}, {}, {})); + EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(), + {intermediate.trusted_any.get()}, {}, {})); + EXPECT_EQ( + X509_V_ERR_CERT_REJECTED, + Verify(leaf.normal.get(), {intermediate.distrusted_any.get()}, {}, {})); + + // If a certificate has trust settings, but only for a different OID, the + // self-signed rule still takes effect. + EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(), {root.trusted_server.get()}, + {intermediate.normal.get()}, {})); + EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(), {root.distrusted_server.get()}, + {intermediate.normal.get()}, {})); + EXPECT_EQ( + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT, + Verify(leaf.normal.get(), {intermediate.trusted_server.get()}, {}, {})); + + // |X509_TRUST_SSL_SERVER| should instead look at self-signedness and + // |NID_server_auth|. + auto set_server_trust = [](X509_STORE_CTX *ctx) { + X509_STORE_CTX_set_trust(ctx, X509_TRUST_SSL_SERVER); + }; + EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(), {root.normal.get()}, + {intermediate.normal.get()}, {}, /*flags=*/0, + set_server_trust)); + EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(), {root.trusted_server.get()}, + {intermediate.normal.get()}, {}, /*flags=*/0, + set_server_trust)); + EXPECT_EQ( + X509_V_ERR_CERT_REJECTED, + Verify(leaf.normal.get(), {root.distrusted_server.get()}, + {intermediate.normal.get()}, {}, /*flags=*/0, set_server_trust)); + + EXPECT_EQ(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT, + Verify(leaf.normal.get(), {intermediate.normal.get()}, {}, {}, + /*flags=*/0, set_server_trust)); + EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(), + {intermediate.trusted_server.get()}, {}, {}, + /*flags=*/0, set_server_trust)); + EXPECT_EQ(X509_V_ERR_CERT_REJECTED, + Verify(leaf.normal.get(), {intermediate.distrusted_server.get()}, + {}, {}, /*flags=*/0, set_server_trust)); + + // NID_anyExtendedKeyUsage is just an unrelated OID to X509_TRUST_SSL_SERVER. + // Unlike the default behavior, once a certificate has explicit trust settings + // for any OID, the self-signed check is disabled. + EXPECT_EQ( + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT, + Verify(leaf.normal.get(), {root.trusted_any.get()}, + {intermediate.normal.get()}, {}, /*flags=*/0, set_server_trust)); +} diff --git a/crypto/x509/x509_trs.c b/crypto/x509/x509_trs.c index 95daf46657..deb8930119 100644 --- a/crypto/x509/x509_trs.c +++ b/crypto/x509/x509_trs.c @@ -85,20 +85,18 @@ static const X509_TRUST trstandard[] = { NULL}}; int X509_check_trust(X509 *x, int id, int flags) { - int idx; if (id == -1) { - return 1; + return X509_TRUST_TRUSTED; } // We get this as a default value if (id == 0) { - int rv; - rv = obj_trust(NID_anyExtendedKeyUsage, x, 0); + int rv = obj_trust(NID_anyExtendedKeyUsage, x, 0); if (rv != X509_TRUST_UNTRUSTED) { return rv; } return trust_compat(NULL, x, 0); } - idx = X509_TRUST_get_by_id(id); + int idx = X509_TRUST_get_by_id(id); if (idx == -1) { return obj_trust(id, x, flags); } diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 298a14f0ab..8fdd82cd92 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -1569,62 +1569,40 @@ void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) { } int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) { - return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); -} + // If |purpose| is zero, this function historically silently did nothing. + if (purpose == 0) { + return 1; + } -int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) { - return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust); -} - -// This function is used to set the X509_STORE_CTX purpose and trust values. -// This is intended to be used when another structure has its own trust and -// purpose values which (if set) will be inherited by the ctx. If they aren't -// set then we will usually have a default purpose in mind which should then -// be used to set the trust value. An example of this is SSL use: an SSL -// structure will have its own purpose and trust settings which the -// application can set: if they aren't set then we use the default of SSL -// client/server. - -int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, - int purpose, int trust) { - int idx; - // If purpose not set use default - if (!purpose) { - purpose = def_purpose; - } - // If we have a purpose then check it is valid - if (purpose) { - idx = X509_PURPOSE_get_by_id(purpose); - if (idx == -1) { - OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID); - return 0; - } - const X509_PURPOSE *ptmp = X509_PURPOSE_get0(idx); - if (ptmp->trust == X509_TRUST_DEFAULT) { - idx = X509_PURPOSE_get_by_id(def_purpose); - if (idx == -1) { - OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID); - return 0; - } - ptmp = X509_PURPOSE_get0(idx); - } - // If trust not set then get from purpose default - if (!trust) { - trust = ptmp->trust; - } + int idx = X509_PURPOSE_get_by_id(purpose); + if (idx == -1) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID); + return 0; } - if (trust) { - idx = X509_TRUST_get_by_id(trust); - if (idx == -1) { - OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID); - return 0; - } + + int trust = X509_PURPOSE_get_trust(X509_PURPOSE_get0(idx)); + if (!X509_STORE_CTX_set_trust(ctx, trust)) { + return 0; } - if (purpose && !ctx->param->purpose) { + if (ctx->param->purpose == 0) { ctx->param->purpose = purpose; } - if (trust && !ctx->param->trust) { + return 1; +} + +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) { + // If |trust| is zero, this function historically silently did nothing. + if (trust == 0) { + return 1; + } + + if (X509_TRUST_get_by_id(trust) == -1) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID); + return 0; + } + + if (ctx->param->trust == 0) { ctx->param->trust = trust; } return 1; @@ -1749,8 +1727,7 @@ void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, } int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) { - const X509_VERIFY_PARAM *param; - param = X509_VERIFY_PARAM_lookup(name); + const X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_lookup(name); if (!param) { return 0; } diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 31824bdb6c..1cf54d2c39 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -676,11 +676,15 @@ OPENSSL_EXPORT const uint8_t *X509_keyid_get0(const X509 *x509, int *out_len); // X509_add1_trust_object configures |x509| as a valid trust anchor for |obj|. // It returns one on success and zero on error. |obj| should be a certificate // usage OID associated with an |X509_TRUST| object. +// +// See |X509_VERIFY_PARAM_set_trust| for details on how this value is evaluated. OPENSSL_EXPORT int X509_add1_trust_object(X509 *x509, const ASN1_OBJECT *obj); // X509_add1_reject_object configures |x509| as distrusted for |obj|. It returns // one on success and zero on error. |obj| should be a certificate usage OID // associated with an |X509_TRUST| object. +// +// See |X509_VERIFY_PARAM_set_trust| for details on how this value is evaluated. OPENSSL_EXPORT int X509_add1_reject_object(X509 *x509, const ASN1_OBJECT *obj); // X509_trust_clear clears the list of OIDs for which |x509| is trusted. See @@ -2247,6 +2251,341 @@ OPENSSL_EXPORT ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); +// Certificate stores. +// +// An |X509_STORE| contains trusted certificates, CRLs, and verification +// parameters that are shared between multiple certificate verifications. +// +// Certificates in an |X509_STORE| are referred to as "trusted certificates", +// but an individual certificate verification may not necessarily treat every +// trusted certificate as a trust anchor. See |X509_VERIFY_PARAM_set_trust| for +// details. +// +// WARNING: Although a trusted certificate which fails the +// |X509_VERIFY_PARAM_set_trust| check is functionally an untrusted +// intermediate certificate, callers should not rely on this to configure +// untrusted intermediates in an |X509_STORE|. The trust check is complex, so +// this risks inadvertently treating it as a trust anchor. Instead, configure +// untrusted intermediates with the |chain| parameter of |X509_STORE_CTX_init|. +// +// Certificates in |X509_STORE| may be specified in several ways: +// - Added by |X509_STORE_add_cert|. +// - Returned by an |X509_LOOKUP| added by |X509_STORE_add_lookup|. +// +// |X509_STORE|s are reference-counted and may be shared by certificate +// verifications running concurrently on multiple threads. However, an +// |X509_STORE|'s verification parameters may not be modified concurrently with +// certificate verification or other operations. Unless otherwise documented, +// functions which take const pointer may be used concurrently, while +// functions which take a non-const pointer may not. Callers that wish to modify +// verification parameters in a shared |X509_STORE| should instead modify +// |X509_STORE_CTX|s individually. + +// X509_STORE_new returns a newly-allocated |X509_STORE|, or NULL on error. +OPENSSL_EXPORT X509_STORE *X509_STORE_new(void); + +// X509_STORE_up_ref adds one to the reference count of |store| and returns one. +// Although |store| is not const, this function's use of |store| is thread-safe. +OPENSSL_EXPORT int X509_STORE_up_ref(X509_STORE *store); + +// X509_STORE_free releases memory associated with |store|. +OPENSSL_EXPORT void X509_STORE_free(X509_STORE *store); + +// X509_STORE_add_cert adds |x509| to |store| as a trusted certificate. It +// returns one on success and zero on error. This function internally increments +// |x509|'s reference count, so the caller retains ownership of |x509|. +// +// Certificates configured by this function are still subject to the checks +// described in |X509_VERIFY_PARAM_set_trust|. +// +// Although |store| is not const, this function's use of |store| is thread-safe. +// However, if this function is called concurrently with |X509_verify_cert|, it +// is a race condition whether |x509| is available for issuer lookups. +// Moreover, the result may differ for each issuer lookup performed by a single +// |X509_verify_cert| call. +OPENSSL_EXPORT int X509_STORE_add_cert(X509_STORE *store, X509 *x509); + +// X509_STORE_add_crl adds |crl| to |store|. It returns one on success and zero +// on error. This function internally increments |crl|'s reference count, so the +// caller retains ownership of |crl|. CRLs added in this way are candidates for +// CRL lookup when |X509_V_FLAG_CRL_CHECK| is set. +// +// Although |store| is not const, this function's use of |store| is thread-safe. +// However, if this function is called concurrently with |X509_verify_cert|, it +// is a race condition whether |crl| is available for CRL checks. Moreover, the +// result may differ for each CRL check performed by a single +// |X509_verify_cert| call. +// +// Note there are no supported APIs to remove CRLs from |store| once inserted. +// To vary the set of CRLs over time, callers should either create a new +// |X509_STORE| or configure CRLs on a per-verification basis with +// |X509_STORE_CTX_set0_crls|. +OPENSSL_EXPORT int X509_STORE_add_crl(X509_STORE *store, X509_CRL *crl); + +// X509_STORE_set_purpose configures the purpose check for |store|. See +// |X509_VERIFY_PARAM_set_purpose| for details. +OPENSSL_EXPORT int X509_STORE_set_purpose(X509_STORE *store, int purpose); + +// X509_STORE_set_trust configures the trust check for |store|. See +// |X509_VERIFY_PARAM_set_trust| for details. +OPENSSL_EXPORT int X509_STORE_set_trust(X509_STORE *store, int trust); + +// TODO(crbug.com/boringssl/426): Move the other |X509_STORE| functions here. + + +// Certificate verification. +// +// An |X509_STORE_CTX| object represents a single certificate verification +// operation. To verify a certificate chain, callers construct an +// |X509_STORE_CTX|, initialize it with |X509_STORE_CTX_init|, configure extra +// parameters, and call |X509_verify_cert|. + +// X509_STORE_CTX_new returns a newly-allocated, empty |X509_STORE_CTX|, or NULL +// on error. +OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_new(void); + +// X509_STORE_CTX_free releases memory associated with |ctx|. +OPENSSL_EXPORT void X509_STORE_CTX_free(X509_STORE_CTX *ctx); + +// X509_STORE_CTX_init initializes |ctx| to verify |x509|, using trusted +// certificates and parameters in |store|. It returns one on success and zero on +// error. |chain| is a list of untrusted intermediate certificates to use in +// verification. +// +// |ctx| stores pointers to |store|, |x509|, and |chain|. Each of these objects +// must outlive |ctx| and may not be mutated for the duration of the certificate +// verification. +OPENSSL_EXPORT int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); + +// X509_verify_cert attempts to discover and validate a certificate chain based +// on parameters in |ctx|. |ctx| usually includes a target certificate to be +// verified, a set of certificates serving as trust anchors, a list of +// non-trusted certificates that may be helpful for chain construction, flags, +// and various other optional components such as callback functions. |ctx| +// must have been initialized with |X509_STORE_CTX_init|. A certificate chain +// is built up starting from the target certificate and ending +// in a trust anchor. The chain is built up iteratively, looking up in turn a +// certificate with suitable key usage that matches as an issuer of the current +// "subject" certificate. +// +// NOTE: +// 1. Applications rarely call this function directly, but it is used +// internally for certificate validation. +// 2. |X509_verify_cert| and other related functions call +// |sk_X509_OBJECT_sort| internally, which rearranges the certificate +// ordering. There will be cases where two certs have an identical +// |subject| and |X509_OBJECT_cmp| will return 0, but one is a valid cert +// and the other is invalid. +// Due to https://github.com/openssl/openssl/issues/18708, certificate +// verification could fail if an invalid cert is checked before the valid +// cert. What we do with sorting behavior when certs are identical is +// considered "unstable" and certain sorting expectations shouldn't be +// depended on. +OPENSSL_EXPORT int X509_verify_cert(X509_STORE_CTX *ctx); + +// X509_STORE_CTX_set0_trusted_stack configures |ctx| to trust the certificates +// in |sk|. |sk| must remain valid for the duration of |ctx|. Calling this +// function causes |ctx| to ignore any certificates configured in the +// |X509_STORE|. Certificates in |sk| are still subject to the check described +// in |X509_VERIFY_PARAM_set_trust|. +// +// WARNING: This function differs from most |set0| functions in that it does not +// take ownership of its input. The caller is required to ensure the lifetimes +// are consistent. +OPENSSL_EXPORT void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, + STACK_OF(X509) *sk); + +// X509_STORE_CTX_set_default looks up the set of parameters named |name| and +// applies those default verification parameters for |ctx|. As in +// |X509_VERIFY_PARAM_inherit|, only unset parameters are changed. This function +// returns one on success and zero on error. +// +// The supported values of |name| are: +// - "default" is an internal value which configures some late defaults. See the +// discussion in |X509_STORE_get0_param|. +// - "pkcs7" configures default trust and purpose checks for PKCS#7 signatures. +// - "smime_sign" configures trust and purpose checks for S/MIME signatures. +// - "ssl_client" configures trust and purpose checks for TLS clients. +// - "ssl_server" configures trust and purpose checks for TLS servers. +// +// TODO(crbug.com/boringssl/441): Make "default" a no-op. +OPENSSL_EXPORT int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, + const char *name); + +// X509_STORE_CTX_set_purpose simultaneously configures |ctx|'s purpose and +// trust checks, if unset. It returns one on success and zero if |purpose| is +// not a valid purpose value. |purpose| should be an |X509_PURPOSE_*| constant. +// If so, it configures |ctx| with a purpose check of |purpose| and a trust +// check of |purpose|'s corresponding trust value. If either the purpose or +// trust check had already been specified for |ctx|, that corresponding +// modification is silently dropped. +// +// See |X509_VERIFY_PARAM_set_purpose| and |X509_VERIFY_PARAM_set_trust| for +// details on the purpose and trust checks, respectively. +// +// If |purpose| is |X509_PURPOSE_ANY|, this function returns an error because it +// has no corresponding |X509_TRUST_*| value. It is not possible to set +// |X509_PURPOSE_ANY| with this function, only |X509_VERIFY_PARAM_set_purpose|. +// +// WARNING: Unlike similarly named functions in this header, this function +// silently does not behave the same as |X509_VERIFY_PARAM_set_purpose|. Callers +// may use |X509_VERIFY_PARAM_set_purpose| with |X509_STORE_CTX_get0_param| to +// avoid this difference. +OPENSSL_EXPORT int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); + +// X509_STORE_CTX_set_trust configures |ctx|'s trust check, if unset. It returns +// one on success and zero if |trust| is not a valid trust value. |trust| should +// be an |X509_TRUST_*| constant. If so, it configures |ctx| with a trust check +// of |trust|. If the trust check had already been specified for |ctx|, it +// silently does nothing. +// +// See |X509_VERIFY_PARAM_set_trust| for details on the purpose and trust check. +// +// WARNING: Unlike similarly named functions in this header, this function +// does not behave the same as |X509_VERIFY_PARAM_set_trust|. Callers may use +// |X509_VERIFY_PARAM_set_trust| with |X509_STORE_CTX_get0_param| to avoid this +// difference. +OPENSSL_EXPORT int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); + +// TODO(crbug.com/boringssl/426): Move the other |X509_STORE_CTX| functions +// here. + + +// Verification parameters +// +// An |X509_VERIFY_PARAM| contains a set of parameters for certificate +// verification. + +// X509_VERIFY_PARAM_new returns a newly-allocated |X509_VERIFY_PARAM|, or NULL +// on error. +OPENSSL_EXPORT X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); + +// X509_VERIFY_PARAM_free releases memory associated with |param|. +OPENSSL_EXPORT void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); + +// X509_PURPOSE_SSL_CLIENT validates TLS client certificates. It checks for the +// id-kp-clientAuth EKU and one of digitalSignature or keyAgreement key usages. +// The TLS library is expected to check for the key usage specific to the +// negotiated TLS parameters. +#define X509_PURPOSE_SSL_CLIENT 1 +// X509_PURPOSE_SSL_SERVER validates TLS server certificates. It checks for the +// id-kp-clientAuth EKU and one of digitalSignature, keyAgreement, or +// keyEncipherment key usages. The TLS library is expected to check for the key +// usage specific to the negotiated TLS parameters. +#define X509_PURPOSE_SSL_SERVER 2 +// X509_PURPOSE_NS_SSL_SERVER is a legacy mode. It behaves like +// |X509_PURPOSE_SSL_SERVER|, but only accepts the keyEncipherment key usage, +// used by SSL 2.0 and RSA key exchange. Do not use this. +#define X509_PURPOSE_NS_SSL_SERVER 3 +// X509_PURPOSE_SMIME_SIGN validates S/MIME signing certificates. It checks for +// the id-kp-emailProtection EKU and one of digitalSignature or nonRepudiation +// key usages. +#define X509_PURPOSE_SMIME_SIGN 4 +// X509_PURPOSE_SMIME_ENCRYPT validates S/MIME encryption certificates. It +// checks for the id-kp-emailProtection EKU and keyEncipherment key usage. +#define X509_PURPOSE_SMIME_ENCRYPT 5 +// X509_PURPOSE_CRL_SIGN validates indirect CRL signers. It checks for the +// cRLSign key usage. BoringSSL does not support indirect CRLs and does not use +// this mode. +#define X509_PURPOSE_CRL_SIGN 6 +// X509_PURPOSE_ANY performs no EKU or key usage checks. Such checks are the +// responsibility of the caller. +#define X509_PURPOSE_ANY 7 +// X509_PURPOSE_OCSP_HELPER performs no EKU or key usage checks. It was +// historically used in OpenSSL's OCSP implementation, which left those checks +// to the OCSP implementation itself. +#define X509_PURPOSE_OCSP_HELPER 8 +// X509_PURPOSE_TIMESTAMP_SIGN validates Time Stamping Authority (RFC 3161) +// certificates. It checks for the id-kp-timeStamping EKU and one of +// digitalSignature or nonRepudiation key usages. It additionally checks that +// the EKU extension is critical and that no other EKUs or key usages are +// asserted. +#define X509_PURPOSE_TIMESTAMP_SIGN 9 + +// X509_VERIFY_PARAM_set_purpose configures |param| to validate certificates for +// a specified purpose. It returns one on success and zero if |purpose| is not a +// valid purpose type. |purpose| should be one of the |X509_PURPOSE_*| values. +// +// This option controls checking the extended key usage (EKU) and key usage +// extensions. These extensions specify how a certificate's public key may be +// used and are important to avoid cross-protocol attacks, particularly in PKIs +// that may issue certificates for multiple protocols, or for protocols that use +// keys in multiple ways. If not configured, these security checks are the +// caller's responsibility. +// +// This library applies the EKU checks to all untrusted intermediates. Although +// not defined in RFC 5280, this matches widely-deployed practice. It also does +// not accept anyExtendedKeyUsage. +// +// Many purpose values have a corresponding trust value, which is not configured +// by this function. See |X509_VERIFY_PARAM_set_trust| for details. Callers +// that wish to configure both should either call both functions, or use +// |X509_STORE_CTX_set_purpose|. +// +// It is currently not possible to configure custom EKU OIDs or key usage bits. +// Contact the BoringSSL maintainers if your application needs to do so. OpenSSL +// had an |X509_PURPOSE_add| API, but it was not thread-safe and relied on +// global mutable state, so we removed it. +// +// TODO(davidben): This function additionally configures checking the legacy +// Netscape certificate type extension. Remove this. +OPENSSL_EXPORT int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, + int purpose); + +// X509_TRUST_COMPAT evaluates trust using only the self-signed fallback. Trust +// and distrust OIDs are ignored. +#define X509_TRUST_COMPAT 1 +// X509_TRUST_SSL_CLIENT evaluates trust with the |NID_client_auth| OID, for +// validating TLS client certificates. +#define X509_TRUST_SSL_CLIENT 2 +// X509_TRUST_SSL_SERVER evaluates trust with the |NID_server_auth| OID, for +// validating TLS server certificates. +#define X509_TRUST_SSL_SERVER 3 +// X509_TRUST_EMAIL evaluates trust with the |NID_email_protect| OID, for +// validating S/MIME email certificates. +#define X509_TRUST_EMAIL 4 +// X509_TRUST_OBJECT_SIGN evaluates trust with the |NID_code_sign| OID, for +// validating code signing certificates. +#define X509_TRUST_OBJECT_SIGN 5 +// X509_TRUST_TSA evaluates trust with the |NID_time_stamp| OID, for validating +// Time Stamping Authority (RFC 3161) certificates. +#define X509_TRUST_TSA 8 + +// X509_VERIFY_PARAM_set_trust configures which certificates from |X509_STORE| +// are trust anchors. It returns one on success and zero if |trust| is not a +// valid trust value. |trust| should be one of the |X509_TRUST_*| constants. +// This function allows applications to vary trust anchors when the same set of +// trusted certificates is used in multiple contexts. +// +// Two properties determine whether a certificate is a trust anchor: +// +// - Whether it is trusted or distrusted for some OID, via auxiliary information +// configured by |X509_add1_trust_object| or |X509_add1_reject_object|. +// +// - Whether it is "self-signed". That is, whether |X509_get_extension_flags| +// includes |EXFLAG_SS|. The signature itself is not checked. +// +// When this function is called, |trust| determines the OID to check in the +// first case. If the certificate is not explicitly trusted or distrusted for +// any OID, it is trusted if self-signed instead. +// +// If unset, the default behavior is to check for the |NID_anyExtendedKeyUsage| +// OID. If the certificate is not explicitly trusted or distrusted for this OID, +// it is trusted if self-signed instead. Note this slightly differs from the +// above. +// +// It is currently not possible to configure custom trust OIDs. Contact the +// BoringSSL maintainers if your application needs to do so. OpenSSL had an +// |X509_TRUST_add| API, but it was not thread-safe and relied on global mutable +// state, so we removed it. +OPENSSL_EXPORT int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, + int trust); + +// TODO(crbug.com/boringssl/426): Move the other |X509_VERIFY_PARAM| functions +// here. + + // SignedPublicKeyAndChallenge structures. // // The SignedPublicKeyAndChallenge (SPKAC) is a legacy structure to request @@ -3202,6 +3541,43 @@ OPENSSL_EXPORT int X509_check_ip(const X509 *x509, const uint8_t *chk, OPENSSL_EXPORT int X509_check_ip_asc(const X509 *x509, const char *ipasc, unsigned int flags); +// X509_STORE_CTX_get1_issuer looks up a candidate trusted issuer for |x509| out +// of |ctx|'s |X509_STORE|, based on the criteria in |X509_check_issued|. If one +// was found, it returns one and sets |*out_issuer| to the issuer. The caller +// must release |*out_issuer| with |X509_free| when done. If none was found, it +// returns zero and leaves |*out_issuer| unchanged. +// +// This function only searches for trusted issuers. It does not consider +// untrusted intermediates passed in to |X509_STORE_CTX_init|. +// +// TODO(crbug.com/boringssl/407): |x509| should be const. +OPENSSL_EXPORT int X509_STORE_CTX_get1_issuer(X509 **out_issuer, + X509_STORE_CTX *ctx, X509 *x509); + +// X509_check_purpose performs checks if |x509|'s basic constraints, key usage, +// and extended key usage extensions for the specified purpose. |purpose| should +// be one of |X509_PURPOSE_*| constants. See |X509_VERIFY_PARAM_set_purpose| for +// details. It returns one if |x509|'s extensions are consistent with |purpose| +// and zero otherwise. If |ca| is non-zero, |x509| is checked as a CA +// certificate. Otherwise, it is checked as an end-entity certificate. +// +// If |purpose| is -1, this function performs no purpose checks, but it parses +// some extensions in |x509| and may return zero on syntax error. Historically, +// callers primarily used this function to trigger this parsing, but this is no +// longer necessary. Functions acting on |X509| will internally parse as needed. +OPENSSL_EXPORT int X509_check_purpose(X509 *x509, int purpose, int ca); + +#define X509_TRUST_TRUSTED 1 +#define X509_TRUST_REJECTED 2 +#define X509_TRUST_UNTRUSTED 3 + +// X509_check_trust checks if |x509| is a valid trust anchor for trust type +// |id|. See |X509_VERIFY_PARAM_set_trust| for details. It returns +// |X509_TRUST_TRUSTED| if |x509| is a trust anchor, |X509_TRUST_REJECTED| if it +// was distrusted, and |X509_TRUST_UNTRUSTED| otherwise. |id| should be one of +// the |X509_TRUST_*| constants, or zero to indicate the default behavior. +// |flags| should be zero and is ignored. +OPENSSL_EXPORT int X509_check_trust(X509 *x509, int id, int flags); // X.509 information. // @@ -3665,19 +4041,6 @@ DEFINE_STACK_OF(X509_TRUST) #define X509_TRUST_DEFAULT (-1) // Only valid in purpose settings -#define X509_TRUST_COMPAT 1 -#define X509_TRUST_SSL_CLIENT 2 -#define X509_TRUST_SSL_SERVER 3 -#define X509_TRUST_EMAIL 4 -#define X509_TRUST_OBJECT_SIGN 5 -#define X509_TRUST_TSA 8 - -// check_trust return codes - -#define X509_TRUST_TRUSTED 1 -#define X509_TRUST_REJECTED 2 -#define X509_TRUST_UNTRUSTED 3 - // X509_verify_cert_error_string returns |err| as a human-readable string, where // |err| should be one of the |X509_V_*| values. If |err| is unknown, it returns // a default description. @@ -3723,32 +4086,6 @@ OPENSSL_EXPORT uint32_t X509_NAME_hash_old(X509_NAME *name); OPENSSL_EXPORT int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); -// X509_verify_cert attempts to discover and validate a certificate chain based -// on parameters in |ctx|. |ctx| usually includes a target certificate to be -// verified, a set of certificates serving as trust anchors, a list of -// non-trusted certificates that may be helpful for chain construction, flags, -// and various other optional components such as callback functions. A -// certificate chain is built up starting from the target certificate and ending -// in a trust anchor. The chain is built up iteratively, looking up in turn a -// certificate with suitable key usage that matches as an issuer of the current -// "subject" certificate. -// -// NOTE: -// 1. Applications rarely call this function directly, but it is used -// internally for certificate validation. -// 2. |X509_verify_cert| and other related functions call -// |sk_X509_OBJECT_sort| internally, which rearranges the certificate -// ordering. There will be cases where two certs have an identical -// |subject| and |X509_OBJECT_cmp| will return 0, but one is a valid cert -// and the other is invalid. -// Due to https://github.com/openssl/openssl/issues/18708, certificate -// verification could fail if an invalid cert is checked before the valid -// cert. What we do with sorting behavior when certs are identical is -// considered "unstable" and certain sorting expectations shouldn't be -// depended on. -OPENSSL_EXPORT int X509_verify_cert(X509_STORE_CTX *ctx); - -OPENSSL_EXPORT int X509_check_trust(X509 *x, int id, int flags); OPENSSL_EXPORT int X509_TRUST_get_count(void); OPENSSL_EXPORT const X509_TRUST *X509_TRUST_get0(int idx); OPENSSL_EXPORT int X509_TRUST_get_by_id(int id); @@ -3996,15 +4333,6 @@ OPENSSL_EXPORT int X509_STORE_lock(X509_STORE *v); // X509_STORE_unlock releases a lock on |v|. return 1 on success, 0 on failure OPENSSL_EXPORT int X509_STORE_unlock(X509_STORE *v); -// X509_STORE_new returns a newly-allocated |X509_STORE|, or NULL on error. -OPENSSL_EXPORT X509_STORE *X509_STORE_new(void); - -// X509_STORE_up_ref adds one to the reference count of |store| and returns one. -OPENSSL_EXPORT int X509_STORE_up_ref(X509_STORE *store); - -// X509_STORE_free releases memory associated with |store|. -OPENSSL_EXPORT void X509_STORE_free(X509_STORE *store); - OPENSSL_EXPORT STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *st); OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *st, X509_NAME *nm); @@ -4019,9 +4347,6 @@ OPENSSL_EXPORT STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *st, // the |X509_STORE|. See discussion in |X509_STORE_get0_param|. OPENSSL_EXPORT int X509_STORE_set_flags(X509_STORE *store, unsigned long flags); -OPENSSL_EXPORT int X509_STORE_set_purpose(X509_STORE *store, int purpose); -OPENSSL_EXPORT int X509_STORE_set_trust(X509_STORE *store, int trust); - // X509_STORE_set1_param copies verification parameters from |param| as in // |X509_VERIFY_PARAM_set1|. It returns one on success and zero on error. OPENSSL_EXPORT int X509_STORE_set1_param(X509_STORE *store, @@ -4047,38 +4372,6 @@ OPENSSL_EXPORT int X509_STORE_set1_param(X509_STORE *store, // |X509_V_FLAG_TRUSTED_FIRST| is mostly a workaround for poor path-building. OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *store); -// X509_STORE_CTX_new returns a newly-allocated, empty |X509_STORE_CTX|, or NULL -// on error. -OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_new(void); - -OPENSSL_EXPORT int X509_STORE_CTX_get1_issuer(X509 **issuer, - X509_STORE_CTX *ctx, X509 *x); - -// X509_STORE_CTX_free releases memory associated with |ctx|. -OPENSSL_EXPORT void X509_STORE_CTX_free(X509_STORE_CTX *ctx); - -// X509_STORE_CTX_init initializes |ctx| to verify |x509|, using trusted -// certificates and parameters in |store|. It returns one on success and zero on -// error. |chain| is a list of untrusted intermediate certificates to use in -// verification. -// -// |ctx| stores pointers to |store|, |x509|, and |chain|. Each of these objects -// must outlive |ctx| and may not be mutated for the duration of the certificate -// verification. -OPENSSL_EXPORT int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, - X509 *x509, STACK_OF(X509) *chain); - -// X509_STORE_CTX_set0_trusted_stack configures |ctx| to trust the certificates -// in |sk|. |sk| must remain valid for the duration of |ctx|. Calling this -// function causes |ctx| to ignore any certificates configured in the -// |X509_STORE|. -// -// WARNING: This function differs from most |set0| functions in that it does not -// take ownership of its input. The caller is required to ensure the lifetimes -// are consistent. -OPENSSL_EXPORT void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, - STACK_OF(X509) *sk); - // X509_STORE_CTX_get0_store returns the |X509_STORE| that |ctx| uses. OPENSSL_EXPORT X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); @@ -4092,8 +4385,17 @@ OPENSSL_EXPORT X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, OPENSSL_EXPORT const X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); OPENSSL_EXPORT const X509_LOOKUP_METHOD *X509_LOOKUP_file(void); -OPENSSL_EXPORT int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); -OPENSSL_EXPORT int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); +// X509_STORE_get_by_subject is an alias to |X509_STORE_CTX_get_by_subject| in +// OpenSSL 1.1.1. +#define X509_STORE_get_by_subject X509_STORE_CTX_get_by_subject + +// X509_STORE_CTX_get_by_subject tries to find an object of a given type, which +// may be |X509_LU_X509| or |X509_LU_CRL|, and the subject name from the store +// in |vs|. If found and |ret| is not NULL, it increments the reference count +// and stores the object in |ret|. +OPENSSL_EXPORT int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, int type, + X509_NAME *name, + X509_OBJECT *ret); OPENSSL_EXPORT int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret); @@ -4134,11 +4436,6 @@ OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get0_untrusted( X509_STORE_CTX *ctx); OPENSSL_EXPORT void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk); -OPENSSL_EXPORT int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); -OPENSSL_EXPORT int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); -OPENSSL_EXPORT int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, - int def_purpose, int purpose, - int trust); // X509_STORE_CTX_set_flags enables all values in |flags| in |ctx|'s // verification flags. |flags| should be a combination of |X509_V_FLAG_*| @@ -4178,34 +4475,6 @@ OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_CTX_get0_param( OPENSSL_EXPORT void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); -// X509_STORE_CTX_set_default looks up the set of parameters named |name| and -// applies those default verification parameters for |ctx|. As in -// |X509_VERIFY_PARAM_inherit|, only unset parameters are changed. This function -// returns one on success and zero on error. -OPENSSL_EXPORT int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, - const char *name); - -// X509_STORE_get_by_subject is an alias to |X509_STORE_CTX_get_by_subject| in -// OpenSSL 1.1.1. -#define X509_STORE_get_by_subject X509_STORE_CTX_get_by_subject - -// X509_STORE_CTX_get_by_subject tries to find an object of a given type, which -// may be |X509_LU_X509| or |X509_LU_CRL|, and the subject name from the store -// in |vs|. If found and |ret| is not NULL, it increments the reference count -// and stores the object in |ret|. -OPENSSL_EXPORT int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, int type, - X509_NAME *name, - X509_OBJECT *ret); - -// X509_VERIFY_PARAM functions - -// X509_VERIFY_PARAM_new returns a newly-allocated |X509_VERIFY_PARAM|, or NULL -// on error. -OPENSSL_EXPORT X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); - -// X509_VERIFY_PARAM_free releases memory associated with |param|. -OPENSSL_EXPORT void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); - // X509_VERIFY_PARAM_inherit applies |from| as the default values for |to|. That // is, for each parameter that is unset in |to|, it copies the value in |from|. // This function returns one on success and zero on error. @@ -4234,11 +4503,6 @@ OPENSSL_EXPORT int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, OPENSSL_EXPORT unsigned long X509_VERIFY_PARAM_get_flags( const X509_VERIFY_PARAM *param); -OPENSSL_EXPORT int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, - int purpose); -OPENSSL_EXPORT int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, - int trust); - // X509_VERIFY_PARAM_set_depth configures |param| to limit certificate chains to // |depth| intermediate certificates. This count excludes both the target // certificate and the trust anchor (root certificate). @@ -4541,16 +4805,6 @@ typedef struct x509_purpose_st { void *usr_data; } X509_PURPOSE; -#define X509_PURPOSE_SSL_CLIENT 1 -#define X509_PURPOSE_SSL_SERVER 2 -#define X509_PURPOSE_NS_SSL_SERVER 3 -#define X509_PURPOSE_SMIME_SIGN 4 -#define X509_PURPOSE_SMIME_ENCRYPT 5 -#define X509_PURPOSE_CRL_SIGN 6 -#define X509_PURPOSE_ANY 7 -#define X509_PURPOSE_OCSP_HELPER 8 -#define X509_PURPOSE_TIMESTAMP_SIGN 9 - DEFINE_STACK_OF(X509_PURPOSE) DECLARE_ASN1_FUNCTIONS_const(BASIC_CONSTRAINTS) @@ -4771,8 +5025,6 @@ OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, OPENSSL_EXPORT int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags); -OPENSSL_EXPORT int X509_check_purpose(X509 *x, int id, int ca); - OPENSSL_EXPORT int X509_PURPOSE_set(int *p, int purpose); OPENSSL_EXPORT int X509_PURPOSE_get_count(void); diff --git a/util/fipstools/delocate/delocate.peg b/util/fipstools/delocate/delocate.peg index f57380f0b3..45984d67d1 100644 --- a/util/fipstools/delocate/delocate.peg +++ b/util/fipstools/delocate/delocate.peg @@ -86,9 +86,12 @@ RegisterOrConstant <- (('%'[[A-Z]][[A-Z0-9]]*) / ('$(-' [0-9]+ ')') / ARMRegister) ![fb:(+\-] -ARMConstantTweak <- (([us] "xt" [xwhb]) / "lsl" / "lsr" / "ror" / "asr") (WS '#'? Offset)? -ARMRegister <- "sp" / ([xwdqshb] [0-9] [0-9]?) / "xzr" / "wzr" / "NZCV" / ARMVectorRegister / ('{' WS? ARMVectorRegister WS? ([,\-] WS? ARMVectorRegister)* WS? '}' ('[' [0-9] [0-9]? ']')? ) -ARMVectorRegister <- "v" [0-9] [0-9]? ('.' [0-9]* [bsdhq] ('[' [0-9] [0-9]? ']')? )? +ARMConstantTweak <- ((([us] "xt" [xwhb]) / "lsl" / "lsr" / "ror" / "asr") (WS '#'? Offset)?)/ + "mul vl" # multiply offset by the hardware's vector length +ARMRegister <- "sp" / ([xwdqshb] [0-9] [0-9]?) / "xzr" / "wzr" / "NZCV" / ARMVectorRegister / SVE2PredicateRegister / + ('{' WS? ARMVectorRegister WS? ([,\-] WS? ARMVectorRegister)* WS? '}' ('[' [0-9] [0-9]? ']')? ) +ARMVectorRegister <- [vz] [0-9] [0-9]? ('.' [0-9]* [bsdhq] ('[' [0-9] [0-9]? ']')? )? +SVE2PredicateRegister <- "p" [0-9] [0-9]? "/" [mMzZ] # Compilers only output a very limited number of expression forms. Rather than # implement a full expression parser, this enumerate those forms plus a few # that appear in our hand-written assembly. diff --git a/util/fipstools/delocate/delocate.peg.go b/util/fipstools/delocate/delocate.peg.go index 9d07100bb6..f20936ea08 100644 --- a/util/fipstools/delocate/delocate.peg.go +++ b/util/fipstools/delocate/delocate.peg.go @@ -1,6 +1,6 @@ package main -// Code generated by /var/folders/1x/_423tbkn7k7c4jxmd4tnnj_r0000gr/T/go-build804476870/b001/exe/peg delocate.peg DO NOT EDIT. +// Code generated by /Users/smittals/go/bin/peg /Users/smittals/Desktop/aws-lc/util/fipstools/delocate/delocate.peg DO NOT EDIT. import ( "fmt" @@ -64,6 +64,7 @@ const ( ruleARMConstantTweak ruleARMRegister ruleARMVectorRegister + ruleSVE2PredicateRegister ruleMemoryRef ruleSymbolRef ruleLow12BitsSymbolRef @@ -126,6 +127,7 @@ var rul3s = [...]string{ "ARMConstantTweak", "ARMRegister", "ARMVectorRegister", + "SVE2PredicateRegister", "MemoryRef", "SymbolRef", "Low12BitsSymbolRef", @@ -252,7 +254,7 @@ func (t *tokens32) Tokens() []token32 { type Asm struct { Buffer string buffer []rune - rules [59]func() bool + rules [60]func() bool parse func(rule ...int) error reset func() Pretty bool @@ -5067,7 +5069,7 @@ func (p *Asm) Init(options ...func(*Asm) error) error { position, tokenIndex = position551, tokenIndex551 return false }, - /* 43 ARMConstantTweak <- <(((('u' / 's') (('x' / 'X') ('t' / 'T')) ('x' / 'w' / 'h' / 'b')) / (('l' / 'L') ('s' / 'S') ('l' / 'L')) / (('l' / 'L') ('s' / 'S') ('r' / 'R')) / (('r' / 'R') ('o' / 'O') ('r' / 'R')) / (('a' / 'A') ('s' / 'S') ('r' / 'R'))) (WS '#'? Offset)?)> */ + /* 43 ARMConstantTweak <- <((((('u' / 's') (('x' / 'X') ('t' / 'T')) ('x' / 'w' / 'h' / 'b')) / (('l' / 'L') ('s' / 'S') ('l' / 'L')) / (('l' / 'L') ('s' / 'S') ('r' / 'R')) / (('r' / 'R') ('o' / 'O') ('r' / 'R')) / (('a' / 'A') ('s' / 'S') ('r' / 'R'))) (WS '#'? Offset)?) / (('m' / 'M') ('u' / 'U') ('l' / 'L') ' ' ('v' / 'V') ('l' / 'L')))> */ func() bool { position631, tokenIndex631 := position, tokenIndex { @@ -5076,296 +5078,382 @@ func (p *Asm) Init(options ...func(*Asm) error) error { position633, tokenIndex633 := position, tokenIndex { position635, tokenIndex635 := position, tokenIndex - if buffer[position] != rune('u') { - goto l636 - } - position++ - goto l635 - l636: - position, tokenIndex = position635, tokenIndex635 - if buffer[position] != rune('s') { - goto l634 - } - position++ - } - l635: - { - position637, tokenIndex637 := position, tokenIndex - if buffer[position] != rune('x') { - goto l638 - } - position++ - goto l637 - l638: - position, tokenIndex = position637, tokenIndex637 - if buffer[position] != rune('X') { - goto l634 - } - position++ - } - l637: - { - position639, tokenIndex639 := position, tokenIndex - if buffer[position] != rune('t') { - goto l640 + { + position637, tokenIndex637 := position, tokenIndex + if buffer[position] != rune('u') { + goto l638 + } + position++ + goto l637 + l638: + position, tokenIndex = position637, tokenIndex637 + if buffer[position] != rune('s') { + goto l636 + } + position++ } - position++ - goto l639 - l640: - position, tokenIndex = position639, tokenIndex639 - if buffer[position] != rune('T') { - goto l634 + l637: + { + position639, tokenIndex639 := position, tokenIndex + if buffer[position] != rune('x') { + goto l640 + } + position++ + goto l639 + l640: + position, tokenIndex = position639, tokenIndex639 + if buffer[position] != rune('X') { + goto l636 + } + position++ } - position++ - } - l639: - { - position641, tokenIndex641 := position, tokenIndex - if buffer[position] != rune('x') { - goto l642 + l639: + { + position641, tokenIndex641 := position, tokenIndex + if buffer[position] != rune('t') { + goto l642 + } + position++ + goto l641 + l642: + position, tokenIndex = position641, tokenIndex641 + if buffer[position] != rune('T') { + goto l636 + } + position++ } - position++ - goto l641 - l642: - position, tokenIndex = position641, tokenIndex641 - if buffer[position] != rune('w') { + l641: + { + position643, tokenIndex643 := position, tokenIndex + if buffer[position] != rune('x') { + goto l644 + } + position++ + goto l643 + l644: + position, tokenIndex = position643, tokenIndex643 + if buffer[position] != rune('w') { + goto l645 + } + position++ + goto l643 + l645: + position, tokenIndex = position643, tokenIndex643 + if buffer[position] != rune('h') { + goto l646 + } + position++ goto l643 + l646: + position, tokenIndex = position643, tokenIndex643 + if buffer[position] != rune('b') { + goto l636 + } + position++ } - position++ - goto l641 l643: - position, tokenIndex = position641, tokenIndex641 - if buffer[position] != rune('h') { - goto l644 + goto l635 + l636: + position, tokenIndex = position635, tokenIndex635 + { + position648, tokenIndex648 := position, tokenIndex + if buffer[position] != rune('l') { + goto l649 + } + position++ + goto l648 + l649: + position, tokenIndex = position648, tokenIndex648 + if buffer[position] != rune('L') { + goto l647 + } + position++ } - position++ - goto l641 - l644: - position, tokenIndex = position641, tokenIndex641 - if buffer[position] != rune('b') { - goto l634 + l648: + { + position650, tokenIndex650 := position, tokenIndex + if buffer[position] != rune('s') { + goto l651 + } + position++ + goto l650 + l651: + position, tokenIndex = position650, tokenIndex650 + if buffer[position] != rune('S') { + goto l647 + } + position++ } - position++ - } - l641: - goto l633 - l634: - position, tokenIndex = position633, tokenIndex633 - { - position646, tokenIndex646 := position, tokenIndex - if buffer[position] != rune('l') { - goto l647 + l650: + { + position652, tokenIndex652 := position, tokenIndex + if buffer[position] != rune('l') { + goto l653 + } + position++ + goto l652 + l653: + position, tokenIndex = position652, tokenIndex652 + if buffer[position] != rune('L') { + goto l647 + } + position++ } - position++ - goto l646 + l652: + goto l635 l647: - position, tokenIndex = position646, tokenIndex646 - if buffer[position] != rune('L') { - goto l645 + position, tokenIndex = position635, tokenIndex635 + { + position655, tokenIndex655 := position, tokenIndex + if buffer[position] != rune('l') { + goto l656 + } + position++ + goto l655 + l656: + position, tokenIndex = position655, tokenIndex655 + if buffer[position] != rune('L') { + goto l654 + } + position++ } - position++ - } - l646: - { - position648, tokenIndex648 := position, tokenIndex - if buffer[position] != rune('s') { - goto l649 + l655: + { + position657, tokenIndex657 := position, tokenIndex + if buffer[position] != rune('s') { + goto l658 + } + position++ + goto l657 + l658: + position, tokenIndex = position657, tokenIndex657 + if buffer[position] != rune('S') { + goto l654 + } + position++ } - position++ - goto l648 - l649: - position, tokenIndex = position648, tokenIndex648 - if buffer[position] != rune('S') { - goto l645 + l657: + { + position659, tokenIndex659 := position, tokenIndex + if buffer[position] != rune('r') { + goto l660 + } + position++ + goto l659 + l660: + position, tokenIndex = position659, tokenIndex659 + if buffer[position] != rune('R') { + goto l654 + } + position++ } - position++ - } - l648: - { - position650, tokenIndex650 := position, tokenIndex - if buffer[position] != rune('l') { - goto l651 + l659: + goto l635 + l654: + position, tokenIndex = position635, tokenIndex635 + { + position662, tokenIndex662 := position, tokenIndex + if buffer[position] != rune('r') { + goto l663 + } + position++ + goto l662 + l663: + position, tokenIndex = position662, tokenIndex662 + if buffer[position] != rune('R') { + goto l661 + } + position++ } - position++ - goto l650 - l651: - position, tokenIndex = position650, tokenIndex650 - if buffer[position] != rune('L') { - goto l645 + l662: + { + position664, tokenIndex664 := position, tokenIndex + if buffer[position] != rune('o') { + goto l665 + } + position++ + goto l664 + l665: + position, tokenIndex = position664, tokenIndex664 + if buffer[position] != rune('O') { + goto l661 + } + position++ } - position++ - } - l650: - goto l633 - l645: - position, tokenIndex = position633, tokenIndex633 - { - position653, tokenIndex653 := position, tokenIndex - if buffer[position] != rune('l') { - goto l654 + l664: + { + position666, tokenIndex666 := position, tokenIndex + if buffer[position] != rune('r') { + goto l667 + } + position++ + goto l666 + l667: + position, tokenIndex = position666, tokenIndex666 + if buffer[position] != rune('R') { + goto l661 + } + position++ } - position++ - goto l653 - l654: - position, tokenIndex = position653, tokenIndex653 - if buffer[position] != rune('L') { - goto l652 + l666: + goto l635 + l661: + position, tokenIndex = position635, tokenIndex635 + { + position668, tokenIndex668 := position, tokenIndex + if buffer[position] != rune('a') { + goto l669 + } + position++ + goto l668 + l669: + position, tokenIndex = position668, tokenIndex668 + if buffer[position] != rune('A') { + goto l634 + } + position++ } - position++ - } - l653: - { - position655, tokenIndex655 := position, tokenIndex - if buffer[position] != rune('s') { - goto l656 + l668: + { + position670, tokenIndex670 := position, tokenIndex + if buffer[position] != rune('s') { + goto l671 + } + position++ + goto l670 + l671: + position, tokenIndex = position670, tokenIndex670 + if buffer[position] != rune('S') { + goto l634 + } + position++ } - position++ - goto l655 - l656: - position, tokenIndex = position655, tokenIndex655 - if buffer[position] != rune('S') { - goto l652 + l670: + { + position672, tokenIndex672 := position, tokenIndex + if buffer[position] != rune('r') { + goto l673 + } + position++ + goto l672 + l673: + position, tokenIndex = position672, tokenIndex672 + if buffer[position] != rune('R') { + goto l634 + } + position++ } - position++ + l672: } - l655: + l635: { - position657, tokenIndex657 := position, tokenIndex - if buffer[position] != rune('r') { - goto l658 + position674, tokenIndex674 := position, tokenIndex + if !_rules[ruleWS]() { + goto l674 } - position++ - goto l657 - l658: - position, tokenIndex = position657, tokenIndex657 - if buffer[position] != rune('R') { - goto l652 + { + position676, tokenIndex676 := position, tokenIndex + if buffer[position] != rune('#') { + goto l676 + } + position++ + goto l677 + l676: + position, tokenIndex = position676, tokenIndex676 } - position++ + l677: + if !_rules[ruleOffset]() { + goto l674 + } + goto l675 + l674: + position, tokenIndex = position674, tokenIndex674 } - l657: + l675: goto l633 - l652: + l634: position, tokenIndex = position633, tokenIndex633 { - position660, tokenIndex660 := position, tokenIndex - if buffer[position] != rune('r') { - goto l661 - } - position++ - goto l660 - l661: - position, tokenIndex = position660, tokenIndex660 - if buffer[position] != rune('R') { - goto l659 - } - position++ - } - l660: - { - position662, tokenIndex662 := position, tokenIndex - if buffer[position] != rune('o') { - goto l663 + position678, tokenIndex678 := position, tokenIndex + if buffer[position] != rune('m') { + goto l679 } position++ - goto l662 - l663: - position, tokenIndex = position662, tokenIndex662 - if buffer[position] != rune('O') { - goto l659 + goto l678 + l679: + position, tokenIndex = position678, tokenIndex678 + if buffer[position] != rune('M') { + goto l631 } position++ } - l662: + l678: { - position664, tokenIndex664 := position, tokenIndex - if buffer[position] != rune('r') { - goto l665 + position680, tokenIndex680 := position, tokenIndex + if buffer[position] != rune('u') { + goto l681 } position++ - goto l664 - l665: - position, tokenIndex = position664, tokenIndex664 - if buffer[position] != rune('R') { - goto l659 + goto l680 + l681: + position, tokenIndex = position680, tokenIndex680 + if buffer[position] != rune('U') { + goto l631 } position++ } - l664: - goto l633 - l659: - position, tokenIndex = position633, tokenIndex633 + l680: { - position666, tokenIndex666 := position, tokenIndex - if buffer[position] != rune('a') { - goto l667 + position682, tokenIndex682 := position, tokenIndex + if buffer[position] != rune('l') { + goto l683 } position++ - goto l666 - l667: - position, tokenIndex = position666, tokenIndex666 - if buffer[position] != rune('A') { + goto l682 + l683: + position, tokenIndex = position682, tokenIndex682 + if buffer[position] != rune('L') { goto l631 } position++ } - l666: + l682: + if buffer[position] != rune(' ') { + goto l631 + } + position++ { - position668, tokenIndex668 := position, tokenIndex - if buffer[position] != rune('s') { - goto l669 + position684, tokenIndex684 := position, tokenIndex + if buffer[position] != rune('v') { + goto l685 } position++ - goto l668 - l669: - position, tokenIndex = position668, tokenIndex668 - if buffer[position] != rune('S') { + goto l684 + l685: + position, tokenIndex = position684, tokenIndex684 + if buffer[position] != rune('V') { goto l631 } position++ } - l668: + l684: { - position670, tokenIndex670 := position, tokenIndex - if buffer[position] != rune('r') { - goto l671 + position686, tokenIndex686 := position, tokenIndex + if buffer[position] != rune('l') { + goto l687 } position++ - goto l670 - l671: - position, tokenIndex = position670, tokenIndex670 - if buffer[position] != rune('R') { + goto l686 + l687: + position, tokenIndex = position686, tokenIndex686 + if buffer[position] != rune('L') { goto l631 } position++ } - l670: + l686: } l633: - { - position672, tokenIndex672 := position, tokenIndex - if !_rules[ruleWS]() { - goto l672 - } - { - position674, tokenIndex674 := position, tokenIndex - if buffer[position] != rune('#') { - goto l674 - } - position++ - goto l675 - l674: - position, tokenIndex = position674, tokenIndex674 - } - l675: - if !_rules[ruleOffset]() { - goto l672 - } - goto l673 - l672: - position, tokenIndex = position672, tokenIndex672 - } - l673: add(ruleARMConstantTweak, position632) } return true @@ -5373,2191 +5461,2272 @@ func (p *Asm) Init(options ...func(*Asm) error) error { position, tokenIndex = position631, tokenIndex631 return false }, - /* 44 ARMRegister <- <((('s' / 'S') ('p' / 'P')) / (('x' / 'w' / 'd' / 'q' / 's' / 'h' / 'b') [0-9] [0-9]?) / (('x' / 'X') ('z' / 'Z') ('r' / 'R')) / (('w' / 'W') ('z' / 'Z') ('r' / 'R')) / (('n' / 'N') ('z' / 'Z') ('c' / 'C') ('v' / 'V')) / ARMVectorRegister / ('{' WS? ARMVectorRegister WS? ((',' / '-') WS? ARMVectorRegister)* WS? '}' ('[' [0-9] [0-9]? ']')?))> */ + /* 44 ARMRegister <- <((('s' / 'S') ('p' / 'P')) / (('x' / 'w' / 'd' / 'q' / 's' / 'h' / 'b') [0-9] [0-9]?) / (('x' / 'X') ('z' / 'Z') ('r' / 'R')) / (('w' / 'W') ('z' / 'Z') ('r' / 'R')) / (('n' / 'N') ('z' / 'Z') ('c' / 'C') ('v' / 'V')) / ARMVectorRegister / SVE2PredicateRegister / ('{' WS? ARMVectorRegister WS? ((',' / '-') WS? ARMVectorRegister)* WS? '}' ('[' [0-9] [0-9]? ']')?))> */ func() bool { - position676, tokenIndex676 := position, tokenIndex + position688, tokenIndex688 := position, tokenIndex { - position677 := position + position689 := position { - position678, tokenIndex678 := position, tokenIndex + position690, tokenIndex690 := position, tokenIndex { - position680, tokenIndex680 := position, tokenIndex + position692, tokenIndex692 := position, tokenIndex if buffer[position] != rune('s') { - goto l681 + goto l693 } position++ - goto l680 - l681: - position, tokenIndex = position680, tokenIndex680 + goto l692 + l693: + position, tokenIndex = position692, tokenIndex692 if buffer[position] != rune('S') { - goto l679 + goto l691 } position++ } - l680: + l692: { - position682, tokenIndex682 := position, tokenIndex + position694, tokenIndex694 := position, tokenIndex if buffer[position] != rune('p') { - goto l683 + goto l695 } position++ - goto l682 - l683: - position, tokenIndex = position682, tokenIndex682 + goto l694 + l695: + position, tokenIndex = position694, tokenIndex694 if buffer[position] != rune('P') { - goto l679 + goto l691 } position++ } - l682: - goto l678 - l679: - position, tokenIndex = position678, tokenIndex678 + l694: + goto l690 + l691: + position, tokenIndex = position690, tokenIndex690 { - position685, tokenIndex685 := position, tokenIndex + position697, tokenIndex697 := position, tokenIndex if buffer[position] != rune('x') { - goto l686 + goto l698 } position++ - goto l685 - l686: - position, tokenIndex = position685, tokenIndex685 + goto l697 + l698: + position, tokenIndex = position697, tokenIndex697 if buffer[position] != rune('w') { - goto l687 + goto l699 } position++ - goto l685 - l687: - position, tokenIndex = position685, tokenIndex685 + goto l697 + l699: + position, tokenIndex = position697, tokenIndex697 if buffer[position] != rune('d') { - goto l688 + goto l700 } position++ - goto l685 - l688: - position, tokenIndex = position685, tokenIndex685 + goto l697 + l700: + position, tokenIndex = position697, tokenIndex697 if buffer[position] != rune('q') { - goto l689 + goto l701 } position++ - goto l685 - l689: - position, tokenIndex = position685, tokenIndex685 + goto l697 + l701: + position, tokenIndex = position697, tokenIndex697 if buffer[position] != rune('s') { - goto l690 + goto l702 } position++ - goto l685 - l690: - position, tokenIndex = position685, tokenIndex685 + goto l697 + l702: + position, tokenIndex = position697, tokenIndex697 if buffer[position] != rune('h') { - goto l691 + goto l703 } position++ - goto l685 - l691: - position, tokenIndex = position685, tokenIndex685 + goto l697 + l703: + position, tokenIndex = position697, tokenIndex697 if buffer[position] != rune('b') { - goto l684 + goto l696 } position++ } - l685: + l697: if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l684 + goto l696 } position++ { - position692, tokenIndex692 := position, tokenIndex + position704, tokenIndex704 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l692 + goto l704 } position++ - goto l693 - l692: - position, tokenIndex = position692, tokenIndex692 + goto l705 + l704: + position, tokenIndex = position704, tokenIndex704 } - l693: - goto l678 - l684: - position, tokenIndex = position678, tokenIndex678 + l705: + goto l690 + l696: + position, tokenIndex = position690, tokenIndex690 { - position695, tokenIndex695 := position, tokenIndex + position707, tokenIndex707 := position, tokenIndex if buffer[position] != rune('x') { - goto l696 + goto l708 } position++ - goto l695 - l696: - position, tokenIndex = position695, tokenIndex695 + goto l707 + l708: + position, tokenIndex = position707, tokenIndex707 if buffer[position] != rune('X') { - goto l694 + goto l706 } position++ } - l695: + l707: { - position697, tokenIndex697 := position, tokenIndex + position709, tokenIndex709 := position, tokenIndex if buffer[position] != rune('z') { - goto l698 + goto l710 } position++ - goto l697 - l698: - position, tokenIndex = position697, tokenIndex697 + goto l709 + l710: + position, tokenIndex = position709, tokenIndex709 if buffer[position] != rune('Z') { - goto l694 + goto l706 } position++ } - l697: + l709: { - position699, tokenIndex699 := position, tokenIndex + position711, tokenIndex711 := position, tokenIndex if buffer[position] != rune('r') { - goto l700 + goto l712 } position++ - goto l699 - l700: - position, tokenIndex = position699, tokenIndex699 + goto l711 + l712: + position, tokenIndex = position711, tokenIndex711 if buffer[position] != rune('R') { - goto l694 + goto l706 } position++ } - l699: - goto l678 - l694: - position, tokenIndex = position678, tokenIndex678 + l711: + goto l690 + l706: + position, tokenIndex = position690, tokenIndex690 { - position702, tokenIndex702 := position, tokenIndex + position714, tokenIndex714 := position, tokenIndex if buffer[position] != rune('w') { - goto l703 + goto l715 } position++ - goto l702 - l703: - position, tokenIndex = position702, tokenIndex702 + goto l714 + l715: + position, tokenIndex = position714, tokenIndex714 if buffer[position] != rune('W') { - goto l701 + goto l713 } position++ } - l702: + l714: { - position704, tokenIndex704 := position, tokenIndex + position716, tokenIndex716 := position, tokenIndex if buffer[position] != rune('z') { - goto l705 + goto l717 } position++ - goto l704 - l705: - position, tokenIndex = position704, tokenIndex704 + goto l716 + l717: + position, tokenIndex = position716, tokenIndex716 if buffer[position] != rune('Z') { - goto l701 + goto l713 } position++ } - l704: + l716: { - position706, tokenIndex706 := position, tokenIndex + position718, tokenIndex718 := position, tokenIndex if buffer[position] != rune('r') { - goto l707 + goto l719 } position++ - goto l706 - l707: - position, tokenIndex = position706, tokenIndex706 + goto l718 + l719: + position, tokenIndex = position718, tokenIndex718 if buffer[position] != rune('R') { - goto l701 + goto l713 } position++ } - l706: - goto l678 - l701: - position, tokenIndex = position678, tokenIndex678 + l718: + goto l690 + l713: + position, tokenIndex = position690, tokenIndex690 { - position709, tokenIndex709 := position, tokenIndex + position721, tokenIndex721 := position, tokenIndex if buffer[position] != rune('n') { - goto l710 + goto l722 } position++ - goto l709 - l710: - position, tokenIndex = position709, tokenIndex709 + goto l721 + l722: + position, tokenIndex = position721, tokenIndex721 if buffer[position] != rune('N') { - goto l708 + goto l720 } position++ } - l709: + l721: { - position711, tokenIndex711 := position, tokenIndex + position723, tokenIndex723 := position, tokenIndex if buffer[position] != rune('z') { - goto l712 + goto l724 } position++ - goto l711 - l712: - position, tokenIndex = position711, tokenIndex711 + goto l723 + l724: + position, tokenIndex = position723, tokenIndex723 if buffer[position] != rune('Z') { - goto l708 + goto l720 } position++ } - l711: + l723: { - position713, tokenIndex713 := position, tokenIndex + position725, tokenIndex725 := position, tokenIndex if buffer[position] != rune('c') { - goto l714 + goto l726 } position++ - goto l713 - l714: - position, tokenIndex = position713, tokenIndex713 + goto l725 + l726: + position, tokenIndex = position725, tokenIndex725 if buffer[position] != rune('C') { - goto l708 + goto l720 } position++ } - l713: + l725: { - position715, tokenIndex715 := position, tokenIndex + position727, tokenIndex727 := position, tokenIndex if buffer[position] != rune('v') { - goto l716 + goto l728 } position++ - goto l715 - l716: - position, tokenIndex = position715, tokenIndex715 + goto l727 + l728: + position, tokenIndex = position727, tokenIndex727 if buffer[position] != rune('V') { - goto l708 + goto l720 } position++ } - l715: - goto l678 - l708: - position, tokenIndex = position678, tokenIndex678 + l727: + goto l690 + l720: + position, tokenIndex = position690, tokenIndex690 if !_rules[ruleARMVectorRegister]() { - goto l717 + goto l729 + } + goto l690 + l729: + position, tokenIndex = position690, tokenIndex690 + if !_rules[ruleSVE2PredicateRegister]() { + goto l730 } - goto l678 - l717: - position, tokenIndex = position678, tokenIndex678 + goto l690 + l730: + position, tokenIndex = position690, tokenIndex690 if buffer[position] != rune('{') { - goto l676 + goto l688 } position++ { - position718, tokenIndex718 := position, tokenIndex + position731, tokenIndex731 := position, tokenIndex if !_rules[ruleWS]() { - goto l718 + goto l731 } - goto l719 - l718: - position, tokenIndex = position718, tokenIndex718 + goto l732 + l731: + position, tokenIndex = position731, tokenIndex731 } - l719: + l732: if !_rules[ruleARMVectorRegister]() { - goto l676 + goto l688 } { - position720, tokenIndex720 := position, tokenIndex + position733, tokenIndex733 := position, tokenIndex if !_rules[ruleWS]() { - goto l720 + goto l733 } - goto l721 - l720: - position, tokenIndex = position720, tokenIndex720 + goto l734 + l733: + position, tokenIndex = position733, tokenIndex733 } - l721: - l722: + l734: + l735: { - position723, tokenIndex723 := position, tokenIndex + position736, tokenIndex736 := position, tokenIndex { - position724, tokenIndex724 := position, tokenIndex + position737, tokenIndex737 := position, tokenIndex if buffer[position] != rune(',') { - goto l725 + goto l738 } position++ - goto l724 - l725: - position, tokenIndex = position724, tokenIndex724 + goto l737 + l738: + position, tokenIndex = position737, tokenIndex737 if buffer[position] != rune('-') { - goto l723 + goto l736 } position++ } - l724: + l737: { - position726, tokenIndex726 := position, tokenIndex + position739, tokenIndex739 := position, tokenIndex if !_rules[ruleWS]() { - goto l726 + goto l739 } - goto l727 - l726: - position, tokenIndex = position726, tokenIndex726 + goto l740 + l739: + position, tokenIndex = position739, tokenIndex739 } - l727: + l740: if !_rules[ruleARMVectorRegister]() { - goto l723 + goto l736 } - goto l722 - l723: - position, tokenIndex = position723, tokenIndex723 + goto l735 + l736: + position, tokenIndex = position736, tokenIndex736 } { - position728, tokenIndex728 := position, tokenIndex + position741, tokenIndex741 := position, tokenIndex if !_rules[ruleWS]() { - goto l728 + goto l741 } - goto l729 - l728: - position, tokenIndex = position728, tokenIndex728 + goto l742 + l741: + position, tokenIndex = position741, tokenIndex741 } - l729: + l742: if buffer[position] != rune('}') { - goto l676 + goto l688 } position++ { - position730, tokenIndex730 := position, tokenIndex + position743, tokenIndex743 := position, tokenIndex if buffer[position] != rune('[') { - goto l730 + goto l743 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l730 + goto l743 } position++ { - position732, tokenIndex732 := position, tokenIndex + position745, tokenIndex745 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l732 + goto l745 } position++ - goto l733 - l732: - position, tokenIndex = position732, tokenIndex732 + goto l746 + l745: + position, tokenIndex = position745, tokenIndex745 } - l733: + l746: if buffer[position] != rune(']') { - goto l730 + goto l743 } position++ - goto l731 - l730: - position, tokenIndex = position730, tokenIndex730 + goto l744 + l743: + position, tokenIndex = position743, tokenIndex743 } - l731: + l744: } - l678: - add(ruleARMRegister, position677) + l690: + add(ruleARMRegister, position689) } return true - l676: - position, tokenIndex = position676, tokenIndex676 + l688: + position, tokenIndex = position688, tokenIndex688 return false }, - /* 45 ARMVectorRegister <- <(('v' / 'V') [0-9] [0-9]? ('.' [0-9]* ('b' / 's' / 'd' / 'h' / 'q') ('[' [0-9] [0-9]? ']')?)?)> */ + /* 45 ARMVectorRegister <- <(('v' / 'z') [0-9] [0-9]? ('.' [0-9]* ('b' / 's' / 'd' / 'h' / 'q') ('[' [0-9] [0-9]? ']')?)?)> */ func() bool { - position734, tokenIndex734 := position, tokenIndex + position747, tokenIndex747 := position, tokenIndex { - position735 := position + position748 := position { - position736, tokenIndex736 := position, tokenIndex + position749, tokenIndex749 := position, tokenIndex if buffer[position] != rune('v') { - goto l737 + goto l750 } position++ - goto l736 - l737: - position, tokenIndex = position736, tokenIndex736 - if buffer[position] != rune('V') { - goto l734 + goto l749 + l750: + position, tokenIndex = position749, tokenIndex749 + if buffer[position] != rune('z') { + goto l747 } position++ } - l736: + l749: if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l734 + goto l747 } position++ { - position738, tokenIndex738 := position, tokenIndex + position751, tokenIndex751 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l738 + goto l751 } position++ - goto l739 - l738: - position, tokenIndex = position738, tokenIndex738 + goto l752 + l751: + position, tokenIndex = position751, tokenIndex751 } - l739: + l752: { - position740, tokenIndex740 := position, tokenIndex + position753, tokenIndex753 := position, tokenIndex if buffer[position] != rune('.') { - goto l740 + goto l753 } position++ - l742: + l755: { - position743, tokenIndex743 := position, tokenIndex + position756, tokenIndex756 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l743 + goto l756 } position++ - goto l742 - l743: - position, tokenIndex = position743, tokenIndex743 + goto l755 + l756: + position, tokenIndex = position756, tokenIndex756 } { - position744, tokenIndex744 := position, tokenIndex + position757, tokenIndex757 := position, tokenIndex if buffer[position] != rune('b') { - goto l745 + goto l758 } position++ - goto l744 - l745: - position, tokenIndex = position744, tokenIndex744 + goto l757 + l758: + position, tokenIndex = position757, tokenIndex757 if buffer[position] != rune('s') { - goto l746 + goto l759 } position++ - goto l744 - l746: - position, tokenIndex = position744, tokenIndex744 + goto l757 + l759: + position, tokenIndex = position757, tokenIndex757 if buffer[position] != rune('d') { - goto l747 + goto l760 } position++ - goto l744 - l747: - position, tokenIndex = position744, tokenIndex744 + goto l757 + l760: + position, tokenIndex = position757, tokenIndex757 if buffer[position] != rune('h') { - goto l748 + goto l761 } position++ - goto l744 - l748: - position, tokenIndex = position744, tokenIndex744 + goto l757 + l761: + position, tokenIndex = position757, tokenIndex757 if buffer[position] != rune('q') { - goto l740 + goto l753 } position++ } - l744: + l757: { - position749, tokenIndex749 := position, tokenIndex + position762, tokenIndex762 := position, tokenIndex if buffer[position] != rune('[') { - goto l749 + goto l762 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l749 + goto l762 } position++ { - position751, tokenIndex751 := position, tokenIndex + position764, tokenIndex764 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l751 + goto l764 } position++ - goto l752 - l751: - position, tokenIndex = position751, tokenIndex751 + goto l765 + l764: + position, tokenIndex = position764, tokenIndex764 } - l752: + l765: if buffer[position] != rune(']') { - goto l749 + goto l762 } position++ - goto l750 - l749: - position, tokenIndex = position749, tokenIndex749 + goto l763 + l762: + position, tokenIndex = position762, tokenIndex762 } - l750: - goto l741 - l740: - position, tokenIndex = position740, tokenIndex740 + l763: + goto l754 + l753: + position, tokenIndex = position753, tokenIndex753 + } + l754: + add(ruleARMVectorRegister, position748) + } + return true + l747: + position, tokenIndex = position747, tokenIndex747 + return false + }, + /* 46 SVE2PredicateRegister <- <(('p' / 'P') [0-9] [0-9]? '/' ('m' / 'M' / 'z' / 'Z'))> */ + func() bool { + position766, tokenIndex766 := position, tokenIndex + { + position767 := position + { + position768, tokenIndex768 := position, tokenIndex + if buffer[position] != rune('p') { + goto l769 + } + position++ + goto l768 + l769: + position, tokenIndex = position768, tokenIndex768 + if buffer[position] != rune('P') { + goto l766 + } + position++ + } + l768: + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l766 + } + position++ + { + position770, tokenIndex770 := position, tokenIndex + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l770 + } + position++ + goto l771 + l770: + position, tokenIndex = position770, tokenIndex770 + } + l771: + if buffer[position] != rune('/') { + goto l766 + } + position++ + { + position772, tokenIndex772 := position, tokenIndex + if buffer[position] != rune('m') { + goto l773 + } + position++ + goto l772 + l773: + position, tokenIndex = position772, tokenIndex772 + if buffer[position] != rune('M') { + goto l774 + } + position++ + goto l772 + l774: + position, tokenIndex = position772, tokenIndex772 + if buffer[position] != rune('z') { + goto l775 + } + position++ + goto l772 + l775: + position, tokenIndex = position772, tokenIndex772 + if buffer[position] != rune('Z') { + goto l766 + } + position++ } - l741: - add(ruleARMVectorRegister, position735) + l772: + add(ruleSVE2PredicateRegister, position767) } return true - l734: - position, tokenIndex = position734, tokenIndex734 + l766: + position, tokenIndex = position766, tokenIndex766 return false }, - /* 46 MemoryRef <- <((SymbolRef BaseIndexScale) / SymbolRef / Low12BitsSymbolRef / (Offset* BaseIndexScale) / (SegmentRegister Offset BaseIndexScale) / (SegmentRegister BaseIndexScale) / (SegmentRegister Offset) / ARMBaseIndexScale / BaseIndexScale)> */ + /* 47 MemoryRef <- <((SymbolRef BaseIndexScale) / SymbolRef / Low12BitsSymbolRef / (Offset* BaseIndexScale) / (SegmentRegister Offset BaseIndexScale) / (SegmentRegister BaseIndexScale) / (SegmentRegister Offset) / ARMBaseIndexScale / BaseIndexScale)> */ func() bool { - position753, tokenIndex753 := position, tokenIndex + position776, tokenIndex776 := position, tokenIndex { - position754 := position + position777 := position { - position755, tokenIndex755 := position, tokenIndex + position778, tokenIndex778 := position, tokenIndex if !_rules[ruleSymbolRef]() { - goto l756 + goto l779 } if !_rules[ruleBaseIndexScale]() { - goto l756 + goto l779 } - goto l755 - l756: - position, tokenIndex = position755, tokenIndex755 + goto l778 + l779: + position, tokenIndex = position778, tokenIndex778 if !_rules[ruleSymbolRef]() { - goto l757 + goto l780 } - goto l755 - l757: - position, tokenIndex = position755, tokenIndex755 + goto l778 + l780: + position, tokenIndex = position778, tokenIndex778 if !_rules[ruleLow12BitsSymbolRef]() { - goto l758 + goto l781 } - goto l755 - l758: - position, tokenIndex = position755, tokenIndex755 - l760: + goto l778 + l781: + position, tokenIndex = position778, tokenIndex778 + l783: { - position761, tokenIndex761 := position, tokenIndex + position784, tokenIndex784 := position, tokenIndex if !_rules[ruleOffset]() { - goto l761 + goto l784 } - goto l760 - l761: - position, tokenIndex = position761, tokenIndex761 + goto l783 + l784: + position, tokenIndex = position784, tokenIndex784 } if !_rules[ruleBaseIndexScale]() { - goto l759 + goto l782 } - goto l755 - l759: - position, tokenIndex = position755, tokenIndex755 + goto l778 + l782: + position, tokenIndex = position778, tokenIndex778 if !_rules[ruleSegmentRegister]() { - goto l762 + goto l785 } if !_rules[ruleOffset]() { - goto l762 + goto l785 } if !_rules[ruleBaseIndexScale]() { - goto l762 + goto l785 } - goto l755 - l762: - position, tokenIndex = position755, tokenIndex755 + goto l778 + l785: + position, tokenIndex = position778, tokenIndex778 if !_rules[ruleSegmentRegister]() { - goto l763 + goto l786 } if !_rules[ruleBaseIndexScale]() { - goto l763 + goto l786 } - goto l755 - l763: - position, tokenIndex = position755, tokenIndex755 + goto l778 + l786: + position, tokenIndex = position778, tokenIndex778 if !_rules[ruleSegmentRegister]() { - goto l764 + goto l787 } if !_rules[ruleOffset]() { - goto l764 + goto l787 } - goto l755 - l764: - position, tokenIndex = position755, tokenIndex755 + goto l778 + l787: + position, tokenIndex = position778, tokenIndex778 if !_rules[ruleARMBaseIndexScale]() { - goto l765 + goto l788 } - goto l755 - l765: - position, tokenIndex = position755, tokenIndex755 + goto l778 + l788: + position, tokenIndex = position778, tokenIndex778 if !_rules[ruleBaseIndexScale]() { - goto l753 + goto l776 } } - l755: - add(ruleMemoryRef, position754) + l778: + add(ruleMemoryRef, position777) } return true - l753: - position, tokenIndex = position753, tokenIndex753 + l776: + position, tokenIndex = position776, tokenIndex776 return false }, - /* 47 SymbolRef <- <((Offset* '+')? (LocalSymbol / SymbolName) Offset* ('@' Section Offset*)?)> */ + /* 48 SymbolRef <- <((Offset* '+')? (LocalSymbol / SymbolName) Offset* ('@' Section Offset*)?)> */ func() bool { - position766, tokenIndex766 := position, tokenIndex + position789, tokenIndex789 := position, tokenIndex { - position767 := position + position790 := position { - position768, tokenIndex768 := position, tokenIndex - l770: + position791, tokenIndex791 := position, tokenIndex + l793: { - position771, tokenIndex771 := position, tokenIndex + position794, tokenIndex794 := position, tokenIndex if !_rules[ruleOffset]() { - goto l771 + goto l794 } - goto l770 - l771: - position, tokenIndex = position771, tokenIndex771 + goto l793 + l794: + position, tokenIndex = position794, tokenIndex794 } if buffer[position] != rune('+') { - goto l768 + goto l791 } position++ - goto l769 - l768: - position, tokenIndex = position768, tokenIndex768 + goto l792 + l791: + position, tokenIndex = position791, tokenIndex791 } - l769: + l792: { - position772, tokenIndex772 := position, tokenIndex + position795, tokenIndex795 := position, tokenIndex if !_rules[ruleLocalSymbol]() { - goto l773 + goto l796 } - goto l772 - l773: - position, tokenIndex = position772, tokenIndex772 + goto l795 + l796: + position, tokenIndex = position795, tokenIndex795 if !_rules[ruleSymbolName]() { - goto l766 + goto l789 } } - l772: - l774: + l795: + l797: { - position775, tokenIndex775 := position, tokenIndex + position798, tokenIndex798 := position, tokenIndex if !_rules[ruleOffset]() { - goto l775 + goto l798 } - goto l774 - l775: - position, tokenIndex = position775, tokenIndex775 + goto l797 + l798: + position, tokenIndex = position798, tokenIndex798 } { - position776, tokenIndex776 := position, tokenIndex + position799, tokenIndex799 := position, tokenIndex if buffer[position] != rune('@') { - goto l776 + goto l799 } position++ if !_rules[ruleSection]() { - goto l776 + goto l799 } - l778: + l801: { - position779, tokenIndex779 := position, tokenIndex + position802, tokenIndex802 := position, tokenIndex if !_rules[ruleOffset]() { - goto l779 + goto l802 } - goto l778 - l779: - position, tokenIndex = position779, tokenIndex779 + goto l801 + l802: + position, tokenIndex = position802, tokenIndex802 } - goto l777 - l776: - position, tokenIndex = position776, tokenIndex776 + goto l800 + l799: + position, tokenIndex = position799, tokenIndex799 } - l777: - add(ruleSymbolRef, position767) + l800: + add(ruleSymbolRef, position790) } return true - l766: - position, tokenIndex = position766, tokenIndex766 + l789: + position, tokenIndex = position789, tokenIndex789 return false }, - /* 48 Low12BitsSymbolRef <- <(':' ('l' / 'L') ('o' / 'O') '1' '2' ':' (LocalSymbol / SymbolName) Offset?)> */ + /* 49 Low12BitsSymbolRef <- <(':' ('l' / 'L') ('o' / 'O') '1' '2' ':' (LocalSymbol / SymbolName) Offset?)> */ func() bool { - position780, tokenIndex780 := position, tokenIndex + position803, tokenIndex803 := position, tokenIndex { - position781 := position + position804 := position if buffer[position] != rune(':') { - goto l780 + goto l803 } position++ { - position782, tokenIndex782 := position, tokenIndex + position805, tokenIndex805 := position, tokenIndex if buffer[position] != rune('l') { - goto l783 + goto l806 } position++ - goto l782 - l783: - position, tokenIndex = position782, tokenIndex782 + goto l805 + l806: + position, tokenIndex = position805, tokenIndex805 if buffer[position] != rune('L') { - goto l780 + goto l803 } position++ } - l782: + l805: { - position784, tokenIndex784 := position, tokenIndex + position807, tokenIndex807 := position, tokenIndex if buffer[position] != rune('o') { - goto l785 + goto l808 } position++ - goto l784 - l785: - position, tokenIndex = position784, tokenIndex784 + goto l807 + l808: + position, tokenIndex = position807, tokenIndex807 if buffer[position] != rune('O') { - goto l780 + goto l803 } position++ } - l784: + l807: if buffer[position] != rune('1') { - goto l780 + goto l803 } position++ if buffer[position] != rune('2') { - goto l780 + goto l803 } position++ if buffer[position] != rune(':') { - goto l780 + goto l803 } position++ { - position786, tokenIndex786 := position, tokenIndex + position809, tokenIndex809 := position, tokenIndex if !_rules[ruleLocalSymbol]() { - goto l787 + goto l810 } - goto l786 - l787: - position, tokenIndex = position786, tokenIndex786 + goto l809 + l810: + position, tokenIndex = position809, tokenIndex809 if !_rules[ruleSymbolName]() { - goto l780 + goto l803 } } - l786: + l809: { - position788, tokenIndex788 := position, tokenIndex + position811, tokenIndex811 := position, tokenIndex if !_rules[ruleOffset]() { - goto l788 + goto l811 } - goto l789 - l788: - position, tokenIndex = position788, tokenIndex788 + goto l812 + l811: + position, tokenIndex = position811, tokenIndex811 } - l789: - add(ruleLow12BitsSymbolRef, position781) + l812: + add(ruleLow12BitsSymbolRef, position804) } return true - l780: - position, tokenIndex = position780, tokenIndex780 + l803: + position, tokenIndex = position803, tokenIndex803 return false }, - /* 49 ARMBaseIndexScale <- <('[' ARMRegister (',' WS? (('#'? Offset (('*' [0-9]+) / ('*' '(' [0-9]+ Operator [0-9]+ ')') / ('+' [0-9]+)*)?) / ('#'? ARMGOTLow12) / ('#'? Low12BitsSymbolRef) / ARMRegister) (',' WS? ARMConstantTweak)?)? ']' ARMPostincrement?)> */ + /* 50 ARMBaseIndexScale <- <('[' ARMRegister (',' WS? (('#'? Offset (('*' [0-9]+) / ('*' '(' [0-9]+ Operator [0-9]+ ')') / ('+' [0-9]+)*)?) / ('#'? ARMGOTLow12) / ('#'? Low12BitsSymbolRef) / ARMRegister) (',' WS? ARMConstantTweak)?)? ']' ARMPostincrement?)> */ func() bool { - position790, tokenIndex790 := position, tokenIndex + position813, tokenIndex813 := position, tokenIndex { - position791 := position + position814 := position if buffer[position] != rune('[') { - goto l790 + goto l813 } position++ if !_rules[ruleARMRegister]() { - goto l790 + goto l813 } { - position792, tokenIndex792 := position, tokenIndex + position815, tokenIndex815 := position, tokenIndex if buffer[position] != rune(',') { - goto l792 + goto l815 } position++ { - position794, tokenIndex794 := position, tokenIndex + position817, tokenIndex817 := position, tokenIndex if !_rules[ruleWS]() { - goto l794 + goto l817 } - goto l795 - l794: - position, tokenIndex = position794, tokenIndex794 + goto l818 + l817: + position, tokenIndex = position817, tokenIndex817 } - l795: + l818: { - position796, tokenIndex796 := position, tokenIndex + position819, tokenIndex819 := position, tokenIndex { - position798, tokenIndex798 := position, tokenIndex + position821, tokenIndex821 := position, tokenIndex if buffer[position] != rune('#') { - goto l798 + goto l821 } position++ - goto l799 - l798: - position, tokenIndex = position798, tokenIndex798 + goto l822 + l821: + position, tokenIndex = position821, tokenIndex821 } - l799: + l822: if !_rules[ruleOffset]() { - goto l797 + goto l820 } { - position800, tokenIndex800 := position, tokenIndex + position823, tokenIndex823 := position, tokenIndex { - position802, tokenIndex802 := position, tokenIndex + position825, tokenIndex825 := position, tokenIndex if buffer[position] != rune('*') { - goto l803 + goto l826 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l803 + goto l826 } position++ - l804: + l827: { - position805, tokenIndex805 := position, tokenIndex + position828, tokenIndex828 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l805 + goto l828 } position++ - goto l804 - l805: - position, tokenIndex = position805, tokenIndex805 + goto l827 + l828: + position, tokenIndex = position828, tokenIndex828 } - goto l802 - l803: - position, tokenIndex = position802, tokenIndex802 + goto l825 + l826: + position, tokenIndex = position825, tokenIndex825 if buffer[position] != rune('*') { - goto l806 + goto l829 } position++ if buffer[position] != rune('(') { - goto l806 + goto l829 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l806 + goto l829 } position++ - l807: + l830: { - position808, tokenIndex808 := position, tokenIndex + position831, tokenIndex831 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l808 + goto l831 } position++ - goto l807 - l808: - position, tokenIndex = position808, tokenIndex808 + goto l830 + l831: + position, tokenIndex = position831, tokenIndex831 } if !_rules[ruleOperator]() { - goto l806 + goto l829 } if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l806 + goto l829 } position++ - l809: + l832: { - position810, tokenIndex810 := position, tokenIndex + position833, tokenIndex833 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l810 + goto l833 } position++ - goto l809 - l810: - position, tokenIndex = position810, tokenIndex810 + goto l832 + l833: + position, tokenIndex = position833, tokenIndex833 } if buffer[position] != rune(')') { - goto l806 + goto l829 } position++ - goto l802 - l806: - position, tokenIndex = position802, tokenIndex802 - l811: + goto l825 + l829: + position, tokenIndex = position825, tokenIndex825 + l834: { - position812, tokenIndex812 := position, tokenIndex + position835, tokenIndex835 := position, tokenIndex if buffer[position] != rune('+') { - goto l812 + goto l835 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l812 + goto l835 } position++ - l813: + l836: { - position814, tokenIndex814 := position, tokenIndex + position837, tokenIndex837 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l814 + goto l837 } position++ - goto l813 - l814: - position, tokenIndex = position814, tokenIndex814 + goto l836 + l837: + position, tokenIndex = position837, tokenIndex837 } - goto l811 - l812: - position, tokenIndex = position812, tokenIndex812 + goto l834 + l835: + position, tokenIndex = position835, tokenIndex835 } } - l802: - goto l801 + l825: + goto l824 - position, tokenIndex = position800, tokenIndex800 + position, tokenIndex = position823, tokenIndex823 } - l801: - goto l796 - l797: - position, tokenIndex = position796, tokenIndex796 + l824: + goto l819 + l820: + position, tokenIndex = position819, tokenIndex819 { - position816, tokenIndex816 := position, tokenIndex + position839, tokenIndex839 := position, tokenIndex if buffer[position] != rune('#') { - goto l816 + goto l839 } position++ - goto l817 - l816: - position, tokenIndex = position816, tokenIndex816 + goto l840 + l839: + position, tokenIndex = position839, tokenIndex839 } - l817: + l840: if !_rules[ruleARMGOTLow12]() { - goto l815 + goto l838 } - goto l796 - l815: - position, tokenIndex = position796, tokenIndex796 + goto l819 + l838: + position, tokenIndex = position819, tokenIndex819 { - position819, tokenIndex819 := position, tokenIndex + position842, tokenIndex842 := position, tokenIndex if buffer[position] != rune('#') { - goto l819 + goto l842 } position++ - goto l820 - l819: - position, tokenIndex = position819, tokenIndex819 + goto l843 + l842: + position, tokenIndex = position842, tokenIndex842 } - l820: + l843: if !_rules[ruleLow12BitsSymbolRef]() { - goto l818 + goto l841 } - goto l796 - l818: - position, tokenIndex = position796, tokenIndex796 + goto l819 + l841: + position, tokenIndex = position819, tokenIndex819 if !_rules[ruleARMRegister]() { - goto l792 + goto l815 } } - l796: + l819: { - position821, tokenIndex821 := position, tokenIndex + position844, tokenIndex844 := position, tokenIndex if buffer[position] != rune(',') { - goto l821 + goto l844 } position++ { - position823, tokenIndex823 := position, tokenIndex + position846, tokenIndex846 := position, tokenIndex if !_rules[ruleWS]() { - goto l823 + goto l846 } - goto l824 - l823: - position, tokenIndex = position823, tokenIndex823 + goto l847 + l846: + position, tokenIndex = position846, tokenIndex846 } - l824: + l847: if !_rules[ruleARMConstantTweak]() { - goto l821 + goto l844 } - goto l822 - l821: - position, tokenIndex = position821, tokenIndex821 + goto l845 + l844: + position, tokenIndex = position844, tokenIndex844 } - l822: - goto l793 - l792: - position, tokenIndex = position792, tokenIndex792 + l845: + goto l816 + l815: + position, tokenIndex = position815, tokenIndex815 } - l793: + l816: if buffer[position] != rune(']') { - goto l790 + goto l813 } position++ { - position825, tokenIndex825 := position, tokenIndex + position848, tokenIndex848 := position, tokenIndex if !_rules[ruleARMPostincrement]() { - goto l825 + goto l848 } - goto l826 - l825: - position, tokenIndex = position825, tokenIndex825 + goto l849 + l848: + position, tokenIndex = position848, tokenIndex848 } - l826: - add(ruleARMBaseIndexScale, position791) + l849: + add(ruleARMBaseIndexScale, position814) } return true - l790: - position, tokenIndex = position790, tokenIndex790 + l813: + position, tokenIndex = position813, tokenIndex813 return false }, - /* 50 ARMGOTLow12 <- <(':' ('g' / 'G') ('o' / 'O') ('t' / 'T') '_' ('l' / 'L') ('o' / 'O') '1' '2' ':' SymbolName)> */ + /* 51 ARMGOTLow12 <- <(':' ('g' / 'G') ('o' / 'O') ('t' / 'T') '_' ('l' / 'L') ('o' / 'O') '1' '2' ':' SymbolName)> */ func() bool { - position827, tokenIndex827 := position, tokenIndex + position850, tokenIndex850 := position, tokenIndex { - position828 := position + position851 := position if buffer[position] != rune(':') { - goto l827 + goto l850 } position++ { - position829, tokenIndex829 := position, tokenIndex + position852, tokenIndex852 := position, tokenIndex if buffer[position] != rune('g') { - goto l830 + goto l853 } position++ - goto l829 - l830: - position, tokenIndex = position829, tokenIndex829 + goto l852 + l853: + position, tokenIndex = position852, tokenIndex852 if buffer[position] != rune('G') { - goto l827 + goto l850 } position++ } - l829: + l852: { - position831, tokenIndex831 := position, tokenIndex + position854, tokenIndex854 := position, tokenIndex if buffer[position] != rune('o') { - goto l832 + goto l855 } position++ - goto l831 - l832: - position, tokenIndex = position831, tokenIndex831 + goto l854 + l855: + position, tokenIndex = position854, tokenIndex854 if buffer[position] != rune('O') { - goto l827 + goto l850 } position++ } - l831: + l854: { - position833, tokenIndex833 := position, tokenIndex + position856, tokenIndex856 := position, tokenIndex if buffer[position] != rune('t') { - goto l834 + goto l857 } position++ - goto l833 - l834: - position, tokenIndex = position833, tokenIndex833 + goto l856 + l857: + position, tokenIndex = position856, tokenIndex856 if buffer[position] != rune('T') { - goto l827 + goto l850 } position++ } - l833: + l856: if buffer[position] != rune('_') { - goto l827 + goto l850 } position++ { - position835, tokenIndex835 := position, tokenIndex + position858, tokenIndex858 := position, tokenIndex if buffer[position] != rune('l') { - goto l836 + goto l859 } position++ - goto l835 - l836: - position, tokenIndex = position835, tokenIndex835 + goto l858 + l859: + position, tokenIndex = position858, tokenIndex858 if buffer[position] != rune('L') { - goto l827 + goto l850 } position++ } - l835: + l858: { - position837, tokenIndex837 := position, tokenIndex + position860, tokenIndex860 := position, tokenIndex if buffer[position] != rune('o') { - goto l838 + goto l861 } position++ - goto l837 - l838: - position, tokenIndex = position837, tokenIndex837 + goto l860 + l861: + position, tokenIndex = position860, tokenIndex860 if buffer[position] != rune('O') { - goto l827 + goto l850 } position++ } - l837: + l860: if buffer[position] != rune('1') { - goto l827 + goto l850 } position++ if buffer[position] != rune('2') { - goto l827 + goto l850 } position++ if buffer[position] != rune(':') { - goto l827 + goto l850 } position++ if !_rules[ruleSymbolName]() { - goto l827 + goto l850 } - add(ruleARMGOTLow12, position828) + add(ruleARMGOTLow12, position851) } return true - l827: - position, tokenIndex = position827, tokenIndex827 + l850: + position, tokenIndex = position850, tokenIndex850 return false }, - /* 51 ARMPostincrement <- <'!'> */ + /* 52 ARMPostincrement <- <'!'> */ func() bool { - position839, tokenIndex839 := position, tokenIndex + position862, tokenIndex862 := position, tokenIndex { - position840 := position + position863 := position if buffer[position] != rune('!') { - goto l839 + goto l862 } position++ - add(ruleARMPostincrement, position840) + add(ruleARMPostincrement, position863) } return true - l839: - position, tokenIndex = position839, tokenIndex839 + l862: + position, tokenIndex = position862, tokenIndex862 return false }, - /* 52 BaseIndexScale <- <('(' RegisterOrConstant? WS? (',' WS? RegisterOrConstant WS? (',' [0-9]+)?)? ')')> */ + /* 53 BaseIndexScale <- <('(' RegisterOrConstant? WS? (',' WS? RegisterOrConstant WS? (',' [0-9]+)?)? ')')> */ func() bool { - position841, tokenIndex841 := position, tokenIndex + position864, tokenIndex864 := position, tokenIndex { - position842 := position + position865 := position if buffer[position] != rune('(') { - goto l841 + goto l864 } position++ { - position843, tokenIndex843 := position, tokenIndex + position866, tokenIndex866 := position, tokenIndex if !_rules[ruleRegisterOrConstant]() { - goto l843 + goto l866 } - goto l844 - l843: - position, tokenIndex = position843, tokenIndex843 + goto l867 + l866: + position, tokenIndex = position866, tokenIndex866 } - l844: + l867: { - position845, tokenIndex845 := position, tokenIndex + position868, tokenIndex868 := position, tokenIndex if !_rules[ruleWS]() { - goto l845 + goto l868 } - goto l846 - l845: - position, tokenIndex = position845, tokenIndex845 + goto l869 + l868: + position, tokenIndex = position868, tokenIndex868 } - l846: + l869: { - position847, tokenIndex847 := position, tokenIndex + position870, tokenIndex870 := position, tokenIndex if buffer[position] != rune(',') { - goto l847 + goto l870 } position++ { - position849, tokenIndex849 := position, tokenIndex + position872, tokenIndex872 := position, tokenIndex if !_rules[ruleWS]() { - goto l849 + goto l872 } - goto l850 - l849: - position, tokenIndex = position849, tokenIndex849 + goto l873 + l872: + position, tokenIndex = position872, tokenIndex872 } - l850: + l873: if !_rules[ruleRegisterOrConstant]() { - goto l847 + goto l870 } { - position851, tokenIndex851 := position, tokenIndex + position874, tokenIndex874 := position, tokenIndex if !_rules[ruleWS]() { - goto l851 + goto l874 } - goto l852 - l851: - position, tokenIndex = position851, tokenIndex851 + goto l875 + l874: + position, tokenIndex = position874, tokenIndex874 } - l852: + l875: { - position853, tokenIndex853 := position, tokenIndex + position876, tokenIndex876 := position, tokenIndex if buffer[position] != rune(',') { - goto l853 + goto l876 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l853 + goto l876 } position++ - l855: + l878: { - position856, tokenIndex856 := position, tokenIndex + position879, tokenIndex879 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l856 + goto l879 } position++ - goto l855 - l856: - position, tokenIndex = position856, tokenIndex856 + goto l878 + l879: + position, tokenIndex = position879, tokenIndex879 } - goto l854 - l853: - position, tokenIndex = position853, tokenIndex853 + goto l877 + l876: + position, tokenIndex = position876, tokenIndex876 } - l854: - goto l848 - l847: - position, tokenIndex = position847, tokenIndex847 + l877: + goto l871 + l870: + position, tokenIndex = position870, tokenIndex870 } - l848: + l871: if buffer[position] != rune(')') { - goto l841 + goto l864 } position++ - add(ruleBaseIndexScale, position842) + add(ruleBaseIndexScale, position865) } return true - l841: - position, tokenIndex = position841, tokenIndex841 + l864: + position, tokenIndex = position864, tokenIndex864 return false }, - /* 53 Operator <- <('+' / '-')> */ + /* 54 Operator <- <('+' / '-')> */ func() bool { - position857, tokenIndex857 := position, tokenIndex + position880, tokenIndex880 := position, tokenIndex { - position858 := position + position881 := position { - position859, tokenIndex859 := position, tokenIndex + position882, tokenIndex882 := position, tokenIndex if buffer[position] != rune('+') { - goto l860 + goto l883 } position++ - goto l859 - l860: - position, tokenIndex = position859, tokenIndex859 + goto l882 + l883: + position, tokenIndex = position882, tokenIndex882 if buffer[position] != rune('-') { - goto l857 + goto l880 } position++ } - l859: - add(ruleOperator, position858) + l882: + add(ruleOperator, position881) } return true - l857: - position, tokenIndex = position857, tokenIndex857 + l880: + position, tokenIndex = position880, tokenIndex880 return false }, - /* 54 OffsetOperator <- <('+' / '-' / '*')> */ + /* 55 OffsetOperator <- <('+' / '-' / '*')> */ func() bool { - position861, tokenIndex861 := position, tokenIndex + position884, tokenIndex884 := position, tokenIndex { - position862 := position + position885 := position { - position863, tokenIndex863 := position, tokenIndex + position886, tokenIndex886 := position, tokenIndex if buffer[position] != rune('+') { - goto l864 + goto l887 } position++ - goto l863 - l864: - position, tokenIndex = position863, tokenIndex863 + goto l886 + l887: + position, tokenIndex = position886, tokenIndex886 if buffer[position] != rune('-') { - goto l865 + goto l888 } position++ - goto l863 - l865: - position, tokenIndex = position863, tokenIndex863 + goto l886 + l888: + position, tokenIndex = position886, tokenIndex886 if buffer[position] != rune('*') { - goto l861 + goto l884 } position++ } - l863: - add(ruleOffsetOperator, position862) + l886: + add(ruleOffsetOperator, position885) } return true - l861: - position, tokenIndex = position861, tokenIndex861 + l884: + position, tokenIndex = position884, tokenIndex884 return false }, - /* 55 Offset <- <('+'? '-'? (('0' ('b' / 'B') ('0' / '1')+) / ('0' ('x' / 'X') ([0-9] / [0-9] / ([a-f] / [A-F]))+) / ((([0-9]+ WS OffsetOperator [0-9]+) / ([0-9]+ (OffsetOperator '(' [0-9]+ OffsetOperator [0-9]+ ')')?) / ([0-9]+ (OffsetOperator [0-9]+ OffsetOperator [0-9]+)?) / ([0-9]+ (OffsetOperator [0-9]+)?) / ('(' [0-9]+ WS? OffsetOperator WS? [0-9]+ ')' OffsetOperator [0-9]+ OffsetOperator [0-9]+) / ('(' [0-9]+ WS? OffsetOperator WS? [0-9]+ ')' OffsetOperator [0-9]+ !'x') / ('(' [0-9]+ WS? OffsetOperator WS? [0-9]+ ')') / ('(' [0-9]+ WS? OffsetOperator WS? [0-9]+ WS? OffsetOperator WS? [0-9]+ ')')) !([a-z] / [A-Z]))))> */ + /* 56 Offset <- <('+'? '-'? (('0' ('b' / 'B') ('0' / '1')+) / ('0' ('x' / 'X') ([0-9] / [0-9] / ([a-f] / [A-F]))+) / ((([0-9]+ WS OffsetOperator [0-9]+) / ([0-9]+ (OffsetOperator '(' [0-9]+ OffsetOperator [0-9]+ ')')?) / ([0-9]+ (OffsetOperator [0-9]+ OffsetOperator [0-9]+)?) / ([0-9]+ (OffsetOperator [0-9]+)?) / ('(' [0-9]+ WS? OffsetOperator WS? [0-9]+ ')' OffsetOperator [0-9]+ OffsetOperator [0-9]+) / ('(' [0-9]+ WS? OffsetOperator WS? [0-9]+ ')' OffsetOperator [0-9]+ !'x') / ('(' [0-9]+ WS? OffsetOperator WS? [0-9]+ ')') / ('(' [0-9]+ WS? OffsetOperator WS? [0-9]+ WS? OffsetOperator WS? [0-9]+ ')')) !([a-z] / [A-Z]))))> */ func() bool { - position866, tokenIndex866 := position, tokenIndex + position889, tokenIndex889 := position, tokenIndex { - position867 := position + position890 := position { - position868, tokenIndex868 := position, tokenIndex + position891, tokenIndex891 := position, tokenIndex if buffer[position] != rune('+') { - goto l868 + goto l891 } position++ - goto l869 - l868: - position, tokenIndex = position868, tokenIndex868 + goto l892 + l891: + position, tokenIndex = position891, tokenIndex891 } - l869: + l892: { - position870, tokenIndex870 := position, tokenIndex + position893, tokenIndex893 := position, tokenIndex if buffer[position] != rune('-') { - goto l870 + goto l893 } position++ - goto l871 - l870: - position, tokenIndex = position870, tokenIndex870 + goto l894 + l893: + position, tokenIndex = position893, tokenIndex893 } - l871: + l894: { - position872, tokenIndex872 := position, tokenIndex + position895, tokenIndex895 := position, tokenIndex if buffer[position] != rune('0') { - goto l873 + goto l896 } position++ { - position874, tokenIndex874 := position, tokenIndex + position897, tokenIndex897 := position, tokenIndex if buffer[position] != rune('b') { - goto l875 + goto l898 } position++ - goto l874 - l875: - position, tokenIndex = position874, tokenIndex874 + goto l897 + l898: + position, tokenIndex = position897, tokenIndex897 if buffer[position] != rune('B') { - goto l873 + goto l896 } position++ } - l874: + l897: { - position878, tokenIndex878 := position, tokenIndex + position901, tokenIndex901 := position, tokenIndex if buffer[position] != rune('0') { - goto l879 + goto l902 } position++ - goto l878 - l879: - position, tokenIndex = position878, tokenIndex878 + goto l901 + l902: + position, tokenIndex = position901, tokenIndex901 if buffer[position] != rune('1') { - goto l873 + goto l896 } position++ } - l878: - l876: + l901: + l899: { - position877, tokenIndex877 := position, tokenIndex + position900, tokenIndex900 := position, tokenIndex { - position880, tokenIndex880 := position, tokenIndex + position903, tokenIndex903 := position, tokenIndex if buffer[position] != rune('0') { - goto l881 + goto l904 } position++ - goto l880 - l881: - position, tokenIndex = position880, tokenIndex880 + goto l903 + l904: + position, tokenIndex = position903, tokenIndex903 if buffer[position] != rune('1') { - goto l877 + goto l900 } position++ } - l880: - goto l876 - l877: - position, tokenIndex = position877, tokenIndex877 + l903: + goto l899 + l900: + position, tokenIndex = position900, tokenIndex900 } - goto l872 - l873: - position, tokenIndex = position872, tokenIndex872 + goto l895 + l896: + position, tokenIndex = position895, tokenIndex895 if buffer[position] != rune('0') { - goto l882 + goto l905 } position++ { - position883, tokenIndex883 := position, tokenIndex + position906, tokenIndex906 := position, tokenIndex if buffer[position] != rune('x') { - goto l884 + goto l907 } position++ - goto l883 - l884: - position, tokenIndex = position883, tokenIndex883 + goto l906 + l907: + position, tokenIndex = position906, tokenIndex906 if buffer[position] != rune('X') { - goto l882 + goto l905 } position++ } - l883: + l906: { - position887, tokenIndex887 := position, tokenIndex + position910, tokenIndex910 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l888 + goto l911 } position++ - goto l887 - l888: - position, tokenIndex = position887, tokenIndex887 + goto l910 + l911: + position, tokenIndex = position910, tokenIndex910 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l889 + goto l912 } position++ - goto l887 - l889: - position, tokenIndex = position887, tokenIndex887 + goto l910 + l912: + position, tokenIndex = position910, tokenIndex910 { - position890, tokenIndex890 := position, tokenIndex + position913, tokenIndex913 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('f') { - goto l891 + goto l914 } position++ - goto l890 - l891: - position, tokenIndex = position890, tokenIndex890 + goto l913 + l914: + position, tokenIndex = position913, tokenIndex913 if c := buffer[position]; c < rune('A') || c > rune('F') { - goto l882 + goto l905 } position++ } - l890: + l913: } - l887: - l885: + l910: + l908: { - position886, tokenIndex886 := position, tokenIndex + position909, tokenIndex909 := position, tokenIndex { - position892, tokenIndex892 := position, tokenIndex + position915, tokenIndex915 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l893 + goto l916 } position++ - goto l892 - l893: - position, tokenIndex = position892, tokenIndex892 + goto l915 + l916: + position, tokenIndex = position915, tokenIndex915 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l894 + goto l917 } position++ - goto l892 - l894: - position, tokenIndex = position892, tokenIndex892 + goto l915 + l917: + position, tokenIndex = position915, tokenIndex915 { - position895, tokenIndex895 := position, tokenIndex + position918, tokenIndex918 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('f') { - goto l896 + goto l919 } position++ - goto l895 - l896: - position, tokenIndex = position895, tokenIndex895 + goto l918 + l919: + position, tokenIndex = position918, tokenIndex918 if c := buffer[position]; c < rune('A') || c > rune('F') { - goto l886 + goto l909 } position++ } - l895: + l918: } - l892: - goto l885 - l886: - position, tokenIndex = position886, tokenIndex886 + l915: + goto l908 + l909: + position, tokenIndex = position909, tokenIndex909 } - goto l872 - l882: - position, tokenIndex = position872, tokenIndex872 + goto l895 + l905: + position, tokenIndex = position895, tokenIndex895 { - position897, tokenIndex897 := position, tokenIndex + position920, tokenIndex920 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l898 + goto l921 } position++ - l899: + l922: { - position900, tokenIndex900 := position, tokenIndex + position923, tokenIndex923 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l900 + goto l923 } position++ - goto l899 - l900: - position, tokenIndex = position900, tokenIndex900 + goto l922 + l923: + position, tokenIndex = position923, tokenIndex923 } if !_rules[ruleWS]() { - goto l898 + goto l921 } if !_rules[ruleOffsetOperator]() { - goto l898 + goto l921 } if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l898 + goto l921 } position++ - l901: + l924: { - position902, tokenIndex902 := position, tokenIndex + position925, tokenIndex925 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l902 + goto l925 } position++ - goto l901 - l902: - position, tokenIndex = position902, tokenIndex902 + goto l924 + l925: + position, tokenIndex = position925, tokenIndex925 } - goto l897 - l898: - position, tokenIndex = position897, tokenIndex897 + goto l920 + l921: + position, tokenIndex = position920, tokenIndex920 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l903 + goto l926 } position++ - l904: + l927: { - position905, tokenIndex905 := position, tokenIndex + position928, tokenIndex928 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l905 + goto l928 } position++ - goto l904 - l905: - position, tokenIndex = position905, tokenIndex905 + goto l927 + l928: + position, tokenIndex = position928, tokenIndex928 } { - position906, tokenIndex906 := position, tokenIndex + position929, tokenIndex929 := position, tokenIndex if !_rules[ruleOffsetOperator]() { - goto l906 + goto l929 } if buffer[position] != rune('(') { - goto l906 + goto l929 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l906 + goto l929 } position++ - l908: + l931: { - position909, tokenIndex909 := position, tokenIndex + position932, tokenIndex932 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l909 + goto l932 } position++ - goto l908 - l909: - position, tokenIndex = position909, tokenIndex909 + goto l931 + l932: + position, tokenIndex = position932, tokenIndex932 } if !_rules[ruleOffsetOperator]() { - goto l906 + goto l929 } if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l906 + goto l929 } position++ - l910: + l933: { - position911, tokenIndex911 := position, tokenIndex + position934, tokenIndex934 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l911 + goto l934 } position++ - goto l910 - l911: - position, tokenIndex = position911, tokenIndex911 + goto l933 + l934: + position, tokenIndex = position934, tokenIndex934 } if buffer[position] != rune(')') { - goto l906 + goto l929 } position++ - goto l907 - l906: - position, tokenIndex = position906, tokenIndex906 - } - l907: - goto l897 - l903: - position, tokenIndex = position897, tokenIndex897 + goto l930 + l929: + position, tokenIndex = position929, tokenIndex929 + } + l930: + goto l920 + l926: + position, tokenIndex = position920, tokenIndex920 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l912 + goto l935 } position++ - l913: + l936: { - position914, tokenIndex914 := position, tokenIndex + position937, tokenIndex937 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l914 + goto l937 } position++ - goto l913 - l914: - position, tokenIndex = position914, tokenIndex914 + goto l936 + l937: + position, tokenIndex = position937, tokenIndex937 } { - position915, tokenIndex915 := position, tokenIndex + position938, tokenIndex938 := position, tokenIndex if !_rules[ruleOffsetOperator]() { - goto l915 + goto l938 } if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l915 + goto l938 } position++ - l917: + l940: { - position918, tokenIndex918 := position, tokenIndex + position941, tokenIndex941 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l918 + goto l941 } position++ - goto l917 - l918: - position, tokenIndex = position918, tokenIndex918 + goto l940 + l941: + position, tokenIndex = position941, tokenIndex941 } if !_rules[ruleOffsetOperator]() { - goto l915 + goto l938 } if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l915 + goto l938 } position++ - l919: + l942: { - position920, tokenIndex920 := position, tokenIndex + position943, tokenIndex943 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l920 + goto l943 } position++ - goto l919 - l920: - position, tokenIndex = position920, tokenIndex920 + goto l942 + l943: + position, tokenIndex = position943, tokenIndex943 } - goto l916 - l915: - position, tokenIndex = position915, tokenIndex915 + goto l939 + l938: + position, tokenIndex = position938, tokenIndex938 } - l916: - goto l897 - l912: - position, tokenIndex = position897, tokenIndex897 + l939: + goto l920 + l935: + position, tokenIndex = position920, tokenIndex920 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l921 + goto l944 } position++ - l922: + l945: { - position923, tokenIndex923 := position, tokenIndex + position946, tokenIndex946 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l923 + goto l946 } position++ - goto l922 - l923: - position, tokenIndex = position923, tokenIndex923 + goto l945 + l946: + position, tokenIndex = position946, tokenIndex946 } { - position924, tokenIndex924 := position, tokenIndex + position947, tokenIndex947 := position, tokenIndex if !_rules[ruleOffsetOperator]() { - goto l924 + goto l947 } if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l924 + goto l947 } position++ - l926: + l949: { - position927, tokenIndex927 := position, tokenIndex + position950, tokenIndex950 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l927 + goto l950 } position++ - goto l926 - l927: - position, tokenIndex = position927, tokenIndex927 + goto l949 + l950: + position, tokenIndex = position950, tokenIndex950 } - goto l925 - l924: - position, tokenIndex = position924, tokenIndex924 + goto l948 + l947: + position, tokenIndex = position947, tokenIndex947 } - l925: - goto l897 - l921: - position, tokenIndex = position897, tokenIndex897 + l948: + goto l920 + l944: + position, tokenIndex = position920, tokenIndex920 if buffer[position] != rune('(') { - goto l928 + goto l951 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l928 + goto l951 } position++ - l929: + l952: { - position930, tokenIndex930 := position, tokenIndex + position953, tokenIndex953 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l930 + goto l953 } position++ - goto l929 - l930: - position, tokenIndex = position930, tokenIndex930 + goto l952 + l953: + position, tokenIndex = position953, tokenIndex953 } { - position931, tokenIndex931 := position, tokenIndex + position954, tokenIndex954 := position, tokenIndex if !_rules[ruleWS]() { - goto l931 + goto l954 } - goto l932 - l931: - position, tokenIndex = position931, tokenIndex931 + goto l955 + l954: + position, tokenIndex = position954, tokenIndex954 } - l932: + l955: if !_rules[ruleOffsetOperator]() { - goto l928 + goto l951 } { - position933, tokenIndex933 := position, tokenIndex + position956, tokenIndex956 := position, tokenIndex if !_rules[ruleWS]() { - goto l933 + goto l956 } - goto l934 - l933: - position, tokenIndex = position933, tokenIndex933 + goto l957 + l956: + position, tokenIndex = position956, tokenIndex956 } - l934: + l957: if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l928 + goto l951 } position++ - l935: + l958: { - position936, tokenIndex936 := position, tokenIndex + position959, tokenIndex959 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l936 + goto l959 } position++ - goto l935 - l936: - position, tokenIndex = position936, tokenIndex936 + goto l958 + l959: + position, tokenIndex = position959, tokenIndex959 } if buffer[position] != rune(')') { - goto l928 + goto l951 } position++ if !_rules[ruleOffsetOperator]() { - goto l928 + goto l951 } if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l928 + goto l951 } position++ - l937: + l960: { - position938, tokenIndex938 := position, tokenIndex + position961, tokenIndex961 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l938 + goto l961 } position++ - goto l937 - l938: - position, tokenIndex = position938, tokenIndex938 + goto l960 + l961: + position, tokenIndex = position961, tokenIndex961 } if !_rules[ruleOffsetOperator]() { - goto l928 + goto l951 } if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l928 + goto l951 } position++ - l939: + l962: { - position940, tokenIndex940 := position, tokenIndex + position963, tokenIndex963 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l940 + goto l963 } position++ - goto l939 - l940: - position, tokenIndex = position940, tokenIndex940 + goto l962 + l963: + position, tokenIndex = position963, tokenIndex963 } - goto l897 - l928: - position, tokenIndex = position897, tokenIndex897 + goto l920 + l951: + position, tokenIndex = position920, tokenIndex920 if buffer[position] != rune('(') { - goto l941 + goto l964 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l941 + goto l964 } position++ - l942: + l965: { - position943, tokenIndex943 := position, tokenIndex + position966, tokenIndex966 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l943 + goto l966 } position++ - goto l942 - l943: - position, tokenIndex = position943, tokenIndex943 + goto l965 + l966: + position, tokenIndex = position966, tokenIndex966 } { - position944, tokenIndex944 := position, tokenIndex + position967, tokenIndex967 := position, tokenIndex if !_rules[ruleWS]() { - goto l944 + goto l967 } - goto l945 - l944: - position, tokenIndex = position944, tokenIndex944 + goto l968 + l967: + position, tokenIndex = position967, tokenIndex967 } - l945: + l968: if !_rules[ruleOffsetOperator]() { - goto l941 + goto l964 } { - position946, tokenIndex946 := position, tokenIndex + position969, tokenIndex969 := position, tokenIndex if !_rules[ruleWS]() { - goto l946 + goto l969 } - goto l947 - l946: - position, tokenIndex = position946, tokenIndex946 + goto l970 + l969: + position, tokenIndex = position969, tokenIndex969 } - l947: + l970: if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l941 + goto l964 } position++ - l948: + l971: { - position949, tokenIndex949 := position, tokenIndex + position972, tokenIndex972 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l949 + goto l972 } position++ - goto l948 - l949: - position, tokenIndex = position949, tokenIndex949 + goto l971 + l972: + position, tokenIndex = position972, tokenIndex972 } if buffer[position] != rune(')') { - goto l941 + goto l964 } position++ if !_rules[ruleOffsetOperator]() { - goto l941 + goto l964 } if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l941 + goto l964 } position++ - l950: + l973: { - position951, tokenIndex951 := position, tokenIndex + position974, tokenIndex974 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l951 + goto l974 } position++ - goto l950 - l951: - position, tokenIndex = position951, tokenIndex951 + goto l973 + l974: + position, tokenIndex = position974, tokenIndex974 } { - position952, tokenIndex952 := position, tokenIndex + position975, tokenIndex975 := position, tokenIndex if buffer[position] != rune('x') { - goto l952 + goto l975 } position++ - goto l941 - l952: - position, tokenIndex = position952, tokenIndex952 + goto l964 + l975: + position, tokenIndex = position975, tokenIndex975 } - goto l897 - l941: - position, tokenIndex = position897, tokenIndex897 + goto l920 + l964: + position, tokenIndex = position920, tokenIndex920 if buffer[position] != rune('(') { - goto l953 + goto l976 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l953 + goto l976 } position++ - l954: + l977: { - position955, tokenIndex955 := position, tokenIndex + position978, tokenIndex978 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l955 + goto l978 } position++ - goto l954 - l955: - position, tokenIndex = position955, tokenIndex955 + goto l977 + l978: + position, tokenIndex = position978, tokenIndex978 } { - position956, tokenIndex956 := position, tokenIndex + position979, tokenIndex979 := position, tokenIndex if !_rules[ruleWS]() { - goto l956 + goto l979 } - goto l957 - l956: - position, tokenIndex = position956, tokenIndex956 + goto l980 + l979: + position, tokenIndex = position979, tokenIndex979 } - l957: + l980: if !_rules[ruleOffsetOperator]() { - goto l953 + goto l976 } { - position958, tokenIndex958 := position, tokenIndex + position981, tokenIndex981 := position, tokenIndex if !_rules[ruleWS]() { - goto l958 + goto l981 } - goto l959 - l958: - position, tokenIndex = position958, tokenIndex958 + goto l982 + l981: + position, tokenIndex = position981, tokenIndex981 } - l959: + l982: if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l953 + goto l976 } position++ - l960: + l983: { - position961, tokenIndex961 := position, tokenIndex + position984, tokenIndex984 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l961 + goto l984 } position++ - goto l960 - l961: - position, tokenIndex = position961, tokenIndex961 + goto l983 + l984: + position, tokenIndex = position984, tokenIndex984 } if buffer[position] != rune(')') { - goto l953 + goto l976 } position++ - goto l897 - l953: - position, tokenIndex = position897, tokenIndex897 + goto l920 + l976: + position, tokenIndex = position920, tokenIndex920 if buffer[position] != rune('(') { - goto l866 + goto l889 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l866 + goto l889 } position++ - l962: + l985: { - position963, tokenIndex963 := position, tokenIndex + position986, tokenIndex986 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l963 + goto l986 } position++ - goto l962 - l963: - position, tokenIndex = position963, tokenIndex963 + goto l985 + l986: + position, tokenIndex = position986, tokenIndex986 } { - position964, tokenIndex964 := position, tokenIndex + position987, tokenIndex987 := position, tokenIndex if !_rules[ruleWS]() { - goto l964 + goto l987 } - goto l965 - l964: - position, tokenIndex = position964, tokenIndex964 + goto l988 + l987: + position, tokenIndex = position987, tokenIndex987 } - l965: + l988: if !_rules[ruleOffsetOperator]() { - goto l866 + goto l889 } { - position966, tokenIndex966 := position, tokenIndex + position989, tokenIndex989 := position, tokenIndex if !_rules[ruleWS]() { - goto l966 + goto l989 } - goto l967 - l966: - position, tokenIndex = position966, tokenIndex966 + goto l990 + l989: + position, tokenIndex = position989, tokenIndex989 } - l967: + l990: if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l866 + goto l889 } position++ - l968: + l991: { - position969, tokenIndex969 := position, tokenIndex + position992, tokenIndex992 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l969 + goto l992 } position++ - goto l968 - l969: - position, tokenIndex = position969, tokenIndex969 + goto l991 + l992: + position, tokenIndex = position992, tokenIndex992 } { - position970, tokenIndex970 := position, tokenIndex + position993, tokenIndex993 := position, tokenIndex if !_rules[ruleWS]() { - goto l970 + goto l993 } - goto l971 - l970: - position, tokenIndex = position970, tokenIndex970 + goto l994 + l993: + position, tokenIndex = position993, tokenIndex993 } - l971: + l994: if !_rules[ruleOffsetOperator]() { - goto l866 + goto l889 } { - position972, tokenIndex972 := position, tokenIndex + position995, tokenIndex995 := position, tokenIndex if !_rules[ruleWS]() { - goto l972 + goto l995 } - goto l973 - l972: - position, tokenIndex = position972, tokenIndex972 + goto l996 + l995: + position, tokenIndex = position995, tokenIndex995 } - l973: + l996: if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l866 + goto l889 } position++ - l974: + l997: { - position975, tokenIndex975 := position, tokenIndex + position998, tokenIndex998 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l975 + goto l998 } position++ - goto l974 - l975: - position, tokenIndex = position975, tokenIndex975 + goto l997 + l998: + position, tokenIndex = position998, tokenIndex998 } if buffer[position] != rune(')') { - goto l866 + goto l889 } position++ } - l897: + l920: { - position976, tokenIndex976 := position, tokenIndex + position999, tokenIndex999 := position, tokenIndex { - position977, tokenIndex977 := position, tokenIndex + position1000, tokenIndex1000 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l978 + goto l1001 } position++ - goto l977 - l978: - position, tokenIndex = position977, tokenIndex977 + goto l1000 + l1001: + position, tokenIndex = position1000, tokenIndex1000 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l976 + goto l999 } position++ } - l977: - goto l866 - l976: - position, tokenIndex = position976, tokenIndex976 + l1000: + goto l889 + l999: + position, tokenIndex = position999, tokenIndex999 } } - l872: - add(ruleOffset, position867) + l895: + add(ruleOffset, position890) } return true - l866: - position, tokenIndex = position866, tokenIndex866 + l889: + position, tokenIndex = position889, tokenIndex889 return false }, - /* 56 Section <- <([a-z] / [A-Z] / '@')+> */ + /* 57 Section <- <([a-z] / [A-Z] / '@')+> */ func() bool { - position979, tokenIndex979 := position, tokenIndex + position1002, tokenIndex1002 := position, tokenIndex { - position980 := position + position1003 := position { - position983, tokenIndex983 := position, tokenIndex + position1006, tokenIndex1006 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l984 + goto l1007 } position++ - goto l983 - l984: - position, tokenIndex = position983, tokenIndex983 + goto l1006 + l1007: + position, tokenIndex = position1006, tokenIndex1006 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l985 + goto l1008 } position++ - goto l983 - l985: - position, tokenIndex = position983, tokenIndex983 + goto l1006 + l1008: + position, tokenIndex = position1006, tokenIndex1006 if buffer[position] != rune('@') { - goto l979 + goto l1002 } position++ } - l983: - l981: + l1006: + l1004: { - position982, tokenIndex982 := position, tokenIndex + position1005, tokenIndex1005 := position, tokenIndex { - position986, tokenIndex986 := position, tokenIndex + position1009, tokenIndex1009 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l987 + goto l1010 } position++ - goto l986 - l987: - position, tokenIndex = position986, tokenIndex986 + goto l1009 + l1010: + position, tokenIndex = position1009, tokenIndex1009 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l988 + goto l1011 } position++ - goto l986 - l988: - position, tokenIndex = position986, tokenIndex986 + goto l1009 + l1011: + position, tokenIndex = position1009, tokenIndex1009 if buffer[position] != rune('@') { - goto l982 + goto l1005 } position++ } - l986: - goto l981 - l982: - position, tokenIndex = position982, tokenIndex982 + l1009: + goto l1004 + l1005: + position, tokenIndex = position1005, tokenIndex1005 } - add(ruleSection, position980) + add(ruleSection, position1003) } return true - l979: - position, tokenIndex = position979, tokenIndex979 + l1002: + position, tokenIndex = position1002, tokenIndex1002 return false }, - /* 57 SegmentRegister <- <('%' ([c-g] / 's') ('s' ':'))> */ + /* 58 SegmentRegister <- <('%' ([c-g] / 's') ('s' ':'))> */ func() bool { - position989, tokenIndex989 := position, tokenIndex + position1012, tokenIndex1012 := position, tokenIndex { - position990 := position + position1013 := position if buffer[position] != rune('%') { - goto l989 + goto l1012 } position++ { - position991, tokenIndex991 := position, tokenIndex + position1014, tokenIndex1014 := position, tokenIndex if c := buffer[position]; c < rune('c') || c > rune('g') { - goto l992 + goto l1015 } position++ - goto l991 - l992: - position, tokenIndex = position991, tokenIndex991 + goto l1014 + l1015: + position, tokenIndex = position1014, tokenIndex1014 if buffer[position] != rune('s') { - goto l989 + goto l1012 } position++ } - l991: + l1014: if buffer[position] != rune('s') { - goto l989 + goto l1012 } position++ if buffer[position] != rune(':') { - goto l989 + goto l1012 } position++ - add(ruleSegmentRegister, position990) + add(ruleSegmentRegister, position1013) } return true - l989: - position, tokenIndex = position989, tokenIndex989 + l1012: + position, tokenIndex = position1012, tokenIndex1012 return false }, } diff --git a/util/fipstools/delocate/testdata/aarch64-Basic/in.s b/util/fipstools/delocate/testdata/aarch64-Basic/in.s index c65a88f0c7..b766821219 100644 --- a/util/fipstools/delocate/testdata/aarch64-Basic/in.s +++ b/util/fipstools/delocate/testdata/aarch64-Basic/in.s @@ -91,6 +91,10 @@ foo: adrp x4, :got:BORINGSSL_bcm_text_start adrp x5, :got:BORINGSSL_bcm_text_end + // Aarch64 SVE2 added these forms: + ld1d { z1.d }, p0/z, [x13, x11, lsl #3] + ld1b { z11.b }, p15/z, [x10, #1, mul vl] + local_function: // BSS data diff --git a/util/fipstools/delocate/testdata/aarch64-Basic/out.s b/util/fipstools/delocate/testdata/aarch64-Basic/out.s index dafe5d2a9b..b4716afdf0 100644 --- a/util/fipstools/delocate/testdata/aarch64-Basic/out.s +++ b/util/fipstools/delocate/testdata/aarch64-Basic/out.s @@ -159,6 +159,10 @@ foo: ldp x0, x30, [sp], #16 add sp, sp, 128 + // Aarch64 SVE2 added these forms: + ld1d { z1.d }, p0/z, [x13, x11, lsl #3] + ld1b { z11.b }, p15/z, [x10, #1, mul vl] + .Llocal_function_local_target: local_function: