Fixes for StackwalkerAPI on BlueGene
[dyninst.git] / common / src / addrtranslate-sysv.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #include <assert.h>
33 #include <link.h>
34 #include <stdio.h>
35 #include <errno.h>
36 #include <sys/types.h>
37 #include <sys/wait.h>
38 #include <string.h>
39
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <unistd.h>
43 #include <fcntl.h>
44 #include <limits.h>
45
46 #include <vector>
47 #include <string>
48
49 #include "common/h/parseauxv.h"
50 #include "common/h/headers.h"
51
52 #include "common/h/addrtranslate.h"
53 #include "common/src/addrtranslate-sysv.h"
54
55 #if defined(os_linux) || defined(os_bg)
56 #define R_DEBUG_NAME "_r_debug"
57 #else
58 #define R_DEBUG_NAME "r_debug"
59 #endif
60
61 #if defined(os_linux)
62 #include "common/h/linuxKludges.h"
63 #endif
64
65 using namespace std;
66 using namespace Dyninst;
67
68 FileCache Dyninst::files;
69
70
71 class ProcessReaderSelf : public ProcessReader {
72 public:
73    ProcessReaderSelf();
74    bool start();
75    bool ReadMem(Address inTraced, void *inSelf, unsigned amount);
76    bool GetReg(MachRegister reg, MachRegisterVal &val);
77    bool done();
78
79   virtual ~ProcessReaderSelf();
80 };
81
82 struct link_map_dyn32
83 {
84    Elf32_Addr l_addr;
85    uint32_t l_name;
86    uint32_t l_ld;
87    uint32_t l_next, l_prev;
88 };
89
90 struct r_debug_dyn32
91 {
92     int r_version;
93     uint32_t r_map;
94     Elf32_Addr r_brk;
95     enum
96     {
97        RT_CONSISTENT,
98        RT_ADD,
99        RT_DELETE
100     } r_state;
101     Elf32_Addr r_ldbase;
102 };
103
104 class link_map_xplat 
105 {
106 public:
107    virtual size_t size() = 0;
108    virtual uint64_t l_addr() = 0;
109    virtual char *l_name() = 0;
110    virtual void *l_ld() = 0;
111    virtual bool is_last() = 0;
112    virtual bool load_next() = 0;   
113    virtual bool is_valid() = 0;   
114    virtual bool load_link(Address addr) = 0;
115    virtual ~link_map_xplat() {};
116 };
117
118 template<class link_map_X> 
119 class link_map_dyn : public link_map_xplat 
120 {
121 public: 
122    link_map_dyn(ProcessReader *proc_, Address addr);
123    ~link_map_dyn();
124    virtual size_t size();
125    virtual uint64_t l_addr();
126    virtual char *l_name();
127    virtual void *l_ld();
128    virtual bool is_last();
129    virtual bool load_next();   
130    virtual bool is_valid();   
131    virtual bool load_link(Address addr);
132
133 protected:
134    ProcessReader *proc;
135    char link_name[256];
136    bool loaded_name;
137    bool valid;
138    link_map_X link_elm;
139 };
140
141 template<class r_debug_X> 
142 class r_debug_dyn {
143 public:
144    r_debug_dyn(ProcessReader *proc_, Address addr);
145    ~r_debug_dyn();
146    void *r_brk();
147    Address r_map();
148    int r_state();
149    bool is_valid();
150 protected:
151    ProcessReader *proc;
152    bool valid;
153    r_debug_X debug_elm;
154 };
155
156 template<class r_debug_X> 
157 r_debug_dyn<r_debug_X>::r_debug_dyn(ProcessReader *proc_, Address addr)
158    : proc(proc_) 
159 {
160    valid = proc->ReadMem(addr, &debug_elm, sizeof(debug_elm));
161    if (!valid)
162       return;
163
164    translate_printf("[%s:%u] - r_debug_dyn valid = %d\n", __FILE__, __LINE__, valid?1:0);
165    translate_printf("[%s:%u] -     Read rdebug structure.  Values were:\n", __FILE__, __LINE__);
166    translate_printf("[%s:%u] -       r_brk:    %lx\n", __FILE__, __LINE__, (unsigned long)debug_elm.r_brk);
167    translate_printf("[%s:%u] -       r_map:    %lx\n", __FILE__, __LINE__, (unsigned long)debug_elm.r_map);
168 #if !defined(os_freebsd)
169    translate_printf("[%s:%u] -       r_ldbase: %lx\n", __FILE__, __LINE__, (unsigned long)debug_elm.r_ldbase);
170 #endif
171 }
172
173 template<class r_debug_X> 
174 r_debug_dyn<r_debug_X>::~r_debug_dyn() 
175 {
176 }
177
178 template<class r_debug_X> 
179 bool r_debug_dyn<r_debug_X>::is_valid() {
180    if (0 == r_map()) return false;
181    else return valid;
182 }
183
184 template<class r_debug_X> 
185 Address r_debug_dyn<r_debug_X>::r_map() {
186         return (Address) debug_elm.r_map;
187 }
188
189 template<class r_debug_X> 
190 void *r_debug_dyn<r_debug_X>::r_brk() { 
191    return reinterpret_cast<void *>(debug_elm.r_brk); 
192 }
193
194 template<class r_debug_X> 
195 int r_debug_dyn<r_debug_X>::r_state() { 
196    return (int)debug_elm.r_state; 
197 }
198  
199 template<class link_map_X>
200 link_map_dyn<link_map_X>::link_map_dyn(ProcessReader *proc_, Address addr_) :
201    proc(proc_),
202    loaded_name(false)
203 {
204    valid = load_link(addr_);
205 }
206
207 template<class link_map_X>
208 link_map_dyn<link_map_X>::~link_map_dyn() {
209 }
210
211 template<class link_map_X>
212 bool link_map_dyn<link_map_X>::is_valid() {
213    return valid;
214 }
215
216 template<class link_map_X>
217 size_t link_map_dyn<link_map_X>::size()
218 {
219    return sizeof(link_elm);
220 }
221
222 template<class link_map_X>
223 uint64_t link_map_dyn<link_map_X>::l_addr() 
224 {
225    return (uint64_t)link_elm.l_addr;
226 }
227
228 template<class link_map_X>
229 char *link_map_dyn<link_map_X>::l_name() 
230 {
231   if (loaded_name) return link_name;
232
233   for (unsigned int i = 0; i < sizeof(link_name); ++i) {
234      if (!proc->ReadMem((Address) (link_elm.l_name + i),
235                         link_name + i, sizeof(char)))
236      {
237         valid = false;
238         return NULL;
239      }
240      if (link_name[i] == '\0') break;
241   }
242   link_name[sizeof(link_name) - 1] = '\0';
243
244   loaded_name = true;  
245   return link_name;
246 }
247
248 template<class link_map_X>
249 void *link_map_dyn<link_map_X>::l_ld() 
250
251    return const_cast<void *>(reinterpret_cast<const void *>(link_elm.l_ld)); 
252 }
253
254 template<class link_map_X>
255 bool link_map_dyn<link_map_X>::is_last() 
256
257    return (link_elm.l_next == 0); 
258 }
259
260 template<class link_map_X>
261 bool link_map_dyn<link_map_X>::load_next() 
262 {
263         if (is_last()) {
264       return false;
265    }
266         if (load_link((Address) link_elm.l_next)) {
267       loaded_name = false;
268       return true;
269         }
270         return false;
271 }
272
273 template<class link_map_X>
274 bool link_map_dyn<link_map_X>::load_link(Address addr) 
275 {
276    return proc->ReadMem(addr, &link_elm, sizeof(link_elm));
277 }
278
279 static const char *deref_link(const char *path)
280 {
281    static char buffer[PATH_MAX], *p;
282    buffer[PATH_MAX-1] = '\0';
283    p = realpath(path, buffer);
284    if (!p)
285       return path;
286    return p;
287 }
288
289 ProcessReaderSelf::ProcessReaderSelf() :
290    ProcessReader() 
291 {
292 }
293
294 ProcessReaderSelf::~ProcessReaderSelf()
295 {
296 }
297
298 bool ProcessReaderSelf::start() {
299    return true;
300 }
301
302 bool ProcessReaderSelf::done() {
303    return true;
304 }
305
306 bool ProcessReaderSelf::ReadMem(Address inTraced, void *inSelf, unsigned amount)
307 {
308    memcpy(inSelf, (void *) inTraced, amount);
309    return true;
310 }
311
312 bool ProcessReaderSelf::GetReg(MachRegister /*reg*/, MachRegisterVal &/*val*/)
313 {
314    assert(0);
315    return false;
316 }
317
318
319 vector< pair<Address, unsigned long> > *LoadedLib::getMappedRegions()
320 {
321    if (mapped_regions.size())
322    {
323       return &mapped_regions;
324    }
325
326    FCNode *fc = files.getNode(name, symreader_factory);
327    if (!fc)
328       return false;
329
330    vector<SymRegion> regs;
331    fc->getRegions(regs);
332    
333    for (unsigned i=0; i<regs.size(); i++) {
334       pair<Address, unsigned long> p(load_addr + regs[i].mem_addr, 
335                                      regs[i].mem_size);
336       mapped_regions.push_back(p);
337    }
338    
339    return &mapped_regions;
340 }
341
342 AddressTranslate *AddressTranslate::createAddressTranslator(int pid_, 
343                                                             ProcessReader *reader_,
344                                                             SymbolReaderFactory *symfactory_,
345                                                             PROC_HANDLE,
346                                                             std::string exename)
347 {
348    translate_printf("[%s:%u] - Creating AddressTranslateSysV\n", __FILE__, __LINE__);
349    AddressTranslate *at = new AddressTranslateSysV(pid_, reader_, symfactory_, exename);
350    translate_printf("[%s:%u] - Created: %lx\n", __FILE__, __LINE__, (long)at);
351    
352    if (!at) {
353       return NULL;
354    }
355    else if (at->creation_error) {
356       delete at;
357       return NULL;
358    }
359    return at;
360 }
361
362 AddressTranslate *AddressTranslate::createAddressTranslator(ProcessReader *reader_,
363                                                             SymbolReaderFactory *factory_,
364                                                             std::string exename)
365 {
366    return createAddressTranslator(getpid(), reader_, factory_, INVALID_HANDLE_VALUE, exename);
367 }
368
369 AddressTranslateSysV::AddressTranslateSysV() :
370    AddressTranslate(NULL_PID),
371    reader(NULL),
372    interpreter_base(0),
373    set_interp_base(0),
374    address_size(0),
375    interpreter(NULL),
376    previous_r_state(0),
377    current_r_state(0),
378    r_debug_addr(0),
379    trap_addr(0)
380 {
381 }
382
383 AddressTranslateSysV::AddressTranslateSysV(int pid, ProcessReader *reader_, 
384                                            SymbolReaderFactory *reader_fact,
385                                            std::string exename) :
386    AddressTranslate(pid, INVALID_HANDLE_VALUE, exename),
387    reader(reader_),
388    interpreter_base(0),
389    set_interp_base(0),
390    address_size(0),
391    interpreter(NULL),
392    previous_r_state(0),
393    current_r_state(0),
394    r_debug_addr(0),
395    trap_addr(0)
396 {
397    bool result;
398    if (!reader) {
399       if (pid == getpid())
400          reader = new ProcessReaderSelf();
401       else
402          reader = createDefaultDebugger(pid);
403    }
404    symfactory = reader_fact;
405    result = init();
406    if (!result) {
407       creation_error = true;
408       return;
409    }
410 }
411
412 bool AddressTranslateSysV::parseDTDebug() {
413     //TODO this could possibly be used on other platforms
414 #if !defined(os_freebsd)
415     return false;
416 #else
417     if( !setAddressSize() ) {
418         translate_printf("[%s:%u] - Failed to set address size.\n", __FILE__, __LINE__);
419         return false;
420     }
421
422     // This information is derived from the DT_DEBUG field in the
423     // executable's program headers -- however, the value needs to
424     // be read from the loaded executable image so determine the
425     // address of the DT_DEBUG field and then read it from the
426     // process
427
428     const char *l_err = "Failed to determine trap address.";
429
430     getExecName();
431     if( exec_name.empty() ) {
432         translate_printf("[%s:%u] - %s\n", __FILE__, __LINE__, l_err);
433         return false;
434     }
435
436     SymReader *exe = symfactory->openSymbolReader(exec_name);
437     if( !exe ) {
438         translate_printf("[%s:%u] - %s\n", __FILE__, __LINE__, l_err);
439         return false;
440     }
441         
442     // Need to get the address of the DYNAMIC segment
443     Address dynAddress = 0;
444     size_t dynSize = 0;
445     unsigned numRegs = exe->numRegions();
446     for(unsigned i = 0; i < numRegs; ++i) {
447         SymRegion reg;
448         exe->getRegion(i, reg);
449
450         if( PT_DYNAMIC == reg.type ) {
451             dynAddress = reg.mem_addr;
452             dynSize = reg.mem_size;
453             break;
454         }
455     }
456     symfactory->closeSymbolReader(exe);
457
458     if( !dynAddress || !dynSize ) {
459         // This is okay for static binaries
460         return false;
461     }
462
463     if( !reader->start() ) {
464         translate_printf("[%s:%u] - %s\n", __FILE__, __LINE__, l_err);
465         return false;
466     }
467
468     // Read the DYNAMIC segment from the process
469     void *dynData = malloc(dynSize);
470     if( !dynData || !reader->ReadMem(dynAddress, dynData, dynSize) ) {
471         translate_printf("[%s:%u] - %s\n", __FILE__, __LINE__, l_err);
472         if( dynData ) free(dynData);
473         return false;
474     }
475     
476     if( address_size == 8 ) {
477         Elf64_Dyn *dynDataElf = (Elf64_Dyn *)dynData;
478         for(unsigned i = 0; i < (dynSize / sizeof(Elf64_Dyn)); ++i) {
479             if( DT_DEBUG == dynDataElf[i].d_tag ) {
480                 r_debug_addr = (Address) dynDataElf[i].d_un.d_ptr;
481                 break;
482             }
483         }
484     }else{
485         Elf32_Dyn *dynDataElf = (Elf32_Dyn *)dynData;
486         for(unsigned i = 0; i < (dynSize / sizeof(Elf32_Dyn)); ++i) {
487             if( DT_DEBUG == dynDataElf[i].d_tag ) {
488                 r_debug_addr = (Address) dynDataElf[i].d_un.d_ptr;
489                 break;
490             }
491         }
492     }
493     free(dynData);
494
495     // When a process is initializing, the DT_DEBUG value could be zero
496     // This function needs to indicate an error so the trap address can
497     // be parsed from other sources (i.e., the interpreter)
498
499     if( r_debug_addr ) {
500         trap_addr = getTrapAddrFromRdebug();
501         if( trap_addr == 0 ) {
502             reader->done();
503             return false;
504         }
505     }
506
507     reader->done();
508     
509     return ( r_debug_addr != 0 );
510 #endif
511 }
512
513 bool AddressTranslateSysV::parseInterpreter() {
514     bool result;
515
516     result = setInterpreter();
517     if (!result) {
518         translate_printf("[%s:%u] - Failed to set interpreter.\n", __FILE__, __LINE__);
519         return false;
520     }
521
522     result = setAddressSize();
523     if (!result) {
524         translate_printf("[%s:%u] - Failed to set address size.\n", __FILE__, __LINE__);
525         return false;
526     }
527
528     result = setInterpreterBase();
529     if (!result) {
530         translate_printf("[%s:%u] - Failed to set interpreter base.\n", __FILE__, __LINE__);
531         return false;
532     }
533
534     if (interpreter) {
535         if( interpreter->get_r_debug() ) {
536             r_debug_addr = interpreter->get_r_debug() + interpreter_base;
537
538             if( !reader->start() ) {
539                 translate_printf("[%s:%u] - Failed to initialize process reader\n", __FILE__, __LINE__);
540                 return false;
541             }
542
543             trap_addr = getTrapAddrFromRdebug();
544
545             if( !reader->done() ) {
546                 translate_printf("[%s:%u] - Failed to finalize process reader\n", __FILE__, __LINE__);
547                 return false;
548             }
549
550             if( trap_addr == 0 ) {
551                 trap_addr = interpreter->get_r_trap() + interpreter_base;
552             }
553         }
554         else
555         {
556             r_debug_addr = 0;
557             trap_addr = interpreter->get_r_trap() + interpreter_base;
558         }
559     } else {
560         r_debug_addr = 0;
561         trap_addr = 0;
562     }
563
564     return true;
565 }
566
567 bool AddressTranslateSysV::init() {
568    translate_printf("[%s:%u] - Initing AddressTranslateSysV\n", __FILE__, __LINE__);
569
570    // Try to use DT_DEBUG first, falling back to parsing the interpreter binary if possible
571    if( !parseDTDebug() ) {
572        if( !parseInterpreter() ) {
573            translate_printf("[%s:%u] - Failed to determine r_debug address\n", 
574                    __FILE__, __LINE__);
575            return false;
576        }
577    }
578
579    translate_printf("[%s:%u] - trap_addr = 0x%lx, r_debug_addr = 0x%lx\n", __FILE__, __LINE__, trap_addr, r_debug_addr);
580    translate_printf("[%s:%u] - Done with AddressTranslateSysV::init()\n", __FILE__, __LINE__);
581
582    return true;
583 }
584
585 LoadedLib *AddressTranslateSysV::getLoadedLibByNameAddr(Address addr, std::string name)
586 {
587    std::pair<Address, std::string> p(addr, name);
588    sorted_libs_t::iterator i = sorted_libs.find(p);
589    LoadedLib *ll = NULL;
590    if (i != sorted_libs.end()) {
591       ll = i->second;
592    }
593    else {
594       ll = new LoadedLib(name, addr);
595       ll->setFactory(symfactory);
596       assert(ll);
597       sorted_libs[p] = ll;
598    }
599    ll->setShouldClean(false);
600    return ll;
601 }
602
603 Address AddressTranslateSysV::getTrapAddrFromRdebug() {
604     Address retVal = 0;
605     assert( r_debug_addr && address_size );
606
607     if( address_size == sizeof(void *) ) {
608         r_debug_dyn<r_debug> *r_debug_native = new r_debug_dyn<r_debug>(reader, r_debug_addr);
609         if( !r_debug_native ) {
610             translate_printf("[%s:%u] - Failed to parse r_debug struct.\n", __FILE__, __LINE__);
611             return 0;
612         }
613         if( !r_debug_native->is_valid() ) {
614             return 0;
615         }
616         retVal = (Address) r_debug_native->r_brk();
617         delete r_debug_native;
618     }else{
619         r_debug_dyn<r_debug_dyn32> *r_debug_32 = new r_debug_dyn<r_debug_dyn32>(reader, r_debug_addr);
620         if( !r_debug_32 ) {
621             translate_printf("[%s:%u] - Failed to parse r_debug struct.\n", __FILE__, __LINE__);
622             return 0;
623         }
624         if( !r_debug_32->is_valid() ) {
625             return 0;
626         }
627         retVal = (Address) r_debug_32->r_brk();
628         delete r_debug_32;
629     }
630
631     return retVal;
632 }
633
634 bool AddressTranslateSysV::refresh()
635 {
636    link_map_xplat *link_elm = NULL;
637    r_debug_dyn<r_debug_dyn32> *r_debug_32 = NULL;
638    r_debug_dyn<r_debug> *r_debug_native = NULL;
639    map_entries *maps = NULL;
640    bool result = false;
641    size_t loaded_lib_count = 0;
642
643    translate_printf("[%s:%u] - Refreshing Libraries\n", __FILE__, __LINE__);
644    if (pid == NULL_PID)
645       return true;
646
647    if (!r_debug_addr) {
648        // On systems that use DT_DEBUG to determine r_debug_addr, DT_DEBUG might
649        // not be set right away -- read DT_DEBUG now and see if it is set
650        if( !parseDTDebug() && !interpreter ) {
651           translate_printf("[%s:%u] - Working with static binary, no libraries to refresh\n",
652                   __FILE__, __LINE__);
653           libs.clear();
654           if (!exec) {
655              exec = getAOut();
656           }
657           getArchLibs(libs);
658           return true;
659        }
660    }
661
662    std::vector<LoadedLib *>::iterator i;
663    for (i = libs.begin(); i != libs.end(); i++)
664       (*i)->setShouldClean(true);
665    libs.clear();
666
667    if (!exec) {
668       exec = getAOut();
669    }   
670    exec->setShouldClean(false);
671    libs.push_back(exec);
672    getArchLibs(libs);
673    
674    if( !reader->start() ) {
675        translate_printf("[%s:%u] - Failed to refresh libraries\n", __FILE__, __LINE__);
676        return false;
677    }
678
679    translate_printf("[%s:%u] -     Starting refresh.\n", __FILE__, __LINE__);
680    translate_printf("[%s:%u] -       trap_addr:    %lx\n", __FILE__, __LINE__, trap_addr);
681    translate_printf("[%s:%u] -       r_debug_addr: %lx\n", __FILE__, __LINE__, r_debug_addr);
682
683    if (address_size == sizeof(void*)) {
684       r_debug_native = new r_debug_dyn<r_debug>(reader, r_debug_addr);
685       if (!r_debug_native)
686       {
687         result = true;
688         goto done;
689       }
690       else if (!r_debug_native->is_valid() && read_abort)
691       {
692          result = false;
693          goto all_done;
694       }
695       else if (!r_debug_native->is_valid())
696       {
697          if (interpreter) {
698             libs.push_back(getLoadedLibByNameAddr(interpreter_base,
699                                                   interpreter->getFilename()));
700          }
701          result = true;
702          goto done;
703       }
704       link_elm = new link_map_dyn<link_map>(reader, r_debug_native->r_map());
705    }
706    else {//64-bit mutator, 32-bit mutatee
707       r_debug_32 = new r_debug_dyn<r_debug_dyn32>(reader, r_debug_addr);
708       if (!r_debug_32)
709       {
710          result = true;
711          goto done;
712       }
713       else if (!r_debug_32->is_valid() && read_abort)
714       {
715          result = false;
716          goto all_done;
717       }
718       else if (!r_debug_32->is_valid())
719       {
720          if (interpreter) {
721             libs.push_back(getLoadedLibByNameAddr(interpreter_base,
722                                                   interpreter->getFilename()));
723          }
724          result = true;
725          goto done;
726       }
727       link_elm = new link_map_dyn<link_map_dyn32>(reader, r_debug_32->r_map());
728    }
729
730    if (!link_elm->is_valid() && read_abort) {
731       result = false;
732       goto all_done;
733    }
734    if (!link_elm->is_valid()) {
735       result = true;
736       goto done;
737    }
738
739    do {
740       if (!link_elm->l_name()) {
741          if (read_abort) {
742             result = false;
743             goto all_done;
744          }
745          continue;
746       }
747       string obj_name(link_elm->l_name());
748
749       // Don't re-add the executable, it has already been added
750       if( getExecName() == string(deref_link(obj_name.c_str())) )
751           continue;
752
753       Address text = (Address) link_elm->l_addr();
754       if (obj_name == "" && !text)
755          continue;
756       if (!link_elm->is_valid())
757          goto done;
758
759 #if defined(os_linux)
760       unsigned maps_size;
761       if (obj_name == "") { //Augment using maps
762          if (!maps)
763             maps = getLinuxMaps(pid, maps_size);
764          for (unsigned i=0; maps && i<maps_size; i++) {
765             if (text == maps[i].start) {
766                obj_name = maps[i].path;
767                break;
768             }
769          }
770       }
771       if (obj_name.c_str()[0] == '[')
772          continue;
773 #endif
774       
775       string s(deref_link(obj_name.c_str()));
776       LoadedLib *ll = getLoadedLibByNameAddr(text, s);
777       loaded_lib_count++;
778       translate_printf("[%s:%u] -     New Loaded Library: %s(%lx)\n", __FILE__, __LINE__, s.c_str(), text);
779
780       libs.push_back(ll);
781    } while (link_elm->load_next());
782    
783    if (read_abort) {
784       result = false;
785       goto all_done;
786    }
787
788    translate_printf("[%s:%u] - Found %d libraries.\n", __FILE__, __LINE__, loaded_lib_count);
789
790    result = true;
791  done:
792    reader->done();
793    
794    //Erase old elements from the sorted_libs
795    sorted_libs.clear();
796    for (vector<LoadedLib *>::iterator i = libs.begin(); i != libs.end(); i++)
797    {
798       LoadedLib *ll = *i;
799       sorted_libs[pair<Address, string>(ll->getCodeLoadAddr(), ll->getName())] = ll;
800    }
801
802   all_done:
803
804    if (read_abort) {
805       translate_printf("[%s:%u] - refresh aborted due to async read\n", __FILE__, __LINE__);
806    }
807    if (link_elm)
808       delete link_elm;
809    if (r_debug_32)
810       delete r_debug_32;
811    if (r_debug_native)
812       delete r_debug_native;
813    if (maps)
814       free(maps);
815
816    return result;
817 }
818
819 FCNode::FCNode(string f, dev_t d, ino_t i, SymbolReaderFactory *factory_) :
820    device(d),
821    inode(i),
822    parsed_file(false),
823    parse_error(false),
824    is_interpreter(false),
825    r_debug_offset(0),
826    r_trap_offset(0),
827    symreader(NULL),
828    factory(factory_)
829 {
830    filename = deref_link(f.c_str());
831 }
832
833 string FCNode::getFilename() {
834    return filename;
835 }
836
837 string FCNode::getInterpreter() {
838    parsefile();
839
840    return interpreter_name;
841 }
842
843 void FCNode::getRegions(vector<SymRegion> &regs) {
844    parsefile();
845
846    regs = regions;
847 }
848
849 unsigned FCNode::getAddrSize() {
850    parsefile();
851
852    return addr_size;
853 }
854
855 Offset FCNode::get_r_debug() {
856    parsefile();
857
858    return r_debug_offset;
859 }
860
861 Offset FCNode::get_r_trap() {
862     parsefile();
863
864     return r_trap_offset;
865 }
866
867 void FCNode::markInterpreter() {
868    if (is_interpreter)
869       return;
870
871    assert(!parsed_file);
872    is_interpreter = true;
873 }
874
875 #define NUM_DBG_BREAK_NAMES 3
876 const char *dbg_break_names[] = { "_dl_debug_state",
877                                   "r_debug_state",
878                                   "_r_debug_state" };
879
880 void FCNode::parsefile()
881 {
882    if (parsed_file || parse_error)
883       return;
884    parsed_file = true;
885    
886    assert(!symreader);
887    symreader = factory->openSymbolReader(filename);
888    if (!symreader) {
889       parse_error = true;
890       translate_printf("[%s:%u] - Failed to open %s\n", __FILE__, __LINE__,
891                        filename.c_str());
892       return;
893    }
894
895    if (is_interpreter) {
896 #if !defined(os_freebsd)
897       //We're parsing the interpreter, don't confuse this with
898       // parsing the interpreter link info (which happens below).
899       Symbol_t r_debug_sym = symreader->getSymbolByName(R_DEBUG_NAME);
900       if (!symreader->isValidSymbol(r_debug_sym)) {
901          translate_printf("[%s:%u] - Failed to find r_debug symbol in %s\n",
902                           __FILE__, __LINE__, filename.c_str());
903          parse_error = true;
904       }
905       r_debug_offset = symreader->getSymbolOffset(r_debug_sym);
906 #endif
907       r_trap_offset = 0;
908       for(unsigned i = 0; i < NUM_DBG_BREAK_NAMES; ++i) {
909           Symbol_t r_trap_sym = symreader->getSymbolByName(dbg_break_names[i]);
910           if( symreader->isValidSymbol(r_trap_sym) ) {
911               r_trap_offset = symreader->getSymbolOffset(r_trap_sym);
912               break;
913           }
914       }
915
916       if( !r_trap_offset ) {
917           translate_printf("[%s:%u] - Failed to find debugging trap symbol in %s\n",
918                   __FILE__, __LINE__, filename.c_str());
919           parse_error = true;
920       }
921    }
922
923    addr_size = symreader->getAddressWidth();   
924    interpreter_name = symreader->getInterpreterName();
925    
926    unsigned num_regions = symreader->numRegions();
927    for (unsigned i=0; i<num_regions; i++) {
928       SymRegion sr;
929       bool result = symreader->getRegion(i, sr);
930       if (!result) {
931          translate_printf("[%s:%u] - Failed to get region info\n",
932                           __FILE__, __LINE__);
933          parse_error = true;
934          break;
935       }
936       
937       regions.push_back(sr);
938    }
939    /*factory->closeSymbolReader(symreader);
940      symreader = NULL;*/
941 }
942
943 FCNode *FileCache::getNode(const string &filename, SymbolReaderFactory *factory)
944 {
945    struct stat buf;
946    int result = stat(filename.c_str(), &buf);
947    if (result == -1)
948       return NULL;
949    if (!filename.length())
950       return NULL;
951
952    for (unsigned i=0; i<nodes.size(); i++)
953    {
954       if (nodes[i]->inode == buf.st_ino &&
955           nodes[i]->device == buf.st_dev)
956       {
957          return nodes[i];
958       }
959    }
960
961    FCNode *fc = new FCNode(filename, buf.st_dev, buf.st_ino, factory);
962    nodes.push_back(fc);
963
964    return fc;
965 }
966
967 FileCache::FileCache()
968 {
969 }
970
971 Address AddressTranslateSysV::getLibraryTrapAddrSysV() {
972   return trap_addr;
973 }