<div dir="ltr">This is likely the same problem that we have with .pdata sections for linkonce_odr functions.<div><br></div><div>We need to create a different line table section for each comdat and associate it with the original section.</div>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jul 9, 2014 at 6:22 AM, Timur Iskhodzhanov <span dir="ltr"><<a href="mailto:timurrrr@google.com" target="_blank">timurrrr@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="">2014-06-27 0:38 GMT+04:00 Jeff Muizelaar <<a href="mailto:jmuizelaar@mozilla.com">jmuizelaar@mozilla.com</a>>:<br>

> commit 848055afc38cd5fc339c5aaea9122e1c8bf27f67<br>
> Author: Jeff Muizelaar <<a href="mailto:jmuizelaar@mozilla.com">jmuizelaar@mozilla.com</a>><br>
> Date:   Wed Jun 4 18:19:32 2014 -0400<br>
><br>
>     Fix dumping codeview line tables when there are multiple debug sections<br>
><br>
>     Codeview line tables for functions in different sections refer<br>
>     to a common STRING_TABLE_SUBSECTION for filenames. This happens<br>
>     when building with -Gy with MSVC.<br>
<br>
</div>After reading the docs on -Gy, I see that we can get multiple sections<br>
if we have inline functions with -fno-inline and/or inline method<br>
definitions even without -Gy (see below).<br>
<div><div class="h5"><br>
> diff --git a/test/tools/llvm-readobj/Inputs/comdat-function-linetables.obj.coff-2008-i386 b/test/tools/llvm-readobj/Inputs/comdat-function-linetables.obj.coff-2008-i386<br>
> new file mode 100644<br>
> index 0000000000000000000000000000000000000000..45416d52c3644aeb8395820268d36693e78d7431<br>
> GIT binary patch<br>
> literal 1635<br>
> zcmcIkF>ljQ5I)zWX$mTC#lX<vQAL6Z>}Du}7OJLAn}SGa)TC7@29elKFiPquc1p_B<br>
> zfeoaxvcbf{!Uhrx>IxeYKLQpg2qA>Zou8j^3T$xF`Q3f*-uK@5-n*O>ht~^Fi}4u1<br>
> z5OC4VmSuPwR^Y-I8mA=T1!KPgnrT(qwPaDuJi?f(`{L4|%xa$1@k9`g{ixr2A^@69<br>
> zDcso4_Y(1#4Dbq-1dj-5<<ES(L5v@WpTF__z_=F&cvQ&8^C*e6!)Uw@VgyEcFviB_<br>
> z=Cd=)xl-=p?Boc3GWpU-H@KLayF8PhFOD!`_=viTIt0=nQDr7|&vHG@soa7|I6o*c<br>
> zfH)k+nM6kl$GmN{9M`FO?8MS2TWorE!@gs$*I34BH0`?8g2ym52*z!b2*Ie+P-r=|<br>
> zR=L5l7~tx^C{}E@U9PjD*EVg3O=u~7C8JmDb=|0IR>uOPVS<`<A}3>N)<k#1m`G_&<br>
> zv%*w^sSBG-T|2|nRi@@kOf41A1h-{?pN?Sw2GS|SBFyMB>QPj>5sGx=&G6Ul@$H*$<br>
> zPe1HQ=%eTOe`(_!7{O0LmSic#l2)b3rf{&EjQnwSl3n)!#0lVz%bl}0i@`a6Ml&kK<br>
> z@`hzDSv8lbgcp3Af^e=-#vkO;0@`-@-iPOO1+MK-rM{phQH9VYjmjZ(=#Gi1UPAjg<br>
> zD1KE%9Ic_4K2%8&s8oev7z$kh2P3|N9_R)5gnlYAC-x^kaW0JAA|G{&_Q11j(YYu#<br>
> z4y%E65cI(6hx;M+AjBwd-0=VBUHeyg$Ai2vXFu;mkT<;>o;O)MZ?bsa9HYEBMwROY<br>
> z$?tLl(5Hkg2}_eU@MUSXndsbwy*>KF>8e%sv{Z_2FGr$nkx*G0!*91lTNrgXS)!)c<br>
> zEzx%9S5p$Tez(&&#@|bnht4faelrY+WWN=XLvtiDFuX=lX1dvO$h`UN+mqj!=@xV|<br>
> m$3o@-qD6^u=17agYTznrlHEdYeY%=XUzxeEx(3rVVf_REpWBT9<br>
><br>
> literal 0<br>
> HcmV?d00001<br>
><br>
> diff --git a/test/tools/llvm-readobj/codeview-linetables.test b/test/tools/llvm-readobj/codeview-linetables.test<br>
> index 4854d7a..b908a59 100644<br>
> --- a/test/tools/llvm-readobj/codeview-linetables.test<br>
> +++ b/test/tools/llvm-readobj/codeview-linetables.test<br>
> @@ -1,16 +1,18 @@<br>
>  RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifunction-linetables.obj.coff-2012-i368 \<br>
>  RUN:   | FileCheck %s -check-prefix MFUN32<br>
>  RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifunction-linetables.obj.coff-2012-x86_64 \<br>
>  RUN:   | FileCheck %s -check-prefix MFUN64<br>
>  RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifile-linetables.obj.coff-2012-i368 \<br>
>  RUN:   | FileCheck %s -check-prefix MFILE32<br>
>  RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifile-linetables.obj.coff-2012-x86_64 \<br>
>  RUN:   | FileCheck %s -check-prefix MFILE64<br>
> +RUN: llvm-readobj -s -codeview-linetables %p/Inputs/comdat-function-linetables.obj.coff-2008-i386 \<br>
> +RUN:   | FileCheck %s -check-prefix MCOMDAT<br>
><br>
>  MFUN32:      CodeViewLineTables [<br>
>  MFUN32-NEXT:   Magic: 0x4<br>
>  MFUN32-NEXT:   Subsection [<br>
>  MFUN32-NEXT:     Type: 0xF1<br>
>  MFUN32-NEXT:     PayloadSize: 0x52<br>
>  MFUN32:        ]<br>
>  MFUN32-NEXT:   Subsection [<br>
> @@ -275,8 +277,29 @@ MFILE64-NEXT:       +0x9: 2<br>
>  MFILE64-NEXT:     ]<br>
>  MFILE64-NEXT:     FilenameSegment [<br>
>  MFILE64-NEXT:       Filename: d:\one.c<br>
>  MFILE64-NEXT:       +0xE: 7<br>
>  MFILE64-NEXT:       +0x13: 8<br>
>  MFILE64-NEXT:     ]<br>
>  MFILE64-NEXT:   ]<br>
>  MFILE64-NEXT: ]<br>
> +<br>
> +MCOMDAT:      FunctionLineTable [<br>
> +MCOMDAT-NEXT:        FunctionName: ?f@@YAHXZ<br>
> +MCOMDAT-NEXT:        CodeSize: 0xA<br>
> +MCOMDAT-NEXT:        FilenameSegment [<br>
> +MCOMDAT-NEXT:          Filename: c:\test.cc<br>
> +MCOMDAT-NEXT:          +0x0: 2<br>
> +MCOMDAT-NEXT:          +0x3: 3<br>
> +MCOMDAT-NEXT:          +0x8: 4<br>
> +MCOMDAT-NEXT:        ]<br>
> +MCOMDAT-NEXT:      ]<br>
> +MCOMDAT:      FunctionLineTable [<br>
> +MCOMDAT-NEXT:        FunctionName: ?g@@YAHXZ<br>
> +MCOMDAT-NEXT:        CodeSize: 0xA<br>
> +MCOMDAT-NEXT:        FilenameSegment [<br>
> +MCOMDAT-NEXT:          Filename: c:\test.cc<br>
> +MCOMDAT-NEXT:          +0x0: 7<br>
> +MCOMDAT-NEXT:          +0x3: 8<br>
> +MCOMDAT-NEXT:          +0x8: 9<br>
> +MCOMDAT-NEXT:        ]<br>
> +MCOMDAT-NEXT:      ]<br>
> diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp<br>
> index 8b0dcb3..092382c 100644<br>
> --- a/tools/llvm-readobj/COFFDumper.cpp<br>
> +++ b/tools/llvm-readobj/COFFDumper.cpp<br>
> @@ -73,16 +73,18 @@ private:<br>
>                                  SymbolRef &Sym);<br>
>    std::error_code resolveSymbolName(const coff_section *Section,<br>
>                                      uint64_t Offset, StringRef &Name);<br>
><br>
>    typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy;<br>
><br>
>    const llvm::object::COFFObjectFile *Obj;<br>
>    RelocMapTy RelocMap;<br>
> +  StringRef FileIndexToStringOffsetTable;<br>
> +  StringRef StringTable;<br>
>  };<br>
><br>
>  } // namespace<br>
><br>
><br>
>  namespace llvm {<br>
><br>
>  std::error_code createCOFFDumper(const object::ObjectFile *Obj,<br>
<br>
</div></div>[+Eric, who has the "approve" rights]<br>
As these are not printCodeViewLineTables-local variables anymore, I<br>
think we'd rather have names that somehow mention CVLT or DI.<br>
<div class=""><br>
> @@ -433,18 +435,16 @@ void COFFDumper::printBaseOfDataField(const pe32plus_header *) {}<br>
><br>
>  void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {<br>
>    StringRef Data;<br>
>    if (error(Section.getContents(Data)))<br>
>      return;<br>
><br>
>    SmallVector<StringRef, 10> FunctionNames;<br>
>    StringMap<StringRef> FunctionLineTables;<br>
> -  StringRef FileIndexToStringOffsetTable;<br>
> -  StringRef StringTable;<br>
><br>
>    ListScope D(W, "CodeViewLineTables");<br>
>    {<br>
>      DataExtractor DE(Data, true, 4);<br>
>      uint32_t Offset = 0,<br>
>               Magic = DE.getU32(&Offset);<br>
>      W.printHex("Magic", Magic);<br>
>      if (Magic != COFF::DEBUG_SECTION_MAGIC) {<br>
><br>
<br>
</div>2014-07-09 1:45 GMT+04:00 Jeff Muizelaar <<a href="mailto:jmuizelaar@mozilla.com">jmuizelaar@mozilla.com</a>>:<br>
<div class="">> I just built a trivial c file with two functions and -Gy -Z7 with msvc 2008.<br>
> -Jeff<br>
<br>
</div>Ah, correct.<br>
<br>
[Self-note, doesn't block your patch]<br>
For this file:<br>
--------------<br>
int f()<br>
{<br>
  return 0;<br>
}<br>
<br>
int g()<br>
{<br>
  return 0;<br>
}<br>
--------------<br>
with -Gy the .obj file has three .debug$S sections.<br>
<br>
The first one has (0xF1, 0xF4, 0xF3) subsection structure and the<br>
other two have (0xF5, 0xF1, 0xF2) structure.  The first one holds the<br>
file-level stuff (e.g. string/index tables), the remaining ones hold<br>
per-function stuff (e.g. line table).<br>
<br>
For this file built *without* -Gy<br>
---------------<br>
inline int f()<br>
{<br>
  return 0;<br>
}<br>
<br>
inline int g()<br>
{<br>
  return 0;<br>
}<br>
<br>
void z() {<br>
  f();<br>
  g();<br>
}<br>
---------------<br>
there are three .debug$S sections as well.<br>
<br>
The first one holds the string/index tables as well as the linetable<br>
for 'z' (again, file-level stuff);<br>
the other two hold linetables for 'f' and 'g' (per-function stuff).<br>
<br>
Currently, LLVM only emits one section on this file.<br>
We should emit separate sections for linkonce_odr functions.<br>
I even think I saw wrong linenumbers showing up when debugging inline<br>
class method definitions once...<br>
I'll wait fixing this until I see a real-world manifestation of the<br>
bug though, so feel free to analyze.<br>
<div class="HOEnZb"><div class="h5"><br>
> On Jul 8, 2014, at 10:05 AM, Timur Iskhodzhanov <<a href="mailto:timurrrr@google.com">timurrrr@google.com</a>> wrote:<br>
><br>
>> Sorry for a long delay as I was on vacation.<br>
>><br>
>> Can you please send me the object file over email (rather than binary<br>
>> in text) and explain how can I generate a similar one myself?<br>
>><br>
>> 2014-06-27 0:38 GMT+04:00 Jeff Muizelaar <<a href="mailto:jmuizelaar@mozilla.com">jmuizelaar@mozilla.com</a>>:<br>
>>> commit 848055afc38cd5fc339c5aaea9122e1c8bf27f67<br>
>>> Author: Jeff Muizelaar <<a href="mailto:jmuizelaar@mozilla.com">jmuizelaar@mozilla.com</a>><br>
>>> Date:   Wed Jun 4 18:19:32 2014 -0400<br>
>>><br>
>>>    Fix dumping codeview line tables when there are multiple debug sections<br>
>>><br>
>>>    Codeview line tables for functions in different sections refer<br>
>>>    to a common STRING_TABLE_SUBSECTION for filenames. This happens<br>
>>>    when building with -Gy with MSVC.<br>
>>><br>
>>> diff --git a/test/tools/llvm-readobj/Inputs/comdat-function-linetables.obj.coff-2008-i386 b/test/tools/llvm-readobj/Inputs/comdat-function-linetables.obj.coff-2008-i386<br>
>>> new file mode 100644<br>
>>> index 0000000000000000000000000000000000000000..45416d52c3644aeb8395820268d36693e78d7431<br>
>>> GIT binary patch<br>
>>> literal 1635<br>
>>> zcmcIkF>ljQ5I)zWX$mTC#lX<vQAL6Z>}Du}7OJLAn}SGa)TC7@29elKFiPquc1p_B<br>
>>> zfeoaxvcbf{!Uhrx>IxeYKLQpg2qA>Zou8j^3T$xF`Q3f*-uK@5-n*O>ht~^Fi}4u1<br>
>>> z5OC4VmSuPwR^Y-I8mA=T1!KPgnrT(qwPaDuJi?f(`{L4|%xa$1@k9`g{ixr2A^@69<br>
>>> zDcso4_Y(1#4Dbq-1dj-5<<ES(L5v@WpTF__z_=F&cvQ&8^C*e6!)Uw@VgyEcFviB_<br>
>>> z=Cd=)xl-=p?Boc3GWpU-H@KLayF8PhFOD!`_=viTIt0=nQDr7|&vHG@soa7|I6o*c<br>
>>> zfH)k+nM6kl$GmN{9M`FO?8MS2TWorE!@gs$*I34BH0`?8g2ym52*z!b2*Ie+P-r=|<br>
>>> zR=L5l7~tx^C{}E@U9PjD*EVg3O=u~7C8JmDb=|0IR>uOPVS<`<A}3>N)<k#1m`G_&<br>
>>> zv%*w^sSBG-T|2|nRi@@kOf41A1h-{?pN?Sw2GS|SBFyMB>QPj>5sGx=&G6Ul@$H*$<br>
>>> zPe1HQ=%eTOe`(_!7{O0LmSic#l2)b3rf{&EjQnwSl3n)!#0lVz%bl}0i@`a6Ml&kK<br>
>>> z@`hzDSv8lbgcp3Af^e=-#vkO;0@`-@-iPOO1+MK-rM{phQH9VYjmjZ(=#Gi1UPAjg<br>
>>> zD1KE%9Ic_4K2%8&s8oev7z$kh2P3|N9_R)5gnlYAC-x^kaW0JAA|G{&_Q11j(YYu#<br>
>>> z4y%E65cI(6hx;M+AjBwd-0=VBUHeyg$Ai2vXFu;mkT<;>o;O)MZ?bsa9HYEBMwROY<br>
>>> z$?tLl(5Hkg2}_eU@MUSXndsbwy*>KF>8e%sv{Z_2FGr$nkx*G0!*91lTNrgXS)!)c<br>
>>> zEzx%9S5p$Tez(&&#@|bnht4faelrY+WWN=XLvtiDFuX=lX1dvO$h`UN+mqj!=@xV|<br>
>>> m$3o@-qD6^u=17agYTznrlHEdYeY%=XUzxeEx(3rVVf_REpWBT9<br>
>>><br>
>>> literal 0<br>
>>> HcmV?d00001<br>
>>><br>
>>> diff --git a/test/tools/llvm-readobj/codeview-linetables.test b/test/tools/llvm-readobj/codeview-linetables.test<br>
>>> index 4854d7a..b908a59 100644<br>
>>> --- a/test/tools/llvm-readobj/codeview-linetables.test<br>
>>> +++ b/test/tools/llvm-readobj/codeview-linetables.test<br>
>>> @@ -1,16 +1,18 @@<br>
>>> RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifunction-linetables.obj.coff-2012-i368 \<br>
>>> RUN:   | FileCheck %s -check-prefix MFUN32<br>
>>> RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifunction-linetables.obj.coff-2012-x86_64 \<br>
>>> RUN:   | FileCheck %s -check-prefix MFUN64<br>
>>> RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifile-linetables.obj.coff-2012-i368 \<br>
>>> RUN:   | FileCheck %s -check-prefix MFILE32<br>
>>> RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifile-linetables.obj.coff-2012-x86_64 \<br>
>>> RUN:   | FileCheck %s -check-prefix MFILE64<br>
>>> +RUN: llvm-readobj -s -codeview-linetables %p/Inputs/comdat-function-linetables.obj.coff-2008-i386 \<br>
>>> +RUN:   | FileCheck %s -check-prefix MCOMDAT<br>
>>><br>
>>> MFUN32:      CodeViewLineTables [<br>
>>> MFUN32-NEXT:   Magic: 0x4<br>
>>> MFUN32-NEXT:   Subsection [<br>
>>> MFUN32-NEXT:     Type: 0xF1<br>
>>> MFUN32-NEXT:     PayloadSize: 0x52<br>
>>> MFUN32:        ]<br>
>>> MFUN32-NEXT:   Subsection [<br>
>>> @@ -275,8 +277,29 @@ MFILE64-NEXT:       +0x9: 2<br>
>>> MFILE64-NEXT:     ]<br>
>>> MFILE64-NEXT:     FilenameSegment [<br>
>>> MFILE64-NEXT:       Filename: d:\one.c<br>
>>> MFILE64-NEXT:       +0xE: 7<br>
>>> MFILE64-NEXT:       +0x13: 8<br>
>>> MFILE64-NEXT:     ]<br>
>>> MFILE64-NEXT:   ]<br>
>>> MFILE64-NEXT: ]<br>
>>> +<br>
>>> +MCOMDAT:      FunctionLineTable [<br>
>>> +MCOMDAT-NEXT:        FunctionName: ?f@@YAHXZ<br>
>>> +MCOMDAT-NEXT:        CodeSize: 0xA<br>
>>> +MCOMDAT-NEXT:        FilenameSegment [<br>
>>> +MCOMDAT-NEXT:          Filename: c:\test.cc<br>
>>> +MCOMDAT-NEXT:          +0x0: 2<br>
>>> +MCOMDAT-NEXT:          +0x3: 3<br>
>>> +MCOMDAT-NEXT:          +0x8: 4<br>
>>> +MCOMDAT-NEXT:        ]<br>
>>> +MCOMDAT-NEXT:      ]<br>
>>> +MCOMDAT:      FunctionLineTable [<br>
>>> +MCOMDAT-NEXT:        FunctionName: ?g@@YAHXZ<br>
>>> +MCOMDAT-NEXT:        CodeSize: 0xA<br>
>>> +MCOMDAT-NEXT:        FilenameSegment [<br>
>>> +MCOMDAT-NEXT:          Filename: c:\test.cc<br>
>>> +MCOMDAT-NEXT:          +0x0: 7<br>
>>> +MCOMDAT-NEXT:          +0x3: 8<br>
>>> +MCOMDAT-NEXT:          +0x8: 9<br>
>>> +MCOMDAT-NEXT:        ]<br>
>>> +MCOMDAT-NEXT:      ]<br>
>>> diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp<br>
>>> index 8b0dcb3..092382c 100644<br>
>>> --- a/tools/llvm-readobj/COFFDumper.cpp<br>
>>> +++ b/tools/llvm-readobj/COFFDumper.cpp<br>
>>> @@ -73,16 +73,18 @@ private:<br>
>>>                                 SymbolRef &Sym);<br>
>>>   std::error_code resolveSymbolName(const coff_section *Section,<br>
>>>                                     uint64_t Offset, StringRef &Name);<br>
>>><br>
>>>   typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy;<br>
>>><br>
>>>   const llvm::object::COFFObjectFile *Obj;<br>
>>>   RelocMapTy RelocMap;<br>
>>> +  StringRef FileIndexToStringOffsetTable;<br>
>>> +  StringRef StringTable;<br>
>>> };<br>
>>><br>
>>> } // namespace<br>
>>><br>
>>><br>
>>> namespace llvm {<br>
>>><br>
>>> std::error_code createCOFFDumper(const object::ObjectFile *Obj,<br>
>>> @@ -433,18 +435,16 @@ void COFFDumper::printBaseOfDataField(const pe32plus_header *) {}<br>
>>><br>
>>> void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {<br>
>>>   StringRef Data;<br>
>>>   if (error(Section.getContents(Data)))<br>
>>>     return;<br>
>>><br>
>>>   SmallVector<StringRef, 10> FunctionNames;<br>
>>>   StringMap<StringRef> FunctionLineTables;<br>
>>> -  StringRef FileIndexToStringOffsetTable;<br>
>>> -  StringRef StringTable;<br>
>>><br>
>>>   ListScope D(W, "CodeViewLineTables");<br>
>>>   {<br>
>>>     DataExtractor DE(Data, true, 4);<br>
>>>     uint32_t Offset = 0,<br>
>>>              Magic = DE.getU32(&Offset);<br>
>>>     W.printHex("Magic", Magic);<br>
>>>     if (Magic != COFF::DEBUG_SECTION_MAGIC) {<br>
>>><br>
><br>
><br>
</div></div></blockquote></div><br></div>