aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/mod
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-06-02 08:15:10 -0400
committerTakashi Iwai <tiwai@suse.de>2010-06-02 08:15:10 -0400
commite4caa8bab3862a7694ab7c6dfede223227ad7fc5 (patch)
tree9fa537a72f00f6b4f86c2da7be2e9554304a8ec4 /scripts/mod
parent9f75c1b12c5ef392ddcea575b13560842c28b1b3 (diff)
parentedb39935c8b19fcd9a8f619d0bc1e9d04594cd2b (diff)
Merge branch 'master' of git.alsa-project.org:alsa-kernel into fix/hda
Diffstat (limited to 'scripts/mod')
-rw-r--r--scripts/mod/modpost.c152
1 files changed, 88 insertions, 64 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 20923613467c..3318692e4e76 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -781,10 +781,13 @@ static void check_section(const char *modname, struct elf_info *elf,
781#define ALL_EXIT_TEXT_SECTIONS \ 781#define ALL_EXIT_TEXT_SECTIONS \
782 ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$" 782 ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$"
783 783
784#define ALL_INIT_SECTIONS INIT_SECTIONS, DEV_INIT_SECTIONS, \ 784#define ALL_XXXINIT_SECTIONS DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, \
785 CPU_INIT_SECTIONS, MEM_INIT_SECTIONS 785 MEM_INIT_SECTIONS
786#define ALL_EXIT_SECTIONS EXIT_SECTIONS, DEV_EXIT_SECTIONS, \ 786#define ALL_XXXEXIT_SECTIONS DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, \
787 CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS 787 MEM_EXIT_SECTIONS
788
789#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
790#define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
788 791
789#define DATA_SECTIONS ".data$", ".data.rel$" 792#define DATA_SECTIONS ".data$", ".data.rel$"
790#define TEXT_SECTIONS ".text$" 793#define TEXT_SECTIONS ".text$"
@@ -814,33 +817,29 @@ static const char *data_sections[] = { DATA_SECTIONS, NULL };
814 817
815 818
816/* symbols in .data that may refer to init/exit sections */ 819/* symbols in .data that may refer to init/exit sections */
817static const char *symbol_white_list[] = 820#define DEFAULT_SYMBOL_WHITE_LIST \
818{ 821 "*driver", \
819 "*driver", 822 "*_template", /* scsi uses *_template a lot */ \
820 "*_template", /* scsi uses *_template a lot */ 823 "*_timer", /* arm uses ops structures named _timer a lot */ \
821 "*_timer", /* arm uses ops structures named _timer a lot */ 824 "*_sht", /* scsi also used *_sht to some extent */ \
822 "*_sht", /* scsi also used *_sht to some extent */ 825 "*_ops", \
823 "*_ops", 826 "*_probe", \
824 "*_probe", 827 "*_probe_one", \
825 "*_probe_one", 828 "*_console"
826 "*_console",
827 NULL
828};
829 829
830static const char *head_sections[] = { ".head.text*", NULL }; 830static const char *head_sections[] = { ".head.text*", NULL };
831static const char *linker_symbols[] = 831static const char *linker_symbols[] =
832 { "__init_begin", "_sinittext", "_einittext", NULL }; 832 { "__init_begin", "_sinittext", "_einittext", NULL };
833 833
834enum mismatch { 834enum mismatch {
835 NO_MISMATCH, 835 TEXT_TO_ANY_INIT,
836 TEXT_TO_INIT, 836 DATA_TO_ANY_INIT,
837 DATA_TO_INIT, 837 TEXT_TO_ANY_EXIT,
838 TEXT_TO_EXIT, 838 DATA_TO_ANY_EXIT,
839 DATA_TO_EXIT, 839 XXXINIT_TO_SOME_INIT,
840 XXXINIT_TO_INIT, 840 XXXEXIT_TO_SOME_EXIT,
841 XXXEXIT_TO_EXIT, 841 ANY_INIT_TO_ANY_EXIT,
842 INIT_TO_EXIT, 842 ANY_EXIT_TO_ANY_INIT,
843 EXIT_TO_INIT,
844 EXPORT_TO_INIT_EXIT, 843 EXPORT_TO_INIT_EXIT,
845}; 844};
846 845
@@ -848,6 +847,7 @@ struct sectioncheck {
848 const char *fromsec[20]; 847 const char *fromsec[20];
849 const char *tosec[20]; 848 const char *tosec[20];
850 enum mismatch mismatch; 849 enum mismatch mismatch;
850 const char *symbol_white_list[20];
851}; 851};
852 852
853const struct sectioncheck sectioncheck[] = { 853const struct sectioncheck sectioncheck[] = {
@@ -857,80 +857,103 @@ const struct sectioncheck sectioncheck[] = {
857{ 857{
858 .fromsec = { TEXT_SECTIONS, NULL }, 858 .fromsec = { TEXT_SECTIONS, NULL },
859 .tosec = { ALL_INIT_SECTIONS, NULL }, 859 .tosec = { ALL_INIT_SECTIONS, NULL },
860 .mismatch = TEXT_TO_INIT, 860 .mismatch = TEXT_TO_ANY_INIT,
861 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
861}, 862},
862{ 863{
863 .fromsec = { DATA_SECTIONS, NULL }, 864 .fromsec = { DATA_SECTIONS, NULL },
864 .tosec = { ALL_INIT_SECTIONS, NULL }, 865 .tosec = { ALL_XXXINIT_SECTIONS, NULL },
865 .mismatch = DATA_TO_INIT, 866 .mismatch = DATA_TO_ANY_INIT,
867 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
868},
869{
870 .fromsec = { DATA_SECTIONS, NULL },
871 .tosec = { INIT_SECTIONS, NULL },
872 .mismatch = DATA_TO_ANY_INIT,
873 .symbol_white_list = {
874 "*_template", "*_timer", "*_sht", "*_ops",
875 "*_probe", "*_probe_one", "*_console", NULL
876 },
866}, 877},
867{ 878{
868 .fromsec = { TEXT_SECTIONS, NULL }, 879 .fromsec = { TEXT_SECTIONS, NULL },
869 .tosec = { ALL_EXIT_SECTIONS, NULL }, 880 .tosec = { ALL_EXIT_SECTIONS, NULL },
870 .mismatch = TEXT_TO_EXIT, 881 .mismatch = TEXT_TO_ANY_EXIT,
882 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
871}, 883},
872{ 884{
873 .fromsec = { DATA_SECTIONS, NULL }, 885 .fromsec = { DATA_SECTIONS, NULL },
874 .tosec = { ALL_EXIT_SECTIONS, NULL }, 886 .tosec = { ALL_EXIT_SECTIONS, NULL },
875 .mismatch = DATA_TO_EXIT, 887 .mismatch = DATA_TO_ANY_EXIT,
888 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
876}, 889},
877/* Do not reference init code/data from devinit/cpuinit/meminit code/data */ 890/* Do not reference init code/data from devinit/cpuinit/meminit code/data */
878{ 891{
879 .fromsec = { DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, MEM_INIT_SECTIONS, NULL }, 892 .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
880 .tosec = { INIT_SECTIONS, NULL }, 893 .tosec = { INIT_SECTIONS, NULL },
881 .mismatch = XXXINIT_TO_INIT, 894 .mismatch = XXXINIT_TO_SOME_INIT,
895 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
882}, 896},
883/* Do not reference cpuinit code/data from meminit code/data */ 897/* Do not reference cpuinit code/data from meminit code/data */
884{ 898{
885 .fromsec = { MEM_INIT_SECTIONS, NULL }, 899 .fromsec = { MEM_INIT_SECTIONS, NULL },
886 .tosec = { CPU_INIT_SECTIONS, NULL }, 900 .tosec = { CPU_INIT_SECTIONS, NULL },
887 .mismatch = XXXINIT_TO_INIT, 901 .mismatch = XXXINIT_TO_SOME_INIT,
902 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
888}, 903},
889/* Do not reference meminit code/data from cpuinit code/data */ 904/* Do not reference meminit code/data from cpuinit code/data */
890{ 905{
891 .fromsec = { CPU_INIT_SECTIONS, NULL }, 906 .fromsec = { CPU_INIT_SECTIONS, NULL },
892 .tosec = { MEM_INIT_SECTIONS, NULL }, 907 .tosec = { MEM_INIT_SECTIONS, NULL },
893 .mismatch = XXXINIT_TO_INIT, 908 .mismatch = XXXINIT_TO_SOME_INIT,
909 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
894}, 910},
895/* Do not reference exit code/data from devexit/cpuexit/memexit code/data */ 911/* Do not reference exit code/data from devexit/cpuexit/memexit code/data */
896{ 912{
897 .fromsec = { DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS, NULL }, 913 .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
898 .tosec = { EXIT_SECTIONS, NULL }, 914 .tosec = { EXIT_SECTIONS, NULL },
899 .mismatch = XXXEXIT_TO_EXIT, 915 .mismatch = XXXEXIT_TO_SOME_EXIT,
916 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
900}, 917},
901/* Do not reference cpuexit code/data from memexit code/data */ 918/* Do not reference cpuexit code/data from memexit code/data */
902{ 919{
903 .fromsec = { MEM_EXIT_SECTIONS, NULL }, 920 .fromsec = { MEM_EXIT_SECTIONS, NULL },
904 .tosec = { CPU_EXIT_SECTIONS, NULL }, 921 .tosec = { CPU_EXIT_SECTIONS, NULL },
905 .mismatch = XXXEXIT_TO_EXIT, 922 .mismatch = XXXEXIT_TO_SOME_EXIT,
923 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
906}, 924},
907/* Do not reference memexit code/data from cpuexit code/data */ 925/* Do not reference memexit code/data from cpuexit code/data */
908{ 926{
909 .fromsec = { CPU_EXIT_SECTIONS, NULL }, 927 .fromsec = { CPU_EXIT_SECTIONS, NULL },
910 .tosec = { MEM_EXIT_SECTIONS, NULL }, 928 .tosec = { MEM_EXIT_SECTIONS, NULL },
911 .mismatch = XXXEXIT_TO_EXIT, 929 .mismatch = XXXEXIT_TO_SOME_EXIT,
930 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
912}, 931},
913/* Do not use exit code/data from init code */ 932/* Do not use exit code/data from init code */
914{ 933{
915 .fromsec = { ALL_INIT_SECTIONS, NULL }, 934 .fromsec = { ALL_INIT_SECTIONS, NULL },
916 .tosec = { ALL_EXIT_SECTIONS, NULL }, 935 .tosec = { ALL_EXIT_SECTIONS, NULL },
917 .mismatch = INIT_TO_EXIT, 936 .mismatch = ANY_INIT_TO_ANY_EXIT,
937 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
918}, 938},
919/* Do not use init code/data from exit code */ 939/* Do not use init code/data from exit code */
920{ 940{
921 .fromsec = { ALL_EXIT_SECTIONS, NULL }, 941 .fromsec = { ALL_EXIT_SECTIONS, NULL },
922 .tosec = { ALL_INIT_SECTIONS, NULL }, 942 .tosec = { ALL_INIT_SECTIONS, NULL },
923 .mismatch = EXIT_TO_INIT, 943 .mismatch = ANY_EXIT_TO_ANY_INIT,
944 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
924}, 945},
925/* Do not export init/exit functions or data */ 946/* Do not export init/exit functions or data */
926{ 947{
927 .fromsec = { "__ksymtab*", NULL }, 948 .fromsec = { "__ksymtab*", NULL },
928 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, 949 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
929 .mismatch = EXPORT_TO_INIT_EXIT 950 .mismatch = EXPORT_TO_INIT_EXIT,
951 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
930} 952}
931}; 953};
932 954
933static int section_mismatch(const char *fromsec, const char *tosec) 955static const struct sectioncheck *section_mismatch(
956 const char *fromsec, const char *tosec)
934{ 957{
935 int i; 958 int i;
936 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck); 959 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
@@ -939,10 +962,10 @@ static int section_mismatch(const char *fromsec, const char *tosec)
939 for (i = 0; i < elems; i++) { 962 for (i = 0; i < elems; i++) {
940 if (match(fromsec, check->fromsec) && 963 if (match(fromsec, check->fromsec) &&
941 match(tosec, check->tosec)) 964 match(tosec, check->tosec))
942 return check->mismatch; 965 return check;
943 check++; 966 check++;
944 } 967 }
945 return NO_MISMATCH; 968 return NULL;
946} 969}
947 970
948/** 971/**
@@ -961,7 +984,7 @@ static int section_mismatch(const char *fromsec, const char *tosec)
961 * Pattern 2: 984 * Pattern 2:
962 * Many drivers utilise a *driver container with references to 985 * Many drivers utilise a *driver container with references to
963 * add, remove, probe functions etc. 986 * add, remove, probe functions etc.
964 * These functions may often be marked __init and we do not want to 987 * These functions may often be marked __devinit and we do not want to
965 * warn here. 988 * warn here.
966 * the pattern is identified by: 989 * the pattern is identified by:
967 * tosec = init or exit section 990 * tosec = init or exit section
@@ -982,7 +1005,8 @@ static int section_mismatch(const char *fromsec, const char *tosec)
982 * refsymname = __init_begin, _sinittext, _einittext 1005 * refsymname = __init_begin, _sinittext, _einittext
983 * 1006 *
984 **/ 1007 **/
985static int secref_whitelist(const char *fromsec, const char *fromsym, 1008static int secref_whitelist(const struct sectioncheck *mismatch,
1009 const char *fromsec, const char *fromsym,
986 const char *tosec, const char *tosym) 1010 const char *tosec, const char *tosym)
987{ 1011{
988 /* Check for pattern 1 */ 1012 /* Check for pattern 1 */
@@ -994,7 +1018,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym,
994 /* Check for pattern 2 */ 1018 /* Check for pattern 2 */
995 if (match(tosec, init_exit_sections) && 1019 if (match(tosec, init_exit_sections) &&
996 match(fromsec, data_sections) && 1020 match(fromsec, data_sections) &&
997 match(fromsym, symbol_white_list)) 1021 match(fromsym, mismatch->symbol_white_list))
998 return 0; 1022 return 0;
999 1023
1000 /* Check for pattern 3 */ 1024 /* Check for pattern 3 */
@@ -1155,7 +1179,8 @@ static int is_function(Elf_Sym *sym)
1155 * Try to find symbols near it so user can find it. 1179 * Try to find symbols near it so user can find it.
1156 * Check whitelist before warning - it may be a false positive. 1180 * Check whitelist before warning - it may be a false positive.
1157 */ 1181 */
1158static void report_sec_mismatch(const char *modname, enum mismatch mismatch, 1182static void report_sec_mismatch(const char *modname,
1183 const struct sectioncheck *mismatch,
1159 const char *fromsec, 1184 const char *fromsec,
1160 unsigned long long fromaddr, 1185 unsigned long long fromaddr,
1161 const char *fromsym, 1186 const char *fromsym,
@@ -1186,8 +1211,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1186 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec, 1211 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
1187 tosym, to_p); 1212 tosym, to_p);
1188 1213
1189 switch (mismatch) { 1214 switch (mismatch->mismatch) {
1190 case TEXT_TO_INIT: 1215 case TEXT_TO_ANY_INIT:
1191 fprintf(stderr, 1216 fprintf(stderr,
1192 "The function %s%s() references\n" 1217 "The function %s%s() references\n"
1193 "the %s %s%s%s.\n" 1218 "the %s %s%s%s.\n"
@@ -1197,8 +1222,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1197 to, sec2annotation(tosec), tosym, to_p, 1222 to, sec2annotation(tosec), tosym, to_p,
1198 fromsym, sec2annotation(tosec), tosym); 1223 fromsym, sec2annotation(tosec), tosym);
1199 break; 1224 break;
1200 case DATA_TO_INIT: { 1225 case DATA_TO_ANY_INIT: {
1201 const char **s = symbol_white_list; 1226 const char *const *s = mismatch->symbol_white_list;
1202 fprintf(stderr, 1227 fprintf(stderr,
1203 "The variable %s references\n" 1228 "The variable %s references\n"
1204 "the %s %s%s%s\n" 1229 "the %s %s%s%s\n"
@@ -1211,15 +1236,15 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1211 fprintf(stderr, "\n"); 1236 fprintf(stderr, "\n");
1212 break; 1237 break;
1213 } 1238 }
1214 case TEXT_TO_EXIT: 1239 case TEXT_TO_ANY_EXIT:
1215 fprintf(stderr, 1240 fprintf(stderr,
1216 "The function %s() references a %s in an exit section.\n" 1241 "The function %s() references a %s in an exit section.\n"
1217 "Often the %s %s%s has valid usage outside the exit section\n" 1242 "Often the %s %s%s has valid usage outside the exit section\n"
1218 "and the fix is to remove the %sannotation of %s.\n", 1243 "and the fix is to remove the %sannotation of %s.\n",
1219 fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym); 1244 fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym);
1220 break; 1245 break;
1221 case DATA_TO_EXIT: { 1246 case DATA_TO_ANY_EXIT: {
1222 const char **s = symbol_white_list; 1247 const char *const *s = mismatch->symbol_white_list;
1223 fprintf(stderr, 1248 fprintf(stderr,
1224 "The variable %s references\n" 1249 "The variable %s references\n"
1225 "the %s %s%s%s\n" 1250 "the %s %s%s%s\n"
@@ -1232,8 +1257,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1232 fprintf(stderr, "\n"); 1257 fprintf(stderr, "\n");
1233 break; 1258 break;
1234 } 1259 }
1235 case XXXINIT_TO_INIT: 1260 case XXXINIT_TO_SOME_INIT:
1236 case XXXEXIT_TO_EXIT: 1261 case XXXEXIT_TO_SOME_EXIT:
1237 fprintf(stderr, 1262 fprintf(stderr,
1238 "The %s %s%s%s references\n" 1263 "The %s %s%s%s references\n"
1239 "a %s %s%s%s.\n" 1264 "a %s %s%s%s.\n"
@@ -1243,7 +1268,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1243 to, sec2annotation(tosec), tosym, to_p, 1268 to, sec2annotation(tosec), tosym, to_p,
1244 tosym, fromsym, tosym); 1269 tosym, fromsym, tosym);
1245 break; 1270 break;
1246 case INIT_TO_EXIT: 1271 case ANY_INIT_TO_ANY_EXIT:
1247 fprintf(stderr, 1272 fprintf(stderr,
1248 "The %s %s%s%s references\n" 1273 "The %s %s%s%s references\n"
1249 "a %s %s%s%s.\n" 1274 "a %s %s%s%s.\n"
@@ -1256,7 +1281,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1256 to, sec2annotation(tosec), tosym, to_p, 1281 to, sec2annotation(tosec), tosym, to_p,
1257 sec2annotation(tosec), tosym, to_p); 1282 sec2annotation(tosec), tosym, to_p);
1258 break; 1283 break;
1259 case EXIT_TO_INIT: 1284 case ANY_EXIT_TO_ANY_INIT:
1260 fprintf(stderr, 1285 fprintf(stderr,
1261 "The %s %s%s%s references\n" 1286 "The %s %s%s%s references\n"
1262 "a %s %s%s%s.\n" 1287 "a %s %s%s%s.\n"
@@ -1275,8 +1300,6 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1275 "Fix this by removing the %sannotation of %s " 1300 "Fix this by removing the %sannotation of %s "
1276 "or drop the export.\n", 1301 "or drop the export.\n",
1277 tosym, sec2annotation(tosec), sec2annotation(tosec), tosym); 1302 tosym, sec2annotation(tosec), sec2annotation(tosec), tosym);
1278 case NO_MISMATCH:
1279 /* To get warnings on missing members */
1280 break; 1303 break;
1281 } 1304 }
1282 fprintf(stderr, "\n"); 1305 fprintf(stderr, "\n");
@@ -1286,11 +1309,11 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
1286 Elf_Rela *r, Elf_Sym *sym, const char *fromsec) 1309 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
1287{ 1310{
1288 const char *tosec; 1311 const char *tosec;
1289 enum mismatch mismatch; 1312 const struct sectioncheck *mismatch;
1290 1313
1291 tosec = sec_name(elf, sym->st_shndx); 1314 tosec = sec_name(elf, sym->st_shndx);
1292 mismatch = section_mismatch(fromsec, tosec); 1315 mismatch = section_mismatch(fromsec, tosec);
1293 if (mismatch != NO_MISMATCH) { 1316 if (mismatch) {
1294 Elf_Sym *to; 1317 Elf_Sym *to;
1295 Elf_Sym *from; 1318 Elf_Sym *from;
1296 const char *tosym; 1319 const char *tosym;
@@ -1302,7 +1325,8 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
1302 tosym = sym_name(elf, to); 1325 tosym = sym_name(elf, to);
1303 1326
1304 /* check whitelist - we may ignore it */ 1327 /* check whitelist - we may ignore it */
1305 if (secref_whitelist(fromsec, fromsym, tosec, tosym)) { 1328 if (secref_whitelist(mismatch,
1329 fromsec, fromsym, tosec, tosym)) {
1306 report_sec_mismatch(modname, mismatch, 1330 report_sec_mismatch(modname, mismatch,
1307 fromsec, r->r_offset, fromsym, 1331 fromsec, r->r_offset, fromsym,
1308 is_function(from), tosec, tosym, 1332 is_function(from), tosec, tosym,