From 1b67bd25b20b153c0fdc799c28250b9e259221ce Mon Sep 17 00:00:00 2001 From: Slavik Gnatenko Date: Sat, 19 Jul 2008 19:27:41 -0700 Subject: [PATCH] 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; } --- output/outobj.c | 7 ++- test/alonesym-obj.asm | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 test/alonesym-obj.asm diff --git a/output/outobj.c b/output/outobj.c index 9ca368dd..e248ac31 100644 --- a/output/outobj.c +++ b/output/outobj.c @@ -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)); } diff --git a/test/alonesym-obj.asm b/test/alonesym-obj.asm new file mode 100644 index 00000000..6be4d5db --- /dev/null +++ b/test/alonesym-obj.asm @@ -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 -- 2.11.4.GIT