On Thu, Sep 28, 2006 at 01:26:00PM +0200, Jan Beulich wrote: > While I'm not certain whether gcc is able to split one function's code > between different sections (if for nothing else, this might help reduce > TLB pressure by moving code unlikely to be executed not just out of
Yes, and that caused major grief recently and is still unfixed, see http://gcc.gnu.org/PR22313 http://gcc.gnu.org/PR29132 where we essentially traded of an assembly time failure for generating invalid unwind info. > the main function body), by way of inline assembly the Linux kernel > certainly does in many places. Obviously, pure assembly make use > of such even more heavily. > > However, when frame unwind information is generated, one quickly > becomes aware of a problem with this - the unwind information at a > continuation point in other than the base section would need to > replicate all unwind directives (note that DW_CFA_remember_state > and DW_CFA_restore_state are not suitable here, as there need > to be separate FDEs attached to the secondary code fragments). > While this is generally possible (albeit tedious) in pure assembly code, > doing so in inline assembly doesn't seem to be possible in any way > (the compiler may not even use .cfi_* directives to emit frame > unwind info). > > To cover all cases, it would basically appear to be necessary to > add a referral op to the set of DW_CFA_* ops, which would > indicate that the frame state at the given point is to be derived > by assuming the location counter would in fact be at the origin > of the control transfer). > > As I don't know how to approach requesting an addition like this > to the Dwarf standard, I'm trying my luck here. > > Any pointers or suggestions are greatly appreciated. I believe the way to go forward is for GCC to start using .cfi_* directives rather than emitting .eh_frame section on its own, that's the only way how inline assembly can add its stuff to what GCC generates for the C code. But, we need first to extend gas .cfi_* support so that everything GCC now generates can be expressed with .cfi_* directives and also we need to fix the .cfi_* directives, so that they are local to the current section/subsection (if you use .section or .subsection directive in assembly, you change the CFI op sequence, either to a newly created one, or to the one that has been populated previously for that section/subsection). One thing that can't be expressed currently is e.g. the LSDA pointer, all .cfi_* created CIEs don't have 'P' at all. So we need some way how to tell GAS that this .cfi_start wants a LSDA, what encoding does it use and a block of data that will be stuck into the FDE. Then I think it would be desirable to have a new .cfi to remember resp. restore state with some ID, a mailbox in which the CFA sequence (except intervening loc adjustments, but e.g. including the LSDA) would be stored. So, you could in inline assembly do something like: asm (".cfi_remember_state .LRS%=; .subsection 25; .cfi_start; .cfi_restore_state .LRS%=; subq $128, %rsp; .cfi_...; ....; .cfi_end; .previous"); and the .cfi_restore_state .LRS25301 would copy there whatever non-DW_CFA_adjust_loc* ops there are in the current section/subsection from its .cfi_start until now. Jakub