1 #include <errno.h>
2 #include <stdbool.h>
3 #include <stddef.h>
4 #include <stdint.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include <fcntl.h>
9 #include <sched.h>
10 #include <sys/stat.h>
11 #include <sys/types.h>
12 #include <unistd.h>
13
14 #if !CPUINFO_MOCK
15 #error This file should be built only in mock mode
16 #endif
17
18 #include <arm/linux/api.h>
19 #include <arm/midr.h>
20 #include <cpuinfo-mock.h>
21 #include <cpuinfo/log.h>
22
23 static struct cpuinfo_mock_file* cpuinfo_mock_files = NULL;
24 static uint32_t cpuinfo_mock_file_count = 0;
25
cpuinfo_mock_filesystem(struct cpuinfo_mock_file * files)26 void CPUINFO_ABI cpuinfo_mock_filesystem(struct cpuinfo_mock_file* files) {
27 cpuinfo_log_info("filesystem mocking enabled");
28 uint32_t file_count = 0;
29 while (files[file_count].path != NULL) {
30 /* Indicate that file is not opened */
31 files[file_count].offset = SIZE_MAX;
32 file_count += 1;
33 }
34 cpuinfo_mock_files = files;
35 cpuinfo_mock_file_count = file_count;
36 }
37
cpuinfo_mock_open(const char * path,int oflag)38 int CPUINFO_ABI cpuinfo_mock_open(const char* path, int oflag) {
39 if (cpuinfo_mock_files == NULL) {
40 cpuinfo_log_warning("cpuinfo_mock_open called without mock filesystem; redictering to open");
41 return open(path, oflag);
42 }
43
44 for (uint32_t i = 0; i < cpuinfo_mock_file_count; i++) {
45 if (strcmp(cpuinfo_mock_files[i].path, path) == 0) {
46 if (oflag != O_RDONLY) {
47 errno = EACCES;
48 return -1;
49 }
50 if (cpuinfo_mock_files[i].offset != SIZE_MAX) {
51 errno = ENFILE;
52 return -1;
53 }
54 cpuinfo_mock_files[i].offset = 0;
55 return (int)i;
56 }
57 }
58 errno = ENOENT;
59 return -1;
60 }
61
cpuinfo_mock_close(int fd)62 int CPUINFO_ABI cpuinfo_mock_close(int fd) {
63 if (cpuinfo_mock_files == NULL) {
64 cpuinfo_log_warning("cpuinfo_mock_close called without mock filesystem; redictering to close");
65 return close(fd);
66 }
67
68 if ((unsigned int)fd >= cpuinfo_mock_file_count) {
69 errno = EBADF;
70 return -1;
71 }
72 if (cpuinfo_mock_files[fd].offset == SIZE_MAX) {
73 errno = EBADF;
74 return -1;
75 }
76 cpuinfo_mock_files[fd].offset = SIZE_MAX;
77 return 0;
78 }
79
cpuinfo_mock_read(int fd,void * buffer,size_t capacity)80 ssize_t CPUINFO_ABI cpuinfo_mock_read(int fd, void* buffer, size_t capacity) {
81 if (cpuinfo_mock_files == NULL) {
82 cpuinfo_log_warning("cpuinfo_mock_read called without mock filesystem; redictering to read");
83 return read(fd, buffer, capacity);
84 }
85
86 if ((unsigned int)fd >= cpuinfo_mock_file_count) {
87 errno = EBADF;
88 return -1;
89 }
90 if (cpuinfo_mock_files[fd].offset == SIZE_MAX) {
91 errno = EBADF;
92 return -1;
93 }
94
95 const size_t offset = cpuinfo_mock_files[fd].offset;
96 size_t count = cpuinfo_mock_files[fd].size - offset;
97 if (count > capacity) {
98 count = capacity;
99 }
100 memcpy(buffer, (void*)cpuinfo_mock_files[fd].content + offset, count);
101 cpuinfo_mock_files[fd].offset += count;
102 return (ssize_t)count;
103 }
104