Archive.C
Go to the documentation of this file.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 #include "symtabAPI/h/Symtab.h"
00032 #include "symtabAPI/h/Archive.h"
00033 #include "symtabAPI/src/Object.h"
00034
00035 #include <iostream>
00036
00037 using namespace Dyninst;
00038 using namespace Dyninst::SymtabAPI;
00039
00040
00041
00042
00043
00044
00045
00046
00047 std::vector<Archive *> Archive::allArchives;
00048 std::string Archive::errMsg;
00049 SymtabError Archive::serr;
00050
00051
00052 static const std::string PARSE_FAILURE = "Failed to parse the archive: ";
00053 static const std::string NO_MEMBER = "Member not found: ";
00054 static const std::string NOT_ARCHIVE = "File is not an archive";
00055 static const std::string DUPLICATE_SYM = "Duplicate symbol found: ";
00056 static const std::string UNKNOWN_ERR = "Unknown Error";
00057
00058
00059 static const std::string MEMBER_DNE = "member does not exist";
00060
00061 SymtabError Archive::getLastError()
00062 {
00063 return serr;
00064 }
00065
00066 std::string Archive::printError(SymtabError err)
00067 {
00068 switch (err) {
00069 case Obj_Parsing:
00070 return PARSE_FAILURE + errMsg;
00071 case No_Such_Member:
00072 return NO_MEMBER + errMsg;
00073 case Not_A_File:
00074 return errMsg;
00075 case Not_An_Archive:
00076 return NOT_ARCHIVE;
00077 case Duplicate_Symbol:
00078 return DUPLICATE_SYM + errMsg;
00079 default:
00080 return UNKNOWN_ERR;
00081 }
00082 }
00083
00084 std::string Archive::name() {
00085 return mf->filename();
00086 }
00087
00088 bool Archive::openArchive(Archive * &img, std::string filename)
00089 {
00090 bool err = false;
00091
00092
00093 std::vector<Archive *>::iterator ar_it;
00094 for (ar_it = allArchives.begin(); ar_it != allArchives.end(); ++ar_it) {
00095 assert( *ar_it != NULL );
00096
00097 if( (*ar_it)->mf->pathname() == filename ) {
00098 img = *ar_it;
00099 return true;
00100 }
00101 }
00102
00103 img = new Archive(filename, err);
00104 if (err) {
00105 allArchives.push_back(img);
00106 } else {
00107 if (img) {
00108 delete img;
00109 img = NULL;
00110 }
00111 }
00112
00113 return err;
00114 }
00115
00116 bool Archive::openArchive(Archive * &img, char *mem_image, size_t size)
00117 {
00118 bool err;
00119
00120 std::vector<Archive *>::iterator ar_it;
00121 for (ar_it = allArchives.begin(); ar_it != allArchives.end(); ++ar_it) {
00122 assert( *ar_it != NULL );
00123
00124 if( (*ar_it)->mf->base_addr() == (void *)mem_image ) {
00125 img = *ar_it;
00126 return true;
00127 }
00128 }
00129
00130 img = new Archive(mem_image, size, err);
00131 if (err) {
00132 allArchives.push_back(img);
00133 } else {
00134 if (img) {
00135 delete img;
00136 img = NULL;
00137 }
00138 }
00139
00140 return err;
00141 }
00142
00143 bool Archive::getMember(Symtab *&img, string& member_name)
00144 {
00145 dyn_hash_map<string, ArchiveMember *>::iterator mem_it;
00146 mem_it = membersByName.find(member_name);
00147 if ( mem_it == membersByName.end() ) {
00148 serr = No_Such_Member;
00149 errMsg = MEMBER_DNE;
00150 return false;
00151 }
00152
00153 img = mem_it->second->getSymtab();
00154 if( img == NULL ) {
00155 if( !parseMember(img, mem_it->second) ) {
00156 return false;
00157 }
00158 }
00159
00160 return true;
00161 }
00162
00163 bool Archive::getMemberByOffset(Symtab *&img, Offset memberOffset)
00164 {
00165 dyn_hash_map<Offset, ArchiveMember *>::iterator off_it;
00166 off_it = membersByOffset.find(memberOffset);
00167 if( off_it == membersByOffset.end() ) {
00168 serr = No_Such_Member;
00169 errMsg = MEMBER_DNE;
00170 return false;
00171 }
00172
00173 img = off_it->second->getSymtab();
00174 if( img == NULL ) {
00175 if( !parseMember(img, off_it->second) ) {
00176 return false;
00177 }
00178 }
00179
00180 return true;
00181 }
00182
00183 bool Archive::getMemberByGlobalSymbol(Symtab *&img, string& symbol_name)
00184 {
00185 if( !symbolTableParsed ) {
00186 if( !parseSymbolTable() ) {
00187 return false;
00188 }
00189 }
00190
00191 std::pair<std::multimap<string, ArchiveMember *>::iterator,
00192 std::multimap<string, ArchiveMember *>::iterator> range_it;
00193 range_it = membersBySymbol.equal_range(symbol_name);
00194
00195
00196 if( range_it.first == range_it.second ) {
00197 serr = No_Such_Member;
00198 errMsg = MEMBER_DNE;
00199 return false;
00200 }
00201 ArchiveMember *foundMember = range_it.first->second;
00202
00203
00204 ++(range_it.first);
00205 if( range_it.first != range_it.second ) {
00206 serr = Duplicate_Symbol;
00207 errMsg = symbol_name;
00208 return false;
00209 }
00210
00211 img = foundMember->getSymtab();
00212 if( img == NULL ) {
00213 if( !parseMember(img, foundMember) ) {
00214 return false;
00215 }
00216 }
00217
00218 return true;
00219 }
00220
00221 bool Archive::getMembersBySymbol(std::string name,
00222 std::vector<Symtab *> &matches) {
00223 if (!symbolTableParsed && !parseSymbolTable())
00224 return false;
00225
00226 std::pair<std::multimap<string, ArchiveMember *>::iterator,
00227 std::multimap<string, ArchiveMember *>::iterator> range_it;
00228
00229 range_it = membersBySymbol.equal_range(name);
00230 auto begin = range_it.first;
00231 auto end = range_it.second;
00232
00233 for (; begin != end; ++begin) {
00234 ArchiveMember *member = begin->second;
00235 Symtab *img = member->getSymtab();
00236 if (!img && !parseMember(img, member)) return false;
00237 matches.push_back(img);
00238 }
00239
00240 return true;
00241 }
00242
00243 bool Archive::getAllMembers(vector<Symtab *> &members)
00244 {
00245 dyn_hash_map<string, ArchiveMember *>::iterator mem_it;
00246 for(mem_it = membersByName.begin(); mem_it != membersByName.end(); ++mem_it) {
00247 Symtab *img = mem_it->second->getSymtab();
00248 if( img == NULL) {
00249 if( !parseMember(img, mem_it->second) ) {
00250 return false;
00251 }
00252 }
00253 members.push_back(mem_it->second->getSymtab());
00254 }
00255 return true;
00256 }
00257
00258 bool Archive::isMemberInArchive(std::string& member_name)
00259 {
00260 if (membersByName.count(member_name)) return true;
00261 return false;
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 bool Archive::findMemberWithDefinition(Symtab * &obj, std::string& name)
00277 {
00278 std::vector<Symtab *> members;
00279 if( !getAllMembers(members) ) {
00280 return false;
00281 }
00282
00283 std::vector<Symtab *>::iterator obj_it;
00284 for (obj_it = members.begin(); obj_it != members.end(); ++obj_it) {
00285 std::vector<Symbol *> syms;
00286 if ((*obj_it)->findSymbol(syms, name, Symbol::ST_UNKNOWN)) {
00287 obj = *obj_it;
00288 return true;
00289 }
00290 }
00291
00292 serr = No_Such_Member;
00293 errMsg = MEMBER_DNE;
00294 return false;
00295 }
00296
00297 Archive::~Archive()
00298 {
00299 dyn_hash_map<string, ArchiveMember *>::iterator it;
00300 for (it = membersByName.begin(); it != membersByName.end(); ++it) {
00301 if (it->second) delete it->second;
00302 }
00303
00304 for (unsigned i = 0; i < allArchives.size(); i++) {
00305 if (allArchives[i] == this)
00306 allArchives.erase(allArchives.begin()+i);
00307 }
00308
00309 if (mf) {
00310 MappedFile::closeMappedFile(mf);
00311 }
00312
00313 }