1 /*
2  * Copyright (C) 2024 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 <json/json.h>
18 #include <string>
19 
20 namespace android {
21 namespace uprobestats {
22 namespace art {
23 
24 // Uses the oatdump binary to retrieve the offset for a given method
getMethodOffsetFromOatdump(std::string oat_file,std::string method_signature)25 int getMethodOffsetFromOatdump(std::string oat_file,
26                                std::string method_signature) {
27   // call oatdump and collect stdout
28   auto command = std::string("oatdump --oat-file=") + oat_file +
29                  std::string(" --dump-method-and-offset-as-json");
30   FILE *pipe = popen(command.c_str(), "r");
31   char buffer[256];
32   std::string result = "";
33   while (fgets(buffer, sizeof(buffer), pipe) != NULL) {
34     result += buffer;
35   }
36   pclose(pipe);
37 
38   // find the first json blob with a method matching the provided signature
39   std::stringstream ss(result);
40   std::string line;
41   Json::Reader reader;
42   while (std::getline(ss, line)) {
43     Json::Value entry;
44     bool success = reader.parse(line, entry);
45     if (success) {
46       auto found_method_signature = entry["method"].asString();
47       if (found_method_signature == method_signature) {
48         auto hex_string = entry["offset"].asString();
49         int offset;
50         std::istringstream stream(hex_string);
51         stream >> std::hex >> offset;
52         return offset + 4096;
53       }
54     }
55   }
56 
57   return 0;
58 }
59 
60 } // namespace art
61 } // namespace uprobestats
62 } // namespace android