Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8054352

ELF decoder should handle prelinked shared library

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Won't Fix
    • Icon: P4 P4
    • 10
    • 9
    • hotspot
    • None

      Per email from Harish Babu (harish.b310@gmail.com)

      Hi,

         I have a question regarding the code for ELF files parsing(Linux).

         Looking at the code below it appears the relative offset address is sent
      like the below code:

      os::dll_address_to_function_name() {
      ....
      Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
                                buf, buflen, offset, dlinfo.dli_fname))
      ....
      }

      This works well for most of the libraries which are not prelinked at
      particular address where the symbol tables are relative offsets.

      But when the libraries are prelinked at an address this does not work well.
      Like libc,
      readelf -l /lib64/libc.so.6
      Program Headers:
        Type Offset VirtAddr PhysAddr
                       FileSiz MemSiz Flags Align
        PHDR 0x0000000000000040 0x00000038e7400040 0x00000038e7400040
                       0x0000000000000230 0x0000000000000230 R E 8
        INTERP 0x000000000013ff60 0x00000038e753ff60 0x00000038e753ff60
                       0x000000000000001c 0x000000000000001c R 10
            [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
        LOAD 0x0000000000000000 0x00000038e7400000 0x00000038e7400000
                       0x000000000016f150 0x000000000016f150 R E 200000
        LOAD 0x000000000016f720 0x00000038e776f720 0x00000038e776f720
                       0x0000000000004678 0x0000000000009188 RW 200000


      Where libc may(or may not) be loaded at a base address 0x38e7400000, and
      the addresses are the absolute address rather than relative offsets.

         131: 00000038e74274b0 192 FUNC LOCAL DEFAULT 12 open_translit
         132: 00000038e7773f78 4 OBJECT LOCAL DEFAULT 34 lock
         133: 00000038e7427c82 31 FUNC LOCAL DEFAULT 12 _L_lock_107
         134: 00000038e7427810 11 FUNC LOCAL DEFAULT 12 trans_compare
         135: 00000038e7773f70 8 OBJECT LOCAL DEFAULT 34 search_tree
         136: 00000038e7427ca1 31 FUNC LOCAL DEFAULT 12 _L_unlock_135




      For pthread(which is not prelinked to an address) which the current code
      deals with correctly there is only relative addresses in the ELF file:

        121: 000000000000da48 19 FUNC LOCAL DEFAULT 14 sem_wait_cleanup
         122: 000000000000dc15 19 FUNC LOCAL DEFAULT 14
      sem_timedwait_cleanup
         123: 000000000000dc28 31 FUNC LOCAL DEFAULT 14
      sem_timedwait_cleanup2
         124: 000000000000df50 33 FUNC LOCAL DEFAULT 14 unwind_cleanup
         125: 000000000000df80 287 FUNC LOCAL DEFAULT 14 unwind_stop
         126: 000000000000e800 237 FUNC LOCAL DEFAULT 14 do_fcntl


      So like I mentioned earlier, the code os::dll_address_to_function_name
      subtracts the base address where the library was loaded from the current
      pc. This results in relative offset which may not work well for the
      libraries which are prelinked to an address.

      Please let me know if I got it completely wrong.

      Thanks,
      Harish


      Here is my current idea for the fix

      FWIK, the first PT_LOAD.p_vaddr in the program header holds the base address for the library which hints the loader and all the other addresses in the file are based on this address. So for each .so file we can remember this in a class variable of ElfFile. And change the call in ElfFile::decode to:

      symbol_table->lookup(addr+(First_PT_LOAD.p_vaddr), &string_table_index, &pos_in_string_table, &off)

      Should probably fix the issue for all the cases.

      Thanks,
      Harish



            Unassigned Unassigned
            zgu Zhengyu Gu
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: