Merge changes from topic "coverage-build" into main
* changes: Add Coverage controller Coverage library on the NS side for the coverage controller
This commit is contained in:
commit
6ac2c1693d
8 changed files with 727 additions and 0 deletions
36
trusty/line-coverage/Android.bp
Normal file
36
trusty/line-coverage/Android.bp
Normal file
|
@ -0,0 +1,36 @@
|
|||
// 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_library {
|
||||
name: "libtrusty_line_coverage",
|
||||
vendor_available: true,
|
||||
srcs: [
|
||||
"coverage.cpp",
|
||||
],
|
||||
export_include_dirs: [
|
||||
"include",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libext2_uuid",
|
||||
"liblog",
|
||||
"libdmabufheap",
|
||||
"libtrusty",
|
||||
],
|
||||
}
|
||||
|
191
trusty/line-coverage/coverage.cpp
Normal file
191
trusty/line-coverage/coverage.cpp
Normal file
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* Copyright (C) 2023 The Android Open Sourete 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "line-coverage"
|
||||
|
||||
#include <BufferAllocator/BufferAllocator.h>
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <assert.h>
|
||||
#include <log/log.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/uio.h>
|
||||
#include <trusty/line-coverage/coverage.h>
|
||||
#include <trusty/line-coverage/tipc.h>
|
||||
#include <trusty/tipc.h>
|
||||
#include <iostream>
|
||||
|
||||
#define LINE_COVERAGE_CLIENT_PORT "com.android.trusty.linecoverage.client"
|
||||
|
||||
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 line_coverage {
|
||||
|
||||
using ::android::base::ErrnoError;
|
||||
using ::android::base::Error;
|
||||
using ::std::string;
|
||||
|
||||
static inline uintptr_t RoundPageUp(uintptr_t val) {
|
||||
return (val + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
|
||||
}
|
||||
|
||||
CoverageRecord::CoverageRecord(string tipc_dev, struct uuid* uuid)
|
||||
: tipc_dev_(std::move(tipc_dev)),
|
||||
coverage_srv_fd_(-1),
|
||||
uuid_(*uuid),
|
||||
record_len_(0),
|
||||
shm_(NULL),
|
||||
shm_len_(0) {}
|
||||
|
||||
CoverageRecord::~CoverageRecord() {
|
||||
if (shm_) {
|
||||
munmap((void*)shm_, shm_len_);
|
||||
}
|
||||
}
|
||||
|
||||
volatile void *CoverageRecord::getShm() {
|
||||
if(!IsOpen()) {
|
||||
fprintf(stderr, "Warning! SHM is NULL!\n");
|
||||
}
|
||||
return shm_;
|
||||
}
|
||||
|
||||
Result<void> CoverageRecord::Rpc(struct line_coverage_client_req* req, \
|
||||
int req_fd, \
|
||||
struct line_coverage_client_resp* resp) {
|
||||
int rc;
|
||||
|
||||
if (req_fd < 0) {
|
||||
rc = write(coverage_srv_fd_, req, sizeof(*req));
|
||||
} else {
|
||||
iovec iov = {
|
||||
.iov_base = req,
|
||||
.iov_len = sizeof(*req),
|
||||
};
|
||||
|
||||
trusty_shm shm = {
|
||||
.fd = req_fd,
|
||||
.transfer = TRUSTY_SHARE,
|
||||
};
|
||||
|
||||
rc = tipc_send(coverage_srv_fd_, &iov, 1, &shm, 1);
|
||||
}
|
||||
|
||||
if (rc != (int)sizeof(*req)) {
|
||||
return ErrnoError() << "failed to send request to coverage server: ";
|
||||
}
|
||||
|
||||
rc = read(coverage_srv_fd_, resp, sizeof(*resp));
|
||||
if (rc != (int)sizeof(*resp)) {
|
||||
return ErrnoError() << "failed to read reply from coverage server: ";
|
||||
}
|
||||
|
||||
if (resp->hdr.cmd != (req->hdr.cmd | LINE_COVERAGE_CLIENT_CMD_RESP_BIT)) {
|
||||
return ErrnoError() << "unknown response cmd: " << resp->hdr.cmd;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<void> CoverageRecord::Open(int fd) {
|
||||
struct line_coverage_client_req req;
|
||||
struct line_coverage_client_resp resp;
|
||||
|
||||
if (shm_) {
|
||||
return {}; /* already initialized */
|
||||
}
|
||||
|
||||
coverage_srv_fd_= fd;
|
||||
|
||||
req.hdr.cmd = LINE_COVERAGE_CLIENT_CMD_OPEN;
|
||||
req.open_args.uuid = uuid_;
|
||||
auto ret = Rpc(&req, -1, &resp);
|
||||
if (!ret.ok()) {
|
||||
return Error() << "failed to open coverage client: " << ret.error();
|
||||
}
|
||||
record_len_ = resp.open_args.record_len;
|
||||
shm_len_ = RoundPageUp(record_len_);
|
||||
|
||||
BufferAllocator allocator;
|
||||
|
||||
fd = allocator.Alloc("system", shm_len_);
|
||||
if (fd < 0) {
|
||||
return ErrnoError() << "failed to create dmabuf of size " << shm_len_
|
||||
<< " err code: " << fd;
|
||||
}
|
||||
unique_fd dma_buf(fd);
|
||||
|
||||
void* shm = mmap(0, shm_len_, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf, 0);
|
||||
if (shm == MAP_FAILED) {
|
||||
return ErrnoError() << "failed to map memfd: ";
|
||||
}
|
||||
|
||||
req.hdr.cmd = LINE_COVERAGE_CLIENT_CMD_SHARE_RECORD;
|
||||
req.share_record_args.shm_len = shm_len_;
|
||||
ret = Rpc(&req, dma_buf, &resp);
|
||||
if (!ret.ok()) {
|
||||
return Error() << "failed to send shared memory: " << ret.error();
|
||||
}
|
||||
|
||||
shm_ = shm;
|
||||
|
||||
req.hdr.cmd = LINE_COVERAGE_CLIENT_CMD_OPEN;
|
||||
req.open_args.uuid = uuid_;
|
||||
ret = Rpc(&req, -1, &resp);
|
||||
if (!ret.ok()) {
|
||||
return Error() << "failed to open coverage client: " << ret.error();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool CoverageRecord::IsOpen() {
|
||||
return shm_;
|
||||
}
|
||||
|
||||
Result<void> CoverageRecord::SaveFile(const std::string& filename) {
|
||||
if(!IsOpen()) {
|
||||
return ErrnoError() << "Warning! SHM is NULL!";
|
||||
}
|
||||
android::base::unique_fd output_fd(TEMP_FAILURE_RETRY(creat(filename.c_str(), 00644)));
|
||||
if (!output_fd.ok()) {
|
||||
return ErrnoError() << "Could not open output file";
|
||||
}
|
||||
|
||||
uintptr_t* begin = (uintptr_t*)((char *)shm_ + sizeof(struct control));
|
||||
bool ret = WriteFully(output_fd, begin, record_len_);
|
||||
if(!ret) {
|
||||
fprintf(stderr, "Coverage write to file failed\n");
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace line_coverage
|
||||
} // namespace trusty
|
||||
} // namespace android
|
61
trusty/line-coverage/include/trusty/line-coverage/coverage.h
Normal file
61
trusty/line-coverage/include/trusty/line-coverage/coverage.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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 <optional>
|
||||
#include <string>
|
||||
|
||||
#include <android-base/result.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <stdint.h>
|
||||
#include <trusty/line-coverage/tipc.h>
|
||||
|
||||
namespace android {
|
||||
namespace trusty {
|
||||
namespace line_coverage {
|
||||
|
||||
using android::base::Result;
|
||||
using android::base::unique_fd;
|
||||
|
||||
class CoverageRecord {
|
||||
public:
|
||||
CoverageRecord(std::string tipc_dev, struct uuid* uuid);
|
||||
|
||||
~CoverageRecord();
|
||||
Result<void> Open(int fd);
|
||||
bool IsOpen();
|
||||
Result<void> SaveFile(const std::string& filename);
|
||||
volatile void* getShm();
|
||||
|
||||
private:
|
||||
Result<void> Rpc(struct line_coverage_client_req* req, \
|
||||
int req_fd, \
|
||||
struct line_coverage_client_resp* resp);
|
||||
|
||||
Result<std::pair<size_t, size_t>> GetRegionBounds(uint32_t region_type);
|
||||
|
||||
std::string tipc_dev_;
|
||||
int coverage_srv_fd_;
|
||||
struct uuid uuid_;
|
||||
size_t record_len_;
|
||||
volatile void* shm_;
|
||||
size_t shm_len_;
|
||||
};
|
||||
|
||||
} // namespace line_coverage
|
||||
} // namespace trusty
|
||||
} // namespace android
|
140
trusty/line-coverage/include/trusty/line-coverage/tipc.h
Normal file
140
trusty/line-coverage/include/trusty/line-coverage/tipc.h
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* This file needs to be kept in-sync with its counterpart on Trusty side */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <trusty/line-coverage/uuid.h>
|
||||
|
||||
|
||||
#define LINE_COVERAGE_CLIENT_PORT "com.android.trusty.linecoverage.client"
|
||||
|
||||
/**
|
||||
* enum line_coverage_client_cmd - command identifiers for coverage client interface
|
||||
* @LINE_COVERAGE_CLIENT_CMD_RESP_BIT: response bit set as part of response
|
||||
* @LINE_COVERAGE_CLIENT_CMD_SHIFT: number of bits used by response bit
|
||||
* @LINE_COVERAGE_CLIENT_CMD_OPEN: command to open coverage record
|
||||
* @LINE_COVERAGE_CLIENT_CMD_SHARE_RECORD: command to register a shared memory region
|
||||
* where coverage record will be written to
|
||||
*/
|
||||
enum line_coverage_client_cmd {
|
||||
LINE_COVERAGE_CLIENT_CMD_RESP_BIT = 1U,
|
||||
LINE_COVERAGE_CLIENT_CMD_SHIFT = 1U,
|
||||
LINE_COVERAGE_CLIENT_CMD_OPEN = (1U << LINE_COVERAGE_CLIENT_CMD_SHIFT),
|
||||
LINE_COVERAGE_CLIENT_CMD_SHARE_RECORD = (2U << LINE_COVERAGE_CLIENT_CMD_SHIFT),
|
||||
LINE_COVERAGE_CLIENT_CMD_SEND_LIST = (3U << LINE_COVERAGE_CLIENT_CMD_SHIFT),
|
||||
};
|
||||
|
||||
/**
|
||||
* struct line_coverage_client_hdr - header for coverage client messages
|
||||
* @cmd: command identifier
|
||||
*
|
||||
* Note that no messages return a status code. Any error on the server side
|
||||
* results in the connection being closed. So, operations can be assumed to be
|
||||
* successful if they return a response.
|
||||
*/
|
||||
struct line_coverage_client_hdr {
|
||||
uint32_t cmd;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct line_coverage_client_open_req - arguments for request to open coverage
|
||||
* record
|
||||
* @uuid: UUID of target TA
|
||||
*
|
||||
* There is one coverage record per TA. @uuid is used to identify both the TA
|
||||
* and corresponding coverage record.
|
||||
*/
|
||||
struct line_coverage_client_open_req {
|
||||
struct uuid uuid;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct line_coverage_client_open_resp - arguments for response to open coverage
|
||||
* record
|
||||
* @record_len: length of coverage record that will be emitted by target TA
|
||||
*
|
||||
* Shared memory allocated for this coverage record must larger than
|
||||
* @record_len.
|
||||
*/
|
||||
struct line_coverage_client_open_resp {
|
||||
uint32_t record_len;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct line_coverage_client_send_list_resp - arguments for response to send list
|
||||
* record
|
||||
* @uuid: UUID of TA that connected to aggregator
|
||||
*/
|
||||
struct line_coverage_client_send_list_resp {
|
||||
struct uuid uuid;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct line_coverage_client_send_list_resp - arguments for response to send list
|
||||
* record
|
||||
* @index: index of the list being requested
|
||||
*/
|
||||
struct line_coverage_client_send_list_req {
|
||||
uint32_t index;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct line_coverage_client_share_record_req - arguments for request to share
|
||||
* memory for coverage record
|
||||
* @shm_len: length of memory region being shared
|
||||
*
|
||||
* A handle to a memory region must be sent along with this message. This memory
|
||||
* is used to store coverage record.
|
||||
*
|
||||
* Upon success, this memory region can be assumed to be shared between the
|
||||
* client and target TA.
|
||||
*/
|
||||
struct line_coverage_client_share_record_req {
|
||||
uint32_t shm_len;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct line_coverage_client_req - structure for a coverage client request
|
||||
* @hdr: message header
|
||||
* @open_args: arguments for %COVERAGE_CLIENT_CMD_OPEN request
|
||||
* @share_record_args: arguments for %COVERAGE_CLIENT_CMD_SHARE_RECORD request
|
||||
* @index: arguments for %COVERAGE_CLIENT_CMD_SHARE_RECORD request
|
||||
*/
|
||||
struct line_coverage_client_req {
|
||||
struct line_coverage_client_hdr hdr;
|
||||
union {
|
||||
struct line_coverage_client_open_req open_args;
|
||||
struct line_coverage_client_share_record_req share_record_args;
|
||||
struct line_coverage_client_send_list_req send_list_args;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* struct line_coverage_client_resp - structure for a coverage client response
|
||||
* @hdr: message header
|
||||
* @open_args: arguments for %COVERAGE_CLIENT_CMD_OPEN response
|
||||
* @send_list_args: arguments for %COVERAGE_CLIENT_CMD_SHARE_RECORD response
|
||||
*/
|
||||
struct line_coverage_client_resp {
|
||||
struct line_coverage_client_hdr hdr;
|
||||
union {
|
||||
struct line_coverage_client_open_resp open_args;
|
||||
struct line_coverage_client_send_list_resp send_list_args;
|
||||
};
|
||||
};
|
37
trusty/line-coverage/include/trusty/line-coverage/uuid.h
Normal file
37
trusty/line-coverage/include/trusty/line-coverage/uuid.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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 <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#define UUCMP(u1, u2) if (u1 != u2) return u1 < u2
|
||||
|
||||
struct uuid {
|
||||
uint32_t time_low;
|
||||
uint16_t time_mid;
|
||||
uint16_t time_hi_and_version;
|
||||
uint8_t clock_seq_and_node[8];
|
||||
|
||||
bool operator<(const struct uuid& rhs) const
|
||||
{
|
||||
UUCMP(time_low, rhs.time_low);
|
||||
UUCMP(time_mid, rhs.time_mid);
|
||||
UUCMP(time_hi_and_version, rhs.time_hi_and_version);
|
||||
return memcmp(clock_seq_and_node, rhs.clock_seq_and_node, 8);
|
||||
}
|
||||
};
|
34
trusty/utils/coverage-controller/Android.bp
Normal file
34
trusty/utils/coverage-controller/Android.bp
Normal file
|
@ -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",
|
||||
],
|
||||
}
|
164
trusty/utils/coverage-controller/controller.cpp
Normal file
164
trusty/utils/coverage-controller/controller.cpp
Normal file
|
@ -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 <getopt.h>
|
||||
#include <trusty/line-coverage/coverage.h>
|
||||
#include <trusty/tipc.h>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#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<void> 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<CoverageRecord>(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;
|
||||
}
|
64
trusty/utils/coverage-controller/controller.h
Normal file
64
trusty/utils/coverage-controller/controller.h
Normal file
|
@ -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 <trusty/line-coverage/coverage.h>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#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<std::unique_ptr<line_coverage::CoverageRecord>>record_list_;
|
||||
std::set<struct uuid>uuid_set_;
|
||||
std::vector<uint64_t> counters;
|
||||
int coverage_srv_fd;
|
||||
|
||||
void connectCoverageServer();
|
||||
void setUpShm();
|
||||
};
|
||||
|
||||
} // namespace controller
|
||||
} // namespace trusty
|
||||
} // namespace android
|
Loading…
Reference in a new issue