[llvm-dev] [RFC] Improving compact x86-64 compact unwind descriptors

Ron Brender via llvm-dev llvm-dev at lists.llvm.org
Mon Jan 29 13:36:55 PST 2018


Hi Nick,

It is a pleasure to be in contact with the creator of the compact unwind
approach!

I can see how an array of 32-bit unwind blocks could be used to describe
each distinct point within a function (within a prolog in particular). But
then you end up with six or seven or more such blocks for a large
percentage of functions, don't you? Seems like a lot of additional space
for something that is usually simple, compact (sic) and idiomatic and
dilutes the original benefit. We are seeking a summary description in a
small fixed size to supplement the base unwind block.

Since you mention it, why have the UNWIND_IS_NOT_FUNCTION_START flag? Seems
like you don't need it for unwinding purposes. Especially in a function
that has a code layout where the entry point is not the first/lowest
addressed instruction of the function (which I have seen in some GEM
produced code for Alpha). An aside, but just curious.

Not being a MAC guy the macOS two-level lookup scheme has always been
rather a mystery. What little I know is gleaned from the
compact_unwind_encoding.h file found around the net. But I have never seen
the .c/.cxx/.cpp that goes with it to better understand how the mapping
works. Always figured the was considered proprietary but maybe I just don't
know where/how to look. Is there public code and/or design note information
to look at?

You are correct that this paper tends toward trying to create a scheme with
little or no linker involvement. There are good reasons to ask more of the
linker for better space economy, so this is still under discussion.

You are also correct that the unwinder needs to interpret the additional
prolog/epilog information. But the rest of your comment has me confused:
the extra 2-bytes is just a widening as you suggest, right? And there is no
Section 5.1--did you mean 3.1?

Thanks again,
Ron

