ia64 vtable entries (was: C implementations of the C++ ABI)

Richard Henderson rth at cygnus.com
Wed Feb 23 20:26:07 UTC 2000


On Wed, Feb 23, 2000 at 10:43:03AM -0800, Jason Merrill wrote:
>  >   o GP/address pairs in vtables
> 
>  >     This one concerns me the most.  I don't even know if there's 
>  >     any kind of standard assembly syntax for this.  Is there?
> 
> Richard Henderson still doesn't believe that there's a suitable reloc for
> this in the base ABI, and apparently I forgot to write up his explanation
> for a wider audience.  Richard, care to repeat it in a less transient
> medium?

There are no relocations in the base ABI to fill in an existing function
descriptor.  Nor are there relocations to acquire a function's gp with
which you could fill in a descriptor yourself.

There are three relocation types that cause the linker or loader to create
a descriptor in linker-controled memory and give the program a pointer to
that memory.

Reference SC-2916 v2.0 Unix System V Application Binary Interface,
Intel IA-64 Processor Supplement, section 4.3.1:

  R_IA_64_FPTR64LSB

	The descriptor is, in the case of dynamic symbols, created by the
	run-time loader.  This is because the descriptor must be globally
	unique to satisfy function pointer equality.

	GNU ld will statically create the descriptors for non-dynamic
	symbols when linking without -shared; dso's will contain no static
	descriptors because it is more work memory-reference-wise to
	adjust the descriptors for the dso load address than it is to
	just create them from scratch.

	The relocation itself is direct against the descriptor.

  R_IA_64_LTOFF_FPTR64LSB

	Same as above, except that a slot in the .got is created to hold
	the pointer to the descriptor.  The relocation itself is slot-gp.

  R_IA_64_PLTOFF64LSB

	Creates a non-unique descriptor to a PLT entry local to the dso.
	The memory is always statically allocated.  Unfortunately, the
	relocation is gp-relative and so is of no use in vtables.
	Moreover, R_IA_64_PLTOFF22 is the variant normally used, so the
	memory allocated for this eats into the small-data area.

I would suspect that this late in the game amending the ABI is not
an option.  So R_IA_64_FPTR64LSB, as heavyweight as it is, is your
only choice for a normal function descriptor.

There is one convoluted way I can see to define a vtable entry that
does not require runtime relocation of any form, at least if the 
symbol were private to the dso (via STV_HIDDEN or so).  If the symbol
is dynamic, there is no escaping some form of runtime relocation.

	data8	@pcrel(func#)
	data8	@gprel(func#)

Suppose r16 contains the address of the first word.

	ld8 r18 = [r16]
	adds r17 = 8, r16
	;;
	add r18 = r18, r16
	ld8 r17 = [r17]
	;;
	sub gp = r18, r17
	mov b6 = r18
	br.call.sptk.many b0 = b6

which is two more instructions, no more insn groups, and one fewer
memory reference than the standard indirect function descriptor sequence.

Note that GNU ld would currently abort on this because it doesn't
believe gp-relative relocations against dynamic symbols are legal.
Nor does glibc's ld.so know how to fix up such relocations.  However,
it is possible to implement if needed.


r~




More information about the cxx-abi-dev mailing list