DebugInfo library and relocations in the .debug_line section

I’m working on adding source-based profiling support for MCJIT and in the process of implementing this, I came across a test case where an object is being generated that wants to have relocations applied to the .debug_line section. I see in the DebugInfo code that it currently only supports relocations applied to either the .debug_info or the .debug_info.dwo section.

Can anyone give me an overview of what I would need to do to extend this to handle the .debug_line section also?

Thanks,

Andy

That relocation handling is only done for the llvm-dwarfdump binary. MCJIT handles relocations a bit different. I think you just need to go ahead and allow the MCJIT relocation handling machinery to work on non-alloc sections and it should go ahead and handle these just fine, unless you’re using the existing stuff in lib/DebugInfo to print out information or something?

If this isn’t what you’re doing can you give me a bit more information on your current code?

-eric

Actually, MCJIT doesn’t perform relocations on debug sections. I’m not sure that would matter anyway. The place where I’m handling the debug information is outside MCJIT and the MCJIT relocation code isn’t really accessible at that point.

Right now, when MCJIT emits an object image, it broadcasts an event to any registered listeners indicating that an object was emitted, passing an ObjectImage reference as the parameter to the listener. The only current listener I’m aware of is the IntelJITEventListener, which wants to notify the Intel VTune Amplifier (if present) about the newly JITed functions.

The listener uses the ObjectImage interface (which is modeled after the ObjectFile interface) to walk through the symbols in the object and look for functions, getting their address and size from the SymbolRef interface. So far, so good, and all of this is currently happening in trunk.

As a next step, I want to use the DWARF information to figure out source file and line number information for the functions. My plan is to add a new function to the DIContext interface called getLineInfoForAddressRange, which will do pretty much what the existing getLineInfoForAddress does except that it will return a vector of <address, DILineInfo> pairs for all lines in the range.

It happens that the ObjectImage class aggregates an ObjectFile, so I’m going to provide a method to retrieve the underlying ObjectFile and use that to create the DIContext. That works. I’m having a bit of an issue with the getLineInfoForAddress function in that it seems to be expecting addresses that are offsets into the function’s section rather than into the file. This seems wrong and may or may not be related to the fact that the generated object doesn’t have a .debug_aranges section and so the DWARFContext code constructs that on the fly. In any event, I’ve got that working for at least simple cases where all the JITed functions are in the same section.

The problem is that I have a test case that is trying to reference an inlined function. In this case, the generated object puts the ‘inlined’ function in a separate section (I’m not clear why that is) and generates relocations for the .debug_line section. Since these relocations are never applied, I end up with multiple sequences in the line table claiming to be at address zero.

FWIW, if I use whatever ‘dwarfdump’ is on my Linux box to look at the generated object, it shows me a line table with multiple entries claiming to be at address zero just like llvm-dwarf does. If I let clang finish things and create an executable, both dwarfdump and llvm-dwarfdump show unique load-based addresses for everything.

I can send you .cpp, .bc, .ll or .o files for my test case if that would help.

Thanks,

Andy

Actually, MCJIT doesn’t perform relocations on debug sections. I’m not
sure that would matter anyway. The place where I’m handling the debug
information is outside MCJIT and the MCJIT relocation code isn’t really
accessible at that point.****

**

I know it doesn't, that's why I made the "non-alloc" comment. :slight_smile:

**

Right now, when MCJIT emits an object image, it broadcasts an event to any
registered listeners indicating that an object was emitted, passing an
ObjectImage reference as the parameter to the listener. The only current
listener I’m aware of is the IntelJITEventListener, which wants to notify
the Intel VTune Amplifier (if present) about the newly JITed functions.***
*

**

OK.

**

The problem is that I have a test case that is trying to reference an
inlined function. In this case, the generated object puts the ‘inlined’
function in a separate section (I’m not clear why that is) and generates
relocations for the .debug_line section. Since these relocations are never
applied, I end up with multiple sequences in the line table claiming to be
at address zero.****

** **

FWIW, if I use whatever ‘dwarfdump’ is on my Linux box to look at the
generated object, it shows me a line table with multiple entries claiming
to be at address zero just like llvm-dwarf does. If I let clang finish
things and create an executable, both dwarfdump and llvm-dwarfdump show
unique load-based addresses for everything.****

**

Right. This is pretty easy, especially if you just look at my last patch
that added a new reloc handler for .debug_info.dwo (r171428). I've been
meaning to do this, but it hasn't bubbled up to the top of my queue yet.

-eric

Well, I saw the .debug_info.dwo stuff (though I didn’t realize it was so recent), but it wasn’t clear to me how adding a map for a section with a different purpose would work – that is, whether it should be yet another member variable in DWARFContextInMemory or if there was some better way to combine them.

It also wasn’t clear to me what the relocation map was doing anyway and what would need to be changed for the .debug_line section, but I suppose that was mostly laziness on my part, hoping that you had a plan that you could just spell out for me.

Having overcome my laziness a bit today and looked at the code some more, it looks like I’d need to pass the new map (however it was stored) into DWARFDebugLine and have that class use it in its parseStatementTable and associated methods. It looks like it would take a bit of thought to figure out which fields might be candidates for relocation and which wouldn’t, but I suppose that’s manageable.

Does this sound basically correct? Or should I just wait for you to do the work? J

-Andy

Well, I saw the .debug_info.dwo stuff (though I didn’t realize it was so
recent), but it wasn’t clear to me how adding a map for a section with a
different purpose would work -- that is, whether it should be yet another
member variable in DWARFContextInMemory or if there was some better way to
combine them.****

**

*shrug* I've been adding them as needed. I knew I needed the debug_line
table, but I've been mostly adding that stuff as I need it to fix something
else. Right now I think we're only going to ultimately need a couple of
them so just adding them as fields sounds fine.

**

It also wasn’t clear to me what the relocation map was doing anyway and
what would need to be changed for the .debug_line section, but I suppose
that was mostly laziness on my part, hoping that you had a plan that you
could just spell out for me.****

**

Oh sorry :slight_smile:

**

Having overcome my laziness a bit today and looked at the code some more,
it looks like I’d need to pass the new map (however it was stored) into
DWARFDebugLine and have that class use it in its parseStatementTable and
associated methods. It looks like it would take a bit of thought to figure
out which fields might be candidates for relocation and which wouldn’t, but
I suppose that’s manageable.****

** **

Does this sound basically correct? Or should I just wait for you to do
the work?

That's pretty much correct, I don't really need to dump the line tables at
the moment, but it shouldn't be too long if you're not in any hurry.

-eric

Alright. I’ll probably take a shot at it once I have the more general stuff for my event handler working and ready for review.

-Andy