Update copyright to LGPL on all files
[dyninst.git] / symtabAPI / src / Object-coff.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 // $Id: Object-coff.C,v 1.6 2008/06/19 19:54:11 legendre Exp $
33
34 #include "common/h/Dictionary.h"
35 #include "Object.h"
36 #include "Object-coff.h"
37 #include <cmplrs/demangle_string.h>  // For native C++ (cxx) name demangling.
38
39 bool GCC_COMPILED=false; //Used to detect compiler type. True if mutatee is 
40                          //compiled with a GNU compiler. parseCoff.C needs this
41
42 /* ScName() and StName() used for debugging only.
43
44 const char *StName(int st)
45 {
46         switch (st) {
47         case stNil:             return "stNil";
48         case stGlobal:          return "stGlobal";
49         case stStatic:          return "stStatic";
50         case stParam:           return "stParam";
51         case stLocal:           return "stLocal";
52         case stLabel:           return "stLabel";
53         case stProc:            return "stProc";
54         case stBlock:           return "stBlock";
55         case stEnd:             return "stEnd";
56         case stMember:          return "stMember";
57         case stTypedef:         return "stTypedef";
58         case stFile:            return "stFile";
59         case stRegReloc:        return "stRegReloc";
60         case stForward:         return "stForward";
61         case stStaticProc:      return "stStaticProc";
62         case stConstant:        return "stConstant";
63         case stStaParam:        return "stStaParam";
64         case stBase:            return "stBase";
65         case stVirtBase:        return "stVirtBase";
66         case stTag:             return "stTag";
67         case stInter:           return "stInter";
68         case stSplit:           return "stSplit";
69         case stModule:          return "stModule";
70         case stModview:         return "stModview";
71         case stAlias:           return "stAlias";
72         case stStr:             return "stStr";
73         case stNumber:          return "stNumber";
74         case stExpr:            return "stExpr";
75         case stType:            return "stType";
76         }
77         return "Bad St";
78 }
79
80 const char *ScName(int sc)
81 {
82         switch (sc) {
83         case scNil:             return "scNil";
84         case scText:            return "scText";
85         case scData:            return "scData";
86         case scBss:             return "scBss";
87         case scRegister:        return "scRegister";
88         case scAbs:             return "scAbs";
89         case scUndefined:       return "scUndefined";
90         case scUnallocated:     return "scUnallocated";
91         case scBits:            return "scBits";
92         case scTlsUndefined:    return "scTlsUndefined";
93         case scRegImage:        return "scRegImage";
94         case scInfo:            return "scInfo";
95         case scUserStruct:      return "scUserStruct";
96         case scSData:           return "scSData";
97         case scSBss:            return "scSBss";
98         case scRData:           return "scRData";
99         case scVar:             return "scVar";
100         case scCommon:          return "scCommon";
101         case scSCommon:         return "scSCommon";
102         case scVarRegister:     return "scVarRegister";
103         case scVariant:         return "scVariant";
104         case scSUndefined:      return "scSUndefined";
105         case scInit:            return "scInit";
106         case scBasedVar:        return "scBasedVar";
107         case scXData:           return "scXData";
108         case scPData:           return "scPData";
109         case scFini:            return "scFini";
110         case scRConst:          return "scRConst";
111         case scSymRef:          return "scSymRef";
112         case scTlsCommon:       return "scTlsCommon";
113         case scTlsData:         return "scTlsData";
114         case scTlsBss:          return "scTlsBss";
115         }
116         return "Bad Sc";
117 }
118 */
119
120 static inline bool obj_read_section(SCNHDR& secthead, LDFILE *ldptr,
121                                     Word *buffer) {
122   if (!secthead.s_scnptr) return false;
123   if (ldfseek(ldptr, secthead.s_scnptr, SEEK_SET) == -1) return false;
124
125   if (ldfread((void*) buffer, 1, secthead.s_size, ldptr) != secthead.s_size)
126     return false;
127   else
128     return true;
129 }
130
131 // The possible data sections
132 // These should only be used locally
133 #define K_D_INDEX    0
134 #define K_XD_INDEX   1
135 #define K_PD_INDEX   2
136 #define K_SD_INDEX   3
137 #define K_RD_INDEX   4
138 #define K_RC_INDEX   5 
139 #define K_L4_INDEX   6
140 #define K_L8_INDEX   7
141 #define K_LA_INDEX   8
142
143 // Attempt to find the largest contiguous (in virtual address space) region.
144 // This region must include ".data", and may include the other data like regions
145 static inline bool find_data_region(vector<Address>& all_addr,
146                                     vector<long>& all_size,
147                                     vector<long>& all_disk,
148                                     unsigned long& data_len, Address& data_off) {
149   // Start at data and work back
150   assert(all_addr[K_D_INDEX]); assert(all_size[K_D_INDEX]);
151   assert(all_addr.size() == all_size.size());
152
153   Address current = all_addr[K_D_INDEX];
154   Address min_adr = current;
155   Address max_adr = current + all_size[K_D_INDEX];
156
157   unsigned index, max=all_addr.size();
158
159   bool updated=true;
160   while (updated) {
161     updated = false;
162     for (index=0; index<max; index++) {
163       if (all_addr[index] && all_size[index] && all_disk[index] &&
164           ((all_addr[index] + all_size[index]) == current)) {
165         current = all_addr[index];
166         updated = true;
167       }
168     }
169   }
170   min_adr = current;
171
172   // Start at data and work forward
173   current = max_adr;
174   updated=true;
175   while (updated) {
176     updated = false;
177     for (index=0; index<max; index++) {
178       if (all_addr[index] && all_size[index] && all_disk[index] && 
179           (all_addr[index] == current)) {
180         current = all_addr[index] + all_size[index];
181         updated = true;
182       }
183     }
184   }
185
186   max_adr = current;
187   
188   data_len = (max_adr - min_adr);
189   data_off = min_adr;
190   assert(min_adr <= all_addr[K_D_INDEX]);
191   assert(max_adr >= all_addr[K_D_INDEX] + all_size[K_D_INDEX]);
192   return true;
193 }
194
195 // Read in from the contiguous data regions, put the data in 'buffer'
196 static inline bool read_data_region(vector<Address>& all_addr,
197                                     vector<long>& all_size,
198                                     vector<long>& all_disk,
199                                     unsigned long& data_len, Address& data_off,
200                                     Word *buffer, LDFILE *ldptr) {
201   unsigned index, max = all_disk.size();
202   Address max_adr = data_off + data_len;
203   assert(all_size.size() == all_addr.size());
204   assert(all_disk.size() == all_addr.size());
205   for (index=0; index<max; index++) {
206     if ((all_addr[index] >= data_off) &&
207         ((all_addr[index] + all_size[index]) <= max_adr)) {
208       if (ldfseek(ldptr, all_disk[index], SEEK_SET) == -1) return false;
209       Word *buf_temp = buffer + (all_addr[index] - data_off);
210       if (ldfread((void*) buf_temp, 1, all_size[index], ldptr) != all_size[index])
211         return false;
212     }
213   }
214   return true;
215 }
216
217 void Object::load_object(bool sharedLibrary) {
218     bool        success=true, text_read=false;
219     HDRR        sym_hdr;
220     pCHDRR      sym_tab_ptr = NULL;
221     long        index=0;
222     SYMR        symbol;
223     unsigned short sectindex=1;
224     SCNHDR      secthead;
225     unsigned    nsymbols;
226     vector<Symbol> allSymbols;
227     vector<Address> all_addr(9, 0);
228     vector<long> all_size(9, 0);
229     vector<bool> all_dex(9, false);
230     vector<long> all_disk(9, 0);
231
232         // Read the text and data sections
233         unsigned short fmax = fhdr.f_nscns;
234
235         dynamicallyLinked = false;
236
237         // Life would be so much easier if there were a guaranteed order for
238         // these sections.  But the man page makes no mention of it.
239         while (sectindex < fmax) {
240           if (ldshread(ldptr, sectindex, &secthead) == SUCCESS) {
241             // cout << "Section: " << secthead.s_name << "\tStart: " << secthead.s_vaddr 
242             // << "\tEnd: " << secthead.s_vaddr + secthead.s_size << endl;
243             sections_.push_back(new Dyn_Section(sectindex, secthead.s_name, secthead.s_vaddr, secthead.s_size));
244             if (!P_strcmp(secthead.s_name, ".text")) {
245               code_len_ = (Word) secthead.s_size;
246               Word *buffer = new Word[code_len_+1];
247               code_ptr_ = buffer;
248               code_off_ = (Address) secthead.s_vaddr;
249               if (!obj_read_section(secthead, ldptr, buffer)) {
250                 success = false;
251                 //bperr("failed text region\n");
252                 ldclose(ldptr);
253                 free(file);
254                 return;
255               }
256               text_read = true;
257             } else if (!P_strcmp(secthead.s_name, ".data")) {
258               if (secthead.s_vaddr && secthead.s_scnptr) {
259                 all_addr[K_D_INDEX] = secthead.s_vaddr;
260                 all_size[K_D_INDEX] = secthead.s_size;
261                 all_dex[K_D_INDEX] = true;
262                 all_disk[K_D_INDEX] = secthead.s_scnptr;
263               } else {
264                 //bperr("failed data region\n");
265                 success = false;
266                 ldclose(ldptr);
267                 free(file);
268                 return;
269               }
270             } else if (!P_strcmp(secthead.s_name, ".xdata")) {
271               if (secthead.s_vaddr && secthead.s_scnptr) {
272                 all_addr[K_XD_INDEX] = secthead.s_vaddr;
273                 all_size[K_XD_INDEX] = secthead.s_size;
274                 all_dex[K_XD_INDEX] = true;
275                 all_disk[K_XD_INDEX] = secthead.s_scnptr;
276               }
277             } else if (!P_strcmp(secthead.s_name, ".sdata")) {
278               if (secthead.s_vaddr && secthead.s_scnptr) {
279                 all_addr[K_SD_INDEX] = secthead.s_vaddr;
280                 all_size[K_SD_INDEX] = secthead.s_size;
281                 all_dex[K_SD_INDEX] = true;
282                 all_disk[K_SD_INDEX] = secthead.s_scnptr;
283               }
284             } else if (!P_strcmp(secthead.s_name, ".rdata")) {
285               if (secthead.s_vaddr && secthead.s_scnptr) {
286                 all_addr[K_RD_INDEX] = secthead.s_vaddr;
287                 all_size[K_RD_INDEX] = secthead.s_size;
288                 all_dex[K_RD_INDEX] = true;
289                 all_disk[K_RD_INDEX] = secthead.s_scnptr;
290               }
291             } else if (!P_strcmp(secthead.s_name, ".lit4")) {
292               if (secthead.s_vaddr && secthead.s_scnptr) {
293                 all_addr[K_L4_INDEX] = secthead.s_vaddr;
294                 all_size[K_L4_INDEX] = secthead.s_size;
295                 all_dex[K_L4_INDEX] = true;
296                 all_disk[K_L4_INDEX] = secthead.s_scnptr;
297               }
298             } else if (!P_strcmp(secthead.s_name, ".lita")) {
299               if (secthead.s_vaddr && secthead.s_scnptr) {
300                 all_addr[K_LA_INDEX] = secthead.s_vaddr;
301                 all_size[K_LA_INDEX] = secthead.s_size;
302                 all_dex[K_LA_INDEX] = true;
303                 all_disk[K_LA_INDEX] = secthead.s_scnptr;
304               }
305             } else if (!P_strcmp(secthead.s_name, ".rconst")) {
306               if (secthead.s_vaddr && secthead.s_scnptr) {
307                 all_addr[K_RC_INDEX] = secthead.s_vaddr;
308                 all_size[K_RC_INDEX] = secthead.s_size;
309                 all_dex[K_RC_INDEX] = true;
310                 all_disk[K_RC_INDEX] = secthead.s_scnptr;
311               }
312             } else if (!P_strcmp(secthead.s_name, ".lit8")) {
313               if (secthead.s_vaddr && secthead.s_scnptr) {
314                 all_addr[K_L8_INDEX] = secthead.s_vaddr;
315                 all_size[K_L8_INDEX] = secthead.s_size;
316                 all_dex[K_L8_INDEX] = true;
317                 all_disk[K_L8_INDEX] = secthead.s_scnptr;
318               }
319             } else if (!P_strncmp(secthead.s_name, ".dynamic", 8)) {
320               // a section .dynamic implies the program is dynamically linked
321               dynamicallyLinked = true; 
322             }
323           } else {
324             success = false;
325             //bperr("failed header region\n");
326             ldclose(ldptr);
327             free(file);
328             return;
329           }
330           sectindex++;
331         }
332         no_of_sections = sectindex;
333
334         if (!text_read) { 
335           success = false;
336           //bperr("failed text region\n");
337           ldclose(ldptr);
338           free(file);
339           return;
340         }
341
342         // I am assuming that .data comes before all other data sections
343         // I will include all other contiguous data sections
344         // Determine the size of the data section(s)
345         if (all_disk[K_D_INDEX]) {
346             if (!find_data_region(all_addr, all_size, all_disk,
347                                   data_len_, data_off_)) {
348               success = false;
349               //bperr("failed find data region\n");
350               ldclose(ldptr);
351               free(file);
352               return;
353             }
354         }
355
356         // Now read in the data from the assorted data regions
357         Word *buffer = new Word[data_len_+1];
358         data_ptr_ = buffer;
359         if (!read_data_region(all_addr, all_size, all_disk,
360                               data_len_, data_off_, buffer, ldptr)) {
361           success = false;
362           //bperr("failed read data region\n");
363           ldclose(ldptr);
364           free(file);
365           return;
366         }
367
368         // COFF doesn't have segments, so the entire code/data sections are valid
369         code_vldS_ = code_off_;
370         code_vldE_ = code_off_ + code_len_;
371         data_vldS_ = data_off_;
372         data_vldE_ = data_off_ + code_len_;
373
374         // Check for the symbol table
375         if (!(sym_tab_ptr = PSYMTAB(ldptr))) {
376             success = false;
377             //bperr("failed check for symbol table - object may be strip'd!\n");
378             ldclose(ldptr);
379             free(file);
380             return;
381         }
382
383         // Read the symbol table
384         sym_hdr = SYMHEADER(ldptr);
385         if (sym_hdr.magic != magicSym) {
386             success = false;
387             //bperr("failed check for magic symbol\n");
388             ldclose(ldptr);
389             free(file);
390             return;
391         }
392         if (!(sym_tab_ptr = SYMTAB(ldptr))) {
393             success = false;
394             //bperr("failed read symbol table\n");
395             ldclose(ldptr);
396             free(file);
397             return;
398         }
399         if (LDSWAP(ldptr)) {
400           // These bytes are swapped
401           // supposedly libsex.a will unswap them
402           assert(0);
403         }
404
405         string module = "DEFAULT_MODULE";
406    if (sharedLibrary) {
407       module = file_;
408       allSymbols.push_back(Symbol(module, module, Symbol::ST_MODULE, 
409                                   Symbol::SL_GLOBAL, (Address) 0, false,));
410         } else {
411       module = "DEFAULT_MODULE";
412         }
413
414    string name = "DEFAULT_SYMBOL";
415         int moduleEndIdx = -1;
416         map<string, int> fcnNames;
417
418         while (ldtbread(ldptr, index, &symbol) == SUCCESS) {
419           // TODO -- when global?
420           Symbol::SymbolLinkage linkage = Symbol::SL_GLOBAL;
421           Symbol::SymbolType type = Symbol::ST_UNKNOWN;
422           bool st_kludge = false;
423           bool sym_use = true;
424           unsigned secNumber;
425           char *name = ldgetname(ldptr, &symbol);
426           char prettyName[1024];
427
428         switch(symbol.st) {
429         case stProc:
430         case stStaticProc:
431                 // Native C++ name demangling.
432                 MLD_demangle_string(name, prettyName, 1024,
433                                     MLD_SHOW_DEMANGLED_NAME | MLD_NO_SPACES);
434                 if (strchr(prettyName, '('))
435                     *strchr(prettyName, '(') = 0;
436                 name = prettyName;
437
438                 if (symbol.sc == scText && (fcnNames.find(name)==fcnNames.end()))
439                 {
440                         type = Symbol::ST_FUNCTION;
441                         fcnNames[name] = 1;
442                         secNumber = findSecNumber(".text");
443                 }
444                 else 
445                         sym_use = false;
446                 break;
447
448         case stGlobal:
449         case stConstant:
450         case stStatic:
451                 switch(symbol.sc) {
452                 case scData:
453                         secNumber = findSecNumber(".data");
454                         type = Symbol::ST_OBJECT;
455                         break;
456                 case scBss:
457                         secNumber = findSecNumber(".bss");
458                         type = Symbol::ST_OBJECT;
459                         break;
460                 case scSData:
461                 case scSBss:
462                 case scRData:
463                 case scRConst:
464                 case scTlsData:
465                 case scTlsBss:
466                         secNumber = findSecNumber(".sdata");
467                         type = Symbol::ST_OBJECT;
468                         break;
469                 default:
470                         sym_use = false;
471                 }
472                 break;
473
474         case stLocal:
475         case stParam:
476                 linkage = Symbol::SL_LOCAL;
477
478                 switch(symbol.sc) {
479                 case scAbs:
480                 case scRegister:
481                 case scVar:
482                 case scVarRegister:
483                 case scUnallocated:
484                         secNumber = findSecNumber(".rdata");
485                         type = Symbol::ST_OBJECT;
486                         break;
487                 case scData:
488                         secNumber = findSecNumber(".data");
489                          //Parameter is static var. Don't know what to do
490                         if (symbol.st == stParam)
491                                 type = Symbol::ST_OBJECT;
492                         else
493                                 sym_use = false;
494                         break;
495                 case scSData:
496                 case scBss:
497                 case scSBss:
498                 case scRConst:
499                 case scRData:
500                         secNumber = findSecNumber(".rdata");
501                          //Parameter is static var. Don't know what to do
502                         if (symbol.st == stParam)
503                                 type = Symbol::ST_OBJECT;
504                         else
505                                 sym_use = false;
506                         break;
507
508                 default:
509                         sym_use = false;
510                 }
511                 break;
512
513         case stTypedef:
514         case stBase: //Base class
515         case stTag: //C++ class, structure or union
516                 secNumber = findSecNumber(".rdata");
517                 if (symbol.sc == scInfo)
518                         type = Symbol::ST_OBJECT;
519                 else
520                         sym_use = false;
521                 break;
522
523         case stFile:    
524                 secNumber = findSecNumber(".rdata");
525                 if (!sharedLibrary) {
526                         module = ldgetname(ldptr, &symbol); assert(module.length());
527                         type   = Symbol::ST_MODULE;
528                         moduleEndIdx = symbol.index - 1;
529                         //Detect the compiler type by searching libgcc.
530                         if (strstr(module.c_str(), "libgcc"))
531                                 GCC_COMPILED = true;
532                 }
533                 break;
534
535         case stLabel:
536                 // For stLabel/scText combinations, if the symbol address falls
537                 // within the text section and has a valid name, process it as
538                 // a function.
539                 if (symbol.sc == scText &&
540                     code_vldS_ <= (unsigned) symbol.value && (unsigned) symbol.value < code_vldE_ &&
541                     name && *name && (fcnNames.find(name)=fcnNames.end())) {
542                         // Native C++ name demangling.
543                         // Keep this in sync with stProc case above.
544                         
545                         secNumber = findSecNumber(".text");
546                         MLD_demangle_string(name, prettyName, 1024,
547                                             MLD_SHOW_DEMANGLED_NAME | MLD_NO_SPACES);
548                         if (strchr(prettyName, '('))
549                             *strchr(prettyName, '(') = 0;
550                         name = prettyName;
551
552                         type = Symbol::ST_FUNCTION;
553                         fcnNames[name] = 1;
554
555                 } else {
556                         sym_use = false;
557                 }
558                 break;
559
560         case stEnd:
561                 if (index == moduleEndIdx)
562                         module = "DEFAULT_MODULE";
563                 sym_use = false;
564                 break;
565
566         default:
567                 sym_use = false;
568         }
569
570         // Skip eCoff encoded stab string.  Functions and global variable
571         // addresses will still be found via the external symbols.
572         if (P_strchr(name, ':'))
573             sym_use = false;
574         
575         // cout << index << "\t" << name << "\t" << StName(symbol.st) << "\t" << ScName(symbol.sc) << "\t" << symbol.value << "\n";
576
577           index++;
578
579           if (sym_use) {
580             // cout << index << "\t" << module << "\t" << name << "\t" << type << "\t" << symbol.value << "\n";
581             allSymbols.push_back(Symbol(name, module, type, linkage,
582                                       (Address) symbol.value, st_kludge,secNumber));
583           }
584
585     } //while
586
587     sort(allSymbols.begin(),allSymbols.end(),symbol_compare());
588     // find the function boundaries
589     nsymbols = allSymbols.size();
590     no_of_symbols = nsymbols;
591
592     //Insert global symbols
593     for (unsigned u = 0; u < nsymbols; u++) {
594         unsigned size = 0;
595         if (allSymbols[u].type() == Symbol::ST_FUNCTION) {
596             unsigned v = u+1;
597             while (v < nsymbols) {
598                 // The .ef below is a special symbol that gcc puts in to
599                 // mark the end of a function.
600                 if (allSymbols[v].addr() != allSymbols[u].addr() &&
601                       (allSymbols[v].type() == Symbol::ST_FUNCTION ||
602                        allSymbols[v].name() == ".ef"))
603                 break;
604                 v++;
605             }
606             if (v < nsymbols) {
607                   size = (unsigned)allSymbols[v].addr()
608                          - (unsigned)allSymbols[u].addr();
609             } else {
610                 size = (unsigned)(code_off_+code_len_)
611                          - (unsigned)allSymbols[u].addr();
612             }
613         }
614         
615         if (allSymbols[u].linkage() != Symbol::SL_LOCAL) {
616                 symbols_[allSymbols[u].name()].push_back( 
617                         Symbol(allSymbols[u].name(), allSymbols[u].module(), 
618                         allSymbols[u].type(), allSymbols[u].linkage(), 
619                         allSymbols[u].addr(), allSymbols[u].kludge(), allSymbols[u].snumber(), size) ); 
620         }
621     }
622
623     //Insert local symbols (Do we need this?)
624     for (unsigned u = 0; u < nsymbols; u++) {
625         if ( (allSymbols[u].linkage() == Symbol::SL_LOCAL) &&
626                 (!symbols_.defines(allSymbols[u].name())) ) {
627                 symbols_[allSymbols[u].name()].push_back( 
628                         Symbol(allSymbols[u].name(), allSymbols[u].module(), 
629                         allSymbols[u].type(), allSymbols[u].linkage(), 
630                         allSymbols[u].addr(), allSymbols[u].kludge(), allSymbols[u].snumber(), 0) );
631         }
632     }
633                 
634     if (did_open && (ldclose(ldptr) == FAILURE)) {
635         log_perror(err_func_, "close");
636     }
637     free(file);
638
639 }
640
641
642 /*Object::Object(const string file, void (*err_func)(const char *))
643     : AObject(file, err_func) {
644     load_object(false);
645 }*/
646
647 /* 
648  * Called to init a shared library.
649  */
650 Object::Object (const string fileName, const Address /*BaseAddr*/,
651         void (*err_func)(const char *))
652   :AObject(fileName,err_func)
653 {
654
655   load_object(true);
656 }
657
658 Object::Object(const fDescriptor &desc, void (*err_func)(const char *))
659   : AObject(desc.file(), err_func) 
660  {
661      switch(desc.type)
662      {
663          case 1:                        //Has a filename
664          {
665              char* file = strdup(file_.c_str());
666              did_open = false;
667              ldptr = NULL;
668         
669              if (!(ldptr = ldopen(file, ldptr))) 
670              {
671                  log_perror(err_func_, file);
672                  success = false;
673                  //bperr("failed open\n");
674                  free(file);
675                  return;
676              }
677              did_open = true;
678
679              if (TYPE(ldptr) != ALPHAMAGIC) 
680              {
681                  //bperr( "%s is not an alpha executable\n", file);
682                  success = false;
683                  //bperr("failed magic region\n");
684                  ldclose(ldptr);
685                  free(file);
686                  return;
687              }
688
689              // Read the text and data sections
690              fhdr = HEADER(ldptr);
691              unsigned flags = fhdr.f_flags;
692              if(flags & F_EXEC )
693                  load_object(false);
694              else
695                  load_object(true);
696        }
697        case 2:                  //mem image todo
698        {
699        }
700        default:
701        {        
702              log_perror(err_func_, "ELF header");
703              return;
704              break;
705         }
706    }    
707  
708    load_object(desc.isSharedObject());
709 }
710
711 Object::Object(const Object& obj)
712     : AObject(obj) {
713     load_object(false);
714 }
715
716 void Dyn_Symtab::getModuleLanguageInfo(dyn_hash_map<string, supportedLanguages> *)
717 {
718 }