diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2023-03-14 12:19:48 +0000 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2023-03-21 16:23:54 -0400 |
commit | d40a598970b04bfe3a867a5e12debc45c149b46b (patch) | |
tree | 26e974f910f7d3047adfbc536d8e10c2d973b7e9 /apps | |
parent | 2fb2364686e5470437f0ee3d214662d51067eb90 (diff) | |
download | rockbox-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
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs.c | 5 | ||||
-rw-r--r-- | apps/plugin.c | 8 | ||||
-rw-r--r-- | apps/plugin.h | 21 | ||||
-rw-r--r-- | apps/plugins/imageviewer/image_decoder.c | 5 | ||||
-rw-r--r-- | apps/plugins/imageviewer/imageviewer.h | 14 | ||||
-rw-r--r-- | apps/plugins/lib/overlay.c | 5 |
6 files changed, 34 insertions, 24 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 */ |
142 | struct imgdec_header { | 142 | struct 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; |