00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
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
00077 return;
00078 }
00079
00080
00081
00082
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
00090
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
00102 return;
00103 }
00104 xcoffArchive *archive = NULL;
00105
00106
00107
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
00172 ArchiveMember *newMember = new ArchiveMember(member_name, archive->aout_offset);
00173 membersByOffset[archive->aout_offset] = newMember;
00174 membersByName[member_name] = newMember;
00175 }
00176
00177
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
00217
00218
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
00239
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
00339 serr = Obj_Parsing;
00340 errMsg = "parsing of the global symbol table in a XCOFF archive is currently unimplemented";
00341 return false;
00342 }