Object-coff.C

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030 
00031 // $Id: Object-coff.C,v 1.6 2008/06/19 19:54:11 legendre Exp $
00032 
00033 #include "common/h/Dictionary.h"
00034 #include "Object.h"
00035 #include "Object-coff.h"
00036 #include <cmplrs/demangle_string.h>  // For native C++ (cxx) name demangling.
00037 
00038 bool GCC_COMPILED=false; //Used to detect compiler type. True if mutatee is 
00039              //compiled with a GNU compiler. parseCoff.C needs this
00040 
00041 /* ScName() and StName() used for debugging only.
00042 
00043 const char *StName(int st)
00044 {
00045     switch (st) {
00046     case stNil:     return "stNil";
00047     case stGlobal:      return "stGlobal";
00048     case stStatic:      return "stStatic";
00049     case stParam:       return "stParam";
00050     case stLocal:       return "stLocal";
00051     case stLabel:       return "stLabel";
00052     case stProc:        return "stProc";
00053     case stBlock:       return "stBlock";
00054     case stEnd:     return "stEnd";
00055     case stMember:      return "stMember";
00056     case stTypedef:     return "stTypedef";
00057     case stFile:        return "stFile";
00058     case stRegReloc:    return "stRegReloc";
00059     case stForward:     return "stForward";
00060     case stStaticProc:  return "stStaticProc";
00061     case stConstant:    return "stConstant";
00062     case stStaParam:    return "stStaParam";
00063     case stBase:        return "stBase";
00064     case stVirtBase:    return "stVirtBase";
00065     case stTag:     return "stTag";
00066     case stInter:       return "stInter";
00067     case stSplit:       return "stSplit";
00068     case stModule:      return "stModule";
00069     case stModview:     return "stModview";
00070     case stAlias:       return "stAlias";
00071     case stStr:     return "stStr";
00072     case stNumber:      return "stNumber";
00073     case stExpr:        return "stExpr";
00074     case stType:        return "stType";
00075     }
00076     return "Bad St";
00077 }
00078 
00079 const char *ScName(int sc)
00080 {
00081     switch (sc) {
00082     case scNil:     return "scNil";
00083     case scText:        return "scText";
00084     case scData:        return "scData";
00085     case scBss:     return "scBss";
00086     case scRegister:    return "scRegister";
00087     case scAbs:     return "scAbs";
00088     case scUndefined:   return "scUndefined";
00089     case scUnallocated: return "scUnallocated";
00090     case scBits:        return "scBits";
00091     case scTlsUndefined:    return "scTlsUndefined";
00092     case scRegImage:    return "scRegImage";
00093     case scInfo:        return "scInfo";
00094     case scUserStruct:  return "scUserStruct";
00095     case scSData:       return "scSData";
00096     case scSBss:        return "scSBss";
00097     case scRData:       return "scRData";
00098     case scVar:     return "scVar";
00099     case scCommon:      return "scCommon";
00100     case scSCommon:     return "scSCommon";
00101     case scVarRegister: return "scVarRegister";
00102     case scVariant:     return "scVariant";
00103     case scSUndefined:  return "scSUndefined";
00104     case scInit:        return "scInit";
00105     case scBasedVar:    return "scBasedVar";
00106     case scXData:       return "scXData";
00107     case scPData:       return "scPData";
00108     case scFini:        return "scFini";
00109     case scRConst:      return "scRConst";
00110     case scSymRef:      return "scSymRef";
00111     case scTlsCommon:   return "scTlsCommon";
00112     case scTlsData:     return "scTlsData";
00113     case scTlsBss:      return "scTlsBss";
00114     }
00115     return "Bad Sc";
00116 }
00117 */
00118 
00119 static inline bool obj_read_section(SCNHDR& secthead, LDFILE *ldptr,
00120                     Word *buffer) {
00121   if (!secthead.s_scnptr) return false;
00122   if (ldfseek(ldptr, secthead.s_scnptr, SEEK_SET) == -1) return false;
00123 
00124   if (ldfread((void*) buffer, 1, secthead.s_size, ldptr) != secthead.s_size)
00125     return false;
00126   else
00127     return true;
00128 }
00129 
00130 // The possible data sections
00131 // These should only be used locally
00132 #define K_D_INDEX    0
00133 #define K_XD_INDEX   1
00134 #define K_PD_INDEX   2
00135 #define K_SD_INDEX   3
00136 #define K_RD_INDEX   4
00137 #define K_RC_INDEX   5 
00138 #define K_L4_INDEX   6
00139 #define K_L8_INDEX   7
00140 #define K_LA_INDEX   8
00141 
00142 // Attempt to find the largest contiguous (in virtual address space) region.
00143 // This region must include ".data", and may include the other data like regions
00144 static inline bool find_data_region(vector<Address>& all_addr,
00145                     vector<long>& all_size,
00146                     vector<long>& all_disk,
00147                     unsigned long& data_len, Address& data_off) {
00148   // Start at data and work back
00149   assert(all_addr[K_D_INDEX]); assert(all_size[K_D_INDEX]);
00150   assert(all_addr.size() == all_size.size());
00151 
00152   Address current = all_addr[K_D_INDEX];
00153   Address min_adr = current;
00154   Address max_adr = current + all_size[K_D_INDEX];
00155 
00156   unsigned index, max=all_addr.size();
00157 
00158   bool updated=true;
00159   while (updated) {
00160     updated = false;
00161     for (index=0; index<max; index++) {
00162       if (all_addr[index] && all_size[index] && all_disk[index] &&
00163       ((all_addr[index] + all_size[index]) == current)) {
00164     current = all_addr[index];
00165     updated = true;
00166       }
00167     }
00168   }
00169   min_adr = current;
00170 
00171   // Start at data and work forward
00172   current = max_adr;
00173   updated=true;
00174   while (updated) {
00175     updated = false;
00176     for (index=0; index<max; index++) {
00177       if (all_addr[index] && all_size[index] && all_disk[index] && 
00178       (all_addr[index] == current)) {
00179     current = all_addr[index] + all_size[index];
00180     updated = true;
00181       }
00182     }
00183   }
00184 
00185   max_adr = current;
00186   
00187   data_len = (max_adr - min_adr);
00188   data_off = min_adr;
00189   assert(min_adr <= all_addr[K_D_INDEX]);
00190   assert(max_adr >= all_addr[K_D_INDEX] + all_size[K_D_INDEX]);
00191   return true;
00192 }
00193 
00194 // Read in from the contiguous data regions, put the data in 'buffer'
00195 static inline bool read_data_region(vector<Address>& all_addr,
00196                     vector<long>& all_size,
00197                     vector<long>& all_disk,
00198                     unsigned long& data_len, Address& data_off,
00199                     Word *buffer, LDFILE *ldptr) {
00200   unsigned index, max = all_disk.size();
00201   Address max_adr = data_off + data_len;
00202   assert(all_size.size() == all_addr.size());
00203   assert(all_disk.size() == all_addr.size());
00204   for (index=0; index<max; index++) {
00205     if ((all_addr[index] >= data_off) &&
00206     ((all_addr[index] + all_size[index]) <= max_adr)) {
00207       if (ldfseek(ldptr, all_disk[index], SEEK_SET) == -1) return false;
00208       Word *buf_temp = buffer + (all_addr[index] - data_off);
00209       if (ldfread((void*) buf_temp, 1, all_size[index], ldptr) != all_size[index])
00210     return false;
00211     }
00212   }
00213   return true;
00214 }
00215 
00216 void Object::load_object(bool sharedLibrary) {
00217     bool        success=true, text_read=false;
00218     HDRR        sym_hdr;
00219     pCHDRR      sym_tab_ptr = NULL;
00220     long        index=0;
00221     SYMR        symbol;
00222     unsigned short sectindex=1;
00223     SCNHDR      secthead;
00224     unsigned    nsymbols;
00225     vector<Symbol> allSymbols;
00226     vector<Address> all_addr(9, 0);
00227     vector<long> all_size(9, 0);
00228     vector<bool> all_dex(9, false);
00229     vector<long> all_disk(9, 0);
00230 
00231     // Read the text and data sections
00232     unsigned short fmax = fhdr.f_nscns;
00233 
00234     dynamicallyLinked = false;
00235 
00236     // Life would be so much easier if there were a guaranteed order for
00237     // these sections.  But the man page makes no mention of it.
00238     while (sectindex < fmax) {
00239       if (ldshread(ldptr, sectindex, &secthead) == SUCCESS) {
00240         // cout << "Section: " << secthead.s_name << "\tStart: " << secthead.s_vaddr 
00241         // << "\tEnd: " << secthead.s_vaddr + secthead.s_size << endl;
00242         sections_.push_back(new Dyn_Section(sectindex, secthead.s_name, secthead.s_vaddr, secthead.s_size));
00243         if (!P_strcmp(secthead.s_name, ".text")) {
00244           code_len_ = (Word) secthead.s_size;
00245           Word *buffer = new Word[code_len_+1];
00246           code_ptr_ = buffer;
00247           code_off_ = (Address) secthead.s_vaddr;
00248           if (!obj_read_section(secthead, ldptr, buffer)) {
00249         success = false;
00250         //bperr("failed text region\n");
00251         ldclose(ldptr);
00252         free(file);
00253         return;
00254           }
00255           text_read = true;
00256         } else if (!P_strcmp(secthead.s_name, ".data")) {
00257           if (secthead.s_vaddr && secthead.s_scnptr) {
00258         all_addr[K_D_INDEX] = secthead.s_vaddr;
00259         all_size[K_D_INDEX] = secthead.s_size;
00260         all_dex[K_D_INDEX] = true;
00261         all_disk[K_D_INDEX] = secthead.s_scnptr;
00262           } else {
00263         //bperr("failed data region\n");
00264         success = false;
00265         ldclose(ldptr);
00266         free(file);
00267         return;
00268           }
00269         } else if (!P_strcmp(secthead.s_name, ".xdata")) {
00270           if (secthead.s_vaddr && secthead.s_scnptr) {
00271         all_addr[K_XD_INDEX] = secthead.s_vaddr;
00272         all_size[K_XD_INDEX] = secthead.s_size;
00273         all_dex[K_XD_INDEX] = true;
00274         all_disk[K_XD_INDEX] = secthead.s_scnptr;
00275           }
00276         } else if (!P_strcmp(secthead.s_name, ".sdata")) {
00277           if (secthead.s_vaddr && secthead.s_scnptr) {
00278         all_addr[K_SD_INDEX] = secthead.s_vaddr;
00279         all_size[K_SD_INDEX] = secthead.s_size;
00280         all_dex[K_SD_INDEX] = true;
00281         all_disk[K_SD_INDEX] = secthead.s_scnptr;
00282           }
00283         } else if (!P_strcmp(secthead.s_name, ".rdata")) {
00284           if (secthead.s_vaddr && secthead.s_scnptr) {
00285         all_addr[K_RD_INDEX] = secthead.s_vaddr;
00286         all_size[K_RD_INDEX] = secthead.s_size;
00287         all_dex[K_RD_INDEX] = true;
00288         all_disk[K_RD_INDEX] = secthead.s_scnptr;
00289           }
00290         } else if (!P_strcmp(secthead.s_name, ".lit4")) {
00291           if (secthead.s_vaddr && secthead.s_scnptr) {
00292         all_addr[K_L4_INDEX] = secthead.s_vaddr;
00293         all_size[K_L4_INDEX] = secthead.s_size;
00294         all_dex[K_L4_INDEX] = true;
00295         all_disk[K_L4_INDEX] = secthead.s_scnptr;
00296           }
00297         } else if (!P_strcmp(secthead.s_name, ".lita")) {
00298           if (secthead.s_vaddr && secthead.s_scnptr) {
00299         all_addr[K_LA_INDEX] = secthead.s_vaddr;
00300         all_size[K_LA_INDEX] = secthead.s_size;
00301         all_dex[K_LA_INDEX] = true;
00302         all_disk[K_LA_INDEX] = secthead.s_scnptr;
00303           }
00304         } else if (!P_strcmp(secthead.s_name, ".rconst")) {
00305           if (secthead.s_vaddr && secthead.s_scnptr) {
00306         all_addr[K_RC_INDEX] = secthead.s_vaddr;
00307         all_size[K_RC_INDEX] = secthead.s_size;
00308         all_dex[K_RC_INDEX] = true;
00309         all_disk[K_RC_INDEX] = secthead.s_scnptr;
00310           }
00311         } else if (!P_strcmp(secthead.s_name, ".lit8")) {
00312           if (secthead.s_vaddr && secthead.s_scnptr) {
00313         all_addr[K_L8_INDEX] = secthead.s_vaddr;
00314         all_size[K_L8_INDEX] = secthead.s_size;
00315         all_dex[K_L8_INDEX] = true;
00316         all_disk[K_L8_INDEX] = secthead.s_scnptr;
00317           }
00318         } else if (!P_strncmp(secthead.s_name, ".dynamic", 8)) {
00319           // a section .dynamic implies the program is dynamically linked
00320           dynamicallyLinked = true; 
00321         }
00322       } else {
00323         success = false;
00324         //bperr("failed header region\n");
00325         ldclose(ldptr);
00326         free(file);
00327         return;
00328       }
00329       sectindex++;
00330     }
00331     no_of_sections = sectindex;
00332 
00333     if (!text_read) { 
00334       success = false;
00335       //bperr("failed text region\n");
00336       ldclose(ldptr);
00337       free(file);
00338       return;
00339     }
00340 
00341     // I am assuming that .data comes before all other data sections
00342     // I will include all other contiguous data sections
00343     // Determine the size of the data section(s)
00344     if (all_disk[K_D_INDEX]) {
00345         if (!find_data_region(all_addr, all_size, all_disk,
00346                                   data_len_, data_off_)) {
00347           success = false;
00348           //bperr("failed find data region\n");
00349           ldclose(ldptr);
00350           free(file);
00351           return;
00352         }
00353     }
00354 
00355     // Now read in the data from the assorted data regions
00356     Word *buffer = new Word[data_len_+1];
00357     data_ptr_ = buffer;
00358     if (!read_data_region(all_addr, all_size, all_disk,
00359                   data_len_, data_off_, buffer, ldptr)) {
00360       success = false;
00361           //bperr("failed read data region\n");
00362       ldclose(ldptr);
00363       free(file);
00364       return;
00365     }
00366 
00367     // COFF doesn't have segments, so the entire code/data sections are valid
00368     code_vldS_ = code_off_;
00369     code_vldE_ = code_off_ + code_len_;
00370     data_vldS_ = data_off_;
00371     data_vldE_ = data_off_ + code_len_;
00372 
00373         // Check for the symbol table
00374     if (!(sym_tab_ptr = PSYMTAB(ldptr))) {
00375         success = false;
00376             //bperr("failed check for symbol table - object may be strip'd!\n");
00377         ldclose(ldptr);
00378         free(file);
00379         return;
00380     }
00381 
00382     // Read the symbol table
00383     sym_hdr = SYMHEADER(ldptr);
00384     if (sym_hdr.magic != magicSym) {
00385         success = false;
00386             //bperr("failed check for magic symbol\n");
00387         ldclose(ldptr);
00388         free(file);
00389         return;
00390         }
00391     if (!(sym_tab_ptr = SYMTAB(ldptr))) {
00392         success = false;
00393             //bperr("failed read symbol table\n");
00394         ldclose(ldptr);
00395         free(file);
00396         return;
00397     }
00398     if (LDSWAP(ldptr)) {
00399       // These bytes are swapped
00400       // supposedly libsex.a will unswap them
00401       assert(0);
00402     }
00403 
00404     string module = "DEFAULT_MODULE";
00405    if (sharedLibrary) {
00406       module = file_;
00407       allSymbols.push_back(Symbol(module, module, Symbol::ST_MODULE, 
00408                                   Symbol::SL_GLOBAL, (Address) 0, false,));
00409     } else {
00410       module = "DEFAULT_MODULE";
00411     }
00412 
00413    string name = "DEFAULT_SYMBOL";
00414     int moduleEndIdx = -1;
00415     map<string, int> fcnNames;
00416 
00417     while (ldtbread(ldptr, index, &symbol) == SUCCESS) {
00418       // TODO -- when global?
00419       Symbol::SymbolLinkage linkage = Symbol::SL_GLOBAL;
00420       Symbol::SymbolType type = Symbol::ST_UNKNOWN;
00421       bool st_kludge = false;
00422       bool sym_use = true;
00423       unsigned secNumber;
00424       char *name = ldgetname(ldptr, &symbol);
00425       char prettyName[1024];
00426 
00427     switch(symbol.st) {
00428     case stProc:
00429     case stStaticProc:
00430         // Native C++ name demangling.
00431         MLD_demangle_string(name, prettyName, 1024,
00432                     MLD_SHOW_DEMANGLED_NAME | MLD_NO_SPACES);
00433         if (strchr(prettyName, '('))
00434             *strchr(prettyName, '(') = 0;
00435         name = prettyName;
00436 
00437         if (symbol.sc == scText && (fcnNames.find(name)==fcnNames.end()))
00438         {
00439             type = Symbol::ST_FUNCTION;
00440             fcnNames[name] = 1;
00441             secNumber = findSecNumber(".text");
00442         }
00443         else 
00444             sym_use = false;
00445         break;
00446 
00447     case stGlobal:
00448     case stConstant:
00449     case stStatic:
00450         switch(symbol.sc) {
00451         case scData:
00452             secNumber = findSecNumber(".data");
00453             type = Symbol::ST_OBJECT;
00454             break;
00455         case scBss:
00456             secNumber = findSecNumber(".bss");
00457             type = Symbol::ST_OBJECT;
00458             break;
00459         case scSData:
00460         case scSBss:
00461         case scRData:
00462         case scRConst:
00463         case scTlsData:
00464         case scTlsBss:
00465             secNumber = findSecNumber(".sdata");
00466             type = Symbol::ST_OBJECT;
00467             break;
00468         default:
00469             sym_use = false;
00470         }
00471         break;
00472 
00473     case stLocal:
00474     case stParam:
00475         linkage = Symbol::SL_LOCAL;
00476 
00477         switch(symbol.sc) {
00478         case scAbs:
00479         case scRegister:
00480         case scVar:
00481         case scVarRegister:
00482         case scUnallocated:
00483             secNumber = findSecNumber(".rdata");
00484             type = Symbol::ST_OBJECT;
00485             break;
00486         case scData:
00487             secNumber = findSecNumber(".data");
00488              //Parameter is static var. Don't know what to do
00489             if (symbol.st == stParam)
00490                 type = Symbol::ST_OBJECT;
00491             else
00492                 sym_use = false;
00493             break;
00494         case scSData:
00495         case scBss:
00496         case scSBss:
00497         case scRConst:
00498         case scRData:
00499             secNumber = findSecNumber(".rdata");
00500              //Parameter is static var. Don't know what to do
00501             if (symbol.st == stParam)
00502                 type = Symbol::ST_OBJECT;
00503             else
00504                 sym_use = false;
00505             break;
00506 
00507         default:
00508             sym_use = false;
00509         }
00510         break;
00511 
00512     case stTypedef:
00513     case stBase: //Base class
00514     case stTag: //C++ class, structure or union
00515         secNumber = findSecNumber(".rdata");
00516         if (symbol.sc == scInfo)
00517             type = Symbol::ST_OBJECT;
00518         else
00519             sym_use = false;
00520         break;
00521 
00522     case stFile:    
00523         secNumber = findSecNumber(".rdata");
00524         if (!sharedLibrary) {
00525             module = ldgetname(ldptr, &symbol); assert(module.length());
00526             type   = Symbol::ST_MODULE;
00527             moduleEndIdx = symbol.index - 1;
00528             //Detect the compiler type by searching libgcc.
00529             if (strstr(module.c_str(), "libgcc"))
00530                 GCC_COMPILED = true;
00531         }
00532         break;
00533 
00534     case stLabel:
00535         // For stLabel/scText combinations, if the symbol address falls
00536         // within the text section and has a valid name, process it as
00537         // a function.
00538         if (symbol.sc == scText &&
00539             code_vldS_ <= (unsigned) symbol.value && (unsigned) symbol.value < code_vldE_ &&
00540             name && *name && (fcnNames.find(name)=fcnNames.end())) {
00541             // Native C++ name demangling.
00542                 // Keep this in sync with stProc case above.
00543             
00544             secNumber = findSecNumber(".text");
00545             MLD_demangle_string(name, prettyName, 1024,
00546                         MLD_SHOW_DEMANGLED_NAME | MLD_NO_SPACES);
00547             if (strchr(prettyName, '('))
00548                 *strchr(prettyName, '(') = 0;
00549             name = prettyName;
00550 
00551             type = Symbol::ST_FUNCTION;
00552             fcnNames[name] = 1;
00553 
00554         } else {
00555             sym_use = false;
00556         }
00557         break;
00558 
00559     case stEnd:
00560         if (index == moduleEndIdx)
00561             module = "DEFAULT_MODULE";
00562         sym_use = false;
00563         break;
00564 
00565     default:
00566         sym_use = false;
00567     }
00568 
00569     // Skip eCoff encoded stab string.  Functions and global variable
00570     // addresses will still be found via the external symbols.
00571     if (P_strchr(name, ':'))
00572         sym_use = false;
00573     
00574     // cout << index << "\t" << name << "\t" << StName(symbol.st) << "\t" << ScName(symbol.sc) << "\t" << symbol.value << "\n";
00575 
00576       index++;
00577 
00578       if (sym_use) {
00579         // cout << index << "\t" << module << "\t" << name << "\t" << type << "\t" << symbol.value << "\n";
00580         allSymbols.push_back(Symbol(name, module, type, linkage,
00581                       (Address) symbol.value, st_kludge,secNumber));
00582       }
00583 
00584     } //while
00585 
00586     sort(allSymbols.begin(),allSymbols.end(),symbol_compare());
00587     // find the function boundaries
00588     nsymbols = allSymbols.size();
00589     no_of_symbols = nsymbols;
00590 
00591     //Insert global symbols
00592     for (unsigned u = 0; u < nsymbols; u++) {
00593     unsigned size = 0;
00594     if (allSymbols[u].type() == Symbol::ST_FUNCTION) {
00595         unsigned v = u+1;
00596         while (v < nsymbols) {
00597         // The .ef below is a special symbol that gcc puts in to
00598                 // mark the end of a function.
00599                 if (allSymbols[v].addr() != allSymbols[u].addr() &&
00600                       (allSymbols[v].type() == Symbol::ST_FUNCTION ||
00601                        allSymbols[v].name() == ".ef"))
00602                 break;
00603                 v++;
00604             }
00605         if (v < nsymbols) {
00606                   size = (unsigned)allSymbols[v].addr()
00607                          - (unsigned)allSymbols[u].addr();
00608         } else {
00609                 size = (unsigned)(code_off_+code_len_)
00610                          - (unsigned)allSymbols[u].addr();
00611         }
00612     }
00613     
00614     if (allSymbols[u].linkage() != Symbol::SL_LOCAL) {
00615         symbols_[allSymbols[u].name()].push_back( 
00616             Symbol(allSymbols[u].name(), allSymbols[u].module(), 
00617                 allSymbols[u].type(), allSymbols[u].linkage(), 
00618                 allSymbols[u].addr(), allSymbols[u].kludge(), allSymbols[u].snumber(), size) ); 
00619     }
00620     }
00621 
00622     //Insert local symbols (Do we need this?)
00623     for (unsigned u = 0; u < nsymbols; u++) {
00624     if ( (allSymbols[u].linkage() == Symbol::SL_LOCAL) &&
00625         (!symbols_.defines(allSymbols[u].name())) ) {
00626         symbols_[allSymbols[u].name()].push_back( 
00627             Symbol(allSymbols[u].name(), allSymbols[u].module(), 
00628                 allSymbols[u].type(), allSymbols[u].linkage(), 
00629                 allSymbols[u].addr(), allSymbols[u].kludge(), allSymbols[u].snumber(), 0) );
00630     }
00631     }
00632         
00633     if (did_open && (ldclose(ldptr) == FAILURE)) {
00634         log_perror(err_func_, "close");
00635     }
00636     free(file);
00637 
00638 }
00639 
00640 
00641 /*Object::Object(const string file, void (*err_func)(const char *))
00642     : AObject(file, err_func) {
00643     load_object(false);
00644 }*/
00645 
00646 /* 
00647  * Called to init a shared library.
00648  */
00649 Object::Object (const string fileName, const Address /*BaseAddr*/,
00650         void (*err_func)(const char *))
00651   :AObject(fileName,err_func)
00652 {
00653 
00654   load_object(true);
00655 }
00656 
00657 Object::Object(const fDescriptor &desc, void (*err_func)(const char *))
00658   : AObject(desc.file(), err_func) 
00659  {
00660      switch(desc.type)
00661      {
00662          case 1:            //Has a filename
00663          {
00664          char* file = strdup(file_.c_str());
00665              did_open = false;
00666              ldptr = NULL;
00667     
00668              if (!(ldptr = ldopen(file, ldptr))) 
00669          {
00670                  log_perror(err_func_, file);
00671          success = false;
00672              //bperr("failed open\n");
00673              free(file);
00674              return;
00675              }
00676              did_open = true;
00677 
00678          if (TYPE(ldptr) != ALPHAMAGIC) 
00679          {
00680              //bperr( "%s is not an alpha executable\n", file);
00681              success = false;
00682              //bperr("failed magic region\n");
00683              ldclose(ldptr);
00684              free(file);
00685              return;
00686              }
00687 
00688          // Read the text and data sections
00689          fhdr = HEADER(ldptr);
00690          unsigned flags = fhdr.f_flags;
00691          if(flags & F_EXEC )
00692              load_object(false);
00693          else
00694              load_object(true);
00695        }
00696        case 2:          //mem image todo
00697        {
00698        }
00699        default:
00700        {    
00701              log_perror(err_func_, "ELF header");
00702          return;
00703          break;
00704         }
00705    }    
00706  
00707    load_object(desc.isSharedObject());
00708 }
00709 
00710 Object::Object(const Object& obj)
00711     : AObject(obj) {
00712     load_object(false);
00713 }
00714 
00715 void Dyn_Symtab::getModuleLanguageInfo(dyn_hash_map<string, supportedLanguages> *)
00716 {
00717 }
00718 
00719 bool Region::isStandardCode()
00720 {
00721    return (getRegionPermissions() == RP_RX ||
00722            getRegionPermissions() == RP_RWX);
00723 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1