If the parameter is passed in a register, then traditionally there are two symbols for each argument:
.stabs "arg:p1" . . . ; N_PSYM .stabs "arg:r1" . . . ; N_RSYM
Debuggers use the second one to find the value, and the first one to know that it is an argument.
Because that approach is kind of ugly, some compilers use symbol
descriptor ‘P’ or ‘R’ to indicate an argument which is in a
register. Symbol type
C_RPSYM is used in XCOFF and
is used otherwise. The symbol's value is the register number. ‘P’
and ‘R’ mean the same thing; the difference is that ‘P’ is a
GNU invention and ‘R’ is an IBM (XCOFF) invention. As of version
4.9, GDB should handle either one.
There is at least one case where GCC uses a ‘p’ and ‘r’ pair rather than ‘P’; this is where the argument is passed in the argument list and then loaded into a register.
According to the AIX documentation, symbol descriptor ‘D’ is for a parameter passed in a floating point register. This seems unnecessary—why not just use ‘R’ with a register number which indicates that it's a floating point register? I haven't verified whether the system actually does what the documentation indicates.
On the sparc and hppa, for a ‘P’ symbol whose type is a structure
or union, the register contains the address of the structure. On the
sparc, this is also true of a ‘p’ and ‘r’ pair (using Sun
cc) or a ‘p’ symbol. However, if a (small) structure is
really in a register, ‘r’ is used. And, to top it all off, on the
hppa it might be a structure which was passed on the stack and loaded
into a register and for which there is a ‘p’ and ‘r’ pair! I
believe that symbol descriptor ‘i’ is supposed to deal with this
case (it is said to mean "value parameter by reference, indirect
access"; I don't know the source for this information), but I don't know
details or what compilers or debuggers use it, if any (not GDB or GCC).
It is not clear to me whether this case needs to be dealt with
differently than parameters passed by reference (see Reference Parameters).