[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::alpha_callstd

Title:ALPHA Calling Standard
Notice:Digital Restricted and Confidential
Moderator:BEGIN::MDAVISR
Created:Thu Jun 29 1989
Last Modified:Thu Jun 05 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:113
Total number of notes:847

108.0. "Must all code be "covered" by some descriptor?" by FLYBA::BRENDER (Ron Brender) Tue Jan 28 1997 15:36

Brought forward from 105.88:

Note 105.88  WNT Call Std ECO 6 re R28 use, new Procedure Descriptor   88 of 88
AD::LOWNEY                                           19 lines  23-JAN-1997 18:27
                          -< covering leaf routines >-

                                                1/23/97

NTOM would like to use procedure descriptors to distinguish code from
data in an image.  GEM and the assembler were changed this fall to
cover all procedures with procedure descriptors.  For GEM, this
required generating procedure descriptors for null-frame procedures
(the typical leaf routine).  These are quite frequent, and,
surprisingly, sometimes quite large.

I was hoping that this ECO was going to introduce this requirement
into the calling standard; specifically, that all code, except for
thunks generated by the linker, need to be covered by procedure
descriptors.

Ron had suggested an optimization where contiguous null frames
procedures can be covered by a single PD.

Does this require a separate ECO?
T.RTitleUserPersonal
Name
DateLines
108.1Are there objections to this?AD::LOWNEYWed Jan 29 1997 21:365
Is there a reason not to support this?  Our products (GEM and asaxp)
have already been changed to behave this way.  NTOM will require it.


108.2Sauce for the goose...WIBBIN::NOYCEPulling weeds, pickin' stonesThu Jan 30 1997 14:054
Does NTOM produce procedure descriptors for all the code it
generates?

I support this proposal.
108.3Need a rule for legacy object and imagesSTEVEN::hobbsSteven HobbsThu Jan 30 1997 14:3511
I would like to include wording that says legacy images and legacy
objects are still supported for execution.  In particular, this new
rule should not permit changes to the linker or image activator that
cause existing objects and images to break.

I am willing to have a rule that says the image optimizers, such as
NTOM, and debuggers can require that old objects and images must be
regenerated in order to use these tools.  It would be nice if these
new tools could detect legacy data and give a warning if the tool
might not work but I do not know if NT objects and images have the
necessary version control information.
108.4re .2 and .3AD::LOWNEYThu Jan 30 1997 17:1423

re: .2

Yes, NTOM creates procedure descriptors for all the code it generates. 

The only exception are the thunks generated by the linker, which have
no procedure descriptors. 


re: .3

In almost all cases, NTOM will be able to detect an old image, for it
will see a bsr to a location without a procedure descriptor.

NTOM has a set of conservative heuristics for dealing with images
without full procedure descriptor coverage.  If it can't prove
something is code, it assumes it is data.  If data looks like a
potential branch, the source and target of the branch are locked so
that no relocation occurs.  Sometimes this locking is so extensive
that no optimization can occur (or we ignore the problem cases, which
are invariably true data).

108.5First cut at possible ECO textGEMGRP::BRENDERRon BrenderFri Feb 07 1997 14:3666
Here is a first cut at trying to capture these ideas in text appropriate
for the WNT calling standard. This is not yet a formal ECO. Look at the
text and consider the questions that follow...

--------------------------------------------------------------------------------
In the introduction to Chapter 8, page 8-1, modify the following

        Every non-null frame procedure must have an associated procedure
        descriptor. Most commonly there will be one procedure descriptor
        for each non-null frame procedure; however, there may be more than
        one procedure descriptor used to describe a procedure.

        When there is more than one procedure descriptor for a procedure, the
        following must hold:

to

  - Insert new text after the first sentence (see below)
  - Start a new paragraph with the second sentence, and merge it with the
    next paragraph.

to get this result:

        Every non-null frame procedure must have an associated procedure
|       descriptor. While not strictly required, for the benefit of post-
|       linktime tools that analyze, manage and/or modify executable images,
|       it is strongly recommended that null frame procedures have an
|       associated procedure descriptor as well. For this purpose, it is
|       valid for a contiguous group of null frame procedures to be described
|       by a single procedure descriptor.

        Most commonly there will be one procedure descriptor for each non-null
        frame procedure; however, there may be more than one procedure
        descriptor used to describe a procedure. When there is more than one
        procedure descriptor for a procedure, the following must hold:
--------------------------------------------------------------------------------

There are two key ideas here:

  - strongly recommend procedure descriptors for null frame procedures
    rather than absolutely require.

    I suggest this because

      . It is "upward compatible" with existing practice, so long as tools
        are prepared to deal gracefully with older images.
      . It does not have to specifically name particular exceptions, such
        as linker transfer vectors
      . It leaves open the possibility of run-time generated code without
        having to provide means to register procedure descriptors at run-time
	(Note: Monty, and TVB before him, have done some work toward providing
	such an interface, but it is not ready for prime time yet.)

  - establish that a group of null frame procedures can be described by a
    single procedure descriptor

The latter is motivated in part to make exceptions for the likes of linker
transfer vectors unnecessary or at least unimportant on the grounds of overhead
space dedicated to "useless" procedure descriptors. So, if you like the
second idea, you might want to go "all the way" and require *all* statically
generated code to have procedure descritors.

What do you think:

  - is "strongly recommended" strong enough?
  - is one procedure descriptor for many null frame procedures OK?
108.6How about data in a text sectionSMURF::GAFJerry Feldman, Unix Dev. Environment, DTN:381-2970Fri Feb 07 1997 17:085
    One area that is not covered is data in the text sections. Currently,
    the rule that the assembler is using is that if it is in the text
    section, it gets a procedure descriptor. I don't know if any of the
    compilers put actual data into text sections, but there are many
    assembler programs that do. 
108.7Not so much sections, but data within instructions?GEMGRP::BRENDERRon BrenderFri Feb 07 1997 17:5117
>    One area that is not covered is data in the text sections...

Actually, that is more or less intentional. The notion of sections, how
managed by the linker, and so on, deal with mechanisms that are not addressed
by the calling standard as such. (Many of us have often wished there was a
book that described such another level of "run time architecture" but...
and actually the Object File and Symbol Table Specification begin produced
by the OF/ST Working Group is going to come pretty close.)

So long as procedure descriptors do not "cover" any data that happens to be
in the text section, I think there is no problem. If a procedure descriptor
does cover data, whether in the text or data section, then tools like om
are likely to be mislead.

Since everything about procedure descriptors is stated in terms of instructions,
it has not occurred to me that a rule prohibiting data within the BeginAddress..
EndAddress range is needed. But, maybe it is?
108.8DECCXL::OUELLETTEMon Feb 10 1997 14:293
Some of NT is compiled with the -cbstring switch.
That causes local string literals to be attached to their procedure's .text
section.
108.9when is data data and not instructionsSMURF::GAFJerry Feldman, Unix Dev. Environment, DTN:381-2970Mon Feb 10 1997 20:108
    WRT: .7
    Actually, there are some interesting issues. We can assume that .ascii
    is generally data, but what about a .long. It is a common practice to
    encode an instruction that is not yet implemented in the assembler. 
    
    In the current version of asaxp, when a data directive is encountered, 
    the assembler terminates the current procedure descriptor and creates a
    new one. However, the data is still covered by a procedure desriptor. 
108.10please make this a requirementAD::LOWNEYMon Feb 10 1997 21:4857
The point of this ECO is to enable NTOM to distinguish code from data.
NO DATA should be covered by a procedure descriptor, and ALL CODE
should be covered by a procedure descriptor.

I would like the ECO to state this clearly.  My motivations:
    - We need to cut over to this policy to make NTOM effective.
      Conservative heuristics can work, but they limit optimization.
    - I would like everyone within Digital to understand the policy.
    - I want a unambiguous document to give to external compiler vendors.

Here is my attempt to write it.   ** marks the new text; any other change
is unintentional.
------------------------------------------------------------------------

    Procedure descriptors serve these functions:

    1. They provide a means to map from an arbitrary program counter
       value to the descriptive information associated with the code at 
       that address.

    2. They provide information about a procedure ... that is needed for
       call chain walking in general and exception handling in particular.

    3. They provide means for link-time, post-link-time and execution-time
       tools to identify all of the the instructions that make up a complete
       procedure, which provides information about the availability of general
       register R28 for use by those tools ...

**  4. They provide a means for link-time and post-link-time tools to distinguish
**     code from data.  No data should be covered by a procedure descriptor, and all
**     instructions should be.

**  Every procedure must have an associated procedure descriptor, with two
**  exceptions discussed below.  Most commonly there will be one procedure
**  descriptor for each procedure; however, there may be more than one.

    When there is more than one procedure descriptor, the following must hold:
        o ...
        o ...
    Two instructions are part of the same procedure if and only if they have the
    same primary procedure descriptor or neither is described by a procedure
    descriptor.

**  We require procedure descriptors for null-frame procedures only to distinguish
**  code from data at link-time or post-link-time.  This permits two exceptions
**  to the requirement:
**      o Procedure descriptors are not required for transfer vectors generated
**        by the linker.
**      o Procedure descriptors are not required for null-frame procedures
**        created a run-time.
**  We also permit a contiguous group of null frame procedures to be described
**  by a single procedure descriptor.

-------------------------------------
We also need to 3.1.4, where it states that null frame procedures do not need
a procedure descriptor.

108.11YesDECWET::GLOSSONMon Feb 10 1997 22:3113
Microsoft feels perfectly at home placing data in .text sections.
Fortunately for us, they have to yet to decide to place it
within a procedure descriptor.  We should approve this ECO
rapidly to forstall them from getting any ideas. :-)  When
data is emitted within a .text section, it is placed either
immediately prior to the entry of or immediately after the 
conclusion of the text associated with a function, so such data
is not currently covered by any procedure descriptor.

