RFR(S): 8019929: PPC64 (part 107): Extend ELF-decoder to support PPC64 function descriptor tables

Volker Simonis volker.simonis at gmail.com
Thu Dec 5 12:48:33 PST 2013

Hi Zhengyu,

thanks for you comments.

The early return in line 99 has no effect on the file pointer position
because it's the block where the symbol table is already in memory, so no
file operations will take place. And even if ElfFuncDescTable::lookup()
will trigger a file operation, it will take care to properly reset the file

The early return in line 127 may indeed change the file position pointer.
But that's no problem because every file access in
ElfStringTable::string_at(), ElfSymbolTable::lookup() and
ElfFunDescTable::lookup() will properly reposition the file position
pointer when they are invoked. Maintaining the value of the file position
pointer is only important and necessary during the runtime of
ElfFile::load_tables() because that method reads from the ELF file in a
loop in the body of which the symbol and string tables are loaded. But
ElfFile::load_tables is only called once, in the ElfFile constructor. All
the other lookup functions can only be called after the constructor
is finished. So no problem here as well.

Thank you and best regards,

On Thursday, December 5, 2013, Zhengyu Gu wrote:

> Hi Volker,
> elfSymbolTable.cpp: ElfSymbolTable::lookup() line 99 and 127
> You added early return true, without restoring file pointer position. I am
> not sure it will break anything, but it was intended in original code.
> Thanks,
> -Zhengyu
> On 12/5/2013 1:37 PM, Volker Simonis wrote:
> Hi,
> so here it comes, the hopefully final webrev of this change:)
> http://cr.openjdk.java.net/~simonis/webrevs/8019929.v3/
> I've:
>   - fixed the comments for the ifdefs as requested by Vladimir
>   - fixed the "else if" indentation as requested by Vladimir
>   - fixed the out-of-memory situation detected by Vitaly
> I' also added a detailed description of why we need all this on PPC64 to
> elfFuncDescTable.hpp and fixed a small problem for old-style PPC64 objects
> with additional 'dot'-symbols (see description below). The correct handling
> of these old-style files also required another small '#ifdef PPC64' section
> in decoder_linux.cpp (for a detailed description why this is necessary see
> below). I hope that's OK.
> Thank you and best regards,
> Volker
> Detailed change description:
> On PowerPC-64 (and other architectures like for example IA64) a pointer to
> a function is not just a plain code address, but instead a pointer to a so
> called function descriptor (which is simply a structure containing 3
> pointers). This fact is also reflected in the ELF ABI for PowerPC-64.
> On architectures like x86 or SPARC, the ELF symbol table contains the start
> address and size of an object. So for example for a function object (i.e.
> type 'STT_FUNC') the symbol table's 'st_value' and 'st_size' fields
> directly represent the starting address and size of that function. On PPC64
> however, the symbol table's 'st_value' field only contains an index into
> another, PPC64 specific '.opd' (official procedure descriptors) section,
> while the 'st_size' field still holds the size of the corresponding
> function. In order to get the actual start address of a function, it is
> necessary to read the corresponding function descriptor entry in the '.opd'
> section at the corresponding index and extract the start address from
> there.
> That's exactly what this 'ElfFuncDescTable' class is used for. If the
> HotSpot runs on a PPC64 machine, and the corresponding ELF files contains
> an '.opd' section (which is actually mandatory on PPC64) it will be read
> into an object of type 'ElfFuncDescTable' just like the string and symbol
> table sections. Later on, during symbol lookup in
> 'ElfSymbolTable::lookup()' this function descriptor table will be used if
> available to find the real function address.
> All this is how things work today (2013) on contemporary Linux
> distributions (i.e. SLES 10) and new version of GCC (i.e. > 4.0). However
> there is a history, and it goes like this:
> In SLES 9 times (sometimes before GCC 3.4) gcc/ld on PPC64 generated two
> entries in the symbol table for every function. The value of the symbol
> with the name of the function was the address of the function descriptor
> while the dot '.' prefixed name was reserved to hold the actual address of
> that function (
> http://refspecs.linuxfoundation.org/ELF/ppc64/
> PPC-elf64abi-1.9.html#FUNC-DES).
> For a C-function 'foo' this resulted in two symbol table entries like this
> (extracted from the output of 'readelf -a '):
> Section Headers:
>    [ 9] .text             PROGBITS         0000000000000a20  00000a20
>         00000000000005a0  0000000000000000  AX       0     0     16
>    [21] .opd              PROGBITS         00000000000113b8  000013b8
>         0000000000000138  0000000000000000  WA       0     0     8
> Symbol table '.symtab' contains 86 entries:
>     Num:    Value          Size Type    Bind   Vis      Ndx Name
>      76: 00000000000114c0    24 FUNC    GLOBAL DEFAULT   21 foo
>      78: 0000000000000bb0    76 FUNC    GLOBAL DEFAULT    9 .foo
>   You can see now that the '.foo' entry actually points into the '.text'
> segment ('Ndx'=9) and its value and size fields represent the functions
> actual address and size. On the other hand, the entry for plain 'foo'
> points into the '.opd' section ('Ndx'=21) and its value and size fields are
> the index into the '.opd' section and the size of the corresponding '.opd'
> section entry (3 pointers on PPC64).
> These so called 'dot symbols' were dropped around gcc 3.4 from GCC and
> BINUTILS, see http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.<http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html>

More information about the hotspot-dev mailing list