diff options
Diffstat (limited to 'applets')
-rw-r--r-- | applets/applet_tables.c | 93 |
1 files changed, 68 insertions, 25 deletions
diff --git a/applets/applet_tables.c b/applets/applet_tables.c index 92bf1e447..843f2ec08 100644 --- a/applets/applet_tables.c +++ b/applets/applet_tables.c | |||
@@ -41,8 +41,6 @@ struct bb_applet { | |||
41 | 41 | ||
42 | enum { NUM_APPLETS = ARRAY_SIZE(applets) }; | 42 | enum { NUM_APPLETS = ARRAY_SIZE(applets) }; |
43 | 43 | ||
44 | static int offset[NUM_APPLETS]; | ||
45 | |||
46 | static int cmp_name(const void *a, const void *b) | 44 | static int cmp_name(const void *a, const void *b) |
47 | { | 45 | { |
48 | const struct bb_applet *aa = a; | 46 | const struct bb_applet *aa = a; |
@@ -62,24 +60,30 @@ static int str_isalnum_(const char *s) | |||
62 | 60 | ||
63 | int main(int argc, char **argv) | 61 | int main(int argc, char **argv) |
64 | { | 62 | { |
65 | int i; | 63 | int i, j; |
66 | int ofs; | 64 | |
67 | // unsigned MAX_APPLET_NAME_LEN = 1; | 65 | // In find_applet_by_name(), before linear search, narrow it down |
66 | // by looking at N "equidistant" names. With ~350 applets: | ||
67 | // KNOWN_APPNAME_OFFSETS cycles | ||
68 | // 0 9057 | ||
69 | // 2 4604 + ~100 bytes of code | ||
70 | // 4 2407 + 4 bytes | ||
71 | // 8 1342 + 8 bytes | ||
72 | // 16 908 + 16 bytes | ||
73 | // 32 884 + 32 bytes | ||
74 | // With 8, int16_t applet_nameofs[] table has 7 elements. | ||
75 | int KNOWN_APPNAME_OFFSETS = 8; | ||
76 | // With 128 applets we do two linear searches, with 1..7 strcmp's in the first one | ||
77 | // and 1..16 strcmp's in the second. With 256 apps, second search does 1..32 strcmp's. | ||
78 | if (NUM_APPLETS < 128) | ||
79 | KNOWN_APPNAME_OFFSETS = 4; | ||
80 | if (NUM_APPLETS < 32) | ||
81 | KNOWN_APPNAME_OFFSETS = 0; | ||
68 | 82 | ||
69 | qsort(applets, NUM_APPLETS, sizeof(applets[0]), cmp_name); | 83 | qsort(applets, NUM_APPLETS, sizeof(applets[0]), cmp_name); |
70 | 84 | ||
71 | ofs = 0; | ||
72 | for (i = 0; i < NUM_APPLETS; i++) { | ||
73 | offset[i] = ofs; | ||
74 | ofs += strlen(applets[i].name) + 1; | ||
75 | } | ||
76 | /* We reuse 4 high-order bits of offset array for other purposes, | ||
77 | * so if they are indeed needed, refuse to proceed */ | ||
78 | if (ofs > 0xfff) | ||
79 | return 1; | ||
80 | if (!argv[1]) | 85 | if (!argv[1]) |
81 | return 1; | 86 | return 1; |
82 | |||
83 | i = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0666); | 87 | i = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0666); |
84 | if (i < 0) | 88 | if (i < 0) |
85 | return 1; | 89 | return 1; |
@@ -94,7 +98,27 @@ int main(int argc, char **argv) | |||
94 | printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name); | 98 | printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name); |
95 | printf("#define SINGLE_APPLET_MAIN %s_main\n", applets[0].main); | 99 | printf("#define SINGLE_APPLET_MAIN %s_main\n", applets[0].main); |
96 | } | 100 | } |
97 | printf("\n"); | 101 | |
102 | printf("#define KNOWN_APPNAME_OFFSETS %u\n\n", KNOWN_APPNAME_OFFSETS); | ||
103 | if (KNOWN_APPNAME_OFFSETS > 0) { | ||
104 | int ofs, offset[KNOWN_APPNAME_OFFSETS], index[KNOWN_APPNAME_OFFSETS]; | ||
105 | for (i = 0; i < KNOWN_APPNAME_OFFSETS; i++) | ||
106 | index[i] = i * NUM_APPLETS / KNOWN_APPNAME_OFFSETS; | ||
107 | ofs = 0; | ||
108 | for (i = 0; i < NUM_APPLETS; i++) { | ||
109 | for (j = 0; j < KNOWN_APPNAME_OFFSETS; j++) | ||
110 | if (i == index[j]) | ||
111 | offset[j] = ofs; | ||
112 | ofs += strlen(applets[i].name) + 1; | ||
113 | } | ||
114 | /* If the list of names is too long refuse to proceed */ | ||
115 | if (ofs > 0xffff) | ||
116 | return 1; | ||
117 | printf("const uint16_t applet_nameofs[] ALIGN2 = {\n"); | ||
118 | for (i = 1; i < KNOWN_APPNAME_OFFSETS; i++) | ||
119 | printf("%d,\n", offset[i]); | ||
120 | printf("};\n\n"); | ||
121 | } | ||
98 | 122 | ||
99 | //printf("#ifndef SKIP_definitions\n"); | 123 | //printf("#ifndef SKIP_definitions\n"); |
100 | printf("const char applet_names[] ALIGN1 = \"\"\n"); | 124 | printf("const char applet_names[] ALIGN1 = \"\"\n"); |
@@ -119,20 +143,39 @@ int main(int argc, char **argv) | |||
119 | printf("};\n"); | 143 | printf("};\n"); |
120 | printf("#endif\n\n"); | 144 | printf("#endif\n\n"); |
121 | 145 | ||
122 | printf("const uint16_t applet_nameofs[] ALIGN2 = {\n"); | ||
123 | for (i = 0; i < NUM_APPLETS; i++) { | ||
124 | printf("0x%04x,\n", | ||
125 | offset[i] | ||
126 | #if ENABLE_FEATURE_PREFER_APPLETS | 146 | #if ENABLE_FEATURE_PREFER_APPLETS |
127 | + (applets[i].nofork << 12) | 147 | printf("const uint8_t applet_flags[] ALIGN1 = {\n"); |
128 | + (applets[i].noexec << 13) | 148 | i = 0; |
149 | while (i < NUM_APPLETS) { | ||
150 | int v = applets[i].nofork + (applets[i].noexec << 1); | ||
151 | if (++i < NUM_APPLETS) | ||
152 | v |= (applets[i].nofork + (applets[i].noexec << 1)) << 2; | ||
153 | if (++i < NUM_APPLETS) | ||
154 | v |= (applets[i].nofork + (applets[i].noexec << 1)) << 4; | ||
155 | if (++i < NUM_APPLETS) | ||
156 | v |= (applets[i].nofork + (applets[i].noexec << 1)) << 6; | ||
157 | printf("0x%02x,\n", v); | ||
158 | i++; | ||
159 | } | ||
160 | printf("};\n\n"); | ||
129 | #endif | 161 | #endif |
162 | |||
130 | #if ENABLE_FEATURE_SUID | 163 | #if ENABLE_FEATURE_SUID |
131 | + (applets[i].need_suid << 14) /* 2 bits */ | 164 | printf("const uint8_t applet_suid[] ALIGN1 = {\n"); |
132 | #endif | 165 | i = 0; |
133 | ); | 166 | while (i < NUM_APPLETS) { |
167 | int v = applets[i].need_suid; /* 2 bits */ | ||
168 | if (++i < NUM_APPLETS) | ||
169 | v |= applets[i].need_suid << 2; | ||
170 | if (++i < NUM_APPLETS) | ||
171 | v |= applets[i].need_suid << 4; | ||
172 | if (++i < NUM_APPLETS) | ||
173 | v |= applets[i].need_suid << 6; | ||
174 | printf("0x%02x,\n", v); | ||
175 | i++; | ||
134 | } | 176 | } |
135 | printf("};\n\n"); | 177 | printf("};\n\n"); |
178 | #endif | ||
136 | 179 | ||
137 | #if ENABLE_FEATURE_INSTALLER | 180 | #if ENABLE_FEATURE_INSTALLER |
138 | printf("const uint8_t applet_install_loc[] ALIGN1 = {\n"); | 181 | printf("const uint8_t applet_install_loc[] ALIGN1 = {\n"); |