BR 2010180: outobj: Garbage may be written in a last PUBDEF

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;
}
This commit is contained in:
Slavik Gnatenko 2008-07-19 19:27:41 -07:00 committed by H. Peter Anvin
parent 4fb7ed0566
commit 1b67bd25b2
2 changed files with 168 additions and 2 deletions

View file

@ -346,8 +346,11 @@ static ObjRecord *obj_x(ObjRecord * orp, uint32_t val)
orp->x_size = 32;
if (val > 0xFFFF)
orp = obj_force(orp, 32);
if (orp->x_size == 32)
return (obj_dword(orp, val));
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;
}
orp->x_size = 16;
return (obj_word(orp, val));
}

163
test/alonesym-obj.asm Normal file
View file

@ -0,0 +1,163 @@
section DOS32DATA align=16 public use32 FLAT class=DOS32DATA
global sym0000
global sym0001
global sym0002
global sym0003
global sym0004
global sym0005
global sym0006
global sym0007
global sym0008
global sym0009
global sym0010
global sym0011
global sym0012
global sym0013
global sym0014
global sym0015
global sym0016
global sym0017
global sym0018
global sym0019
global sym0020
global sym0021
global sym0022
global sym0023
global sym0024
global sym0025
global sym0026
global sym0027
global sym0028
global sym0029
global sym0030
global sym0031
global sym0032
global sym0033
global sym0034
global sym0035
global sym0036
global sym0037
global sym0038
global sym0039
global sym0040
global sym0041
global sym0042
global sym0043
global sym0044
global sym0045
global sym0046
global sym0047
global sym0048
global sym0049
global sym0050
global sym0051
global sym0052
global sym0053
global sym0054
global sym0055
global sym0056
global sym0057
global sym0058
global sym0059
global sym0060
global sym0061
global sym0062
global sym0063
global sym0064
global sym0065
global sym0066
global sym0067
global sym0068
global sym0069
global sym0070
global sym0071
global sym0072
global sym0073
global sym0074
global sym0075
global sym0076
global sym0077
global s
resb 20000h
sym0000 resd 1
sym0001 resd 1
sym0002 resd 1
sym0003 resd 1
sym0004 resd 1
sym0005 resd 1
sym0006 resd 1
sym0007 resd 1
sym0008 resd 1
sym0009 resd 1
sym0010 resd 1
sym0011 resd 1
sym0012 resd 1
sym0013 resd 1
sym0014 resd 1
sym0015 resd 1
sym0016 resd 1
sym0017 resd 1
sym0018 resd 1
sym0019 resd 1
sym0020 resd 1
sym0021 resd 1
sym0022 resd 1
sym0023 resd 1
sym0024 resd 1
sym0025 resd 1
sym0026 resd 1
sym0027 resd 1
sym0028 resd 1
sym0029 resd 1
sym0030 resd 1
sym0031 resd 1
sym0032 resd 1
sym0033 resd 1
sym0034 resd 1
sym0035 resd 1
sym0036 resd 1
sym0037 resd 1
sym0038 resd 1
sym0039 resd 1
sym0040 resd 1
sym0041 resd 1
sym0042 resd 1
sym0043 resd 1
sym0044 resd 1
sym0045 resd 1
sym0046 resd 1
sym0047 resd 1
sym0048 resd 1
sym0049 resd 1
sym0050 resd 1
sym0051 resd 1
sym0052 resd 1
sym0053 resd 1
sym0054 resd 1
sym0055 resd 1
sym0056 resd 1
sym0057 resd 1
sym0058 resd 1
sym0059 resd 1
sym0060 resd 1
sym0061 resd 1
sym0062 resd 1
sym0063 resd 1
sym0064 resd 1
sym0065 resd 1
sym0066 resd 1
sym0067 resd 1
sym0068 resd 1
sym0069 resd 1
sym0070 resd 1
sym0071 resd 1
sym0072 resd 1
sym0073 resd 1
sym0074 resd 1
sym0075 resd 1
sym0076 resd 1
sym0077 resd 1
s resd 1