• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "verification/config/debug_breakpoint/breakpoint_private.h"
17 #include "verification/config/process/config_process.h"
18 #include "verification/util/parser/parser.h"
19 #include "verification/util/struct_field.h"
20 
21 #include "literal_parser.h"
22 
23 #include "verifier_messages.h"
24 
25 #include "runtime/include/method.h"
26 #include "runtime/include/runtime.h"
27 #include "runtime/include/mem/panda_containers.h"
28 #include "runtime/include/mem/panda_string.h"
29 
30 #include "utils/logger.h"
31 
32 #include <cstring>
33 #include <cstdint>
34 #include <string>
35 #include <unordered_map>
36 
37 namespace panda::verifier::debug {
38 
39 namespace {
40 
41 template <typename M>
GetKeys(const M & map)42 PandaString GetKeys(const M &map)
43 {
44     PandaString keys;
45     for (const auto &p : map) {
46         if (keys.empty()) {
47             keys += "'";
48             keys += p.first;
49             keys += "'";
50         } else {
51             keys += ", '";
52             keys += p.first;
53             keys += "'";
54         }
55     }
56     return keys;
57 }
58 
59 }  // namespace
60 
61 using panda::verifier::config::Section;
62 
RegisterConfigHandlerOptions()63 void RegisterConfigHandlerOptions()
64 {
65     static const auto CONFIG_DEBUG_OPTIONS_VERIFIER = [](const Section &section) {
66         using bool_field = struct_field<VerificationOptions, bool>;
67         using flags = PandaUnorderedMap<PandaString, bool_field>;
68         using flags_section = PandaUnorderedMap<PandaString, flags>;
69 
70         const flags_section FLAGS = {
71             {"show",
72              {{"context", bool_field {offsetof(VerificationOptions, Debug.Show.Context)}},
73               {"reg-changes", bool_field {offsetof(VerificationOptions, Debug.Show.RegChanges)}},
74               {"typesystem", bool_field {offsetof(VerificationOptions, Debug.Show.TypeSystem)}},
75               {"status", bool_field {offsetof(VerificationOptions, Show.Status)}}}},
76             {"allow",
77              {{"undefined-class", bool_field {offsetof(VerificationOptions, Debug.Allow.UndefinedClass)}},
78               {"undefined-method", bool_field {offsetof(VerificationOptions, Debug.Allow.UndefinedMethod)}},
79               {"undefined-field", bool_field {offsetof(VerificationOptions, Debug.Allow.UndefinedField)}},
80               {"undefined-type", bool_field {offsetof(VerificationOptions, Debug.Allow.UndefinedType)}},
81               {"undefined-string", bool_field {offsetof(VerificationOptions, Debug.Allow.UndefinedString)}},
82               {"method-access-violation",
83                bool_field {offsetof(VerificationOptions, Debug.Allow.MethodAccessViolation)}},
84               {"field-access-violation", bool_field {offsetof(VerificationOptions, Debug.Allow.FieldAccessViolation)}},
85               {"wrong-subclassing-in-method-args",
86                bool_field {offsetof(VerificationOptions, Debug.Allow.WrongSubclassingInMethodArgs)}},
87               {"error-in-exception-handler",
88                bool_field {offsetof(VerificationOptions, Debug.Allow.ErrorInExceptionHandler)}},
89               {"permanent-runtime-exception",
90                bool_field {offsetof(VerificationOptions, Debug.Allow.PermanentRuntimeException)}}}},
91             {"cflow",
92              {{"body-to-handler", bool_field {offsetof(VerificationOptions, Cflow.AllowJmpBodyToHandler)}},
93               {"body-into-handler", bool_field {offsetof(VerificationOptions, Cflow.AllowJmpBodyIntoHandler)}},
94               {"handler-to-handler", bool_field {offsetof(VerificationOptions, Cflow.AllowJmpHandlerToHandler)}},
95               {"handler-into-handler", bool_field {offsetof(VerificationOptions, Cflow.AllowJmpHandlerIntoHandler)}},
96               {"handler-into-body", bool_field {offsetof(VerificationOptions, Cflow.AllowJmpHandlerIntoBody)}}}}};
97 
98         auto &verif_opts = Runtime::GetCurrent()->GetVerificationOptions();
99         for (const auto &s : section.sections) {
100             if (FLAGS.count(s.name) == 0) {
101                 LOG_VERIFIER_DEBUG_CONFIG_WRONG_OPTIONS_SECTION(s.name, GetKeys(FLAGS));
102                 return false;
103             }
104             const auto &section_flags = FLAGS.at(s.name);
105             for (const auto &i : s.items) {
106                 PandaVector<PandaString> c;
107                 const char *start = i.c_str();
108                 const char *end = i.c_str() + i.length();  // NOLINT
109                 if (!LiteralsParser()(c, start, end)) {
110                     LOG_VERIFIER_DEBUG_CONFIG_WRONG_OPTIONS_LINE(i);
111                     return false;
112                 }
113                 if (!c.empty()) {
114                     for (const auto &l : c) {
115                         if (section_flags.count(l) == 0) {
116                             LOG_VERIFIER_DEBUG_CONFIG_WRONG_OPTION_FOR_SECTION(l, s.name, GetKeys(section_flags));
117                             return false;
118                         }
119                         section_flags.at(l).of(verif_opts) = true;
120                         LOG_VERIFIER_DEBUG_CONFIG_OPTION_IS_ACTIVE_INFO(s.name, l);
121                     }
122                 }
123             }
124         }
125         return true;
126     };
127 
128     config::RegisterConfigHandler("config.debug.options.verifier", CONFIG_DEBUG_OPTIONS_VERIFIER);
129 }
130 
131 }  // namespace panda::verifier::debug
132