1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <dex2oat_return_codes.h>
18 
19 namespace android {
20 namespace installd {
21 
22 // Constants for exit codes that installd code emits. These are failure situations before calling
23 // any tools, e.g., in validation, and must not overlap with the exit codes of tools, so they
24 // can be distinguished.
25 enum DexoptReturnCodes : int {
26     kSetGid = 64,
27     kSetUid = 65,
28     kCapSet = 66,
29     kFlock = 67,
30     kProfmanExec = 68,
31     kSetSchedPolicy = 70,
32     kSetPriority = 71,
33     kDex2oatExec = 72,
34     kInstructionSetLength = 73,
35     kHashValidatePath = 74,
36     kHashOpenPath = 75,
37     kHashReadDex = 76,
38     kHashWrite = 77,
39 };
40 
get_installd_return_code_name(DexoptReturnCodes code)41 inline const char* get_installd_return_code_name(DexoptReturnCodes code) {
42     switch (code) {
43         case kSetGid:
44             return "setgid";
45         case kSetUid:
46             return "setuid";
47         case kCapSet:
48             return "capset";
49         case kFlock:
50             return "flock";
51         case kProfmanExec:
52             return "exec(profman)";
53         case kSetSchedPolicy:
54             return "setschedpolicy";
55         case kSetPriority:
56             return "setpriority";
57         case kDex2oatExec:
58             return "exec(dex2oat)";
59         case kInstructionSetLength:
60             return "instruction-set-length";
61         case kHashValidatePath:
62             return "hash(validate-path)";
63         case kHashOpenPath:
64             return "hash(open-path)";
65         case kHashReadDex:
66             return "hash(read-dex)";
67         case kHashWrite:
68             return "hash(write)";
69     }
70     return nullptr;
71 }
72 
get_dex2oat_return_code_name(art::dex2oat::ReturnCode code)73 inline const char* get_dex2oat_return_code_name(art::dex2oat::ReturnCode code) {
74     switch (code) {
75         case art::dex2oat::ReturnCode::kNoFailure:
76             return "dex2oat success";
77         case art::dex2oat::ReturnCode::kOther:
78             return "unspecified dex2oat error";
79         case art::dex2oat::ReturnCode::kCreateRuntime:
80             return "dex2oat failed to create a runtime";
81     }
82     return nullptr;
83 }
84 
85 // Get some slightly descriptive string for the return code. Handles both DexoptReturnCodes (local
86 // exit codes) as well as art::dex2oat::ReturnCode.
get_return_code_name(int code)87 inline const char* get_return_code_name(int code) {
88     // Try to enforce non-overlap (see comment on DexoptReturnCodes)
89     // TODO: How could switch-case checks be used to enforce completeness?
90     switch (code) {
91         case kSetGid:
92         case kSetUid:
93         case kCapSet:
94         case kFlock:
95         case kProfmanExec:
96         case kSetSchedPolicy:
97         case kSetPriority:
98         case kDex2oatExec:
99         case kInstructionSetLength:
100         case kHashValidatePath:
101         case kHashOpenPath:
102         case kHashReadDex:
103         case kHashWrite:
104             break;
105         case static_cast<int>(art::dex2oat::ReturnCode::kNoFailure):
106         case static_cast<int>(art::dex2oat::ReturnCode::kOther):
107         case static_cast<int>(art::dex2oat::ReturnCode::kCreateRuntime):
108             break;
109     }
110     const char* value = get_installd_return_code_name(static_cast<DexoptReturnCodes>(code));
111     if (value != nullptr) {
112         return value;
113     }
114     value = get_dex2oat_return_code_name(static_cast<art::dex2oat::ReturnCode>(code));
115     return value;
116 }
117 
118 }  // namespace installd
119 }  // namespace android
120