Actually, I don't have any problem with this ECO as it is well
within the bounds of actual practice.

I vote Yes.
108.12There are some real world MS casesSMURF::GAFJerry Feldman, Unix Dev. Environment, DTN:381-2970Tue Feb 11 1997 16:018
    I have seen a case in some Visual Basic code where there are no
    .ent/.end pairs, in sequences of code/data/code/data...
    
    In the assembler, we have a way to automatically generate the correct
    procedure descriptors around the data. Through a miscommunication with
    Geoff, this does allow data to creep into the procedure. I am currently
    correcting that problem, and we will hopefully get that version of the
    assembler into VC++5.0. 
108.13"Coverage" is independent of sectionsGEMGRP::BRENDERRon BrenderThu Feb 13 1997 12:5326
If I am interpreting correctly, I am hearing a strong pitch from Geoff to
make it mandatory to "cover" all code (with named exceptions) and no
resistance from others. Accordingly, I will re-draft the proposed ECO along
those lines (using language similar to that suggested by Geoff).

Before I do that, however, I do want to comment on a couple related notions
that been mentioned above.

Re .6 & .8: The ECO says nothing about sections, and does not prohibit
mixing code and data in the same section (whether .text, .data, or otherwise).

Re .9: It is not clear to me that the assembler should assume that a .long
directive necessarily is data or necessarily should start a new procedure
descriptor. But that is probably the dominant case, so maybe that is the
right handling. Of course, if .long is assumed to be data then it should
terminate the current procedure descriptor, but *not start a new one* of
itself, so that the data is not covered by a procedure descriptor. This
is probably the correction that Jerry is taking about in .12.

