From 806e70bb941acc590d9bd9c1f29a77d648d5f928 Mon Sep 17 00:00:00 2001 From: Snehal Date: Fri, 30 Jun 2023 15:23:14 +0000 Subject: [PATCH] Add Coverage controller Bug: 289523068 Change-Id: I5b36c274acc7da4e2d6b9cf91409a7b1af5f0d34 --- trusty/utils/coverage-controller/Android.bp | 34 ++++ .../utils/coverage-controller/controller.cpp | 164 ++++++++++++++++++ trusty/utils/coverage-controller/controller.h | 64 +++++++ 3 files changed, 262 insertions(+) create mode 100644 trusty/utils/coverage-controller/Android.bp create mode 100644 trusty/utils/coverage-controller/controller.cpp create mode 100644 trusty/utils/coverage-controller/controller.h diff --git a/trusty/utils/coverage-controller/Android.bp b/trusty/utils/coverage-controller/Android.bp new file mode 100644 index 000000000..1aa88cc12 --- /dev/null +++ b/trusty/utils/coverage-controller/Android.bp @@ -0,0 +1,34 @@ +// Copyright (C) 2023 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_binary { + name: "coverage-controller", + vendor: true, + + srcs: ["controller.cpp"], + shared_libs: [ + "libc", + "liblog", + "libbase", + "libdmabufheap", + ], + static_libs: [ + "libtrusty", + "libtrusty_line_coverage", + ], +} diff --git a/trusty/utils/coverage-controller/controller.cpp b/trusty/utils/coverage-controller/controller.cpp new file mode 100644 index 000000000..730c0109b --- /dev/null +++ b/trusty/utils/coverage-controller/controller.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include "controller.h" + +#define READ_ONCE(x) (*((volatile __typeof__(x) *) &(x))) +#define WRITE_ONCE(x, val) (*((volatile __typeof__(val) *) &(x)) = (val)) + +namespace android { +namespace trusty { +namespace controller { + +using ::android::trusty::line_coverage::CoverageRecord; + +void Controller::run(std::string output_dir) { + connectCoverageServer(); + struct control *control; + uint64_t complete_cnt = 0, start_cnt = 0, flags; + + while(1) { + setUpShm(); + + for (int index = 0; index < record_list_.size(); index++) { + control = (struct control *)record_list_[index]->getShm(); + start_cnt = READ_ONCE((control->write_buffer_start_count)); + complete_cnt = READ_ONCE(control->write_buffer_complete_count); + flags = READ_ONCE(control->cntrl_flags); + + if (complete_cnt != counters[index] && start_cnt == complete_cnt) { + WRITE_ONCE(control->cntrl_flags, FLAG_NONE); + std::string fmt = "/%d.%lu.profraw"; + int sz = std::snprintf(nullptr, 0, fmt.c_str(), index, counters[index]); + std::string filename(sz+1, '.'); + std::sprintf(filename.data(), fmt.c_str(), index, counters[index]); + filename.insert(0, output_dir); + android::base::Result res = record_list_[index]->SaveFile(filename); + counters[index]++; + } + if(complete_cnt == counters[index] && + !(flags & FLAG_RUN)) { + flags |= FLAG_RUN; + WRITE_ONCE(control->cntrl_flags, flags); + } + } + } +} + +void Controller::connectCoverageServer() { + coverage_srv_fd = tipc_connect(TIPC_DEV, LINE_COVERAGE_CLIENT_PORT); + if (coverage_srv_fd < 0) { + fprintf(stderr, \ + "Error: Failed to connect to Trusty coverage server: %d\n", coverage_srv_fd); + return; + } +} + +void Controller::setUpShm() { + struct line_coverage_client_req req; + struct line_coverage_client_resp resp; + uint32_t cur_index = record_list_.size(); + struct uuid zero_uuid = {0, 0, 0, { 0 }}; + req.hdr.cmd = LINE_COVERAGE_CLIENT_CMD_SEND_LIST; + int rc = write(coverage_srv_fd, &req, sizeof(req)); + if (rc != (int)sizeof(req)) { + fprintf(stderr, "failed to send request to coverage server: %d\n", rc); + return; + } + + while(1) { + rc = read(coverage_srv_fd, &resp, sizeof(resp)); + if (rc != (int)sizeof(resp)) { + fprintf(stderr, "failed to read reply from coverage server:: %d\n", rc); + } + + if (resp.hdr.cmd == (req.hdr.cmd | LINE_COVERAGE_CLIENT_CMD_RESP_BIT)) { + if (!memcmp(&resp.send_list_args.uuid, &zero_uuid, sizeof(struct uuid))) { + break; + } + if(uuid_set_.find(resp.send_list_args.uuid) == uuid_set_.end()) { + uuid_set_.insert(resp.send_list_args.uuid); + record_list_.push_back(std::make_unique(TIPC_DEV, + &resp.send_list_args.uuid)); + counters.push_back(0); + } + } + else { + fprintf(stderr, "Unknown response header\n"); + } + cur_index++; + req.hdr.cmd = LINE_COVERAGE_CLIENT_CMD_SEND_LIST; + req.send_list_args.index = cur_index; + int rc = write(coverage_srv_fd, &req, sizeof(req)); + if (rc != (int)sizeof(req)) { + fprintf(stderr, "failed to send request to coverage server: %d\n", rc); + } + } + + for(int ind = 0 ; ind < record_list_.size() ; ind++) { + record_list_[ind]->Open(coverage_srv_fd); + } +} + + +} // namespace controller +} // namespace trusty +} // namespace android + +int main(int argc, char* argv[]) { + + std::string optarg = ""; + do { + int c; + c = getopt(argc, argv, "o"); + + if (c == -1) { + break; + } + + switch (c) { + case 'o': + break; + default: + fprintf(stderr, "usage: %s -o [output_directory]\n", argv[0]); + exit(EXIT_FAILURE); + } + } while (1); + + if (argc > optind + 1) { + fprintf(stderr, "%s: too many arguments\n", argv[0]); + exit(EXIT_FAILURE); + } + + if (argc > optind) { + optarg = argv[optind]; + } + if (optarg.size()==0) { + optarg = "data/local/tmp"; + } + + android::trusty::controller::Controller cur; + cur.run(optarg); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/trusty/utils/coverage-controller/controller.h b/trusty/utils/coverage-controller/controller.h new file mode 100644 index 000000000..b771c1615 --- /dev/null +++ b/trusty/utils/coverage-controller/controller.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#define TIPC_DEV "/dev/trusty-ipc-dev0" +#define TEST_SRV_PORT "com.android.trusty.sancov.test.srv" +#define TEST_SRV_MODULE "srv.syms.elf" + +#define FLAG_NONE 0x0 +#define FLAG_RUN 0x1 +#define FLAG_TOGGLE_CLEAR 0x2 + +struct control { + /* Written by controller, read by instrumented TA */ + uint64_t cntrl_flags; + + /* Written by instrumented TA, read by controller */ + uint64_t oper_flags; + uint64_t write_buffer_start_count; + uint64_t write_buffer_complete_count; +}; + +namespace android { +namespace trusty { +namespace controller { + +class Controller { + public: + public: + void run(std::string output_dir); + + private: + std::vector>record_list_; + std::setuuid_set_; + std::vector counters; + int coverage_srv_fd; + + void connectCoverageServer(); + void setUpShm(); +}; + +} // namespace controller +} // namespace trusty +} // namespace android