Mercurial > hg > index.cgi
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) |