In order to support the reported practice of using .long to encode instructions
prior to the availability of appropriate nmemonics, there are several
alternatives. Perhaps the simplest is to add a .inst directive, which
behaves very much like .long except that it is treated as an instruction
wrt to procedure descriptor management. Other solutions might involve the
ability to define new instruction nmemonics. In any case, the solution is
outside the scope of the call standard per se.
108.14I concur with Geoff's assesmentSMURF::GAFJerry Feldman, Unix Dev. Environment, DTN:381-2970Thu Feb 13 1997 14:0423
    Re: .13
    I agree with Geoff. The assembler currently covers all code by a
    procedure desriptor. It does not cover data.
    
    Also, the assembler has already implemented the .instr directive which
    has the identical syntax as .long, but is treated as an instruction of
    unknown type. I had implemented this as a way to support NTOM. 
    In the current version of the NT assembler, data directives, .long, 
    .ascii, .quad, etc, cause the assembler to generate a .end directive,
    terminating the procedure descriptor. A new procedure descriptor is
    created upon encountering an instruction, or a procedure entry
    directive, such as .ent or .aent. The assembler also guarantees proper
    alignment in some perverse cases:
    
    	.ent main
    	.globl main
    main:
    	<some code>
    	.ascii "ab\0"
    1:
    	<more code>
    The assembler will insert an alignment prior to the symbol, 1: and the
    resumption of code. 
108.15Remember inline parameters on 7094 and pdp-10STEVEN::hobbsSteven HobbsThu Feb 13 1997 16:4218
One of the reasons assembler programmers use .long in a code section
is for "inline parameters" (it is possible that John Yates
has used these in the FX32 emulator).  Here is an example of a call
with two inline parameters.

	jsr	R28,routine
	.long	parameter1
	.long	parameter2
	nop			! return location

