2010-09-01 11 views
9

Quando ld-linux risolve un simbolo, cerca nelle librerie condivise in un ordine particolare e si ferma quando trova una libreria condivisa con un simbolo corrispondente.In quale ordine ld-linux.so cerca le librerie condivise?

Che cosa determina l'ordine che cerca nelle librerie? Fa la differenza se il simbolo non risolto è nel programma principale o in un'altra libreria condivisa?

Come è possibile determinare l'ordine di ricerca in modo programmato senza chiamare programmi esterni come ldd?

risposta

9

Da http://www.muppetlabs.com/~breadbox/software/ELF.txt (come menzionato da sarnold):

Quando risolvere i riferimenti simbolici, il linker dinamico esamina il simbolo tavoli con una ricerca breadth-first. Che è, in primo luogo guarda la tabella dei simboli del programma eseguibile sé, poi le tabelle dei simboli di voci DT_NEEDED (in ordine), poi alle voci secondo livello DT_NEEDED, e così via.

3

Questo libro http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html suggerisce l'ordine da sinistra a destra come indicato nella riga di comando gcc. (Ho imparato molto tempo fa a mettere sempre -lm come l'ultima libreria in un elenco di librerie di collegamento con, ma ho anche dimenticato da tempo la ragione cargo-cult per questo.)

EDIT

Aha, grazie per l'aggiornamento. Avrai bisogno di analizzare da solo l'ELF; cercare "Dipendenze oggetto condiviso" e "DT_RPATH" in http://www.muppetlabs.com/~breadbox/software/ELF.txt. (Raccomando anche http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html, ma è meno applicabile al tuo problema - solo lettura divertente.)

/usr/include/linux/elf.h ha tutti i typedefs.

+0

Grazie, ma ho bisogno di lavorare con arb programmi itrary, anche se non conosco la linea di collegamento con cui è stato compilato il programma. – atomice

-1

in realtà l'ordine di collegamento può essere dedotto utilizzando ldd; se libreria1 si trova nella riga di comando del linker prima della libreria2 quindi ldd visualizzerà la libreria1 prima della libreria2

Ora basato su questo ho scritto un breve script python che mostra le librerie condivise in ordine di collegamento - fa una prima ricerca di ampiezza su tutte le dipendenze visualizzate . da LDD (per un dato eseguibile

Ecco lo script

EDIT: notare che lo script utilizza LDD, comunque potrebbe essere utile ;-)

#!/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 domanda dice "senza chiamare programmi esterni come ldd". Il tuo programma chiama un programma esterno, vale a dire ldd. – atomice

Problemi correlati