diff --git a/History.txt b/History.txt
index 0aa6839..9bf6a1b 100644
--- a/History.txt
+++ b/History.txt
@@ -15,7 +15,10 @@
!= ES wasn't rejected; see string5.asm.
- string operations with symbolic memory operands did ignore assumes, thus
no segment prefix was created; see string8.asm.
- - comment behind MACRO directive was appended to all lines inside the macro.
+ - comment behind MACRO directive was appended to all lines inside the macro;
+ see lst2.asm.
+ - jwasmr.exe: memory corruption may have caused a system crash if pass one
+ ended with an error.
03/14/2020, v2.13:
diff --git a/Html/Manual.html b/Html/Manual.html
index eb950d1..be77562 100644
--- a/Html/Manual.html
+++ b/Html/Manual.html
@@ -5162,8 +5162,8 @@
Appendix C. Errors and Warnings
x211 |
- |
- |
+Model must be FLAT |
+In 64-bit mode, or if output format is -pe, there's no segmented model available. |
@@ -5574,6 +5574,13 @@ Appendix C. Errors and Warnings
A 16-bit procedure that is to be exported must be declared with the FAR distance attribute. |
+
+x277 |
+Start label not in a 16-bit segment |
+MZ format only: the start label is in a 32- or 64-bit segment.
+The resulting MZ binary won't run without further modification, i.e. adding a DOS-extender stub. |
+
+
Appendix D. Differences between Masm 6 and Masm 8
diff --git a/bin/JWasm_v214pre5_dos.zip b/bin/JWasm_v214pre5_dos.zip
deleted file mode 100644
index 6f05ddb..0000000
Binary files a/bin/JWasm_v214pre5_dos.zip and /dev/null differ
diff --git a/bin/JWasm_v214pre6_dos.zip b/bin/JWasm_v214pre6_dos.zip
new file mode 100644
index 0000000..576b8e9
Binary files /dev/null and b/bin/JWasm_v214pre6_dos.zip differ
diff --git a/bin/JWasm_v214pre5_win32.zip b/bin/JWasm_v214pre6_win32.zip
similarity index 69%
rename from bin/JWasm_v214pre5_win32.zip
rename to bin/JWasm_v214pre6_win32.zip
index 5832740..207a159 100644
Binary files a/bin/JWasm_v214pre5_win32.zip and b/bin/JWasm_v214pre6_win32.zip differ
diff --git a/bin/JWasmr.exe b/bin/JWasmr.exe
new file mode 100755
index 0000000..21a2d49
Binary files /dev/null and b/bin/JWasmr.exe differ
diff --git a/src/H/fixup.h b/src/H/fixup.h
index f6f098d..da07523 100644
--- a/src/H/fixup.h
+++ b/src/H/fixup.h
@@ -113,6 +113,9 @@ struct fixup {
#endif
unsigned char loader_resolved:1; /* operator LROFFSET */
unsigned char orgoccured:1; /* v2.04 ORG occured behind this fix */
+#if FASTMEM==0
+ unsigned char count:2; /* v2.14 ref count */
+#endif
};
};
union {
diff --git a/src/backptch.c b/src/backptch.c
index e4efcfb..54e8eef 100644
--- a/src/backptch.c
+++ b/src/backptch.c
@@ -253,7 +253,7 @@ ret_code BackPatch( struct asym *sym )
uint_32 oldofs = sym->offset;
#endif
- DebugMsg1(("BackPatch(%s): location=%s:%X, bp_fixup=%p\n", sym->name, sym->segment ? sym->segment->name : "!NULL!", sym->offset, sym->bp_fixup ));
+ DebugMsg1(("BackPatch(%s): location=%s:%" I32_SPEC "X, bp_fixup=%p\n", sym->name, sym->segment ? sym->segment->name : "!NULL!", sym->offset, sym->bp_fixup ));
for( fixup = sym->bp_fixup; fixup; fixup = next ) {
next = fixup->nextbp;
diff --git a/src/expreval.c b/src/expreval.c
index e8654dd..3f8ea73 100644
--- a/src/expreval.c
+++ b/src/expreval.c
@@ -3189,7 +3189,7 @@ static ret_code evaluate( struct expr *opnd1, int *i, struct asm_tok tokenarray[
struct expr opnd2;
curr_operator = *i;
- DebugMsg1(("%u evaluate loop, operator=>%s< opnd1->sym=%X, type=%s\n",
+ DebugMsg1(("%u evaluate loop, operator=>%s< opnd1->sym=%p, type=%s\n",
evallvl, tokenarray[curr_operator].string_ptr, opnd1->sym, (opnd1->type ? opnd1->type->name : "NULL") ));
if ( opnd1->kind != EXPR_EMPTY ) {
diff --git a/src/fixup.c b/src/fixup.c
index 1a25c86..11b9fde 100644
--- a/src/fixup.c
+++ b/src/fixup.c
@@ -69,6 +69,7 @@ struct fixup *CreateFixup( struct asym *sym, enum fixup_types type, enum fixup_o
fixup->marker = 'XF';
DebugMsg1(("CreateFixup, pass=%u: fix=%p sym=%s\n", Parse_Pass+1, fixup, sym ? sym->name : "NULL" ));
#endif
+ fixup->flags = 0; /* v2.14: moved up here so count won't be overwritten */
/* add the fixup to the symbol's linked list (used for backpatch)
* this is done for pass 1 only.
@@ -80,6 +81,9 @@ struct fixup *CreateFixup( struct asym *sym, enum fixup_types type, enum fixup_o
if ( sym ) { /* changed v1.96 */
fixup->nextbp = sym->bp_fixup;
sym->bp_fixup = fixup;
+#if FASTMEM==0
+ fixup->count++;
+#endif
}
/* v2.03: in pass one, create a linked list of
* fixup locations for a segment. This is to improve
@@ -92,6 +96,9 @@ struct fixup *CreateFixup( struct asym *sym, enum fixup_types type, enum fixup_o
if ( CurrSeg ) {
fixup->nextrlc = CurrSeg->e.seginfo->FixupList.head;
CurrSeg->e.seginfo->FixupList.head = fixup;
+#if FASTMEM==0
+ fixup->count++;
+#endif
}
}
/* initialize locofs member with current offset.
@@ -101,13 +108,12 @@ struct fixup *CreateFixup( struct asym *sym, enum fixup_types type, enum fixup_o
fixup->offset = 0;
fixup->type = type;
fixup->option = option;
- fixup->flags = 0;
fixup->frame_type = Frame_Type; /* this is just a guess */
fixup->frame_datum = Frame_Datum;
fixup->def_seg = CurrSeg; /* may be NULL (END directive) */
fixup->sym = sym;
- DebugMsg1(("CreateFixup(sym=%s type=%u, opt=%u) cnt=%" I32_SPEC "X, loc=%" I32_SPEC "Xh frame_type/datum=%u/%u\n",
+ DebugMsg1(("CreateFixup(sym=%s type=%u, opt=%u) cnt=%" I32_SPEC "u, loc=%" I32_SPEC "Xh frame_type/datum=%u/%u\n",
sym ? sym->name : "NULL", type, option, ++cnt, fixup->locofs, fixup->frame_type, fixup->frame_datum ));
return( fixup );
}
@@ -125,17 +131,30 @@ void FreeFixup( struct fixup *fixup )
if ( dir ) {
if ( fixup == dir->e.seginfo->FixupList.head ) {
dir->e.seginfo->FixupList.head = fixup->nextrlc;
+#if FASTMEM==0
+ fixup->count--;
+#endif
} else {
for ( fixup2 = dir->e.seginfo->FixupList.head; fixup2; fixup2 = fixup2->nextrlc ) {
if ( fixup2->nextrlc == fixup ) {
fixup2->nextrlc = fixup->nextrlc;
+#if FASTMEM==0
+ fixup->count--;
+#endif
break;
}
}
}
}
}
+#if FASTMEM==0
+ DebugMsg1(("FreeFixup( %p ), count=%u, def_seg=%p\n", fixup, fixup->count, fixup->def_seg ));
+ if ( !fixup->count ) {
+ LclFree( fixup );
+ }
+#else
LclFree( fixup );
+#endif
}
/*
diff --git a/src/parser.c b/src/parser.c
index bf5bb4a..e171c28 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1426,7 +1426,7 @@ static ret_code memory_operand( struct code_info *CodeInfo, unsigned CurrOpnd, s
uint_8 Ofssize;
enum fixup_types fixup_type;
- DebugMsg1(("memory_operand(opndx.value=%X / sym=%s / memtype=%Xh, with_fixup=%u) enter, [CodeInfo->memtype=%Xh, Ofssize=%u, adrsiz=%u]\n",
+ DebugMsg1(("memory_operand(opndx.value=%" I32_SPEC "X / sym=%s / memtype=%Xh, with_fixup=%u) enter, [CodeInfo->memtype=%Xh, Ofssize=%u, adrsiz=%u]\n",
opndx->value, opndx->sym ? opndx->sym->name : "NULL", opndx->mem_type, with_fixup, CodeInfo->mem_type, CodeInfo->Ofssize, CodeInfo->prefix.adrsiz ));
/* v211: use full 64-bit value */
diff --git a/src/segment.c b/src/segment.c
index 31a9717..d427674 100644
--- a/src/segment.c
+++ b/src/segment.c
@@ -1505,8 +1505,13 @@ void SegmentFini( void )
DebugMsg(("SegmentFini: segment %s\n", curr->sym.name ));
for ( fix = curr->e.seginfo->FixupList.head; fix ; ) {
struct fixup *next = fix->nextrlc;
- DebugMsg(("SegmentFini: free fixup [sym=%s, loc=%" I32_SPEC "X]\n", fix->sym ? fix->sym->name : "NULL", fix->location ));
- LclFree( fix );
+ DebugMsg(("SegmentFini: free fixup %p [sym=%s, count=%u]\n", fix, fix->sym ? fix->sym->name : "NULL", fix->count ));
+ /* v2.14: problem is that a fixup may be in two linked lists after step 1;
+ * hence only free the fixup if nextbp is NULL.
+ */
+ fix->count--;
+ if ( !fix->count )
+ LclFree( fix );
fix = next;
}
}
diff --git a/src/symbols.c b/src/symbols.c
index ddf9952..557f337 100644
--- a/src/symbols.c
+++ b/src/symbols.c
@@ -410,7 +410,7 @@ static void free_ext( struct asym *sym )
}
/* free a symbol.
- * the symbol is no unlinked from hash tables chains,
+ * the symbol is not unlinked from hash table chains,
* hence it is assumed that this is either not needed
* or done by the caller.
*/
@@ -418,15 +418,18 @@ static void free_ext( struct asym *sym )
void SymFree( struct asym *sym )
/******************************/
{
- //DebugMsg(("SymFree: free %X, name=%s, state=%X\n", sym, sym->name, sym->state));
+ //DebugMsg(("SymFree: free %p, name=%s, state=%u\n", sym, sym->name, sym->state));
free_ext( sym );
#if FASTMEM==0
- if ( sym->state != SYM_EXTERNAL ) {
+ if ( sym->state != SYM_EXTERNAL ) { /* external backpatches are cleared in PassOneChecks() */
struct fixup *fix;
for( fix = sym->bp_fixup ; fix; ) {
struct fixup *next = fix->nextbp;
- DebugMsg(("SymFree: free bp fixup %p\n", fix ));
- LclFree( fix );
+ DebugMsg(("SymFree: free backpatch fixup %p [count=%u]\n", fix, fix->count ));
+ /* v2.14: free fixup only if not referenced anymore */
+ fix->count--;
+ if ( !fix->count )
+ LclFree( fix );
fix = next;
}
}