The called routine uses r28 to address the two inline parameters and
bumps r28 by 8 before returning.

I believe that inline parameters are prohibited and that these
parameters need not be supported by NTOM (but NTOM can easily support
them if they not described as being code).  I also believe that inline
parameters need not be supported by the jacketting code that supports
sharable images.
108.16ECO follows, please voteGEMGRP::BRENDERRon BrenderThu Feb 13 1997 18:026
The following note presents the formal ECO on this topic. Please cast your
ballot in this conference no later than

	Monday, 24 February

Thanks.
108.17Proposed WNT ECO 8GEMGRP::BRENDERRon BrenderThu Feb 13 1997 18:0356
			WNT Call Standard ECO 8
			      regarding
		      Procedure Descriptor Coverage


Abstract
--------

Procedure descriptors are required for all code (and no data).


Proposal
--------

In Chapter 8-1, page 8-1, introductory paragraph, add a new numbered bullet
as follows:

	4.  They provide the means for link-time and post-link-time tools
	    to distinguish code and data.


Change the next paragraph to:

	Every procedure must have an associated procedure descriptor, with
|	the exception of certain null frame procedures as described below.
	Most commonly there will be one procedure descriptor for each
	procedure; however, there may be more than one procedure descriptor
|	used to describe a procedure. In addition, it is valid for a
|	contiguous group of null frame procedures to be described by a
|	single procedure descriptor.


Just prior to Section 8.1, insert the following new paragraph:

	Procedure descriptors are rquired for null frame procedures except
	for the following:

	1.  Transfer vectors created by the linker

	2.  Null frame procedures created at run-time


Discussion
----------

See the discussion in ALPHA_CALLSTD notes 108.*, especially .0, .10 & .13.

Steve Hobbs has verbally argued that this new requirement must not be
construed to prevent old/exiting objects from linking and/or old/existing
images from loading and successfully executing. That is, it is OK for the
likes of NTOM to be less effective, or even fail, if this requirement is not
met, but not other traditional linking and execution activities. We don't
have a way to state should backward compatibility support rules in the call
standard, so I won't try to create any language along these lines. In this
case at least, I don't think there is any real problem since GEM has been
following this rule for some time (and transfer vectors are not affected).
108.18YESWIBBIN::NOYCEPulling weeds, pickin' stonesThu Feb 13 1997 18:5314
I vote YES.

Some editorial clarifications:

change
	4.  They provide the means for link-time and post-link-time tools
	    to distinguish code and data.
to
	... to distinguish code from data.

	Procedure descriptors are rquired for null frame procedures except
typo                              required

	-- WOL (Ring if an Rnsr is Rquird)
108.19YesWIDTH::MDAVISMark Davis - compiler maniacFri Feb 14 1997 13:270
108.20section 3.1.4 as wellAD::LOWNEYFri Feb 14 1997 19:252
    Do you need to change 3.1.4 as well, where it says a reg. frame
    procedure need not have a procedure descriptor?
108.21Per .18 & .20: Updated WNT ECO 8GEMGRP::BRENDERRon BrenderMon Feb 17 1997 17:2163
			WNT Call Standard ECO 8
			      regarding
		      Procedure Descriptor Coverage


Abstract
--------

Procedure descriptors are required for all code (and no data).


Proposal
--------

In Section 3.1.4, page 3-5, change the last sentence to:

	This special case of a register frame procedure is of interest
|	because such procedures may not need an associated procedure
|	descriptor in certain cases (see Chapter 8, Procedure Descriptors).

In Chapter 8, page 8-1, introductory paragraph, add a new numbered bullet
as follows:

	4.  They provide the means for link-time and post-link-time tools
	    to distinguish code from data.


Change the next paragraph to:

	Every procedure must have an associated procedure descriptor, with
|	the exception of certain null frame procedures as described below.
	Most commonly there will be one procedure descriptor for each
	procedure; however, there may be more than one procedure descriptor
|	used to describe a procedure. In addition, it is valid for a
|	contiguous group of null frame procedures to be described by a
|	single procedure descriptor.


Just prior to Section 8.1, insert the following new paragraph:

	Procedure descriptors are required for null frame procedures except
	for the following:

	1.  Transfer vectors created by the linker

	2.  Null frame procedures created at run-time


Discussion
----------

See the discussion in ALPHA_CALLSTD notes 108.*, especially .0, .10 & .13.

