23 #include "ns3/assert.h"
29 #include <sys/types.h>
52 void AddLibrary (
string l);
53 void AddPath (
string p);
54 void SetSoName (
string s);
57 string GetName (
bool full)
const;
58 bool GetArch32 ()
const;
59 bool GetArch64 ()
const;
60 set <pair<string,string> > GetLibs ()
const;
61 vector <string> GetPath ()
const;
62 string GetSoname ()
const;
64 bool CalcDepth (
int max, map <string, SharedLibrary*> &mapScanned);
65 int GetDepth ()
const;
94 m_libs.insert (make_pair (l,
""));
100 char *start = (
char*) p.c_str ();
108 while (*crsr && (*crsr !=
':'))
117 string res = string (f, l - f);
118 if ((prec != 0) && (prec !=
'/'))
122 if (res.length () > 0)
124 DIR *d = opendir (res.c_str ());
145 set <pair<string,string> >
195 set<pair<string,string> > n;
197 for (
set<pair<string,string> >::const_iterator i =
m_libs.begin (); i !=
m_libs.end (); ++i)
200 pair <string,string> p = *i;
202 for (vector<string>::const_iterator j =
m_path.begin (); j !=
m_path.end (); ++j)
204 string fullPath = *j + p.first;
207 if (!stat (fullPath.c_str (), &st))
218 NS_LOG_DEBUG (p.first <<
" NOT FOUND");
221 if (
m_libs.size () == count)
245 for (
set<pair<string,string> >::const_iterator i =
m_libs.begin (); i !=
m_libs.end (); ++i)
247 if (!mapScanned[(*i).second]->CalcDepth (max - 1, mapScanned))
251 if (mapScanned[(*i).second]->GetDepth () > calc - 1)
253 calc = mapScanned[(*i).second]->GetDepth () + 1;
265 ElfW (Addr) vaddr_2_foffset (const
ElfW (Ehdr) * he, const
ElfW (Phdr) * pr, const
ElfW (Addr) vma)
267 for (
int p = 0; p < he->e_phnum; p++)
269 if (pr[p].p_type == PT_LOAD)
271 if ((vma >= pr[p].p_vaddr))
273 return vma - pr[p].p_vaddr + pr[p].p_offset;
283 NS_LOG_FUNCTION (sName << fullPath);
284 int fd = open (fullPath.c_str (), O_RDONLY);
287 NS_LOG_ERROR (fullPath <<
": unable to open file errno: " <<
errno);
291 int retval = fstat (fd, &st);
294 NS_LOG_ERROR (fullPath <<
": unable to fstat file errno: " <<
errno);
297 uint64_t size = st.st_size;
298 uint8_t *buffer = (uint8_t *) mmap (0, size, PROT_READ, MAP_PRIVATE, fd, 0);
299 if (((
void*)-1) == buffer)
301 NS_LOG_ERROR (fullPath <<
": unable to mmap file errno: " <<
errno);
306 const ElfW (Ehdr) * header = (
ElfW (Ehdr) *)buffer;
307 if (header->e_ident [EI_CLASS] == ELFCLASS64)
311 if (header->e_ident [EI_CLASS] == ELFCLASS32)
315 const ElfW (Phdr) * programTable = (
ElfW (Phdr) *)(buffer + header->e_phoff);
316 const ElfW (Shdr) * sectionTable = (
ElfW (Shdr) *)(buffer + header->e_shoff);
317 for (
int s = 0; s < header->e_shnum ; s++)
319 if (SHT_DYNAMIC == sectionTable [s].sh_type)
322 ElfW (Dyn) * dynamics = (
ElfW (Dyn) *)(buffer + sectionTable [s].sh_offset);
324 ElfW (Addr) dt_strtab = 0;
327 if (dynamics [n].d_tag == DT_STRTAB)
330 dt_strtab = vaddr_2_foffset (header, programTable, dynamics [n].d_un.d_ptr);
332 if (dynamics [n].d_tag == DT_NULL)
343 switch (dynamics [n].d_tag)
353 res->
AddLibrary (
string ((
char*)(buffer + dt_strtab + dynamics [n].d_un.d_ptr)));
360 res->
AddPath (
string ((
char*)(buffer + dt_strtab + dynamics [n].d_un.d_ptr)));
366 res->
SetSoName (
string ((
char*)(buffer + dt_strtab + dynamics [n].d_un.d_ptr)));
375 retval = ::munmap (buffer, size);
383 set<pair<string,string> > todo;
385 map <string, SharedLibrary*> mapScanned;
386 todo.insert (make_pair (s,f));
387 vector<SharedLibrary*> toFree;
389 while (todo.size () > 0)
391 const pair<string,string> name = *(todo.begin ());
396 toFree.push_back (l);
397 if (getenv (
"LD_LIBRARY_PATH"))
399 l->
AddPath (getenv (
"LD_LIBRARY_PATH"));
403 l->
AddPath (
"/lib/:/usr/lib/:/lib/i386-linux-gnu/:/usr/lib/i386-linux-gnu/");
407 l->
AddPath (
"/lib64/:/usr/lib64/:/lib/x86_64-linux-gnu/:/usr/lib/x86_64-linux-gnu/:/lib/:/usr/lib/");
411 done.insert (name.second);
412 mapScanned [name.second] = l;
413 set <pair<string,string> > full = l->
GetLibs ();
415 for (
set <pair<string,string> >::const_iterator ii = full.begin ();
416 ii != full.end (); ++ii)
418 string lalib = (*ii).second;
420 if ((todo.find (*ii) == todo.end ())
422 (done.end () == done.find (lalib)))
431 if (0 == mapScanned[f])
433 NS_LOG_DEBUG (
"No libraries found for " << f);
437 if (!mapScanned[f]->CalcDepth (mapScanned.size (), mapScanned))
439 NS_LOG_ERROR (
"There is a loop in dependencies of " << f);
442 map <int, vector <SharedLibrary*> > tri;
444 for (map <string, SharedLibrary*>::const_iterator i = mapScanned.begin ();
445 i != mapScanned.end (); i++)
447 int p = i->second->GetDepth ();
453 if (tri.find (p) == tri.end ())
455 vector <SharedLibrary*> vide;
458 tri [p].push_back (i->second);
460 for (
int j = 0 ; j <= maxi ; j++)
462 vector <SharedLibrary*> vectore = tri [j];
463 for (vector<SharedLibrary*>::const_iterator s = vectore.begin (); s != vectore.end (); s++)
467 d.
found = (*s)->GetName (1);
471 for (vector<SharedLibrary*>::const_iterator s = toFree.begin (); s != toFree.end (); s++)
482 std::vector<struct ElfDependencies::Dependency>