2010-09-01 25 views
9

Cuando ld-linux resuelve un símbolo, busca entre las bibliotecas compartidas en un orden particular y se detiene cuando encuentra una biblioteca compartida con un símbolo coincidente.¿En qué orden ld-linux.so busca bibliotecas compartidas?

¿Qué determina el orden que busca a través de las bibliotecas? ¿Hay alguna diferencia si el símbolo no resuelto se encuentra en el programa principal o en otra biblioteca compartida?

¿Cómo puedo determinar el orden de búsqueda programáticamente sin llamar a programas externos como ldd?

Respuesta

9

De http://www.muppetlabs.com/~breadbox/software/ELF.txt (como se ha mencionado por sarnold):

Al resolver referencias simbólicas, enlazador dinámico examina el símbolo tablas con una búsqueda en amplitud. Eso es, primero busca en la tabla de símbolos del programa ejecutable sí, entonces en las tablas de símbolos de las entradas DT_NEEDED (en orden), entonces en las entradas de segundo nivel DT_NEEDED, y así sucesivamente.

3

Este libro http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html sugiere una orden de izquierda a derecha como aparece en la línea de comando gcc. (Aprendí hace mucho tiempo que coloque siempre -lm como el último de la biblioteca en una lista de bibliotecas para enlazar con, pero también he olvidado desde hace mucho tiempo la razón de cargo y de culto para eso.)

EDITAR

Aha, gracias por la actualización. Necesitarás analizar el ELF tú mismo; busque "Dependencias de objetos compartidos" y "DT_RPATH" en http://www.muppetlabs.com/~breadbox/software/ELF.txt. (También recomiendo http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html, pero es menos aplicable a su problema - solo lectura divertida.)

/usr/include/linux/elf.h tiene todos los typedefs.

+0

Gracias, pero lo necesito para trabajar con arb programas originales, incluso si no conozco la línea de enlace con la que se compiló el programa. – atomice

-1

En realidad, la orden de enlace se puede deducir mediante el uso de ldd; si library1 está en la línea de comando del enlazador antes de library2 luego ldd mostrará library1 antes de library2

Ahora, basado en esto, escribí un script corto de python que muestra las bibliotecas compartidas en orden de enlace - hace una búsqueda de ancho sobre todas las dependencias mostradas . por LDD (para un ejecutable dado

Aquí está la secuencia de comandos

EDIT: tenga en cuenta que la secuencia de comandos utiliza LDD, aún podría ser útil ;-)

#!/usr/bin/python 

import subprocess 
import sys 
import re 

visited_so = {} 
ssplit = re.compile('\S+') 
verbose = 0 

def run_ldd(sopath): 
     ret = [] 

     pop = subprocess.Popen([ 'ldd', sopath ], stdin = subprocess.PIPE, stdout = subprocess.PIPE) 
     [out, err] = pop.communicate() 

     for l in out.splitlines(): 
      toks = ssplit.findall(l) 
      if len(toks) > 3: 
       ret.append(toks[2]) 
     return ret 

def load_order_bfs(pqueue): 
    while len(pqueue) != 0: 
     nextexe = pqueue.pop(0) 
     if verbose: 
      print 'visit ' + nextexe 

     if not nextexe in visited_so: 
      print nextexe 
      visited_so[ nextexe ] = 1 

      dependents = run_ldd(nextexe) 
      for sopath in dependents: 
        if not sopath in visited_so: 
         if verbose: 
          print '\tnext ' + sopath 
         pqueue.append(sopath) 

if len(sys.argv) == 1: 
    print sys.argv[0] + """ <path> 
shows dependents of executable in symbol search order; 
does a breadth first search over the dependents of the executable 
""" 
    sys.exit(1) 

load_order_bfs([ sys.argv[1] ])  
+0

La pregunta dice "sin llamar a programas externos como ldd". Su programa llama a un programa externo, es decir, ldd. – atomice

Cuestiones relacionadas