Changeset 11871


Ignore:
Timestamp:
Mar 31, 2009, 11:10:45 AM (10 years ago)
Author:
gb
Message:

When trying to determine names of ELF shared libraries, don't
try too hard if the map entry has a null path (typically the
case with Linux VDSOs, which sometimes handle their their
dynamic string table pointers inconsistently.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/level-0/l0-cfm-support.lisp

    r11606 r11871  
    140140
    141141(defun soname-ptr-from-link-map (map)
    142   (with-macptrs ((dyn-strings)
    143                  (dynamic-entries (pref map :link_map.l_ld)))
    144     (let* ((soname-offset nil))
    145       ;; Walk over the entries in the file's dynamic segment; the
    146       ;; last such entry will have a tag of #$DT_NULL.  Note the
    147       ;; (loaded,on Linux; relative to link_map.l_addr on FreeBSD)
    148       ;; address of the dynamic string table and the offset of the
    149       ;; #$DT_SONAME string in that string table.
    150       ;; Actually, the above isn't quite right; there seem to
    151       ;; be cases (involving vDSO) where the address of a library's
    152       ;; dynamic string table is expressed as an offset relative
    153       ;; to link_map.l_addr as well.
    154       (loop
    155           (case #+32-bit-target (pref dynamic-entries :<E>lf32_<D>yn.d_tag)
    156                 #+64-bit-target (pref dynamic-entries :<E>lf64_<D>yn.d_tag)
    157             (#. #$DT_NULL (return))
    158             (#. #$DT_SONAME
    159                 (setq soname-offset
    160                       #+32-bit-target (pref dynamic-entries
    161                                            :<E>lf32_<D>yn.d_un.d_val)
    162                       #+64-bit-target (pref dynamic-entries
    163                                            :<E>lf64_<D>yn.d_un.d_val)))
    164             (#. #$DT_STRTAB
    165                 (%setf-macptr dyn-strings
    166                               ;; Try to guess whether we're dealing
    167                               ;; with a displacement or with an
    168                               ;; absolute address.  There may be
    169                               ;; a better way to determine this,
    170                               ;; but for now we assume that absolute
    171                               ;; addresses aren't negative and that
    172                               ;; displacements are.
    173                                (let* ((disp (%get-signed-natural
    174                                              dynamic-entries
    175                                              target::node-size)))
    176                                  #+(or freebsd-target solaris-target)
    177                                  (%inc-ptr (pref map :link_map.l_addr) disp)
    178                                  #-(or freebsd-target solaris-target)
    179                                  (let* ((udisp #+32-bit-target (pref dynamic-entries
    180                                                                      :<E>lf32_<D>yn.d_un.d_val)
    181                                                #+64-bit-target (pref dynamic-entries
    182                                                                      :<E>lf64_<D>yn.d_un.d_val)))
    183                                    (if (and (> udisp (pref map :link_map.l_addr))
    184                                             (< udisp (%ptr-to-int dynamic-entries)))
    185                                      (%int-to-ptr udisp)
    186                                      (%int-to-ptr
    187                                       (if (< disp 0)
    188                                         (+ disp (pref map :link_map.l_addr))
    189                                         disp))))))))
    190           (%setf-macptr dynamic-entries
    191                         (%inc-ptr dynamic-entries
    192                                   #+32-bit-target
    193                                   (record-length :<E>lf32_<D>yn)
    194                                   #+64-bit-target
    195                                   (record-length :<E>lf64_<D>yn))))
    196       (if (and soname-offset
    197                (not (%null-ptr-p dyn-strings)))
    198         (%inc-ptr dyn-strings soname-offset)
    199         ;; Use the full pathname of the library.
    200         (pref map :link_map.l_name)))))
     142  (let* ((path (pref map :link_map.l_name)))
     143    (if (%null-ptr-p path)
     144      (let* ((p (malloc 1)))
     145        (setf (%get-unsigned-byte p 0) 0)
     146        p)
     147      (if (eql (%get-unsigned-byte path 0) 0)
     148        path
     149        (with-macptrs ((dyn-strings)
     150                       (dynamic-entries (pref map :link_map.l_ld)))
     151          (let* ((soname-offset nil))
     152            ;; Walk over the entries in the file's dynamic segment; the
     153            ;; last such entry will have a tag of #$DT_NULL.  Note the
     154            ;; (loaded,on Linux; relative to link_map.l_addr on FreeBSD)
     155            ;; address of the dynamic string table and the offset of the
     156            ;; #$DT_SONAME string in that string table.
     157            ;; Actually, the above isn't quite right; there seem to
     158            ;; be cases (involving vDSO) where the address of a library's
     159            ;; dynamic string table is expressed as an offset relative
     160            ;; to link_map.l_addr as well.
     161            (loop
     162              (case #+32-bit-target (pref dynamic-entries :<E>lf32_<D>yn.d_tag)
     163                    #+64-bit-target (pref dynamic-entries :<E>lf64_<D>yn.d_tag)
     164                    (#. #$DT_NULL (return))
     165                    (#. #$DT_SONAME
     166                        (setq soname-offset
     167                              #+32-bit-target (pref dynamic-entries
     168                                                    :<E>lf32_<D>yn.d_un.d_val)
     169                              #+64-bit-target (pref dynamic-entries
     170                                                    :<E>lf64_<D>yn.d_un.d_val)))
     171                    (#. #$DT_STRTAB
     172                        (%setf-macptr dyn-strings
     173                                      ;; Try to guess whether we're dealing
     174                                      ;; with a displacement or with an
     175                                      ;; absolute address.  There may be
     176                                      ;; a better way to determine this,
     177                                      ;; but for now we assume that absolute
     178                                      ;; addresses aren't negative and that
     179                                      ;; displacements are.
     180                                      (let* ((disp (%get-signed-natural
     181                                                    dynamic-entries
     182                                                    target::node-size)))
     183                                        #+(or freebsd-target solaris-target)
     184                                        (%inc-ptr (pref map :link_map.l_addr) disp)
     185                                        #-(or freebsd-target solaris-target)
     186                                        (let* ((udisp #+32-bit-target (pref dynamic-entries
     187                                                                            :<E>lf32_<D>yn.d_un.d_val)
     188                                                      #+64-bit-target (pref dynamic-entries
     189                                                                            :<E>lf64_<D>yn.d_un.d_val)))
     190                                          (if (and (> udisp (pref map :link_map.l_addr))
     191                                                   (< udisp (%ptr-to-int dynamic-entries)))
     192                                            (%int-to-ptr udisp)
     193                                            (%int-to-ptr
     194                                             (if (< disp 0)
     195                                               (+ disp (pref map :link_map.l_addr))
     196                                               disp))))))))
     197              (%setf-macptr dynamic-entries
     198                            (%inc-ptr dynamic-entries
     199                                      #+32-bit-target
     200                                      (record-length :<E>lf32_<D>yn)
     201                                      #+64-bit-target
     202                                      (record-length :<E>lf64_<D>yn))))
     203            (if (and soname-offset
     204                     (not (%null-ptr-p dyn-strings)))
     205              (%inc-ptr dyn-strings soname-offset)
     206              ;; Use the full pathname of the library.
     207             (pref map :link_map.l_name))))))))
    201208
    202209(defun shared-library-at (base)
     
    852859(defun last-dot-pos (name)
    853860  (do* ((i (1- (length name)) (1- i))
    854        (trailing-digits nil))
    855        ((<= i 0))
     861        (default i)
     862        (trailing-digits nil))
     863       ((<= i 0) default)
    856864    (declare (fixnum i))
    857865    (let* ((code (%scharcode name i)))
     
    862870        (if (= code (char-code #\.))
    863871          (return (if trailing-digits i))
    864           (return nil))))))
     872          (return default))))))
    865873 
    866874;;; It's assumed that the set of libraries that the OS has open
Note: See TracChangeset for help on using the changeset viewer.