40
40
#include <plugins/text_input.h>
41
41
#include <plugins/raw_keyboard.h>
42
42
43
+ #include <elf.h>
44
+ #include <sys/mman.h>
45
+ #include <aot.h>
43
46
44
47
char * usage = "\
45
48
flutter-pi - run flutter apps on your Raspberry Pi.\n\
@@ -61,6 +64,7 @@ OPTIONS:\n\
61
64
you use as a parameter so it isn't implicitly expanded\n\
62
65
by your shell.\n\
63
66
\n\
67
+ -a <path libapp.so> Enable AOT\n\
64
68
-h Show this help and exit.\n\
65
69
\n\
66
70
EXAMPLES:\n\
@@ -107,6 +111,9 @@ enum device_orientation orientation;
107
111
/// is used to determine if width/height should be swapped when sending a WindowMetrics event to flutter)
108
112
int rotation = 0 ;
109
113
114
+ /// AOT library path, for example './libapp.so'
115
+ char * aot_library = NULL ;
116
+
110
117
struct {
111
118
char device [PATH_MAX ];
112
119
bool has_device ;
@@ -1196,6 +1203,64 @@ void destroy_display(void) {
1196
1203
fprintf (stderr , "Deinitializing display not yet implemented\n" );
1197
1204
}
1198
1205
1206
+ bool init_aot (void ){
1207
+ int fd = open (aot_library , O_RDONLY );
1208
+ if (!fd ) {
1209
+ printf ("Error open '%s'\n" , aot_library );
1210
+ return false;
1211
+ }
1212
+ struct stat statbuf ;
1213
+ fstat (fd , & statbuf );
1214
+ char * fbase = mmap (NULL , statbuf .st_size , PROT_READ , MAP_SHARED , fd , 0 );
1215
+ close (fd );
1216
+
1217
+ Elf32_Ehdr * ehdr = (Elf32_Ehdr * ) fbase ;
1218
+ Elf32_Shdr * sects = (Elf32_Shdr * )(fbase + ehdr -> e_shoff );
1219
+ int shsize = ehdr -> e_shentsize ;
1220
+ int shnum = ehdr -> e_shnum ;
1221
+ int shstrndx = ehdr -> e_shstrndx ;
1222
+
1223
+ Elf32_Shdr * shstrsect = & sects [shstrndx ];
1224
+ char * shstrtab = fbase + shstrsect -> sh_offset ;
1225
+
1226
+ int i , ii ;
1227
+ Elf32_Shdr dynamic_str ;
1228
+ Elf32_Shdr dynamic_sym ;
1229
+ for (i = 0 ; i < shnum ; i ++ ) {
1230
+ if (!strcmp (shstrtab + sects [i ].sh_name , ".dynstr" )) {
1231
+ dynamic_str = sects [i ]; // count == sects[i].sh_size
1232
+ }else
1233
+ if (!strcmp (shstrtab + sects [i ].sh_name , ".dynsym" )) {
1234
+ dynamic_sym = sects [i ]; //unsigned long number = dynamic_sym.sh_size / dynamic_sym.sh_entsize;
1235
+ }
1236
+ }
1237
+
1238
+ char * d_strs = (char * )(fbase + dynamic_str .sh_offset );
1239
+ Elf32_Sym * d_syms = (Elf32_Sym * )(fbase + dynamic_sym .sh_offset );
1240
+ unsigned long number = dynamic_sym .sh_size / dynamic_sym .sh_entsize ;
1241
+
1242
+ for (ii = 0 ; ii < number ; ii ++ ) {
1243
+ printf ("Symbol value:%i, size:%i name:%s\n" , d_syms [ii ].st_value , d_syms [ii ].st_size , d_strs + d_syms [ii ].st_name );
1244
+ if (!strcmp (d_strs + d_syms [ii ].st_name , "_kDartIsolateSnapshotData" )) {
1245
+ _kDartIsolateSnapshotDataSize = d_syms [ii ].st_size ;
1246
+ }
1247
+ else if (!strcmp (d_strs + d_syms [ii ].st_name , "_kDartIsolateSnapshotInstructions" )) {
1248
+ _kDartIsolateSnapshotInstructionsSize = d_syms [ii ].st_size ;
1249
+ }
1250
+ else if (!strcmp (d_strs + d_syms [ii ].st_name , "_kDartVmSnapshotData" )) {
1251
+ _kDartVmSnapshotDataSize = d_syms [ii ].st_size ;
1252
+ }
1253
+ else if (!strcmp (d_strs + d_syms [ii ].st_name , "_kDartVmSnapshotInstructions" )) {
1254
+ _kDartVmSnapshotInstructionsSize = d_syms [ii ].st_size ;
1255
+ }
1256
+ }
1257
+
1258
+ munmap (fbase ,statbuf .st_size );
1259
+ printf ("Done\n" );
1260
+ return true;
1261
+ }
1262
+
1263
+
1199
1264
bool init_application (void ) {
1200
1265
int ok , _errno ;
1201
1266
@@ -1205,6 +1270,27 @@ bool init_application(void) {
1205
1270
fprintf (stderr , "Could not initialize plugin registry: %s\n" , strerror (ok ));
1206
1271
return false;
1207
1272
}
1273
+
1274
+ if (aot_library ){
1275
+ printf ("Initializing AOT...\n" );
1276
+ if (!init_aot ()){
1277
+ fprintf (stderr , "Could not initialize AOT\n" );
1278
+ return false;
1279
+ }
1280
+ void * library_handler ;
1281
+
1282
+ library_handler = dlopen (aot_library ,RTLD_LAZY );
1283
+ if (!library_handler ){
1284
+ fprintf (stderr ,"dlopen() error: %s\n" , dlerror ());
1285
+ return false;
1286
+ };
1287
+ _kDartIsolateSnapshotData = dlsym (library_handler ,"_kDartIsolateSnapshotData" );
1288
+ _kDartIsolateSnapshotInstructions = dlsym (library_handler ,"_kDartIsolateSnapshotInstructions" );
1289
+ _kDartVmSnapshotData = dlsym (library_handler ,"_kDartVmSnapshotData" );
1290
+ _kDartVmSnapshotInstructions = dlsym (library_handler ,"_kDartVmSnapshotInstructions" );
1291
+ } else {
1292
+ printf ("AOT skipped\n" );
1293
+ }
1208
1294
1209
1295
// configure flutter rendering
1210
1296
flutter .renderer_config .type = kOpenGL ;
@@ -1220,14 +1306,14 @@ bool init_application(void) {
1220
1306
flutter .args .struct_size = sizeof (FlutterProjectArgs );
1221
1307
flutter .args .assets_path = flutter .asset_bundle_path ;
1222
1308
flutter .args .icu_data_path = flutter .icu_data_path ;
1223
- flutter .args .isolate_snapshot_data_size = 0 ;
1224
- flutter .args .isolate_snapshot_data = NULL ;
1225
- flutter .args .isolate_snapshot_instructions_size = 0 ;
1226
- flutter .args .isolate_snapshot_instructions = NULL ;
1227
- flutter .args .vm_snapshot_data_size = 0 ;
1228
- flutter .args .vm_snapshot_data = NULL ;
1229
- flutter .args .vm_snapshot_instructions_size = 0 ;
1230
- flutter .args .vm_snapshot_instructions = NULL ;
1309
+ flutter .args .isolate_snapshot_data_size = _kDartIsolateSnapshotDataSize ;
1310
+ flutter .args .isolate_snapshot_data = _kDartIsolateSnapshotData ;
1311
+ flutter .args .isolate_snapshot_instructions_size = _kDartIsolateSnapshotInstructionsSize ;
1312
+ flutter .args .isolate_snapshot_instructions = _kDartIsolateSnapshotInstructions ;
1313
+ flutter .args .vm_snapshot_data_size = _kDartVmSnapshotDataSize ;
1314
+ flutter .args .vm_snapshot_data = _kDartVmSnapshotData ;
1315
+ flutter .args .vm_snapshot_instructions_size = _kDartVmSnapshotInstructionsSize ;
1316
+ flutter .args .vm_snapshot_instructions = _kDartVmSnapshotInstructions ;
1231
1317
flutter .args .command_line_argc = flutter .engine_argc ;
1232
1318
flutter .args .command_line_argv = flutter .engine_argv ;
1233
1319
flutter .args .platform_message_callback = on_platform_message ;
@@ -1770,14 +1856,18 @@ bool parse_cmd_args(int argc, char **argv) {
1770
1856
int ok , opt , index = 0 ;
1771
1857
input_devices_glob = (glob_t ) {0 };
1772
1858
1773
- while ((opt = getopt (argc , (char * const * ) argv , "+i:h" )) != -1 ) {
1859
+ while ((opt = getopt (argc , (char * const * ) argv , "+i:a: h" )) != -1 ) {
1774
1860
index ++ ;
1775
1861
switch (opt ) {
1776
1862
case 'i' :
1777
1863
input_specified = true;
1778
1864
glob (optarg , GLOB_BRACE | GLOB_TILDE | (input_specified ? GLOB_APPEND : 0 ), NULL , & input_devices_glob );
1779
1865
index ++ ;
1780
1866
break ;
1867
+ case 'a' :
1868
+ aot_library = optarg ;
1869
+ index ++ ;
1870
+ break ;
1781
1871
case 'h' :
1782
1872
default :
1783
1873
printf ("%s" , usage );
@@ -1848,4 +1938,4 @@ int main(int argc, char **argv) {
1848
1938
destroy_display ();
1849
1939
1850
1940
return EXIT_SUCCESS ;
1851
- }
1941
+ }
0 commit comments