8
8
#include < dirent.h>
9
9
#include < errno.h>
10
10
#include " log.h"
11
+ #include < linux/ashmem.h>
12
+ #include < sys/mman.h>
11
13
12
14
#include < vector>
13
15
#include < string>
@@ -21,20 +23,40 @@ struct FileExtraData
21
23
FileExtraData* self;
22
24
ShadowZip* shadow_zip;
23
25
FILE* file;
26
+ char * mmap_buffer;
24
27
int fd;
25
28
};
29
+ bool use_shared_mem = false ;
30
+ static dev_t g_shm_device_id = -1 ;
31
+ static ino_t g_shm_ino = -1 ;
26
32
27
33
// posix shm is not supported on Android.
28
34
// we should use memfd, but it is not supported in older android(platform api < 26)
29
35
// https://developer.android.google.cn/ndk/reference/group/memory.html
30
36
// file fd is slow theoratically, but it is ok on a flash disk and I don't notice it.
31
37
// no other choice, as the mutex is buggy in fclose with timing irq.
32
38
33
- static int init_file_mapping_data ()
39
+ static int init_mapping_data ()
34
40
{
41
+ FILE* file = ::fopen (" /dev/ashmem" , " r+" );
42
+ if (file != NULL ){
43
+ int fd = fileno (file);
44
+ struct stat shm_stat;
45
+ memset (&shm_stat, 0 , sizeof (struct stat ));
46
+ if (fstat (fd, &shm_stat) == 0 ) {
47
+ ::fclose (file);
48
+ g_shm_device_id = shm_stat.st_dev ;
49
+ g_shm_ino = shm_stat.st_ino ;
50
+ use_shared_mem = true ;
51
+ MY_METHOD (" shmem mapping is enabled. dev:%lu:%lu" , (unsigned long )g_shm_device_id, (unsigned long )g_shm_ino);
52
+ return 0 ;
53
+ }
54
+ ::fclose (file);
55
+ }
56
+
35
57
char fds_dir[512 ] = {0 };
36
58
snprintf (fds_dir, sizeof (fds_dir), " %s/rt_fd_mappings" , g_use_data_path);
37
- MY_INFO ( " init_file_mapping_data %s with apk_path:%s" , TARGET_ARCH_ABI, fds_dir);
59
+ MY_METHOD ( " init_mapping_data %s with apk_path:%s" , TARGET_ARCH_ABI, fds_dir);
38
60
39
61
// create dir if not exist
40
62
DIR* dir = opendir (fds_dir);
@@ -81,13 +103,36 @@ static int init_file_mapping_data()
81
103
return 0 ;
82
104
}
83
105
84
- static FileExtraData* save_file_mapping (ShadowZip* shadow_zip)
85
- {
86
- FileExtraData* file_extra_data = new FileExtraData ();
87
- file_extra_data->magic_num = MY_MAGIC_NUM;
88
- file_extra_data->self = file_extra_data;
89
- file_extra_data->shadow_zip = shadow_zip;
106
+ static void save_mem_mapping (FileExtraData* file_extra_data){
107
+ file_extra_data->file = ::fopen (" /dev/ashmem" , " r+" );
108
+ if (file_extra_data->file == NULL )
109
+ {
110
+ MY_ERROR (" open /dev/ashmem failed! errno:%d" , errno);
111
+ _exit (-1 );
112
+ }
113
+ int fd = fileno (file_extra_data->file );
114
+ file_extra_data->fd = fd;
115
+
116
+ char name[256 ] = {0 };
117
+ snprintf (name, sizeof (name), " %08llx_%d" , (unsigned long long )file_extra_data->file , file_extra_data->fd );
118
+ ioctl (fd, ASHMEM_SET_NAME, name);
119
+ ioctl (fd, ASHMEM_SET_SIZE, sizeof (FileExtraData));
120
+
121
+ char * buff = (char *)mmap (NULL , sizeof (FileExtraData), PROT_READ | PROT_WRITE, MAP_SHARED, file_extra_data->fd , 0 );
122
+ if (buff == MAP_FAILED)
123
+ {
124
+ MY_ERROR (" mmap /dev/ashmem failed! errno:%d" , errno);
125
+ _exit (-1 );
126
+ }
127
+
128
+ file_extra_data->mmap_buffer = buff;
129
+ memcpy (buff, file_extra_data, sizeof (FileExtraData));
90
130
131
+ msync (buff, sizeof (FileExtraData), MS_SYNC);
132
+ MY_METHOD (" FileExtraData saved to mem:0x%08llx. fd:0x%08x, file*: 0x%08llx" , (unsigned long long )buff, file_extra_data->fd , (unsigned long long )file_extra_data->file );
133
+ }
134
+
135
+ static void save_file_mapping (FileExtraData* file_extra_data){
91
136
char save_path[512 ] = {0 };
92
137
snprintf (save_path, sizeof (save_path), " %s/rt_fd_mappings/%08llx" , g_use_data_path, (unsigned long long )file_extra_data);
93
138
file_extra_data->file = ::fopen (save_path, " wb+" );
@@ -103,54 +148,111 @@ static FileExtraData* save_file_mapping(ShadowZip* shadow_zip)
103
148
fseek (file_extra_data->file , 0 , SEEK_SET);
104
149
105
150
MY_METHOD (" FileExtraData saved to %s. fd:0x%08x, file*: 0x%08llx" , save_path, file_extra_data->fd , (unsigned long long )file_extra_data->file );
151
+ }
152
+
153
+ static FileExtraData* save_mapping (ShadowZip* shadow_zip)
154
+ {
155
+ FileExtraData* file_extra_data = new FileExtraData ();
156
+ file_extra_data->magic_num = MY_MAGIC_NUM;
157
+ file_extra_data->self = file_extra_data;
158
+ file_extra_data->shadow_zip = shadow_zip;
159
+
160
+ if (use_shared_mem){
161
+ save_mem_mapping (file_extra_data);
162
+ }
163
+ else {
164
+ save_file_mapping (file_extra_data);
165
+ }
166
+
106
167
return file_extra_data;
107
168
}
108
169
109
- static FileExtraData* get_file_mapping (int fd)
170
+ static FileExtraData* get_mem_mapping (int fd)
110
171
{
111
- off_t pos = lseek (fd, 0 , SEEK_CUR);
112
- if (pos != 0 ){return NULL ;}
172
+ struct stat shm_stat;
173
+ memset (&shm_stat, 0 , sizeof (struct stat ));
174
+ if (fstat (fd, &shm_stat) != 0 ) {
175
+ return NULL ;
176
+ }
177
+ if (g_shm_device_id != shm_stat.st_dev || g_shm_ino != shm_stat.st_ino ){
178
+ return NULL ;
179
+ }
180
+
181
+ char * buff = (char *)mmap (NULL , sizeof (FileExtraData), PROT_READ, MAP_SHARED, fd, 0 );
182
+ if (buff == MAP_FAILED) { return NULL ; }
183
+ if (*((uint64_t *)buff) != MY_MAGIC_NUM){
184
+ munmap (buff, sizeof (FileExtraData));
185
+ return NULL ;
186
+ }
113
187
114
- lseek (fd, 0 , SEEK_SET);
115
188
FileExtraData file_extra_data_copy;
116
- int read_cnt = read (fd, ( void *) &file_extra_data_copy, sizeof (FileExtraData));
117
- lseek (fd, 0 , SEEK_SET);
189
+ memcpy ( &file_extra_data_copy, buff , sizeof (FileExtraData));
190
+ munmap (buff, sizeof (FileExtraData));
118
191
119
192
// validate
120
- if (read_cnt != sizeof (FileExtraData)){ return NULL ; }
121
193
if (file_extra_data_copy.magic_num != MY_MAGIC_NUM) { return NULL ; }
122
194
if (file_extra_data_copy.fd != fd) { return NULL ; }
123
195
124
196
return file_extra_data_copy.self ;
125
197
}
126
198
127
- static FileExtraData* get_file_mapping (FILE* file )
199
+ static FileExtraData* get_file_mapping (int fd )
128
200
{
129
- off_t pos = ftell (file );
201
+ off_t pos = lseek (fd, 0 , SEEK_CUR );
130
202
if (pos != 0 ){return NULL ;}
131
203
132
- fseek (file , 0 , SEEK_SET);
204
+ lseek (fd , 0 , SEEK_SET);
133
205
FileExtraData file_extra_data_copy;
134
- int read_cnt = fread ( (void *)&file_extra_data_copy, 1 , sizeof (FileExtraData), file );
135
- fseek (file , 0 , SEEK_SET);
206
+ int read_cnt = read (fd, (void *)&file_extra_data_copy, sizeof (FileExtraData));
207
+ lseek (fd , 0 , SEEK_SET);
136
208
137
209
// validate
138
210
if (read_cnt != sizeof (FileExtraData)){ return NULL ; }
139
211
if (file_extra_data_copy.magic_num != MY_MAGIC_NUM) { return NULL ; }
140
- if (file_extra_data_copy.file != file ) { return NULL ; }
212
+ if (file_extra_data_copy.fd != fd ) { return NULL ; }
141
213
142
214
return file_extra_data_copy.self ;
143
215
}
144
216
145
- static void clean_mapping_data ( FileExtraData* file_extra_data )
217
+ static FileExtraData* get_mapping ( int fd )
146
218
{
219
+ if (use_shared_mem){
220
+ return get_mem_mapping (fd);
221
+ }
222
+ else {
223
+ return get_file_mapping (fd);
224
+ }
225
+ }
226
+
227
+ static FileExtraData* get_mapping (FILE* file)
228
+ {
229
+ int fd = fileno (file);
230
+ return get_mapping (fd);
231
+ }
232
+
233
+ static void clean_mem_mapping_data (FileExtraData* file_extra_data){
234
+ MY_METHOD (" FileExtraData deleted mem: 0x%08llx. fd:0x%08x, file*: 0x%08llx" , (unsigned long long )file_extra_data->mmap_buffer , file_extra_data->fd , (unsigned long long )file_extra_data->file );
235
+ munmap (file_extra_data->mmap_buffer , sizeof (FileExtraData));
236
+ }
237
+
238
+ static void clean_file_mapping_data (FileExtraData* file_extra_data){
147
239
char save_path[512 ] = {0 };
148
240
snprintf (save_path, sizeof (save_path), " %s/rt_fd_mappings/%08llx" , g_use_data_path, (unsigned long long )file_extra_data->self );
149
241
unlink (save_path);
242
+ MY_METHOD (" FileExtraData deleted %s. fd:0x%08x, file*: 0x%08llx" , save_path, file_extra_data->fd , (unsigned long long )file_extra_data->file );
243
+ }
244
+
245
+ static void clean_mapping_data (FileExtraData* file_extra_data)
246
+ {
247
+ if (use_shared_mem){
248
+ clean_mem_mapping_data (file_extra_data);
249
+ }
250
+ else {
251
+ clean_file_mapping_data (file_extra_data);
252
+ }
150
253
151
254
fclose (file_extra_data->file );
152
255
delete file_extra_data->shadow_zip ;
153
- MY_METHOD (" FileExtraData deleted %s. fd:0x%08x, file*: 0x%08llx" , save_path, file_extra_data->fd , (unsigned long long )file_extra_data->file );
154
256
155
257
delete file_extra_data->self ;
156
258
}
0 commit comments