On Sun, Sep 5, 2010 at 1:02 PM, Renato Golin <span dir="ltr"><<a href="mailto:rengolin@systemcall.org">rengolin@systemcall.org</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div class="im">On 5 September 2010 19:32, Talin <<a href="mailto:viridia@gmail.com">viridia@gmail.com</a>> wrote:<br>
> I've carefully studied the source code of CGDebugInfo in clang as a working<br>
> example. One puzzlement is that there's a discrepancy between what the<br>
> "source level debugging with LLVM" docs say and what clang does: According<br>
> to the docs, DW_TAG_formal_parameter is used to specify a formal parameter<br>
> in a function type descriptor, but according to a code search, the name<br>
> "DW_TAG_formal_parameter" does not appear anywhere in the clang source code.<br>
> Instead, the argument array that is used when creating a function type<br>
> descriptor contains only the bare types, not types wrapped in a formal<br>
> parameter DIE.<br>
<br>
</div>Hi Talin,<br>
<br>
Like in CGDebugInfo, you have to use the Subprogram type only for the<br>
return type. What gives you the parameters is passing the Function* as<br>
the last parameter on DIFactory.CreateSubprogram().<br></blockquote><div><br></div><div>I understand about passing the Function* as the last argument. I'm not sure I understand the first sentance ("You have to use the Subprogram type only for the return type").</div>

<div><br></div><div>Here's what my code for creating function descriptors currently looks like (note that some parts are commented out for debugging purposes):</div><div><br></div></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;">

<div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">DISubprogram CodeGenerator::genDISubprogram(const FunctionDefn * fn, Function * f) {</font></div></div></div><div class="gmail_quote">

<div><div><font class="Apple-style-span" face="'courier new', monospace">  DASSERT(fn != NULL);</font></div></div><div><font class="Apple-style-span" face="'courier new', monospace">  // Look up in the map to see if already generated.</font></div>

</div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">  DISubprogram & sp = dbgSubprograms_[fn];</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">  if (!sp.isSubprogram()) {</font></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">    DIType dbgFuncType = genDIType(fn->functionType());</font></div></div></div><div class="gmail_quote">

<div><div><font class="Apple-style-span" face="'courier new', monospace">    DASSERT(dbgFuncType.Verify());</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">    DASSERT(dbgCompileUnit_.Verify());</font></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">    sp = dbgFactory_.CreateSubprogram(</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">        dbgCompileUnit_,</font></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">        fn->name(),</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">        fn->qualifiedName(),</font></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">        fn->linkageName(),</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">        dbgFile_, // genDIFile(fn),</font></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">        1, // getSourceLineNumber(fn->location()),</font></div></div></div><div class="gmail_quote">

<div><div><font class="Apple-style-span" face="'courier new', monospace">        dbgFuncType,</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">        fn->isSynthetic() /* isLocalToUnit */,</font></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">        false /* isDefinition */,</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">        0, 0 /* VK, Index */,</font></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">        DIType(),</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">        false /* isArtificial */,</font></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">        false /* isOptimized */,</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">        f);</font></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">    DASSERT(sp.Verify());</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">  }</font></div>

</div></div></blockquote><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace"><br>

</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">  return sp;</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">}</font></div>

</div></div></blockquote><div class="gmail_quote"><div><div><br></div></div><div>And here's the code that generates function type descriptors:</div><div><br></div></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;">

<div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">DICompositeType CodeGenerator::genDIFunctionType(const FunctionType * type) {</font></div></div></div><div class="gmail_quote">

<div><div><span class="Apple-style-span" style="font-family: 'courier new', monospace; ">  DIDescriptorArray args;</span></div></div></div><div class="gmail_quote"><div><div><span class="Apple-style-span" style="font-family: 'courier new', monospace; ">  args.push_back(genDIType(type->returnType()));</span></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">  if (type->selfParam() != NULL) {</font></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">    const ParameterDefn * param = type->selfParam();</font></div></div><div><font class="Apple-style-span" face="'courier new', monospace">    // genDIParameterType() calls genDIType and then makes it a pointer</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">    // if the underlying type is a reference type.</font></div></div><div class="gmail_quote"><div><div><span class="Apple-style-span" style="font-family: 'courier new', monospace; ">    args.push_back(genDIParameterType(param->type()));</span></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">  }</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace"><br>

</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">  const ParameterList & params = type->params();</font></div></div></div><div class="gmail_quote">

<div><div><font class="Apple-style-span" face="'courier new', monospace">  for (ParameterList::const_iterator it = params.begin(); it != params.end(); ++it) {</font></div></div></div><div class="gmail_quote"><div>

<div><font class="Apple-style-span" face="'courier new', monospace">    const ParameterDefn * param = *it;</font></div></div></div><div class="gmail_quote"><div><div><span class="Apple-style-span" style="font-family: 'courier new', monospace; ">    args.push_back(genDIParameterType(param->type()));</span></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">  }</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace"><br>

</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">  DICompositeType fnType = dbgFactory_.CreateCompositeType(</font></div></div></div><div class="gmail_quote">

<div><div><font class="Apple-style-span" face="'courier new', monospace">      dwarf::DW_TAG_subroutine_type,</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">      dbgCompileUnit_,</font></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">      "",</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">      dbgFile_,</font></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">      0, // Source line</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">      0, // Size</font></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">      0, // Align</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">      0, // Offset</font></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">      0, // Flags</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">      DIType(),</font></div>

</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">      dbgFactory_.GetOrCreateArray(args.data(), args.size()));</font></div></div></div><div class="gmail_quote">

<div><div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">  dbgTypeMap_[type] = fnType;</font></div>

</div></div><div class="gmail_quote"><div><div><span class="Apple-style-span" style="font-family: 'courier new', monospace; ">  DASSERT(fnType.Verify());</span></div></div></div><div class="gmail_quote"><div><div>

<font class="Apple-style-span" face="'courier new', monospace">  return fnType;</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="'courier new', monospace">}</font></div>

</div></div></blockquote><div class="gmail_quote"><div><div><br></div></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
I suppose DIFactory was done tailored to C-like languages using Clang<br>
as the primary driver for changes. I'd not be surprised if you could<br>
do things that it didn't expect and then it'd generate images with bad<br>
Dwarf (enough to cause segfault in dwarfdump).<br>
<br>
I'd try to mimic exactly what CGDebugInfo does, even if that makes<br>
your "info func" look like C functions in GDB, or if the parameters<br>
are all mixed up. At least you get something out of it and can, then,<br>
work your way to fix it in LLVM.<br>
<br>
I'm putting together some help with using DIFactory, maybe I can turn<br>
that into a proper doc. I'll keep you posted.<br>
<font color="#888888"><br>
--<br>
cheers,<br>
--renato<br>
<br>
<a href="http://systemcall.org/" target="_blank">http://systemcall.org/</a><br>
<br>
Reclaim your digital rights, eliminate DRM, learn more at<br>
<a href="http://www.defectivebydesign.org/what_is_drm" target="_blank">http://www.defectivebydesign.org/what_is_drm</a><br>
</font></blockquote></div><br><br clear="all"><br>-- <br>-- Talin<br>