Don't use a redundant "const" for macros_t (which is const unsigned
char), since OpenWatcom doesn't like it, and I believe it is incorrect
per the C standard.
Any use of ins->forw_ref that isn't related to control of the
optimizer is fundamentally broken. Use
operand->opflags & OPERAND_FORWARD instead. This even has the nice
side benefit of simplifying the code.
The testcase illustrates the problem. After "nasm -f obj
alonesym.nasm"
let's look to dump:
======
PUBDEF386(91) recnum:5, offset:0000005bh, len:03f9h, chksum:bbh(bb)
Group: 0, Seg: 1
00020000h - 'sym0000' Type:0
00020004h - 'sym0001' Type:0
....
00020134h - 'sym0077' Type:0
PUBDEF(90) recnum:6, offset:00000457h, len:000ah, chksum:b6h(b6)
Group: 0, Seg: 1
00000138h - 's' Type:2
0000b600h - '' Type:0
======
The problem is while 's' offset is 20138h it is marked as type 90h not
91h. The root cause is located in obj_x():
static ObjRecord *obj_x(ObjRecord * orp, uint32_t val)
{
if (orp->type & 1)
orp->x_size = 32;
if (val > 0xFFFF)
orp = obj_force(orp, 32);
if (orp->x_size == 32)
return (obj_dword(orp, val));
orp->x_size = 16;
return (obj_word(orp, val));
}
It sets up x_size and than writes data. In the testcase data are the
offset and this offset overflows a record. In this case the record is
emitted and its x_size is cleared. Because this is last PUBDEF the new
record with only 's' symbol is emitted also but its x_size is not 32
(it's still zero) so obj_fwrite doesn't switch to 91h type.
The problem seems to be very generic and expected to be occurred on
many other record types as well.
----
And the fix is simple:
if (orp->x_size == 32)
{
ObjRecord * nxt = obj_dword(orp, val);
nxt->x_size = 32; /* x_size is cleared when a record overflows */
return nxt;
}
Apparently the current recommendation is for a smaller threshold when
using the "generic"-style alignment macros (short jumps are cheaper on
newer CPUs.)
Also change the alignment threshold definition to reflect the maximum
number of padding instead of when to start using jumps.
Add %un[i]macro, and a few stylistic cleanups.
Note: unlike %undef, %un[i]macro takes an argument specification,
which must *exactly* match the macro being undefined. Similarly,
%unimacro has to be used to undefine a macro defined with %imacro, and
vice versa.
Apply updated version of fix submitted with feature request 803785.
This fix causes %exitrep to terminate only the innermost %rep block,
and also allows the count for nested blocks to be calculated in the
containing block.
I noticed there was no sane way to concatenate the contents of quoted
strings, so add the %strcat directive.
These really need to become preprocessor functions at some stage.