[PATCH] Fix dumping codeview line tables when there are multiple debug sections

Timur Iskhodzhanov timurrrr at google.com
Wed Jul 9 06:22:41 PDT 2014


2014-06-27 0:38 GMT+04:00 Jeff Muizelaar <jmuizelaar at mozilla.com>:
> commit 848055afc38cd5fc339c5aaea9122e1c8bf27f67
> Author: Jeff Muizelaar <jmuizelaar at mozilla.com>
> Date:   Wed Jun 4 18:19:32 2014 -0400
>
>     Fix dumping codeview line tables when there are multiple debug sections
>
>     Codeview line tables for functions in different sections refer
>     to a common STRING_TABLE_SUBSECTION for filenames. This happens
>     when building with -Gy with MSVC.

After reading the docs on -Gy, I see that we can get multiple sections
if we have inline functions with -fno-inline and/or inline method
definitions even without -Gy (see below).

> 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
> new file mode 100644
> index 0000000000000000000000000000000000000000..45416d52c3644aeb8395820268d36693e78d7431
> GIT binary patch
> literal 1635
> zcmcIkF>ljQ5I)zWX$mTC#lX<vQAL6Z>}Du}7OJLAn}SGa)TC7 at 29elKFiPquc1p_B
> zfeoaxvcbf{!Uhrx>IxeYKLQpg2qA>Zou8j^3T$xF`Q3f*-uK at 5-n*O>ht~^Fi}4u1
> z5OC4VmSuPwR^Y-I8mA=T1!KPgnrT(qwPaDuJi?f(`{L4|%xa$1 at k9`g{ixr2A^@69
> zDcso4_Y(1#4Dbq-1dj-5<<ES(L5v at WpTF__z_=F&cvQ&8^C*e6!)Uw at VgyEcFviB_
> z=Cd=)xl-=p?Boc3GWpU-H at KLayF8PhFOD!`_=viTIt0=nQDr7|&vHG at soa7|I6o*c
> zfH)k+nM6kl$GmN{9M`FO?8MS2TWorE!@gs$*I34BH0`?8g2ym52*z!b2*Ie+P-r=|
> zR=L5l7~tx^C{}E at U9PjD*EVg3O=u~7C8JmDb=|0IR>uOPVS<`<A}3>N)<k#1m`G_&
> zv%*w^sSBG-T|2|nRi@@kOf41A1h-{?pN?Sw2GS|SBFyMB>QPj>5sGx=&G6Ul@$H*$
> zPe1HQ=%eTOe`(_!7{O0LmSic#l2)b3rf{&EjQnwSl3n)!#0lVz%bl}0i@`a6Ml&kK
> z@`hzDSv8lbgcp3Af^e=-#vkO;0@`- at -iPOO1+MK-rM{phQH9VYjmjZ(=#Gi1UPAjg
> zD1KE%9Ic_4K2%8&s8oev7z$kh2P3|N9_R)5gnlYAC-x^kaW0JAA|G{&_Q11j(YYu#
> z4y%E65cI(6hx;M+AjBwd-0=VBUHeyg$Ai2vXFu;mkT<;>o;O)MZ?bsa9HYEBMwROY
> z$?tLl(5Hkg2}_eU at MUSXndsbwy*>KF>8e%sv{Z_2FGr$nkx*G0!*91lTNrgXS)!)c
> zEzx%9S5p$Tez(&&#@|bnht4faelrY+WWN=XLvtiDFuX=lX1dvO$h`UN+mqj!=@xV|
> m$3o at -qD6^u=17agYTznrlHEdYeY%=XUzxeEx(3rVVf_REpWBT9
>
> literal 0
> HcmV?d00001
>
> diff --git a/test/tools/llvm-readobj/codeview-linetables.test b/test/tools/llvm-readobj/codeview-linetables.test
> index 4854d7a..b908a59 100644
> --- a/test/tools/llvm-readobj/codeview-linetables.test
> +++ b/test/tools/llvm-readobj/codeview-linetables.test
> @@ -1,16 +1,18 @@
>  RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifunction-linetables.obj.coff-2012-i368 \
>  RUN:   | FileCheck %s -check-prefix MFUN32
>  RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifunction-linetables.obj.coff-2012-x86_64 \
>  RUN:   | FileCheck %s -check-prefix MFUN64
>  RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifile-linetables.obj.coff-2012-i368 \
>  RUN:   | FileCheck %s -check-prefix MFILE32
>  RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifile-linetables.obj.coff-2012-x86_64 \
>  RUN:   | FileCheck %s -check-prefix MFILE64
> +RUN: llvm-readobj -s -codeview-linetables %p/Inputs/comdat-function-linetables.obj.coff-2008-i386 \
> +RUN:   | FileCheck %s -check-prefix MCOMDAT
>
>  MFUN32:      CodeViewLineTables [
>  MFUN32-NEXT:   Magic: 0x4
>  MFUN32-NEXT:   Subsection [
>  MFUN32-NEXT:     Type: 0xF1
>  MFUN32-NEXT:     PayloadSize: 0x52
>  MFUN32:        ]
>  MFUN32-NEXT:   Subsection [
> @@ -275,8 +277,29 @@ MFILE64-NEXT:       +0x9: 2
>  MFILE64-NEXT:     ]
>  MFILE64-NEXT:     FilenameSegment [
>  MFILE64-NEXT:       Filename: d:\one.c
>  MFILE64-NEXT:       +0xE: 7
>  MFILE64-NEXT:       +0x13: 8
>  MFILE64-NEXT:     ]
>  MFILE64-NEXT:   ]
>  MFILE64-NEXT: ]
> +
> +MCOMDAT:      FunctionLineTable [
> +MCOMDAT-NEXT:        FunctionName: ?f@@YAHXZ
> +MCOMDAT-NEXT:        CodeSize: 0xA
> +MCOMDAT-NEXT:        FilenameSegment [
> +MCOMDAT-NEXT:          Filename: c:\test.cc
> +MCOMDAT-NEXT:          +0x0: 2
> +MCOMDAT-NEXT:          +0x3: 3
> +MCOMDAT-NEXT:          +0x8: 4
> +MCOMDAT-NEXT:        ]
> +MCOMDAT-NEXT:      ]
> +MCOMDAT:      FunctionLineTable [
> +MCOMDAT-NEXT:        FunctionName: ?g@@YAHXZ
> +MCOMDAT-NEXT:        CodeSize: 0xA
> +MCOMDAT-NEXT:        FilenameSegment [
> +MCOMDAT-NEXT:          Filename: c:\test.cc
> +MCOMDAT-NEXT:          +0x0: 7
> +MCOMDAT-NEXT:          +0x3: 8
> +MCOMDAT-NEXT:          +0x8: 9
> +MCOMDAT-NEXT:        ]
> +MCOMDAT-NEXT:      ]
> diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp
> index 8b0dcb3..092382c 100644
> --- a/tools/llvm-readobj/COFFDumper.cpp
> +++ b/tools/llvm-readobj/COFFDumper.cpp
> @@ -73,16 +73,18 @@ private:
>                                  SymbolRef &Sym);
>    std::error_code resolveSymbolName(const coff_section *Section,
>                                      uint64_t Offset, StringRef &Name);
>
>    typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy;
>
>    const llvm::object::COFFObjectFile *Obj;
>    RelocMapTy RelocMap;
> +  StringRef FileIndexToStringOffsetTable;
> +  StringRef StringTable;
>  };
>
>  } // namespace
>
>
>  namespace llvm {
>
>  std::error_code createCOFFDumper(const object::ObjectFile *Obj,

[+Eric, who has the "approve" rights]
As these are not printCodeViewLineTables-local variables anymore, I
think we'd rather have names that somehow mention CVLT or DI.

> @@ -433,18 +435,16 @@ void COFFDumper::printBaseOfDataField(const pe32plus_header *) {}
>
>  void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {
>    StringRef Data;
>    if (error(Section.getContents(Data)))
>      return;
>
>    SmallVector<StringRef, 10> FunctionNames;
>    StringMap<StringRef> FunctionLineTables;
> -  StringRef FileIndexToStringOffsetTable;
> -  StringRef StringTable;
>
>    ListScope D(W, "CodeViewLineTables");
>    {
>      DataExtractor DE(Data, true, 4);
>      uint32_t Offset = 0,
>               Magic = DE.getU32(&Offset);
>      W.printHex("Magic", Magic);
>      if (Magic != COFF::DEBUG_SECTION_MAGIC) {
>

2014-07-09 1:45 GMT+04:00 Jeff Muizelaar <jmuizelaar at mozilla.com>:
> I just built a trivial c file with two functions and -Gy -Z7 with msvc 2008.
> -Jeff

Ah, correct.

[Self-note, doesn't block your patch]
For this file:
--------------
int f()
{
  return 0;
}

int g()
{
  return 0;
}
--------------
with -Gy the .obj file has three .debug$S sections.

The first one has (0xF1, 0xF4, 0xF3) subsection structure and the
other two have (0xF5, 0xF1, 0xF2) structure.  The first one holds the
file-level stuff (e.g. string/index tables), the remaining ones hold
per-function stuff (e.g. line table).

For this file built *without* -Gy
---------------
inline int f()
{
  return 0;
}

inline int g()
{
  return 0;
}

void z() {
  f();
  g();
}
---------------
there are three .debug$S sections as well.

The first one holds the string/index tables as well as the linetable
for 'z' (again, file-level stuff);
the other two hold linetables for 'f' and 'g' (per-function stuff).

Currently, LLVM only emits one section on this file.
We should emit separate sections for linkonce_odr functions.
I even think I saw wrong linenumbers showing up when debugging inline
class method definitions once...
I'll wait fixing this until I see a real-world manifestation of the
bug though, so feel free to analyze.

> On Jul 8, 2014, at 10:05 AM, Timur Iskhodzhanov <timurrrr at google.com> wrote:
>
>> Sorry for a long delay as I was on vacation.
>>
>> Can you please send me the object file over email (rather than binary
>> in text) and explain how can I generate a similar one myself?
>>
>> 2014-06-27 0:38 GMT+04:00 Jeff Muizelaar <jmuizelaar at mozilla.com>:
>>> commit 848055afc38cd5fc339c5aaea9122e1c8bf27f67
>>> Author: Jeff Muizelaar <jmuizelaar at mozilla.com>
>>> Date:   Wed Jun 4 18:19:32 2014 -0400
>>>
>>>    Fix dumping codeview line tables when there are multiple debug sections
>>>
>>>    Codeview line tables for functions in different sections refer
>>>    to a common STRING_TABLE_SUBSECTION for filenames. This happens
>>>    when building with -Gy with MSVC.
>>>
>>> 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
>>> new file mode 100644
>>> index 0000000000000000000000000000000000000000..45416d52c3644aeb8395820268d36693e78d7431
>>> GIT binary patch
>>> literal 1635
>>> zcmcIkF>ljQ5I)zWX$mTC#lX<vQAL6Z>}Du}7OJLAn}SGa)TC7 at 29elKFiPquc1p_B
>>> zfeoaxvcbf{!Uhrx>IxeYKLQpg2qA>Zou8j^3T$xF`Q3f*-uK at 5-n*O>ht~^Fi}4u1
>>> z5OC4VmSuPwR^Y-I8mA=T1!KPgnrT(qwPaDuJi?f(`{L4|%xa$1 at k9`g{ixr2A^@69
>>> zDcso4_Y(1#4Dbq-1dj-5<<ES(L5v at WpTF__z_=F&cvQ&8^C*e6!)Uw at VgyEcFviB_
>>> z=Cd=)xl-=p?Boc3GWpU-H at KLayF8PhFOD!`_=viTIt0=nQDr7|&vHG at soa7|I6o*c
>>> zfH)k+nM6kl$GmN{9M`FO?8MS2TWorE!@gs$*I34BH0`?8g2ym52*z!b2*Ie+P-r=|
>>> zR=L5l7~tx^C{}E at U9PjD*EVg3O=u~7C8JmDb=|0IR>uOPVS<`<A}3>N)<k#1m`G_&
>>> zv%*w^sSBG-T|2|nRi@@kOf41A1h-{?pN?Sw2GS|SBFyMB>QPj>5sGx=&G6Ul@$H*$
>>> zPe1HQ=%eTOe`(_!7{O0LmSic#l2)b3rf{&EjQnwSl3n)!#0lVz%bl}0i@`a6Ml&kK
>>> z@`hzDSv8lbgcp3Af^e=-#vkO;0@`- at -iPOO1+MK-rM{phQH9VYjmjZ(=#Gi1UPAjg
>>> zD1KE%9Ic_4K2%8&s8oev7z$kh2P3|N9_R)5gnlYAC-x^kaW0JAA|G{&_Q11j(YYu#
>>> z4y%E65cI(6hx;M+AjBwd-0=VBUHeyg$Ai2vXFu;mkT<;>o;O)MZ?bsa9HYEBMwROY
>>> z$?tLl(5Hkg2}_eU at MUSXndsbwy*>KF>8e%sv{Z_2FGr$nkx*G0!*91lTNrgXS)!)c
>>> zEzx%9S5p$Tez(&&#@|bnht4faelrY+WWN=XLvtiDFuX=lX1dvO$h`UN+mqj!=@xV|
>>> m$3o at -qD6^u=17agYTznrlHEdYeY%=XUzxeEx(3rVVf_REpWBT9
>>>
>>> literal 0
>>> HcmV?d00001
>>>
>>> diff --git a/test/tools/llvm-readobj/codeview-linetables.test b/test/tools/llvm-readobj/codeview-linetables.test
>>> index 4854d7a..b908a59 100644
>>> --- a/test/tools/llvm-readobj/codeview-linetables.test
>>> +++ b/test/tools/llvm-readobj/codeview-linetables.test
>>> @@ -1,16 +1,18 @@
>>> RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifunction-linetables.obj.coff-2012-i368 \
>>> RUN:   | FileCheck %s -check-prefix MFUN32
>>> RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifunction-linetables.obj.coff-2012-x86_64 \
>>> RUN:   | FileCheck %s -check-prefix MFUN64
>>> RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifile-linetables.obj.coff-2012-i368 \
>>> RUN:   | FileCheck %s -check-prefix MFILE32
>>> RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifile-linetables.obj.coff-2012-x86_64 \
>>> RUN:   | FileCheck %s -check-prefix MFILE64
>>> +RUN: llvm-readobj -s -codeview-linetables %p/Inputs/comdat-function-linetables.obj.coff-2008-i386 \
>>> +RUN:   | FileCheck %s -check-prefix MCOMDAT
>>>
>>> MFUN32:      CodeViewLineTables [
>>> MFUN32-NEXT:   Magic: 0x4
>>> MFUN32-NEXT:   Subsection [
>>> MFUN32-NEXT:     Type: 0xF1
>>> MFUN32-NEXT:     PayloadSize: 0x52
>>> MFUN32:        ]
>>> MFUN32-NEXT:   Subsection [
>>> @@ -275,8 +277,29 @@ MFILE64-NEXT:       +0x9: 2
>>> MFILE64-NEXT:     ]
>>> MFILE64-NEXT:     FilenameSegment [
>>> MFILE64-NEXT:       Filename: d:\one.c
>>> MFILE64-NEXT:       +0xE: 7
>>> MFILE64-NEXT:       +0x13: 8
>>> MFILE64-NEXT:     ]
>>> MFILE64-NEXT:   ]
>>> MFILE64-NEXT: ]
>>> +
>>> +MCOMDAT:      FunctionLineTable [
>>> +MCOMDAT-NEXT:        FunctionName: ?f@@YAHXZ
>>> +MCOMDAT-NEXT:        CodeSize: 0xA
>>> +MCOMDAT-NEXT:        FilenameSegment [
>>> +MCOMDAT-NEXT:          Filename: c:\test.cc
>>> +MCOMDAT-NEXT:          +0x0: 2
>>> +MCOMDAT-NEXT:          +0x3: 3
>>> +MCOMDAT-NEXT:          +0x8: 4
>>> +MCOMDAT-NEXT:        ]
>>> +MCOMDAT-NEXT:      ]
>>> +MCOMDAT:      FunctionLineTable [
>>> +MCOMDAT-NEXT:        FunctionName: ?g@@YAHXZ
>>> +MCOMDAT-NEXT:        CodeSize: 0xA
>>> +MCOMDAT-NEXT:        FilenameSegment [
>>> +MCOMDAT-NEXT:          Filename: c:\test.cc
>>> +MCOMDAT-NEXT:          +0x0: 7
>>> +MCOMDAT-NEXT:          +0x3: 8
>>> +MCOMDAT-NEXT:          +0x8: 9
>>> +MCOMDAT-NEXT:        ]
>>> +MCOMDAT-NEXT:      ]
>>> diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp
>>> index 8b0dcb3..092382c 100644
>>> --- a/tools/llvm-readobj/COFFDumper.cpp
>>> +++ b/tools/llvm-readobj/COFFDumper.cpp
>>> @@ -73,16 +73,18 @@ private:
>>>                                 SymbolRef &Sym);
>>>   std::error_code resolveSymbolName(const coff_section *Section,
>>>                                     uint64_t Offset, StringRef &Name);
>>>
>>>   typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy;
>>>
>>>   const llvm::object::COFFObjectFile *Obj;
>>>   RelocMapTy RelocMap;
>>> +  StringRef FileIndexToStringOffsetTable;
>>> +  StringRef StringTable;
>>> };
>>>
>>> } // namespace
>>>
>>>
>>> namespace llvm {
>>>
>>> std::error_code createCOFFDumper(const object::ObjectFile *Obj,
>>> @@ -433,18 +435,16 @@ void COFFDumper::printBaseOfDataField(const pe32plus_header *) {}
>>>
>>> void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {
>>>   StringRef Data;
>>>   if (error(Section.getContents(Data)))
>>>     return;
>>>
>>>   SmallVector<StringRef, 10> FunctionNames;
>>>   StringMap<StringRef> FunctionLineTables;
>>> -  StringRef FileIndexToStringOffsetTable;
>>> -  StringRef StringTable;
>>>
>>>   ListScope D(W, "CodeViewLineTables");
>>>   {
>>>     DataExtractor DE(Data, true, 4);
>>>     uint32_t Offset = 0,
>>>              Magic = DE.getU32(&Offset);
>>>     W.printHex("Magic", Magic);
>>>     if (Magic != COFF::DEBUG_SECTION_MAGIC) {
>>>
>
>



More information about the llvm-commits mailing list