Compare commits

...

2 commits

Author SHA1 Message Date
Ruslan Garipov
9225a0edf0 Merge branch 'fix/winedump_loop' into 'master'
Avoid the for-loop be optimized out

See merge request wine/wine!6780
2024-11-16 11:32:03 +00:00
Ruslan Garipov
a2c3cb4050
Avoid the for-loop be optimized out
This stops GCC from optimizing out a for-loop inside the
dump_cv_sst_src_module() function, when tools/winedump is compiled with
optimization settings -O1 or higher.

Because the baseSrcLn field of the 'struct OMFSourceFile' was declared
as a flexible array of one element **and it is an interior member** of
the structure:

  typedef struct OMFSourceFile
  {
      unsigned short  cSeg;
      unsigned short  reserved;
      unsigned int    baseSrcLn[1];
      unsigned short  cFName;
      char            Name;
  } OMFSourceFile;

The compiler/optimizer assumes that the baseSrcLn array may have only
zero or one element.  And generates the corresponding code.

The following shows code that GCC 14.2.1 generates before and after this
patch.

Before patch:

  # this printf(3)'s "File table: ..."
  524f:  call   4160 <printf@plt>
  # r15 stores sourceFile->cSeg; assigned above.
  5254:   cmpw   $0x0,(%r12)  # r12 is sourceFile
  525a:   je     527e <dump_codeview+0x70e>
  525c:   lea    0x4(%r12,%r15,4),%rax  #rax is seg_info_dw
  5261:   mov    0x4(%r12),%r8d  # sourceFile->baseSrcLn[0]
  5266:   mov    $0x1,%esi
  526b:   lea    0x402fe(%rip),%rdi        # 45570
  5272:   mov    0x4(%rax),%ecx
  5275:   mov    (%rax),%edx
  5277:   xor    %eax,%eax
  5279:   call   4160 <printf@plt>
  527e:   movzbl (%r14),%eax  # eax = sourceModule + ofs

The code checks if the sourceFile->cSeg is zero or not, and if not it
printf(3)'s information about the first element in the baseSrcLn and
first offset pair.  There is no for-loop there, only its first
iteration.

After patch:

  # this printf(3)'s "File table: ..."
  525c:  call   4160 <printf@plt>
  # r12 is seg_info_dw and r15 stores integer 1; both assigned above.
  # r15 is `i' -- the loop counter.
  5261:  cmpw   $0x0,(%r14)  # r14 is sourceFile
  5266:  je     529f <dump_codeview+0x72f>
  5268:  nopl   0x0(%rax,%rax,1)
  526f:
  5270:  mov    -0x8(%r12,%r15,8),%edx
  5275:  mov    -0x4(%r12,%r15,8),%ecx
  527a:  mov    %r15d,%esi
  527d:  xor    %eax,%eax
  527f:  mov    (%r14,%r15,4),%r8d  # sourceFile->baseSrcLn[i]
  5283:  lea    0x402e6(%rip),%rdi        # 45570
  528a:  add    $0x1,%r15
  528e:  call   4160 <printf@plt>
  5293:  movzwl (%r14),%eax
  5297:  lea    -0x1(%r15),%edx
  529b:  cmp    %eax,%edx
  529d:  jl     5270 <dump_codeview+0x700>
  529f:  mov    0x18(%rsp),%rax  # rax = sourceModule + ofs

The for-loop now is where it should be.

Signed-off-by: Ruslan Garipov <ruslanngaripov@gmail.com>
2024-11-10 00:09:42 +05:00

View file

@ -2779,9 +2779,9 @@ typedef struct OMFSourceFile
{
unsigned short cSeg;
unsigned short reserved;
unsigned int baseSrcLn[1];
unsigned short cFName;
char Name;
unsigned int baseSrcLn[];
/* unsigned short cFName; */
/* char Name; */
} OMFSourceFile;
typedef struct OMFSourceModule