Archive-xcoff.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 
00032 #include "symtabAPI/h/Symtab.h"
00033 #include "symtabAPI/h/Archive.h"
00034 #include "symtabAPI/src/Object.h"
00035 
00036 using namespace Dyninst;
00037 using namespace Dyninst::SymtabAPI;
00038 
00039 extern char errorLine[];
00040 
00041 Archive::Archive(std::string &filename, bool &ok) :
00042    basePtr(NULL), symbolTableParsed(false)
00043 {
00044    mf  = MappedFile::createMappedFile(filename);
00045    if( mf == NULL ) {
00046        serr = Not_A_File;
00047        errMsg = "Failed to locate file";
00048        ok = false;
00049        return;
00050    }
00051    fileOpener *fo_ = fileOpener::openFile(mf->base_addr(), mf->size());
00052    fo_->set_file(mf->filename());
00053 
00054    assert(fo_);
00055     unsigned char magic_number[2];
00056     
00057    if (!fo_->set(0)) 
00058     {
00059       sprintf(errorLine, "Error reading file %s\n", 
00060               filename.c_str());
00061         serr = Obj_Parsing;
00062         errMsg = errorLine;
00063         ok = false;
00064       fprintf(stderr, "%s[%d]:  error in Archive ctor\n", FILE__, __LINE__);
00065       //MappedFile::closeMappedFile(mf);
00066       return;
00067    }
00068    if (!fo_->read((void *)magic_number, 2)) 
00069     {
00070       sprintf(errorLine, "Error reading file %s\n", 
00071               filename.c_str());
00072         serr = Obj_Parsing;
00073         errMsg = errorLine;
00074         ok = false;
00075       fprintf(stderr, "%s[%d]:  error in Archive ctor\n", FILE__, __LINE__);
00076       //MappedFile::closeMappedFile(mf);
00077       return;
00078    }
00079 
00080    // a.out file: magic number = 0x01df
00081    // archive file: magic number = 0x3c62 "<b", actually "<bigaf>"
00082    // or magic number = "<a", actually "<aiaff>"
00083    if (magic_number[0] == 0x01)
00084     {
00085         serr = Not_An_Archive;
00086       sprintf(errorLine, "Not an Archive. Call Symtab::openFile"); 
00087         errMsg = errorLine;
00088         ok = false;
00089       //fprintf(stderr, "%s[%d]:  error in Archive ctor\n", FILE__, __LINE__);
00090       //MappedFile::closeMappedFile(mf);
00091         return;
00092     }
00093    else if ( magic_number[0] != '<')
00094     {
00095       sprintf(errorLine, "Bad magic number in file %s\n",
00096               filename.c_str());
00097         serr = Obj_Parsing;
00098         errMsg = errorLine;
00099         ok = false;
00100       fprintf(stderr, "%s[%d]:  error in Archive ctor\n", FILE__, __LINE__);
00101      // MappedFile::closeMappedFile(mf);
00102         return;
00103    }
00104     xcoffArchive *archive = NULL;
00105     
00106    // Determine archive type
00107    // Start at the beginning...
00108    if (!fo_->set(0))
00109     {
00110       sprintf(errorLine, "Error parsing a.out file %s: %s \n",
00111               filename.c_str(), "Seeking to file start" );  
00112         serr = Obj_Parsing;
00113         errMsg = errorLine;
00114       fprintf(stderr, "%s[%d]:  error in Archive ctor\n", FILE__, __LINE__);
00115         ok = false;
00116     }                        
00117 
00118    char magicNumber[SAIAMAG];
00119    if (!fo_->read(magicNumber, SAIAMAG))
00120     {
00121         sprintf(errorLine, "Error parsing a.out file %s: %s \n",
00122               filename.c_str(), "Reading magic number" );
00123         serr = Obj_Parsing;
00124         errMsg = errorLine;
00125       fprintf(stderr, "%s[%d]:  error in Archive ctor\n", FILE__, __LINE__);
00126         ok = false;
00127     }   
00128 
00129    if (!strncmp(magicNumber, AIAMAG, SAIAMAG))
00130       archive = (xcoffArchive *) new xcoffArchive_32(fo_);
00131    else if (!strncmp(magicNumber, AIAMAGBIG, SAIAMAG))
00132       archive = (xcoffArchive *) new xcoffArchive_64(fo_);
00133    else
00134     {
00135         sprintf(errorLine, "Error parsing a.out file %s: %s \n",
00136               filename.c_str(), "Unknown Magic number" );
00137         serr = Obj_Parsing;
00138         errMsg = errorLine;
00139       fprintf(stderr, "%s[%d]:  error in Archive ctor\n", FILE__, __LINE__);
00140         ok = false;
00141     }   
00142     
00143    if (archive->read_arhdr())
00144     {
00145         sprintf(errorLine, "Error parsing a.out file %s: %s \n",
00146               filename.c_str(), "Reading file header" );
00147         serr = Obj_Parsing;
00148         errMsg = errorLine;
00149       fprintf(stderr, "%s[%d]:  error in Archive ctor\n", FILE__, __LINE__);
00150         ok = false;
00151     }   
00152     
00153    while (archive->next_offset !=0)
00154    {
00155       if (archive->read_mbrhdr())
00156       {
00157          sprintf(errorLine, "Error parsing a.out file %s: %s \n",
00158                filename.c_str(), "Reading Member Header" );
00159          serr = Obj_Parsing;
00160          errMsg = errorLine;
00161          fprintf(stderr, "%s[%d]:  error in Archive ctor\n", FILE__, __LINE__);
00162          ok = false;
00163       } 
00164 
00165       std::string member_name = archive->member_name;
00166       std::string::size_type len = member_name.length();
00167       if ((len >= 4)&&(member_name.substr(len-4,4) == ".imp" || 
00168                member_name.substr(len-4,4) == ".exp"))
00169          continue;
00170 
00171       // Member is parsed lazily
00172       ArchiveMember *newMember = new ArchiveMember(member_name, archive->aout_offset);
00173       membersByOffset[archive->aout_offset] = newMember;
00174       membersByName[member_name] = newMember;
00175    }    
00176 
00177    //  why do we close the file mapping??  I must be missing something
00178 #if 0 
00179    if (mf)
00180       MappedFile::closeMappedFile(mf);
00181    delete archive;
00182    mf = NULL;
00183 #endif
00184 
00185    ok = true;
00186 }
00187 
00188 Archive::Archive(char *mem_image, size_t size, bool &err)
00189     : basePtr(NULL), symbolTableParsed(false)
00190 {
00191     mf  = MappedFile::createMappedFile(mem_image, size);
00192     fileOpener *fo_ = fileOpener::openFile(mf->base_addr(), mf->size());
00193 
00194     assert(fo_);
00195     unsigned char magic_number[2];
00196 
00197     if (!fo_->set(0)) 
00198     {
00199         sprintf(errorLine, "Error reading memory image %p with size %u\n",
00200                 mem_image, (unsigned int)size);
00201         serr = Obj_Parsing;
00202         errMsg = errorLine;
00203         err = false;
00204         return;
00205     }
00206     if (!fo_->read((void *)magic_number, 2)) 
00207     {
00208         sprintf(errorLine, "Error reading memory image %p with size %u\n",
00209                 mem_image, (unsigned int)size);
00210         serr = Obj_Parsing;
00211         errMsg = errorLine;
00212         err = false;
00213         return;
00214     }
00215 
00216     // a.out file: magic number = 0x01df
00217     // archive file: magic number = 0x3c62 "<b", actually "<bigaf>"
00218     // or magic number = "<a", actually "<aiaff>"
00219     if (magic_number[0] == 0x01)
00220     {
00221         serr = Not_An_Archive;
00222         sprintf(errorLine, "Not an Archive. Call Symtab::openFile"); 
00223         errMsg = errorLine;
00224         err = false;
00225         return;
00226     }
00227     else if ( magic_number[0] != '<')
00228     {
00229         sprintf(errorLine, "Error reading memory image %p with size %u\n",
00230                 mem_image, (unsigned int)size);
00231         serr = Obj_Parsing;
00232         errMsg = errorLine;
00233         err = false;
00234         return;
00235     }
00236     xcoffArchive *archive = NULL;
00237 
00238     // Determine archive type
00239     // Start at the beginning...
00240     if (!fo_->set(0))
00241     {
00242         sprintf(errorLine, "Error parsing memory image %p with size %u : %s\n",
00243                 mem_image, (unsigned int)size, "Seeking to file start");
00244         serr = Obj_Parsing;
00245         errMsg = errorLine;
00246         err = false;
00247     }
00248 
00249     char magicNumber[SAIAMAG];
00250     if (!fo_->read(magicNumber, SAIAMAG))
00251     {
00252         sprintf(errorLine, "Error parsing memory image %p with size %u : %s\n",
00253                 mem_image, (unsigned int)size, "Reading magic number");
00254         serr = Obj_Parsing;
00255         errMsg = errorLine;
00256         err = false;
00257     }   
00258 
00259     if (!strncmp(magicNumber, AIAMAG, SAIAMAG))
00260         archive = (xcoffArchive *) new xcoffArchive_32(fo_);
00261     else if (!strncmp(magicNumber, AIAMAGBIG, SAIAMAG))
00262         archive = (xcoffArchive *) new xcoffArchive_64(fo_);
00263     else
00264     {
00265         sprintf(errorLine, "Error parsing memory image %p with size %u : %s\n",
00266                 mem_image, (unsigned int)size, "Unknown magic number");
00267         serr = Obj_Parsing;
00268         errMsg = errorLine;
00269         err = false;
00270     }    
00271     if (archive->read_arhdr())
00272     {
00273         sprintf(errorLine, "Error parsing memory image %p with size %u : %s\n",
00274                 mem_image, (unsigned int)size, "Reading file header");
00275         serr = Obj_Parsing;
00276         errMsg = errorLine;
00277         err = false;
00278     }
00279 
00280     while (archive->next_offset !=0)
00281     {
00282         if (archive->read_mbrhdr())
00283         {
00284             sprintf(errorLine, "Error parsing memory image %p with size %u : %s\n",
00285                     mem_image, (unsigned int)size, "Reading memory header");
00286             serr = Obj_Parsing;
00287             errMsg = errorLine;
00288             err = false;
00289         }   
00290         std::string member_name = archive->member_name;
00291         std::string::size_type len = member_name.length();
00292         if((len >= 4)&&(member_name.substr(len-4,4) == ".imp" || member_name.substr(len-4,4) == ".exp"))
00293             continue;
00294 
00295         ArchiveMember *newMember = new ArchiveMember(member_name, archive->aout_offset);
00296         membersByOffset[archive->aout_offset] = newMember;
00297         membersByName[member_name] = newMember;
00298     }
00299 
00300     fprintf(stderr, "%s[%d]:  deleting archive\n", FILE__, __LINE__);
00301     delete archive;
00302     err = true;
00303 }
00304 
00305 bool Archive::parseMember(Symtab *&img, ArchiveMember *member) 
00306 {
00307     bool err;
00308     if (mf->getFD() == -1) {
00309         img = new Symtab((char *)mf->base_addr(),mf->size(),
00310                          member->getName(), member->getOffset(), err, basePtr);
00311     } else {
00312         if (!mf) {
00313             fprintf(stderr, "%s[%d]:  ERROR: mf has not been set\n", FILE__, __LINE__);
00314             return false;
00315         }
00316 
00317         std::string pname = mf->pathname();
00318         if (pname.length()) {
00319             img = new Symtab(std::string(pname), member->getName(), member->getOffset(),
00320                   err, basePtr);
00321         } else {
00322             fprintf(stderr, "%s[%d]:  WARNING:  got mapped file with non existant path name\n", FILE__, __LINE__);
00323             img = new Symtab(std::string(""), member->getName(), member->getOffset(),
00324                   err, basePtr);
00325         }
00326     }
00327 
00328     if( !err ) {
00329         img->parentArchive_ = this;
00330         member->setSymtab(img);
00331     }
00332 
00333     return !err;
00334 }
00335 
00336 bool Archive::parseSymbolTable() 
00337 {
00338     //TODO
00339     serr = Obj_Parsing;
00340     errMsg = "parsing of the global symbol table in a XCOFF archive is currently unimplemented";
00341     return false;
00342 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1