Consider we have function with jump tables. Currently we're doing something like this: .text ... function body .. ret .section .rodata ... jump table entries ... .size funcname, .-funcname Note, that .size directive is actually located in rodata section and "." refers to .rodata section too, so size is definitely incorrect. Ok. This doesn't make things too much bad. Consider we have eh enabled. We have: .text eh_func_begin: ... function body ... ret .section .rodata ... jump table entries ... .size funcname, .-funcname eh_func_end: .section eh_frame .... Note, eh_func_end is in *rodata* section. eh_frame should contain misc. offsets, involving eh_func_begin and eh_func_end. Surely this information will be invalid. Even more, as blames, because it cannot compute cross-section offsets. The solution seems to be easy: just emit JT info in the late end, but I'm little bit worried, because I saw the following comment in X86ATTAsmPrinter.cpp: // Print out jump tables referenced by the function. // Mac OS X requires that the jump table follow the function, so that the jump // table is part of the same atom that the function is in. EmitJumpTableInfo(MF.getJumpTableInfo(), MF); if (TAI->hasDotTypeDotSizeDirective()) O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n"; if (Subtarget->isTargetDarwin() || Subtarget->isTargetELF() || Subtarget->isTargetCygMing()) { // Emit post-function debug information. DW.EndFunction(); } It seems for me, that EmitJumpTableInfo() should be moved to the late end, but what does that comment mean" What is "atom" for MacOS X? We really need someone with darwin knowledge to resolve this.
Here are the constraints. Darwin does dead code stripping on a per-atom basis. Atoms are chunks of the .s file delimited by non-local labels. For example, the start of a function is the start of an atom, the start of a global var is, etc. The problem we have is that we can't have the function and the jump tables end up in different sections or even have a global label between them. Doing so lets the linker delete one but not the other, which is bad. :) The solution is that the jump tables have to be emitted into the text section, right after the function bodies. On darwin, stuff like this is ok: .text ... function body .. ret .section .rodata ... jump table entries ... .size funcname, .-funcname because we don't have a "section rodata". Also, in the EH case, eh_func_end is in the right section, because it never switched. There are really two bugs here. First, the .size directive should be emitted before the JT entries for linux. Second, eh_func_end should be put at the end of the function, before the JT entries. I assume (please verify) that eh_func_end is used to represent the range of potential throw sites. Since the jump table itself will never throw, it does not need to be covered by this region. Also, eh_func_end doesn't sound like a legal label. It should start with an L/., no? -Chris
Created attachment 817 [details] example
Created attachment 818 [details] GCC-generated darwin/ppc .s file
Created attachment 819 [details] GCC-generated darwin/x86 .s file
I attached some GCC generated code. GCC emits the jump tables *inside* the functions. We don't want to do that, we should just emit them at the end.
Fixed with: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070430/049144.html http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070430/049143.html http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070430/049142.html