comparison lwasm/lwasm.c @ 432:58cafa61ab40

Add support for undocumented custom module format (for LW) Nothing to see here. Move along. These are not the droids you are looking for.
author William Astle <lost@l-w.ca>
date Fri, 18 Nov 2016 21:25:43 -0700
parents 5dc9f9d47064
children b1adf549d181
comparison
equal deleted inserted replaced
431:6df8d62302e2 432:58cafa61ab40
117 { 117 {
118 case lwasm_expr_secbase: 118 case lwasm_expr_secbase:
119 { 119 {
120 // sectiontab_t *s = priv; 120 // sectiontab_t *s = priv;
121 asmstate_t *as = priv; 121 asmstate_t *as = priv;
122 if (((sectiontab_t *)ptr) -> tbase != -1)
123 {
124 return lw_expr_build(lw_expr_type_int, ((sectiontab_t *)ptr) -> tbase);
125 }
122 if (as -> exportcheck && ptr == as -> csect) 126 if (as -> exportcheck && ptr == as -> csect)
123 return lw_expr_build(lw_expr_type_int, 0); 127 return lw_expr_build(lw_expr_type_int, 0);
124 if (((sectiontab_t *)ptr) -> flags & section_flag_constant) 128 if (((sectiontab_t *)ptr) -> flags & section_flag_constant)
125 return lw_expr_build(lw_expr_type_int, 0); 129 return lw_expr_build(lw_expr_type_int, 0);
126 return NULL; 130 return NULL;
270 case E_STRUCT_NOSYMBOL: return "Structure definition with no effect - no symbol"; 274 case E_STRUCT_NOSYMBOL: return "Structure definition with no effect - no symbol";
271 case E_STRUCT_RECURSE: return "Attempt to define a structure inside a structure"; 275 case E_STRUCT_RECURSE: return "Attempt to define a structure inside a structure";
272 case E_SYMBOL_DUPE: return "Multiply defined symbol"; 276 case E_SYMBOL_DUPE: return "Multiply defined symbol";
273 case E_UNKNOWN_OPERATION: return "Unknown operation"; 277 case E_UNKNOWN_OPERATION: return "Unknown operation";
274 case E_ORG_NOT_FOUND: return "Previous ORG not found"; 278 case E_ORG_NOT_FOUND: return "Previous ORG not found";
279 case E_COMPLEX_INCOMPLETE: return "Incomplete expression too complex";
275 case E_USER_SPECIFIED: return "User Specified:"; 280 case E_USER_SPECIFIED: return "User Specified:";
276 281
277 case W_ENDSTRUCT_WITHOUT: return "ENDSTRUCT without STRUCT"; 282 case W_ENDSTRUCT_WITHOUT: return "ENDSTRUCT without STRUCT";
278 case W_DUPLICATE_SECTION: return "Section flags can only be specified the first time; ignoring duplicate definition"; 283 case W_DUPLICATE_SECTION: return "Section flags can only be specified the first time; ignoring duplicate definition";
279 case W_NOT_SUPPORTED: return "Not supported"; 284 case W_NOT_SUPPORTED: return "Not supported";
945 return; 950 return;
946 for (; **p && !isspace(**p); (*p)++) 951 for (; **p && !isspace(**p); (*p)++)
947 /* do nothing */ ; 952 /* do nothing */ ;
948 } 953 }
949 954
955 struct auxdata {
956 int v;
957 int oc;
958 int ms;
959 };
960
961 int lwasm_emitexpr_auxlwmod(lw_expr_t expr, void *arg)
962 {
963 struct auxdata *ad = arg;
964 if (lw_expr_istype(expr, lw_expr_type_int))
965 {
966 ad -> v = lw_expr_intval(expr);
967 return 0;
968 }
969 if (lw_expr_istype(expr, lw_expr_type_special))
970 {
971 if (lw_expr_specint(expr) == lwasm_expr_secbase)
972 {
973 sectiontab_t *s;
974 s = lw_expr_specptr(expr);
975 if (strcmp(s -> name, "main") == 0)
976 {
977 ad -> ms = 1;
978 return 0;
979 }
980 if (strcmp(s -> name, "bss"))
981 return -1;
982 return 0;
983 }
984 return -1;
985 }
986 if (lw_expr_whichop(expr) == lw_expr_oper_plus)
987 {
988 if (ad -> oc)
989 return -1;
990 ad -> oc = 1;
991 return 0;
992 }
993 return -1;
994 }
995
950 int lwasm_emitexpr(line_t *l, lw_expr_t expr, int size) 996 int lwasm_emitexpr(line_t *l, lw_expr_t expr, int size)
951 { 997 {
952 int v = 0; 998 int v = 0;
953 int ol; 999 int ol;
954 1000
961 v = lw_expr_intval(expr); 1007 v = lw_expr_intval(expr);
962 } 1008 }
963 // handle external/cross-section/incomplete references here 1009 // handle external/cross-section/incomplete references here
964 else 1010 else
965 { 1011 {
966 if (l -> as -> output_format == OUTPUT_OBJ) 1012 if (l -> as -> output_format == OUTPUT_LWMOD)
1013 {
1014 reloctab_t *re;
1015 lw_expr_t te;
1016 struct auxdata ad;
1017 ad.v = 0;
1018 ad.oc = 0;
1019 ad.ms = 0;
1020
1021 if (l -> csect == NULL)
1022 {
1023 lwasm_register_error(l -> as, l, E_INSTRUCTION_SECTION);
1024 return -1;
1025 }
1026 if (size != 2)
1027 {
1028 lwasm_register_error(l -> as, l, E_OPERAND_BAD);
1029 return -1;
1030 }
1031 // we have a 16 bit reference here - we need to check to make sure
1032 // it's at most a + or - with the BSS section base
1033 v = lw_expr_whichop(expr);
1034 if (v == -1)
1035 {
1036 v = 0;
1037 if (lw_expr_testterms(expr, lwasm_emitexpr_auxlwmod, &ad) != 0)
1038 {
1039 lwasm_register_error(l -> as, l, E_COMPLEX_INCOMPLETE);
1040 return -1;
1041 }
1042 v = ad.v;
1043 }
1044 else if (v == lw_expr_oper_plus)
1045 {
1046 v = 0;
1047 if (lw_expr_operandcount(expr) > 2)
1048 {
1049 lwasm_register_error(l -> as, l, E_COMPLEX_INCOMPLETE);
1050 return -1;
1051 }
1052 if (lw_expr_testterms(expr, lwasm_emitexpr_auxlwmod, &ad) != 0)
1053 {
1054 lwasm_register_error(l -> as, l, E_COMPLEX_INCOMPLETE);
1055 return -1;
1056 }
1057 v = ad.v;
1058 }
1059 else
1060 {
1061 lwasm_register_error(l -> as, l, E_COMPLEX_INCOMPLETE);
1062 return -1;
1063 }
1064
1065 // add "expression" record to section table
1066 re = lw_alloc(sizeof(reloctab_t));
1067 re -> next = l -> csect -> reloctab;
1068 l -> csect -> reloctab = re;
1069 te = lw_expr_build(lw_expr_type_int, ol);
1070 re -> offset = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, l -> addr, te);
1071 lw_expr_destroy(te);
1072 lwasm_reduce_expr(l -> as, re -> offset);
1073 re -> size = size;
1074 if (ad.ms == 1)
1075 re -> expr = lw_expr_copy(expr);
1076 else
1077 re -> expr = NULL;
1078
1079 lwasm_emit(l, v >> 8);
1080 lwasm_emit(l, v & 0xff);
1081 return 0;
1082 }
1083 else if (l -> as -> output_format == OUTPUT_OBJ)
967 { 1084 {
968 reloctab_t *re; 1085 reloctab_t *re;
969 lw_expr_t te; 1086 lw_expr_t te;
970 1087
971 if (l -> csect == NULL) 1088 if (l -> csect == NULL)