On Fri, Jan 26, 2018 at 9:54 PM, Nick Kledzik via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> John and Ron,
>
> I developed the original compact unwind implementation for macOS 10.6 back
> in 2009.  I tried to leave space in the design to support finer grain
> exception handling such as for asynchronous or for the shrink wrap
> optimization.   The idea I had at the time was  instead of having just one
> 32-bit compact unwind info per function, there could be an array of them
> each covering a different range. All but the first would have the
> UNWIND_IS_NOT_FUNCTION_START bit set.
>
> On macOS, the linker takes the 32-byte “compact unwind group description”
> records and folds them down into a complete different (read only) runtime
> table which basically maps an offset in the DSO into a 32-bit compact info
> for that address.
>
> It seems like from your proposal that your linker keeps the “compact
> unwind group description” records as is and just concatenates them, and the
> runtime would need to understand the prolog/epilog encoding.  I would think
> that just widening the group record (as you suggest in 5.1) would be much
> simpler (like SHT_REL was widened to SHT_RELA).
>
> -Nick
>
>
>
> > On Jan 26, 2018, at 7:54 AM, John Reagan via llvm-dev <
> llvm-dev at lists.llvm.org> wrote:
> >
> > Here is our proposal to extend/enhance the x86-64 compact unwind
> > descriptors to fully describe the prologue/epilogue for asynchronous
> > unwinding.  I believe there are missing/lacking CFI directives as well,
> > but I'll save that for another thread.
> >
> >
> > Asynchronous Compact Unwind Descriptors
> > Ron Brender, VMS Software, Inc.
> > Revised January 25, 2018
> >
> > 1  Introduction
> > This document proposes means to extend so-called compact unwind
> > descriptors to support fully
> > asynchronous exception handling. This will make extended compact unwind
> > descriptors an
> > alternative to DWARF CFI (call frame information) for achieving
> > asynchronous exception
> > support.
> >
> > Compact unwind descriptors can and have been used in both 64- and 32-bit
> > environments.
> > However, this proposal addresses only 64-bit environments. While the
> > ideas presented here can
> > be readily adapted for use in a 32-bit environment, for simplicity this
> > document makes no
> > attempt to do so.
> >
> > There are generally three kinds of information that together form the
> > heart of modern software
> > exception handling systems:
> >
> >  1. Information that is used to divide the remaining unwind information
> > into groups that are
> >     specific to particular regions of memory (often, but not
> > necessarily, associated with a
> >     single function) as well as provide a way to efficiently search for
> > and identify the
> >     grouping that is associated with a particular address in memory.
> >
> >  2. Information that can be used to virtually or actually unwind from
> > the call frame of an
> >     executing function to the call frame of its caller (at the point of
> > the call).
> >
> >  3. Identification of an associated personality routine that is invoked
> > by the general exception
> >     handling mechanization to guide how processing should proceed for a
> > given function, as
> >     well as additional “language specific data” needed for the
> > personality routine to do its
> >     job. Note that the personality routine and its related data are
> > specified as an adjunct to
> >     compiled code and totally opaque to the general mechanism (other
> > than the specified
> >     interface).
> >
> > Note in particular that C++ exception handling is built on top of a
> > personality routine and
> > language specific data area ABI that itself can be implemented using
> > either DWARE CFI or
> > extended compact unwind information as described here. The choice
> > between the two is
> > transparent to C++.
> >
> >
> > 2  Compact Unwind Overview
> > This section provides a brief overview of key features of the LLVM
> > compact unwind design. It
> > does not attempt a comprehensive re-statement of all aspects of the
> > design except to the extent
> > necessary to motivate and understand later proposed changes and
> > enhancements.
> >
> > 2.1  Compact Unwind Group Description
> > A compact unwind group consist of five fields, as follows:
> >
> > | 63                             32 31                            0 |
> > |-------------------------------------------------------------------|
> > | STARTING-ADDRESS                                                  |
> > | LENGTH                           | COMPACT-UNWIND-DESCRIPTION     |
> > | PERSONALITY-FUNCTION-POINTER                                      |
> > | LANGUAGE-SPECIFIC-DATA-ADDRESS                                    |
> > |-------------------------------------------------------------------|
> >
> > STARTING-ADDRESS (64-bits) is the lowest address of a region of memory
> > occupied by some
> > code, typically the entry point of a function.
> >
> > LENGTH (32-bits) is the number of bytes included in this group,
> > typically including all and only
> > the code of a function.
> >
> > COMPACT-UNWIND-DESCRIPTION (32-bits) is a description of the fully
> > formed frame of a
> > function and how to unwind it. This is described further following.
> >
> > PERSONALITY-FUNCTION-POINTER (64-bit) is a pointer to the personality
> > routine.
> >
> > LANGUAGE-SPECIFIC-DATA-ADDRESS (64-bits, sometimes abbreviated LSDA) is a
> > pointer to some data to be passed to the personality routine when it is
> > called.
> >
> > A key observation is that the starting address plus length way of
> > describing a group means that
> > the set of groups for a compilation unit need not describe all of the
> > code in that unit. In
> > particular, it appears to be expected that no unwind information need be
> > generated for leaf
> > functions.
> >
> > On the other hand, it is reasonable to expect that the groups that are
> > emitted are ordered by the
> > starting address. This means that a simple and fast binary search can be
> > used to map an address
> > to the group that applies to that address, if any.
> >
> > It is useful to note that the run-time representation of unwind
> > information can vary from little
> > more than a simple concatenation of the compile-time information to a
> > substantial rewriting of
> > unwind information by the linker. The proposal favors simple
> > concatenation while maintaining
> > the same ordering of groups as their associated code.
> >
> > 2.2  Compact Unwind Frame Description
> > A compact unwind frame description describes a frame in sufficient
> > detail to be able to unwind
> > that frame to the frame of its caller.
> >
> > | 31    28 27    24 23                                            0 |
> > |-------------------------------------------------------------------|
> > | FLAGS   | MODE   |                                                |
> > |-------------------------------------------------------------------|
> >
> > At the top most level, there are four bits that are not of further
> > interest here. Interpretation of
> > these bits is neither used nor changed.
> >
> > Also at the top-level is a 4-bit mode field. This is the tag of a
> > discriminated (tagged, variant)
> > union that selects the interpretation of the remaining 24 bits.
> >
> > Of the 16 possible modes, only 5 are defined :
> >
> > Code    Meaning      Description
> > 0       Old          “Old” is presumed to refer to some historical
> > design that is no longer of interest.
> >                      It is treated here as Reserved.
> > 1       RBP-based    The frame uses the RBP register as a frame pointer.
> > The size of the frame can
> >         frame        vary during execution.
> > 2       RSP-based    The frame uses RSP as the frame pointer. The size
> > of the frame is fixed (at
> >         frame        compilation time).
> > 3       Large RSP-   The frame uses RSP as the frame pointer, The size
> > of the frame is fixed (at
> >         based frame  compilation time); however, that size is too large
> > to express within this 32-bit
> >                      descriptor encoding.
> > 4       DWARF        The frame, for whatever reason, cannot be
> > adequately described using the
> >         escape       compact unwind frame description. The remaining
> > 24-bits are an index into
> >                      what the DWARF standard calls the .debug_frame
> > section (__eh_frame in
> >                      LLVM).
> >
> > 2.2.1  RBP-based Frame (MODE=1)
> > For a RBP-based frame, the remaining 24 bits are encoded as follows:
> >
> > | 23        16 | 15 | 14                                          0 |
> > |-------------------------------------------------------------------|
> > | OFFSET       | 0  | REGS                                          |
> > |-------------------------------------------------------------------|
> >
> > In a RBP-based frame the RBP register is pushed on the stack immediately
> > after the return
> > address, then RSP is moved to RBP. To unwind, RSP is restored with the
> > current RPB value,
> > then RBP is restored by popping off the stack, and the return is done by
> > popping the stack once
> > more into the instruction pointer.
> >
> > All preserved registers are saved in a small range in the stack that
> > starts at RBP-8 to RBP-2040.
> > The offset/8 relative to RBP is encoded in the 8-bit OFFSET field. The
> > registers saved are
> > encoded in the 15-bit REGS field as five 3-bit entries.
> >
> > 2.2.2  RSP-Based Frame (MODE=2)
> > For a RSP-based frame, the remaining 24 bits are encoded as follows:
> >
> > |23        16 | 15      13 | 12      10 | 9                       0 |
> > |-------------------------------------------------------------------|
> > | SIZE        |            | CNT        | REG_PERM                  |
> > |-------------------------------------------------------------------|
> >
> > In a RSP-based frame the stack pointer serves directly as the frame
> > pointer and RBP is available
> > for use as a general register. Upon entry, the stack pointer is
> > decremented by 8*SIZE bytes (the
> > maximum stack allocation is thus 2040 bytes). To unwind, the stack size
> > is added to the stack
> > pointer, and completed by popping the stack once more into the
> > instruction pointer.
> >
> > All preserved registers are saved on the stack immediately after the
> > return address.  The number
> > of registers saved (up to 6) is encoded in the 3-bit CNT field. The
> > 11-bit REG_PERM field
> > encodes which registers were saved and in what order.
> >
> > 2.2.3  Large RSP-Based Frame (MODE=3)
> > For a large RSP-based frame, the remaining 24 bits are encoded as
> follows:
> >
> > |23        16 | 15      13 | 12      10 | 9                       0 |
> > |-------------------------------------------------------------------|
> > | SIZE        | ADJ        | CNT        | REG_PERM                  |
> > |-------------------------------------------------------------------|
> >
> > This case is like the previous, except the stack size is too large to
> > encode in the compact unwind
> > encoding.  Instead, the function must include a "subq $nnnnnnnn, RSP"
> > instruction in its
> > prologue to allocate the stack.  The offset from the entry point of the
> > function to the nnnnnnnn
> > value in the function is given in the SIZE field.
> >
> > Depending on the exact instructions used to save registers (PUSH versus
> > MOV), the nnnnnnnn
> > value in the instruction stream may not be quite the full stack size.
> > ADJ * 8 is the additional
> > adjustment needed to get the actual size.
> >
> > 2.2.4  DWARF Escape (MODE=4)
> > The frame, for whatever reason, cannot be adequately described using a
> > compact unwind frame
> > description. The remaining 24-bits are an index into what the DWARF
> > standard calls the
> > .debug_frame section (called __eh_frame in LLVM).
> >
> >
> > 3  Asynchronous Changes and Enhancements
> > It is immediately obvious that omission of unwind information for leaf
> > functions (with any kind
> > of frame) precludes handling an exception that might occur during its
> > execution. It follows that
> > unwind information must cover all of the code of a module (with one
> > exception discussed
> > below). But if successive unwind groups are ordered (as previously
> > assumed) and also leave no
> > gaps, then the LENGTH field is redundant and can be omitted. The
> > beginning address of a
> > following group is always one byte past the end of the predecessor
> > group. There remains only the
> > question of how to identify the last group of a set.
> >
> > It should also be clear that the unwind representation described in the
> > prior section is not
> > sufficient to unwind from an asynchronous exception that might occur in
> > either the prologue or
> > epilogue of a function. To see this consider what would happen if an
> > exception occurred at either
> > the entry point or the return instruction of either a RBP- or RSP-frame
> > function. To be able to
> > handle asynchronous exceptions at any point during function execution,
> > it is necessary to add
> > additional information to each unwind group.
> >
> > These two considerations can be combined. The result is simply to
> > repurpose the LENGTH field
> > to encode prologue and epilogue information.
> >
> > 3.1  Extended MODEs
> > To preserve backward compatibility and to allow intermixing of
> > traditional and extended
> > compact unwind groups, new MODEs are defined as follows:
> >
> > Code        Meaning                   Description
> > ------------------------------------------------------------
> ----------------------------------
> > 8           Null frame                See below.
> > 9           Extended RBP-based frame  Like mode 1 but combined with
> > extended prologue/epilogue
> >                                       information in place of a LENGTH
> field
> > 10          Extended RSP-based frame  Like mode 2 but combined with
> > extended prologue/epilogue
> >                                       information in place of a LENGTH
> field
> > 11          Extended Large RSP-based  Like mode 3 but combined with
> > extended prologue/epilogue
> >             frame                     information in place of a LENGTH
> field
> > 12          Extended parameter(s)     See below.
> >
> > A null frame (MODE = 8) is the simplest possible frame, with no
> > allocated stack of either kind
> > (hence no saved registers).  A null frame might be considered just a
> > special case of a RSP-based
> > frame with a stack size of zero. But unlike other frames, its frame
> > pointer is usually not 16-byte
> > aligned.
> >
> > It appears technically feasible for a null frame function to have a
> > personality routine. However,
> > the utility of such a capability seems too meager to justify allowing
> > this. We propose to not
> > support this.
> >
> > There remains the question of whether it is necessary or at least
> > desirable to strictly apply the
> > requirement that “all” code be covered by an unwind group. Based on
> > successful experience in
> > OpenVMS on the Itanium architecture (as well as Windows systems we
> > think), this alternative is
> > proposed:
> >
> >     If the first attempt to lookup an unwind group for an exception
> > address fails, then it is
> >     (tentatively) assumed to have occurred within a null frame function
> > or in a part of a function
> >     that is adequately described by a null frame. The presumed return
> > address is (virtually or
> >     actually) popped from the top of stack and looked up. This second
> > attempted lookup must
> >     succeed, in which case processing continues normally. A failure is a
> > fatal error.
> >
> > This concept of a “default null frame group” is especially convenient
> > for dealing with
> > disconnected code sequences such as trampolines, PLTs, and the like.
> >
> > The extended RBP-based and RSP-based frame modes (MODEs = 9 and 10) are
> > simple
> > supersets of their more traditional predecessors.
> >
> > The large RSP-based frame mode (MODE = 11) is also a superset of mode 3
> > except that instead
> > of finding the stack size in the instruction stream, it is found in a
> > preceding extended parameter
> > unwind group (MODE = 12). This difference is essential for support of
> > execute-only code.
> >
> > To understand the extended parameter group, suppose that two groups
> > occur one after the other
> > but have the same STARTING-ADDRESS value. A binary search using the
> > STARTING-
> > ADDRESS field will ignore the first of the pair because the address
> > being sought can never be at
> > least as large as the first but less than the second. Such a group can
> > be used as an escape
> > convention that allows inserting additional information into the
> > sequence of groups that
> > otherwise cannot be easily included.
> >
> > The extended modes are described more fully in the following sections.
> >
> > 3.2  Function Parts
> > Functions are generally considered to consist of three distinct parts:
> >
> > 1. A prologue, which allocates local storage, saves registers that must
> > be preserved for the
> >    benefit of callers, and possibly other housekeeping (such as
> > initializing any local state
> >    necessary for the correct management of the function’s execution).
> >
> > 2. A body, which performs the main work of the function.
> >
> > 3. An epilogue, which makes the result available to the caller, and
> > undoes the effects of the
> >    prologue (restores preserved registers, deallocates local storage,
> > and so on).
> >
> > Here a word of caution is in order. This vocabulary tends to be applied
> > at multiple levels in
> > software architecture and each level has its own set of issues to
> > consider and resulting
> > requirements to be observed.
> >
> > Note that a null frame function has no distinct prologue, body or
> > epilogue. Every instruction can
> > be viewed as simultaneously in all three parts, or in none of them.
> >
> > This leads to the following proposal for the upper part of the extended
> > compact unwind
> > quadword for use in combination with MODE = 8 in the lower part.
> >
> > | 63                            48 | 47                          32 |
> > |-------------------------------------------------------------------|
> > | RESERVED                         | 0            ...             0 |
> > |-------------------------------------------------------------------|
> >
> >
> > | 31                            16 | 15                           0 |
> > |-------------------------------------------------------------------|
> > | 0 0 0 0 | 1 0 0 0 | 0   ...    0 | 0            ...             0 |
> > |-------------------------------------------------------------------|
> >
> >
> >
> > 3.2.1  Function Prologue
> > For the purposes of exception handling, the key steps are:
> >
> >  1. Allocate space on the stack in which to save preserved registers and
> > for other purposes
> >  2. Save the registers that must be preserved.
> >
> > The DWARF call frame information (CFI) provides a description that is
> > precise and accurate at
> > each and every instruction in a function (not limited to just the
> > prologue). But experience shows
> > that this representation is bulky in space and expensive in time to
> > decode and interpret. Indeed,
> > compact unwind descriptors as described in Section 2 were created to
> > avoid these issues.
> >
> > Experience with OpenVMS on the Alpha and Itanium architectures shows
> > that a key constraint
> > can greatly simplify the unwind description: require that no preserved
> > register can be changed
> > until all of them have been saved. The last such save ends the prologue
> > and the next instruction
> > begins the body. An unwind does not need (must not) restore any
> > preserved registers because
> > they are still valid. A simple length from the entry point suffices to
> > describe this boundary.
> > [The body does not necessarily need to begin until at least one of the
> > preserved registers is
> > actually changed.]
> >
> > 3.2.1.1  RSP-Based Frame (MODE = 10)
> > For a RSP-based frame, it is also necessary to know which instruction
> > adjusts the stack pointer:
> > before this instruction an unwind must only (virtually or actually) pop
> > the return address; and
> > after this instruction, the stack pointer must first be incremented to
> > deallocate the stack frame,
> > then the instruction pointer restored.
> >
> > This leads to the following proposal for the upper part of the extended
> > compact unwind
> > quadword for use in combination with MODE = 10 in the lower part.
> >
> > | 63                       48 47 46             40 39            32 |
> > |-------------------------------------------------------------------|
> > | RESERVED                   |  |  PROLOGUE-SIZE2 |  PROLOGUE-SIZE1 |
> > |-------------------------------------------------------------------|
> >
> >
> > Except for the MODE, the lower part is exactly like it would be for MODE
> > = 2.
> >
> > PROLOGUE-SIZE1 is the length in bytes of the first part of the prologue
> > relative to the
> > STARTING-ADDRESS, up to and including the instruction that allocates the
> > stack.
> >
> > PROLOGUE-SIZE2 is the length in bytes of the second part of the prologue
> > relative to the end
> > of the first part, up to a point after the last preserved register is
> > saved and before the first
> > preserved register is changed. (Recall, this point may not be unique.)
> >
> > PROLOGUE-SIZE1 + PROLOGUE-SIZE2 gives the total size of the prologue.
> >
> > The maximum prologue size allowed here is much greater than will be
> > typical. This is deliberate
> > to allow compilers freedom to use shrink-wrap type optimizations in
> > which safe operations that
> > need no body state are moved from the body to the beginning of the
> > prologue. This avoids the
> > cost of stack frame setup and teardown for simple special case handling
> > that often leads to an
> > early exit.
> >
> > 3.2.1.2  Large RSP-based Frame (MODE = 11)
> > This case is like the previous, except the stack size is too large to
> > encode in the compact unwind
> > encoding.  The SIZE field is interpreted as an offset relative to the
> > beginning of the containing
> > unwind group to (what is necessarily) an earlier extended parameter
> group.
> >
> > 3.2.1.3  RBP-Based Frame (MODE = 9)
> > The RBP-based frame is the same as for a RSP-based frame except that
> > there are two instructions
> > that mark the transition between the two parts of the prologue: the push
> > of the prior RBP value
> > onto the stack followed by the copy of RSP to RBP to establish the new
> > frame pointer.
> >
> > There appears to be no reason to not make this simplifying requirement:
> > the push and copy
> > always occur together.
> >
> > This leads to the following proposal for the upper part of the extended
> > compact unwind
> > quadword for use in combination with MODE = 9 in the lower part.
> >
> > | 63                       48 47 46             40 39            32 |
> > |-------------------------------------------------------------------|
> > | RESERVED                   |  |  PROLOGUE-SIZE2 |  PROLOGUE-SIZE1 |
> > |-------------------------------------------------------------------|
> >
> > Except for the MODE, the lower part is exactly like it would be for MODE
> > = 1.
> >
> > PROLOGUE-SIZE1 is the length in bytes of the first part of the prologue
> > relative to the
> > STARTING-ADDRESS, up to and including the instruction that pushes the
> > prior RBP contents.
> >
> > PROLOGUE-SIZE2 is the length in bytes of the second part of the prologue
> > relative to the end
> > of the first part, up to a point after the last preserved register is
> > saved and before the first
> > preserved register is changed. (Recall, this point may not be unique.)
> >
> > PROLOGUE-SIZE1 + PROLOGUE-SIZE2 gives the total size of the prologue.
> >
> > 3.2.2  Function Epilogue
> > For the purposes of exception handling, the key steps in an epilogue are:
> >
> >  1. Restore the registers that were preserved
> >  2. Deallocate space on the stack that was used to preserve registers
> > and for other purposes
> >
> > A key observation is that restoring registers is idempotent. That is, if
> > in the midst of restoring
> > registers when an exception occurs, it will do no harm if all of the
> > preserved registers are
> > restored again when unwinding. In effect, restoration of registers need
> > not be distinguished from
> > the body of a function. It is not until reaching the first instruction
> > that deallocates stack is
> > executed that the “real” epilogue begins.
> >
> > 3.2.2.1  RSP-Based Frame (MODE = 10 or 11)
> > For a RSP-based frame, whether small or large, the only unwind action
> > remaining after stack
> > deallocation is to pop the return address into the instruction pointer
> > (RIP). In the vast majority of
> > cases this means that the epilogue of the code described by an unwind
> > group is just a 1-byte RET
> > instruction that occurs at the end of the unwind group. There are other
> > possibilities but they are
> > rare and con be dealt with separately (see below).
> >
> > It suffices to include a single 1-bit field, E, in the upper part of the
> > extended compact unwind
> > description:
> >
> > | 63                       48 47 46             40 39            32 |
> > |-------------------------------------------------------------------|
> > | RESERVED                  | E |  PROLOGUE-SIZE2 |  PROLOGUE-SIZE1 |
> > |-------------------------------------------------------------------|
> >
> >
> > The E flag indicates that the unwind group ends with a standard 1-byte
> > RET instruction.
> >
> > 3.2.2.2  RBP-Based Frame (MODE = 9)
> > The RBP-based frame is much the same as for a RSP-based frame except
> > that there are two
> > instructions that mark the transition between the two parts of the
> > prologue: the copy of RBP to
> > RSP to cut back the stack, followed by the pop of RBP to restore what
> > may be the callers frame
> > pointer. Thus the epilogue, for the purposes of unwinding, begins
> > immediately after the copy of
> > RBP to RSP. In the vast majority of cases, the immediately following two
> > instructions will
> > consist of POP RBP and RET. The POP is not idempotent because it changes
> > the stack pointer,
> > but the unwind processing code can distinguish whether the stack has
> > been popped or not based
> > on the address (3 versus 1 byte less than the highest address of the
> group).
> >
> > It suffices to include a single 1-bit field, E, in the upper part of the
> > extended compact unwind
> > description:
> >
> > | 63                       48 47 46             40 39            32 |
> > |-------------------------------------------------------------------|
> > | RESERVED                  | E |  PROLOGUE-SIZE2 |  PROLOGUE-SIZE1 |
> > |-------------------------------------------------------------------|
> >
> > The E flag indicates that the unwind group ends with a standard
> > 3-instruction return sequence.
> >
> > 3.3  Special Issues
> > Up until this point, it might appear that each unwind group corresponds
> > one-for-one to the code
> > for a single function. While common, this is not required. Important
> > variations are illustrated
> > here.
> >
> > Issue/Problem                                        Possible Resolution
> > ------------------------------------------------------------
> -------------------------------------
> > The first part of the prologue is too large to be    Use two unwind
> groups:
> > described by the 8-bit RxP-FRAME-SIZE1 field.        1) a null frame
> > group of any appropriate size,
> >                                                      2) a suitable
> > RxP-based frame.
> >
> > The second part of the prologue is too large to be   Use three unwind
> > groups:
> > described by the 8-bit RxP-FRAME-SIZE2 field.        1) a RSP-frame
> > group to describe the first part of
> >                                                      the prologue only
> > (PROLOGUE-SIZE1 = the
> >                                                      length of the
> > entire group and PROLOGUE-SIZE2
> >                                                      = 0,
> >                                                      2) a RSP-frame
> > group to describe the second part
> >                                                      of the prologue
> > (PROLOGUE-SIZE1 & 2 both = 0
> >                                                      and no registers
> > saved),
> >                                                      3) a suitable
> > RxP-based frame group (with
> >                                                      PROLOGUE-SIZE1 & 2
> > both = 0).
> >
> > There is more than one return location (without a    Generally use one
> > unwind group for each sequence
> > shared epilogue sequence).                           of code ending with
> > a RET. A group following a
> >                                                      RET will have no
> > prologue (PROLOGUE-SIZE1
> >                                                      & 2 both = 0).
> >
> > There is more than one entry point to a function     Generally use one
> > unwind group for each sequence
> > (for example, a FORTRAN multiple entry point         of code beginning
> > at an entry point. Each group
> > subroutine or analogous assembly language            may have a normal
> > prologue and all but the last
> > equivalents)                                         might have NO
> > epilogue (E flag clear).
> >
> >
> > These examples are not exhaustive, of course. But they illustrate the
> > flexibility of the
> > mechanism, which should be suitable for the vast majority of cases in
> > practice.
> >
> > 3.4  Number of Unwind Groups
> > A simple concatenation of unwind groups by the linker that combines
> > unwind group sections
> > from multiple modules does not, of itself, provide direct information to
> > the unwind software
> > regarding how many unwind groups are present. However, the image
> > information (ELF
> > segments) should suffice to determine this number based on the size of
> > the segment and the
> > known size of each group. Alternatively, the linker might create special
> > symbols that can be used
> > to help determine the number of groups.
> >
> > This proposal leaves this detail to target-specific linker, image loader
> > and exception handling
> > system to specify.
> >
> > 3.5  Interaction with Code Generation
> > The relatively simple and fixed size nature of the extended compact
> > unwind information
> > proposed here depends on observing certain restrictions on optimization
> > that might affect code in
> > prologues and epilogues. These restrictions were noted where relevant
> > throughout this section.
> > Here is a summary of those requirements:
> >
> >  1. Use of any preserved register must be delayed until all of the
> > preserved registers have
> >     been saved.
> >  2. In the prologue of a function with a RBP-based frame, the two
> > instructions that save the
> >     prior RBP contents and copy the stack pointer to RBP must be kept
> > adjacent. Similarly,
> >     in the epilogue of a function with a RBP-based frame, the two
> > instructions that cut back
> >     the stack and restore the prior RBP contents must be kept adjacent.
> > [This adjacency
> >     requirement could be relaxed by introducing an additional MODE that
> > corresponds to having
> >     the RBP saved in memory but not yet updated from RSP. This does not
> > seem worthwhile.]
> >  3. For shrink wrap optimization in the presence of a
> > handler/personality routine, care must
> >     be taken to not move instructions into the prologue that might cause
> > an exception.
> >     Floating point exceptions and access violations are of particular
> > concern in this regard.
> >
> > 4  System Specific Extensions for OpenVMS
> > Omitted since nobody other than OpenVMS should care but it describes
> > adding an additional
> > four byte extension to the extended compact unwind group to pass along
> > some information from
> > the VAX Macro-32 compiler about VAX register usage.
> >
> >
> >
> > _______________________________________________
> > LLVM Developers mailing list
> > llvm-dev at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180129/93e4346b/attachment.html>


More information about the llvm-dev mailing list