summaryrefslogtreecommitdiff
path: root/apps/plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugin.c')
-rw-r--r--apps/plugin.c102
1 files changed, 31 insertions, 71 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index cc540cd988..53a05bf527 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -42,6 +42,7 @@
42#include "errno.h" 42#include "errno.h"
43#include "diacritic.h" 43#include "diacritic.h"
44#include "filefuncs.h" 44#include "filefuncs.h"
45#include "load_code.h"
45 46
46#if CONFIG_CHARGING 47#if CONFIG_CHARGING
47#include "power.h" 48#include "power.h"
@@ -75,21 +76,19 @@ static unsigned int open_files;
75 76
76#if (CONFIG_PLATFORM & PLATFORM_HOSTED) 77#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
77static unsigned char pluginbuf[PLUGIN_BUFFER_SIZE]; 78static unsigned char pluginbuf[PLUGIN_BUFFER_SIZE];
78void *sim_plugin_load(char *plugin, void **pd);
79void sim_plugin_close(void *pd);
80void sim_lcd_ex_init(unsigned long (*getpixel)(int, int)); 79void sim_lcd_ex_init(unsigned long (*getpixel)(int, int));
81void sim_lcd_ex_update_rect(int x, int y, int width, int height); 80void sim_lcd_ex_update_rect(int x, int y, int width, int height);
82#else 81#else
83#define sim_plugin_close(x)
84extern unsigned char pluginbuf[]; 82extern unsigned char pluginbuf[];
85#include "bitswap.h" 83#include "bitswap.h"
86#endif 84#endif
87 85
88/* for actual plugins only, not for codecs */ 86/* for actual plugins only, not for codecs */
89static bool plugin_loaded = false;
90static int plugin_size = 0; 87static int plugin_size = 0;
91static bool (*pfn_tsr_exit)(bool reenter) = NULL; /* TSR exit callback */ 88static bool (*pfn_tsr_exit)(bool reenter) = NULL; /* TSR exit callback */
92static char current_plugin[MAX_PATH]; 89static char current_plugin[MAX_PATH];
90/* NULL if no plugin is loaded, otherwise the handle that lc_open() returned */
91static void *current_plugin_handle;
93 92
94char *plugin_get_current_filename(void); 93char *plugin_get_current_filename(void);
95 94
@@ -728,98 +727,60 @@ int plugin_load(const char* plugin, const void* parameter)
728{ 727{
729 int rc, i; 728 int rc, i;
730 struct plugin_header *hdr; 729 struct plugin_header *hdr;
731#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
732 void *pd;
733#else /* PLATFOR_NATIVE */
734 int fd;
735 ssize_t readsize;
736#if NUM_CORES > 1
737 unsigned my_core;
738#endif
739#endif /* CONFIG_PLATFORM */
740 730
741#if LCD_DEPTH > 1 731#if LCD_DEPTH > 1
742 fb_data* old_backdrop; 732 fb_data* old_backdrop;
743#endif 733#endif
744 734
745 if (pfn_tsr_exit != NULL) /* if we have a resident old plugin: */ 735 if (current_plugin_handle && pfn_tsr_exit)
746 { 736 { /* if we have a resident old plugin and a callback */
747 if (pfn_tsr_exit(!strcmp(current_plugin, plugin)) == false ) 737 if (pfn_tsr_exit(!strcmp(current_plugin, plugin)) == false )
748 { 738 {
749 /* not allowing another plugin to load */ 739 /* not allowing another plugin to load */
750 return PLUGIN_OK; 740 return PLUGIN_OK;
751 } 741 }
752 pfn_tsr_exit = NULL; 742 lc_close(current_plugin_handle);
753 plugin_loaded = false; 743 current_plugin_handle = pfn_tsr_exit = NULL;
754 } 744 }
755 745
756 splash(0, ID2P(LANG_WAIT)); 746 splash(0, ID2P(LANG_WAIT));
757 strcpy(current_plugin, plugin); 747 strcpy(current_plugin, plugin);
758 748
759#if (CONFIG_PLATFORM & PLATFORM_HOSTED) 749 current_plugin_handle = lc_open(plugin, pluginbuf, PLUGIN_BUFFER_SIZE);
760 hdr = sim_plugin_load((char *)plugin, &pd); 750 if (current_plugin_handle == NULL) {
761 if (pd == NULL) {
762 splashf(HZ*2, str(LANG_PLUGIN_CANT_OPEN), plugin); 751 splashf(HZ*2, str(LANG_PLUGIN_CANT_OPEN), plugin);
763 return -1; 752 return -1;
764 } 753 }
765 if (hdr == NULL
766 || hdr->magic != PLUGIN_MAGIC
767 || hdr->target_id != TARGET_ID) {
768 sim_plugin_close(pd);
769 splash(HZ*2, str(LANG_PLUGIN_WRONG_MODEL));
770 return -1;
771 }
772 if (hdr->api_version > PLUGIN_API_VERSION
773 || hdr->api_version < PLUGIN_MIN_API_VERSION) {
774 sim_plugin_close(pd);
775 splash(HZ*2, str(LANG_PLUGIN_WRONG_VERSION));
776 return -1;
777 }
778#else
779 fd = open(plugin, O_RDONLY);
780 if (fd < 0) {
781 splashf(HZ*2, str(LANG_PLUGIN_CANT_OPEN), plugin);
782 return fd;
783 }
784#if NUM_CORES > 1
785 /* Make sure COP cache is flushed and invalidated before loading */
786 my_core = switch_core(CURRENT_CORE ^ 1);
787 cpucache_invalidate();
788 switch_core(my_core);
789#endif
790 754
791 readsize = read(fd, pluginbuf, PLUGIN_BUFFER_SIZE); 755 hdr = lc_get_header(current_plugin_handle);
792 close(fd);
793 756
794 if (readsize < 0) { 757 if (hdr == NULL
795 splashf(HZ*2, str(LANG_READ_FAILED), plugin);
796 return -1;
797 }
798 hdr = (struct plugin_header *)pluginbuf;
799
800 if ((unsigned)readsize <= sizeof(struct plugin_header)
801 || hdr->magic != PLUGIN_MAGIC 758 || hdr->magic != PLUGIN_MAGIC
802 || hdr->target_id != TARGET_ID 759 || hdr->target_id != TARGET_ID
760#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
803 || hdr->load_addr != pluginbuf 761 || hdr->load_addr != pluginbuf
804 || hdr->end_addr > pluginbuf + PLUGIN_BUFFER_SIZE) { 762 || hdr->end_addr > pluginbuf + PLUGIN_BUFFER_SIZE
763#endif
764 )
765 {
766 lc_close(current_plugin_handle);
805 splash(HZ*2, str(LANG_PLUGIN_WRONG_MODEL)); 767 splash(HZ*2, str(LANG_PLUGIN_WRONG_MODEL));
806 return -1; 768 return -1;
807 } 769 }
808 if (hdr->api_version > PLUGIN_API_VERSION 770 if (hdr->api_version > PLUGIN_API_VERSION
809 || hdr->api_version < PLUGIN_MIN_API_VERSION) { 771 || hdr->api_version < PLUGIN_MIN_API_VERSION)
772 {
773 lc_close(current_plugin_handle);
810 splash(HZ*2, str(LANG_PLUGIN_WRONG_VERSION)); 774 splash(HZ*2, str(LANG_PLUGIN_WRONG_VERSION));
811 return -1; 775 return -1;
812 } 776 }
777#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
813 plugin_size = hdr->end_addr - pluginbuf; 778 plugin_size = hdr->end_addr - pluginbuf;
814 779#else
815 /* zero out bss area only, above guards end of pluginbuf */ 780 plugin_size = 0;
816 if (plugin_size > readsize)
817 memset(pluginbuf + readsize, 0, plugin_size - readsize);
818#endif 781#endif
819 782
820 *(hdr->api) = &rockbox_api; 783 *(hdr->api) = &rockbox_api;
821 plugin_loaded = true;
822
823 784
824#if defined HAVE_LCD_BITMAP && LCD_DEPTH > 1 785#if defined HAVE_LCD_BITMAP && LCD_DEPTH > 1
825 old_backdrop = lcd_get_backdrop(); 786 old_backdrop = lcd_get_backdrop();
@@ -834,8 +795,6 @@ int plugin_load(const char* plugin, const void* parameter)
834 795
835 FOR_NB_SCREENS(i) 796 FOR_NB_SCREENS(i)
836 viewportmanager_theme_enable(i, false, NULL); 797 viewportmanager_theme_enable(i, false, NULL);
837
838 cpucache_invalidate();
839 798
840#ifdef HAVE_TOUCHSCREEN 799#ifdef HAVE_TOUCHSCREEN
841 touchscreen_set_mode(TOUCHSCREEN_BUTTON); 800 touchscreen_set_mode(TOUCHSCREEN_BUTTON);
@@ -847,6 +806,12 @@ int plugin_load(const char* plugin, const void* parameter)
847 806
848 rc = hdr->entry_point(parameter); 807 rc = hdr->entry_point(parameter);
849 808
809 if (!pfn_tsr_exit)
810 { /* close handle if plugin is no tsr one */
811 lc_close(current_plugin_handle);
812 current_plugin_handle = NULL;
813 }
814
850 /* Go back to the global setting in case the plugin changed it */ 815 /* Go back to the global setting in case the plugin changed it */
851#ifdef HAVE_TOUCHSCREEN 816#ifdef HAVE_TOUCHSCREEN
852 touchscreen_set_mode(global_settings.touch_mode); 817 touchscreen_set_mode(global_settings.touch_mode);
@@ -887,11 +852,8 @@ int plugin_load(const char* plugin, const void* parameter)
887 FOR_NB_SCREENS(i) 852 FOR_NB_SCREENS(i)
888 viewportmanager_theme_undo(i, false); 853 viewportmanager_theme_undo(i, false);
889 854
890 if (pfn_tsr_exit == NULL)
891 plugin_loaded = false;
892
893#ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE 855#ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
894 if(open_files != 0 && !plugin_loaded) 856 if(open_files != 0 && !current_plugin_handle)
895 { 857 {
896 int fd; 858 int fd;
897 logf("Plugin '%s' leaks file handles", plugin); 859 logf("Plugin '%s' leaks file handles", plugin);
@@ -909,8 +871,6 @@ int plugin_load(const char* plugin, const void* parameter)
909 } 871 }
910#endif 872#endif
911 873
912 sim_plugin_close(pd);
913
914 if (rc == PLUGIN_ERROR) 874 if (rc == PLUGIN_ERROR)
915 splash(HZ*2, str(LANG_PLUGIN_ERROR)); 875 splash(HZ*2, str(LANG_PLUGIN_ERROR));
916 876
@@ -923,7 +883,7 @@ void* plugin_get_buffer(size_t *buffer_size)
923{ 883{
924 int buffer_pos; 884 int buffer_pos;
925 885
926 if (plugin_loaded) 886 if (current_plugin_handle)
927 { 887 {
928 if (plugin_size >= PLUGIN_BUFFER_SIZE) 888 if (plugin_size >= PLUGIN_BUFFER_SIZE)
929 return NULL; 889 return NULL;