RFR(S): 8019929: PPC64 (part 107): Extend ELF-decoder to support PPC64 function descriptor tables
vladimir.kozlov at oracle.com
Thu Dec 5 13:38:39 PST 2013
I am pushing these changes.
On 12/5/13 12:58 PM, Zhengyu Gu wrote:
> Okay. It looks good to me.
> On 12/5/2013 3:48 PM, Volker Simonis wrote:
>> 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 pointer.
>> 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.
>> On 12/5/2013 1:37 PM, Volker Simonis wrote:
>> so here it comes, the hopefully final webrev of this change:)
>> - 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,
>> 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
>> 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'
>> 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
>> 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
>> 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
>> while the dot '.' prefixed name was reserved to hold the
>> actual address of
>> that function (
>> 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
>> 00000000000005a0 0000000000000000 AX 0 0
>>  .opd PROGBITS 00000000000113b8
>> 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
>> 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
More information about the hotspot-dev