Steve Hobbs has verbally argued that this new requirement must not be
construed to prevent old/exiting objects from linking and/or old/existing
images from loading and successfully executing. That is, it is OK for the
likes of NTOM to be less effective, or even fail, if this requirement is not
met, but not other traditional linking and execution activities. We don't
have a way to state should backward compatibility support rules in the call
standard, so I won't try to create any language along these lines. In this
case at least, I don't think there is any real problem since GEM has been
following this rule for some time (and transfer vectors are not affected).

108.22DECWET::MVBMonty VanderBiltTue Feb 18 1997 19:311
Yes
108.23APPROVEDGEMGRP::BRENDERRon BrenderTue Feb 25 1997 17:285
Having been accepted by the Calling Standard Committee and there being no
issues or suggestions posted, this ECO is

                                APPROVED

108.24WNT Call Std Working Draft X1.10 AvailableGEMGRP::BRENDERRon BrenderTue Feb 25 1997 18:195
Working draft X1.10 (with change bars) of the Alpha WNT Calling Standard, which
incorporates ECOs 6 through 8 is available in

        GEMGRP::GEM2$:<BRENDER.PUBLIC>ALPHA-WNT-CALL-STD-X110-970225.PS

108.25Some assembler anomalies with PDs.SMURF::GAFJerry Feldman, Unix Dev. Environment, DTN:381-2970Wed Mar 12 1997 16:0760
    We discovered a few problems related to procedure descriptors. This
    probably only affects assemblers.
    Case 1: A sub-procedure that contains a .prologue directive, 
            but no instructions in the prolog. 
            The WNT assembler was generating a descriptor for
            the empty prolog as well as for the body. 
            This was definitely a bug in the assembler. 
            The ots divide functions present this case>
    
    Case 2: A procedure with at least one alternate entry point
            (or a split procedure) where the main entry point
    	    and the following alternate entry point have the same
            address, for example:
    	
    		.globl foo
    		.ent   foo
    foo:
    		.set noat
    		.set noreorder
    		.frame	sp, 0, r26
                .globl fubar
    	        .aent  fubar
    fubar:
                .set noat
                .set noreorder
                .frame  sp, 0, r26
                --- Some code
    		.globl bar
    		.aent  bar
    bar:
                .set noat
                .set noreorder
                .frame  sp, 0, r26
        	--- mode code
    		.end
    	In this case, the assembler was generating 3 procedure descriptors.
    	The PD for the primary entry point, foo, had the begin, end, and
    prologend all pointing to the same address. The implemented solution
    was to produce 2 procedure desriptors:
    1. foo ending at the .aent bar directive.
    2. bar ending at the .end directive.          
    Entry point fubar would not receive a procedure descriptor of its own.
    The net effect is that the .ent fubar directive would be parsed for
    syntax, but would contain no semantic actions.
    
    Both of these cases came from the ots_divide module in Windows NT. 
    The empty prolog case is probably more common in the real world where
    there might be a common code base for NT and DU:
    
    	.globl foo
    	.aent   foo
    foo:
    	ldgp	$gp, 0($27)		# load the global pointer
    	.prologue 1
    	---- some code
    	.end
    
    The assembler in NT treats the ldgp as a nop causing the prologue to be
    empty.  
    
108.26No Call Std bug, right?FLYBA::BRENDERRon BrenderTue Mar 25 1997 14:1010
Re .-1

Jerry,

Just let me make sure I am understanding correctly: You are posting some info
regarding problems with the implementation of this ECO in the assembler, but
you are not suggesting that there is any problem to be dealt with in the Call
Standard itself -- right?

Ron
108.27Maybe we should add a sentenceSMURF::GAFJerry Feldman, Unix Dev. Environment, DTN:381-2970Tue Mar 25 1997 16:3818
    Re .-2 and .-1
    Ron,
    The two issues I raised were more implementation issues. In essence,
    what to do if a procedure actually contains no code. I don't think that
    the GEM based compilers would produce that type of code, but the ACC
    compiler and, presumably the GCC compiler could. In both cases, the
    assembler must have a rule to deal with these. I don't think that we
    need to go into that kind of detail in the calling standard. 
    
    The problem was that the assembler did not check (nor did it have the
    information available) to determine if a procedure (or prologue) did
    not contain any actual code, but it generated the procedure descriptors
    based on the what the programmer told it. 
    
    I think the case of a zero length procedure should be addressed in 8.1.
    I would suggest adding a sentence to the EndAddress paragraph that the
    EndAddress must be greater than the BeginAddress. We actually had
    real-world examples of this in the OTS Divide sources.