summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2023-03-14 12:19:48 +0000
committerAidan MacDonald <amachronic@protonmail.com>2023-03-21 16:23:54 -0400
commitd40a598970b04bfe3a867a5e12debc45c149b46b (patch)
tree26e974f910f7d3047adfbc536d8e10c2d973b7e9
parent2fb2364686e5470437f0ee3d214662d51067eb90 (diff)
downloadrockbox-d40a598970b04bfe3a867a5e12debc45c149b46b.tar.gz
rockbox-d40a598970b04bfe3a867a5e12debc45c149b46b.zip
plugins: Simplify plugin/codec API versioning
Replace the minimum version bound with a check on the size of the API struct. The version only needs to be incremented for ABI breaking changes. Additions to the API won't need to touch the version number, resulting in fewer merge conflicts. Change-Id: I916a04a7bf5890dcf5d615ce30087643165f8e1f
-rw-r--r--apps/codecs.c5
-rw-r--r--apps/plugin.c8
-rw-r--r--apps/plugin.h21
-rw-r--r--apps/plugins/imageviewer/image_decoder.c5
-rw-r--r--apps/plugins/imageviewer/imageviewer.h14
-rw-r--r--apps/plugins/lib/overlay.c5
-rw-r--r--lib/rbcodec/codecs/codecs.h28
7 files changed, 49 insertions, 37 deletions
diff --git a/apps/codecs.c b/apps/codecs.c
index 4d2dd34ce0..9f34d26e14 100644
--- a/apps/codecs.c
+++ b/apps/codecs.c
@@ -203,8 +203,9 @@ static int codec_load_ram(struct codec_api *api)
203 return CODEC_ERROR; 203 return CODEC_ERROR;
204 } 204 }
205 205
206 if (hdr->api_version > CODEC_API_VERSION 206 if (hdr->api_version != CODEC_API_VERSION ||
207 || hdr->api_version < CODEC_MIN_API_VERSION) { 207 c_hdr->api_size > sizeof(struct codec_api))
208 {
208 logf("codec api version error"); 209 logf("codec api version error");
209 lc_close(curr_handle); 210 lc_close(curr_handle);
210 curr_handle = NULL; 211 curr_handle = NULL;
diff --git a/apps/plugin.c b/apps/plugin.c
index cdbe340ddd..1a0aedf3cc 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -864,10 +864,8 @@ int plugin_load(const char* plugin, const void* parameter)
864 } 864 }
865 865
866 p_hdr = lc_get_header(current_plugin_handle); 866 p_hdr = lc_get_header(current_plugin_handle);
867
868 hdr = p_hdr ? &p_hdr->lc_hdr : NULL; 867 hdr = p_hdr ? &p_hdr->lc_hdr : NULL;
869 868
870
871 if (hdr == NULL 869 if (hdr == NULL
872 || hdr->magic != PLUGIN_MAGIC 870 || hdr->magic != PLUGIN_MAGIC
873 || hdr->target_id != TARGET_ID 871 || hdr->target_id != TARGET_ID
@@ -881,13 +879,15 @@ int plugin_load(const char* plugin, const void* parameter)
881 splash(HZ*2, ID2P(LANG_PLUGIN_WRONG_MODEL)); 879 splash(HZ*2, ID2P(LANG_PLUGIN_WRONG_MODEL));
882 return -1; 880 return -1;
883 } 881 }
884 if (hdr->api_version > PLUGIN_API_VERSION 882
885 || hdr->api_version < PLUGIN_MIN_API_VERSION) 883 if (hdr->api_version != PLUGIN_API_VERSION ||
884 p_hdr->api_size > sizeof(struct plugin_api))
886 { 885 {
887 lc_close(current_plugin_handle); 886 lc_close(current_plugin_handle);
888 splash(HZ*2, ID2P(LANG_PLUGIN_WRONG_VERSION)); 887 splash(HZ*2, ID2P(LANG_PLUGIN_WRONG_VERSION));
889 return -1; 888 return -1;
890 } 889 }
890
891#if (CONFIG_PLATFORM & PLATFORM_NATIVE) 891#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
892 /* tlsf crashes observed on arm with 0x4 aligned addresses */ 892 /* tlsf crashes observed on arm with 0x4 aligned addresses */
893 plugin_size = ALIGN_UP(hdr->end_addr - pluginbuf, 0x8); 893 plugin_size = ALIGN_UP(hdr->end_addr - pluginbuf, 0x8);
diff --git a/apps/plugin.h b/apps/plugin.h
index 286a5e2794..cf6a1bc4e4 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -157,13 +157,12 @@ int plugin_open(const char *plugin, const char *parameter);
157 157
158#define PLUGIN_MAGIC 0x526F634B /* RocK */ 158#define PLUGIN_MAGIC 0x526F634B /* RocK */
159 159
160/* increase this every time the api struct changes */ 160/*
161#define PLUGIN_API_VERSION 265 161 * Increment this whenever a change breaks the plugin ABI,
162 162 * when this happens please take the opportunity to sort in
163/* update this to latest version if a change to the api struct breaks 163 * any new functions "waiting" at the end of the list.
164 backwards compatibility (and please take the opportunity to sort in any 164 */
165 new function which are "waiting" at the end of the function table) */ 165#define PLUGIN_API_VERSION 266
166#define PLUGIN_MIN_API_VERSION 260
167 166
168/* 239 Marks the removal of ARCHOS HWCODEC and CHARCELL */ 167/* 239 Marks the removal of ARCHOS HWCODEC and CHARCELL */
169 168
@@ -962,6 +961,7 @@ struct plugin_header {
962 struct lc_header lc_hdr; /* must be the first */ 961 struct lc_header lc_hdr; /* must be the first */
963 enum plugin_status(*entry_point)(const void*); 962 enum plugin_status(*entry_point)(const void*);
964 const struct plugin_api **api; 963 const struct plugin_api **api;
964 size_t api_size;
965}; 965};
966 966
967#ifdef PLUGIN 967#ifdef PLUGIN
@@ -973,14 +973,15 @@ extern unsigned char plugin_end_addr[];
973 const struct plugin_header __header \ 973 const struct plugin_header __header \
974 __attribute__ ((section (".header")))= { \ 974 __attribute__ ((section (".header")))= { \
975 { PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, \ 975 { PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, \
976 plugin_start_addr, plugin_end_addr }, plugin__start, &rb }; 976 plugin_start_addr, plugin_end_addr, }, \
977 plugin__start, &rb, sizeof(struct plugin_api) };
977#else /* PLATFORM_HOSTED */ 978#else /* PLATFORM_HOSTED */
978#define PLUGIN_HEADER \ 979#define PLUGIN_HEADER \
979 const struct plugin_api *rb DATA_ATTR; \ 980 const struct plugin_api *rb DATA_ATTR; \
980 const struct plugin_header __header \ 981 const struct plugin_header __header \
981 __attribute__((visibility("default"))) = { \ 982 __attribute__((visibility("default"))) = { \
982 { PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, NULL, NULL }, \ 983 { PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, NULL, NULL }, \
983 plugin__start, &rb }; 984 plugin__start, &rb, sizeof(struct plugin_api) };
984#endif /* CONFIG_PLATFORM */ 985#endif /* CONFIG_PLATFORM */
985#endif /* PLUGIN */ 986#endif /* PLUGIN */
986 987
diff --git a/apps/plugins/imageviewer/image_decoder.c b/apps/plugins/imageviewer/image_decoder.c
index eab1c01dbc..0c1776daaa 100644
--- a/apps/plugins/imageviewer/image_decoder.c
+++ b/apps/plugins/imageviewer/image_decoder.c
@@ -155,7 +155,10 @@ const struct image_decoder *load_decoder(struct loader_info *loader_info)
155 goto error_close; 155 goto error_close;
156 } 156 }
157 157
158 if (lc_hdr->api_version != IMGDEC_API_VERSION) 158 if (lc_hdr->api_version != IMGDEC_API_VERSION ||
159 hdr->img_api_size > sizeof(struct imgdec_api) ||
160 hdr->plugin_api_version != PLUGIN_API_VERSION ||
161 hdr->plugin_api_size > sizeof(struct plugin_api))
159 { 162 {
160 rb->splashf(2*HZ, "%s decoder: Incompatible version.", name); 163 rb->splashf(2*HZ, "%s decoder: Incompatible version.", name);
161 goto error_close; 164 goto error_close;
diff --git a/apps/plugins/imageviewer/imageviewer.h b/apps/plugins/imageviewer/imageviewer.h
index 19b5db15bb..ac15df5960 100644
--- a/apps/plugins/imageviewer/imageviewer.h
+++ b/apps/plugins/imageviewer/imageviewer.h
@@ -136,14 +136,17 @@ struct image_decoder {
136 int x, int y, int width, int height); 136 int x, int y, int width, int height);
137}; 137};
138 138
139#define IMGDEC_API_VERSION (PLUGIN_API_VERSION << 4 | 0) 139#define IMGDEC_API_VERSION 1
140 140
141/* image decoder header */ 141/* image decoder header */
142struct imgdec_header { 142struct imgdec_header {
143 struct lc_header lc_hdr; /* must be the first */ 143 struct lc_header lc_hdr; /* must be the first */
144 const struct image_decoder *decoder; 144 const struct image_decoder *decoder;
145 const struct plugin_api **api; 145 const struct plugin_api **api;
146 unsigned short plugin_api_version;
147 size_t plugin_api_size;
146 const struct imgdec_api **img_api; 148 const struct imgdec_api **img_api;
149 size_t img_api_size;
147}; 150};
148 151
149#ifdef IMGDEC 152#ifdef IMGDEC
@@ -157,15 +160,18 @@ extern const struct image_decoder image_decoder;
157 const struct imgdec_header __header \ 160 const struct imgdec_header __header \
158 __attribute__ ((section (".header")))= { \ 161 __attribute__ ((section (".header")))= { \
159 { PLUGIN_MAGIC, TARGET_ID, IMGDEC_API_VERSION, \ 162 { PLUGIN_MAGIC, TARGET_ID, IMGDEC_API_VERSION, \
160 plugin_start_addr, plugin_end_addr }, &image_decoder, &rb, &iv }; 163 plugin_start_addr, plugin_end_addr, }, &image_decoder, \
164 &rb, PLUGIN_API_VERSION, sizeof(struct plugin_api), \
165 &iv, sizeof(struct imgdec_api) };
161#else /* PLATFORM_HOSTED */ 166#else /* PLATFORM_HOSTED */
162#define IMGDEC_HEADER \ 167#define IMGDEC_HEADER \
163 const struct plugin_api *rb DATA_ATTR; \ 168 const struct plugin_api *rb DATA_ATTR; \
164 const struct imgdec_api *iv DATA_ATTR; \ 169 const struct imgdec_api *iv DATA_ATTR; \
165 const struct imgdec_header __header \ 170 const struct imgdec_header __header \
166 __attribute__((visibility("default"))) = { \ 171 __attribute__((visibility("default"))) = { \
167 { PLUGIN_MAGIC, TARGET_ID, IMGDEC_API_VERSION, \ 172 { PLUGIN_MAGIC, TARGET_ID, IMGDEC_API_VERSION, NULL, NULL }, \
168 NULL, NULL }, &image_decoder, &rb, &iv }; 173 &image_decoder, &rb, PLUGIN_API_VERSION, sizeof(struct plugin_api), \
174 &iv, sizeof(struct imgdec_api), };
169#endif /* CONFIG_PLATFORM */ 175#endif /* CONFIG_PLATFORM */
170#endif 176#endif
171 177
diff --git a/apps/plugins/lib/overlay.c b/apps/plugins/lib/overlay.c
index 0ecc1bf3e7..065273534e 100644
--- a/apps/plugins/lib/overlay.c
+++ b/apps/plugins/lib/overlay.c
@@ -83,9 +83,8 @@ enum plugin_status run_overlay(const void* parameter,
83 goto error_close; 83 goto error_close;
84 } 84 }
85 85
86 86 if (hdr->api_version != PLUGIN_API_VERSION ||
87 if (hdr->api_version > PLUGIN_API_VERSION 87 p_hdr->api_size > sizeof(struct plugin_api))
88 || hdr->api_version < PLUGIN_MIN_API_VERSION)
89 { 88 {
90 rb->splashf(2*HZ, "%s overlay: Incompatible version.", name); 89 rb->splashf(2*HZ, "%s overlay: Incompatible version.", name);
91 goto error_close; 90 goto error_close;
diff --git a/lib/rbcodec/codecs/codecs.h b/lib/rbcodec/codecs/codecs.h
index fd19dcb6b5..aa9d2e8a0d 100644
--- a/lib/rbcodec/codecs/codecs.h
+++ b/lib/rbcodec/codecs/codecs.h
@@ -71,13 +71,12 @@
71/* magic for encoder codecs */ 71/* magic for encoder codecs */
72#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */ 72#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */
73 73
74/* increase this every time the api struct changes */ 74/*
75#define CODEC_API_VERSION 49 75 * Increment this whenever a change breaks the codec ABI,
76 76 * when this happens please take the opportunity to sort in
77/* update this to latest version if a change to the api struct breaks 77 * any new functions "waiting" at the end of the list.
78 backwards compatibility (and please take the opportunity to sort in any 78 */
79 new function which are "waiting" at the end of the function table) */ 79#define CODEC_API_VERSION 50
80#define CODEC_MIN_API_VERSION 49
81 80
82/* reasons for calling codec main entrypoint */ 81/* reasons for calling codec main entrypoint */
83enum codec_entry_call_reason { 82enum codec_entry_call_reason {
@@ -228,6 +227,7 @@ struct codec_header {
228 enum codec_status(*entry_point)(enum codec_entry_call_reason reason); 227 enum codec_status(*entry_point)(enum codec_entry_call_reason reason);
229 enum codec_status(*run_proc)(void); 228 enum codec_status(*run_proc)(void);
230 struct codec_api **api; 229 struct codec_api **api;
230 size_t api_size;
231 void * rec_extension[]; /* extension for encoders */ 231 void * rec_extension[]; /* extension for encoders */
232}; 232};
233 233
@@ -241,15 +241,16 @@ extern unsigned char plugin_end_addr[];
241 const struct codec_header __header \ 241 const struct codec_header __header \
242 __attribute__ ((section (".header")))= { \ 242 __attribute__ ((section (".header")))= { \
243 { CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, \ 243 { CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, \
244 plugin_start_addr, plugin_end_addr }, codec_start, \ 244 plugin_start_addr, plugin_end_addr }, \
245 codec_run, &ci }; 245 codec_start, codec_run, &ci, sizeof(struct codec_api) };
246/* encoders */ 246/* encoders */
247#define CODEC_ENC_HEADER \ 247#define CODEC_ENC_HEADER \
248 const struct codec_header __header \ 248 const struct codec_header __header \
249 __attribute__ ((section (".header")))= { \ 249 __attribute__ ((section (".header")))= { \
250 { CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, \ 250 { CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, \
251 plugin_start_addr, plugin_end_addr }, codec_start, \ 251 plugin_start_addr, plugin_end_addr }, \
252 codec_run, &ci, { enc_callback } }; 252 codec_start, codec_run, &ci, sizeof(struct codec_api), \
253 { enc_callback } };
253 254
254#else /* def SIMULATOR */ 255#else /* def SIMULATOR */
255/* decoders */ 256/* decoders */
@@ -257,13 +258,14 @@ extern unsigned char plugin_end_addr[];
257 const struct codec_header __header \ 258 const struct codec_header __header \
258 __attribute__((visibility("default"))) = { \ 259 __attribute__((visibility("default"))) = { \
259 { CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, NULL, NULL }, \ 260 { CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, NULL, NULL }, \
260 codec_start, codec_run, &ci }; 261 codec_start, codec_run, &ci, sizeof(struct codec_api) };
261/* encoders */ 262/* encoders */
262#define CODEC_ENC_HEADER \ 263#define CODEC_ENC_HEADER \
263 const struct codec_header __header \ 264 const struct codec_header __header \
264 __attribute__((visibility("default"))) = { \ 265 __attribute__((visibility("default"))) = { \
265 { CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, NULL, NULL }, \ 266 { CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, NULL, NULL }, \
266 codec_start, codec_run, &ci, { enc_callback } }; 267 codec_start, codec_run, &ci, sizeof(struct codec_api), \
268 { enc_callback } };
267#endif /* SIMULATOR */ 269#endif /* SIMULATOR */
268#endif /* CODEC */ 270#endif /* CODEC */
269 271