I traced the process of llvm-dwarfdump with gdb and it looks like the .debug_info section isn’t generated correctly.
I’ve had a look at the documentation relating to LLVM and DWARF. It looks like they are mostly about how to adapt DWARF for a new language on the front end.
I also googled a combination of keywords like LLVM and DWARF and didn’t find anyone with the same problem.
I grep’d the keywords under Target/X86 and Target/AArch64. It doesn’t look like there is any code related to the .debug_info section either.
I’m wondering if I need to write some additional code for a new backend to support DWARF and if so, is there a document that tells me what code I need to write? If not, where should I start to debug this problem?
The error messages from llvm-dwarfdump certainly sound like at least the header isn’t being generated correctly. It might help if you could post a hex dump of the .debug_info section.
That first word (first 32 bits) is supposed to be the length of the .debug_info for the compilation unit. As you can see, for x86_64 it’s 0x51 but for your case it is 0. That causes llvm-dwarfdump to misinterpret the entire section.
That length is typically computed by the assembler as a label difference, so my first guess is that the labels aren’t being emitted correctly. I suggest comparing the assembly source (compile with -S) and look at how that first word is computed for x86_64, versus your target. Possibly something in your target code isn’t being done in the correct order, or might be missing entirely.
Although the assembly code for my target seems odd, it looks like the start and end tags for .debug_info are emitted correctly, as is the unit length .Ldebug_info_end0-.Ldebug_info_start0. It looks like something may have gone wrong converting from assembly to binary.
Yes, the labels and label difference expression look correct in the assembly text. You probably do have some issue in your MC code that is causing the problem. I can’t really help you there.
I have solved the problem and here is my journey. In a nutshell, it’s basically fixing problems with the hook functions my partner wrote when introducing the new backend.
First, in LLVMTargetMachine::initAsmInfo, I set Options.MCOptions.AsmVerbose to true. This prints comments in assembly, which helps me to make sure that the workflow up to assembly is correct. Here I found the first problem. My target machine is VLIW architecture. It needs a special assembly format to fit the downstream emulator, which doesn’t take into account the .debug_* sections, so the result is a messy assembly.
BTW, I can’t find any target-dependent code in the assembler that enables AsmVerbose, but it defaults to true on X86, and I don’t know why.
The second problem (perhaps) is with XXAsmInfo. My partner specified CodePointerSize as 2. However, for a 32-bit machine, this number should probably be 4. I suspect this will cause some problems with both assembly generation and parsing.
The third problem is that in XXAsmBackend::applyFixup, my partner provides an XXAsmBackend::adjustFixupValue, modelled on the AArch64 implementation. This function is supposed to return Value itself by default, but is incorrectly written as return 0. This means that all the calculations we provided for Fixup are wasted.
The last problem occurs with the linker. The hook XX::relocate provided by the new backend for relocation filters out the Rel.expr == RelExpr::R_NONE scenario because of a problem I have not yet identified. However, the relocation of the .debug_* sections arrives here via relocateNoSym, and Rel.expr must be RelExpr::R_NONE.
As I said at the beginning, I didn’t need to do anything special to support DWARF on the new backend, all the problems stemmed from the hooks written when the new backend was introduced. I hope this report will help anyone who encounters this problem later.