Annotatable.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: Annotatable.C,v 1.12 2008/11/03 15:19:23 jaw Exp $
00032 
00033 #include "common/h/headers.h"
00034 #include "dyntypes.h"
00035 #include "Annotatable.h"
00036 #include "Serialization.h"
00037 #include "common/h/serialize.h"
00038 
00039 using namespace Dyninst;
00040 
00041 #if defined (NON_STATIC_SPARSE_MAP)
00042 char buffer[1024];
00043 //AnnotatableSparse::annos_t *AnnotatableSparse::annos = NULL;
00044 AnnotatableSparse::annos_t *annos = NULL;
00045 AnnotatableSparse::annos_t *AnnotatableSparse::getAnnos() const
00046 {
00047     if (!annos)
00048     {
00049         sprintf(buffer, "booga_booga");
00050         annos = new annos_t();
00051     }
00052     return annos;
00053 }
00054 #else
00055 AnnotatableSparse::annos_t AnnotatableSparse::annos;
00056 AnnotatableSparse::annos_t *AnnotatableSparse::getAnnos() const
00057 {
00058     return &annos;
00059 }
00060 #endif
00061 
00062 dyn_hash_map<void *, unsigned short> AnnotatableSparse::ser_ndx_map;
00063 
00064 namespace Dyninst 
00065 {
00066 
00067 bool dyn_debug_annotations = false;
00068 bool annotation_debug_flag()
00069 {
00070     return dyn_debug_annotations;
00071 }
00072 
00073 void annotations_debug_init()
00074 {
00075     if (dyn_debug_annotations) return;
00076 
00077     if (getenv("DYNINST_DEBUG_ANNOTATIONS")) {
00078         fprintf(stderr, "Enabling DyninstAPI annotations debug\n");
00079         dyn_debug_annotations = true;
00080     }
00081     else if (getenv("DYNINST_DEBUG_ANNOTATION")) {
00082         fprintf(stderr, "Enabling DyninstAPI annotations debug\n");
00083         dyn_debug_annotations = true;
00084     }
00085     else if (getenv("DYNINST_DEBUG_ANNOTATABLE")) {
00086         fprintf(stderr, "Enabling DyninstAPI annotations debug\n");
00087         dyn_debug_annotations = true;
00088     }
00089 }
00090 
00091 int annotatable_printf(const char *format, ...)
00092 {
00093     if (!dyn_debug_annotations) return 0;
00094     if (NULL == format) return -1;
00095 
00096     //debugPrintLock->_Lock(FILE__, __LINE__);
00097 
00098     //  probably want to have basic thread-id routines in libcommon...
00099     //  uh...  later....
00100 
00101     //fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
00102     va_list va;
00103     va_start(va, format);
00104     int ret = vfprintf(stderr, format, va);
00105     va_end(va);
00106 
00107     //debugPrintLock->_Unlock(FILE__, __LINE__);
00108 
00109     return ret;
00110 }
00111 
00112 COMMON_EXPORT int AnnotationClass_nextId;
00113 
00114 bool void_ptr_cmp_func(void *v1, void *v2)
00115 {
00116     return v1 == v2;
00117 }
00118 }
00119 
00120 std::vector<AnnotationClassBase *> *AnnotationClassBase::annotation_types = NULL;
00121 dyn_hash_map<std::string, AnnotationClassID> *AnnotationClassBase::annotation_ids_by_name = NULL;
00122 
00123 AnnotationClassBase::AnnotationClassBase(std::string n, 
00124         anno_cmp_func_t cmp_func_, 
00125         ser_func_t sf_) :
00126    name(n),
00127    serialize_func(sf_)
00128 {
00129     annotations_debug_init();
00130     // Using a static vector led to the following pattern on AIX:
00131     //   dyninstAPI static initialization
00132     //     ... add annotation types
00133     //   common static initialization
00134     //     ... vector constructor called, resetting size to 0.
00135 
00136     if (annotation_types == NULL)
00137         annotation_types = new std::vector<AnnotationClassBase *>;
00138     if (annotation_ids_by_name == NULL)
00139         annotation_ids_by_name = new dyn_hash_map<std::string, AnnotationClassID>;
00140 
00141    if (NULL == cmp_func_)
00142       cmp_func = void_ptr_cmp_func;
00143    else
00144       cmp_func = cmp_func_;
00145 
00146    dyn_hash_map<std::string, AnnotationClassID>::iterator iter;
00147    iter = annotation_ids_by_name->find(n);
00148    if (iter == annotation_ids_by_name->end()) 
00149    {
00150       id = (AnnotationClassID) annotation_types->size();
00151       annotatable_printf("%s[%d]:  New AnnotationClass %d: %s\n", 
00152               FILE__, __LINE__, id, n.c_str());
00153       annotation_types->push_back(this);
00154       (*annotation_ids_by_name)[name] = id;
00155    }
00156    else
00157    {
00158       id = iter->second;
00159       annotatable_printf("%s[%d]:  Existing AnnotationClass %d\n", FILE__, __LINE__, id);
00160    }
00161 
00162    if (id >= annotation_types->size())
00163        assert(0 && "bad anno id");
00164 }
00165 
00166 AnnotationClassBase::~AnnotationClassBase()
00167 {
00168     //  Still waffling...  maybe a bad idea
00169 #if 0 
00170     //  The general rule in dyninst/symtab etc is to use global/static
00171     //  Annotation classes, so they never go away.  This is good.
00172     //  But in the testsuite, we have a bunch of transient fly-by-night
00173     //  AnnotationClasses for the purposes of testing.  
00174     //
00175     //  This may be a bit dangerous and might require a bit more thought,
00176     //  but for now, if this AnnotationClass was the last one allocated
00177     //  remove it from the static mapping so it can be reused.
00178 
00179     if (!annotation_types)  return; //  should never happen
00180     if (id >= annotation_types->size()) return; //  should never happen
00181     if (id == (annotation_types->size() -1))
00182     {
00183         annotatable_printf("%s[%d]:  removing annotation class %d: %s\n", 
00184                 FILE__, __LINE__, id, name.c_str());
00185         //  this is the special case where we can "undo" the existence of
00186         // the annotation type
00187         annotation_types->pop_back();
00188         assert((*annotation_types)[id] == this);
00189         dyn_hash_map<std::string, AnnotationClassID>::iterator iter;
00190         iter = annotation_ids_by_name->find(name);
00191         if (iter != annotation_ids_by_name->end()) 
00192         {
00193             annotation_ids_by_name->erase(iter);
00194         }
00195     }
00196 #endif
00197 }
00198 
00199 #if 0
00200 void AnnotationClassBase::clearAnnotationIDMap()
00201 {
00202     if (!annotation_ids_by_name) return;
00203     annotation_ids_by_name->clear();
00204     delete annotation_ids_by_name;
00205     annotation_ids_by_name = NULL;
00206 }
00207 #endif
00208 
00209 Dyninst::AnnotationClassBase* AnnotationClassBase::findAnnotationClass(unsigned int id)
00210 {
00211     if(id > annotation_types->size())
00212     {
00213         fprintf(stderr, "%s[%d]:  cannot find annotation class base for id %d, max is %ld\n", FILE__, __LINE__, id, (long int) annotation_types->size());
00214         return NULL;
00215     }
00216     if (NULL == (*annotation_types)[id])
00217     {
00218         fprintf(stderr, "%s[%d]:  FIXME:  have NULL slot\n", FILE__, __LINE__);
00219     }
00220     if ((*annotation_types)[id]->getID() != id)
00221     {
00222         fprintf(stderr, "%s[%d]:  FIXME:  have bad id in annotation class: %d, not %d\n", FILE__, __LINE__, (*annotation_types)[id]->getID(), id);
00223         return NULL;
00224     }
00225     return (*annotation_types)[id];
00226 }
00227 void AnnotationClassBase::dumpAnnotationClasses()
00228 {
00229     fprintf(stderr, "%s[%d]: have the following annotation classes:\n", FILE__, __LINE__);
00230     for (unsigned int i = 0; i < annotation_types->size(); ++i)
00231     {
00232         AnnotationClassBase *acb = (*annotation_types)[i];
00233         if (!acb)
00234         {
00235             fprintf(stderr, "\t<NULL>\n");
00236             continue;
00237         }
00238         fprintf(stderr, "\tid-%d\t%s, type %s\n", acb->getID(), acb->getName().c_str(), acb->getTypeName());
00239     }
00240 }
00241 
00242 namespace Dyninst {
00243 
00244 #if !defined(SERIALIZATION_DISABLED)
00245 bool is_input(SerializerBase *sb)
00246 {
00247     return sb->isInput();
00248 }
00249 bool is_output(SerializerBase *sb)
00250 {
00251     return sb->isOutput();
00252 }
00253 bool serialize_annotation_list(void *id, std::vector<ser_rec_t> &sers, SerializerBase *sb, const char *tag)
00254 {
00255     if (sers.size())
00256         serialize_printf("%s[%d]:  welcome to serialize_annotation_list, size %lu, id = %p\n", FILE__, __LINE__, sers.size(), id);
00257     assert(sb);
00258     assert(id);
00259     try {
00260         sb->serialize_annotations(id, sers, tag);
00261     } 
00262     catch (const SerializerError &err)
00263     {
00264         fprintf(stderr, "%s[%d]:  serializer error translating annotations\n", FILE__, __LINE__);
00265         printSerErr(err);
00266         return false;
00267     }
00268     return true;
00269 }
00270 
00271 bool serialize_post_annotation(void *parent, void *anno, SerializerBase *sb, AnnotationClassBase *acb, sparse_or_dense_anno_t sod, const char *tag)
00272 {
00273     serialize_printf("%s[%d]:  welcome to serialize_post_annotation_list, id = %p\n", 
00274             FILE__, __LINE__, parent);
00275     assert(parent);
00276     assert(anno);
00277     if (!sb)
00278     {
00279         fprintf(stderr, "%s[%d]:  no existing output serializer\n", FILE__, __LINE__);
00280         return true;
00281     }
00282     try {
00283         sb->serialize_post_annotation(parent, anno, acb, sod, tag);
00284     }
00285     catch (const SerializerError &err)
00286     {
00287         fprintf(stderr, "%s[%d]:  serializer error translating annotations\n", FILE__, __LINE__);
00288         printSerErr(err);
00289         return false;
00290     }
00291     return true;
00292 }
00293 
00294 bool add_annotations(SerializerBase *sb, AnnotatableSparse *an, std::vector<ser_rec_t> &sers)
00295 {
00296     if (sers.size())
00297         serialize_printf("%s[%d]:  welcome to addAnnotations: got %lu\n", FILE__, __LINE__, sers.size());
00298     //  if we are not doing deserialization, there is nothing to do here, just return true
00299     //  to keep from triggering error handling.
00300     if (sb->isOutput())
00301         return true;
00302     bool err = false;
00303     for (unsigned int i = 0; i < sers.size(); ++i)
00304     {
00305         ser_rec_t &sr = sers[i];
00306         if (!sr.data)
00307         {
00308             fprintf(stderr, "%s[%d]:  bad deserialize annotation record\n", FILE__, __LINE__);
00309             err = true;
00310             continue;
00311         }
00312         if (!sr.acb)
00313         {
00314             fprintf(stderr, "%s[%d]:  bad deserialize annotation record\n", FILE__, __LINE__);
00315             err = true;
00316             continue;
00317         }
00318 
00319         if (!an->addAnnotation(sr.data, sr.acb->getID()))
00320         {
00321             fprintf(stderr, "%s[%d]:  failed to add deserialized annotation here\n", FILE__, __LINE__);
00322             err = true;
00323         }
00324     }
00325     return (err == false);
00326 }
00327 
00328 bool add_annotations(SerializerBase *sb, AnnotatableDense *an, std::vector<ser_rec_t> &sers)
00329 {
00330     serialize_printf("%s[%d]:  welcome to addAnnotations: got %lu\n", FILE__, __LINE__, sers.size());
00331     //  if we are not doing deserialization, there is nothing to do here, just return true
00332     //  to keep from triggering error handling.
00333     if (sb->isOutput())
00334         return true;
00335     bool err = false;
00336     for (unsigned int i = 0; i < sers.size(); ++i)
00337     {
00338         ser_rec_t &sr = sers[i];
00339         if (!sr.data)
00340         {
00341             fprintf(stderr, "%s[%d]:  bad deserialize annotation record\n", FILE__, __LINE__);
00342             err = true;
00343             continue;
00344         }
00345         if (!sr.acb)
00346         {
00347             fprintf(stderr, "%s[%d]:  bad deserialize annotation record\n", FILE__, __LINE__);
00348             err = true;
00349             continue;
00350         }
00351         serialize_printf("%s[%d]:  adding pre annotation\n", FILE__, __LINE__);
00352         if (!an->addAnnotation(sr.data, sr.acb->getID()))
00353         {
00354             fprintf(stderr, "%s[%d]:  failed to add deserialized annotation here\n", FILE__, __LINE__);
00355             err = true;
00356         }
00357     }
00358     return (err == false);
00359 }
00360 
00361 #else
00362 bool is_input(SerializerBase *)
00363 {
00364    return false;
00365 }
00366 
00367 bool is_output(SerializerBase *) {
00368    return false;
00369 }
00370 
00371 bool serialize_annotation_list(void *, std::vector<ser_rec_t> &, SerializerBase *, const char *) {
00372    return false;
00373 }
00374 
00375 bool serialize_post_annotation(void *, void *, SerializerBase *, AnnotationClassBase *, sparse_or_dense_anno_t, const char *) {
00376    return false;
00377 }
00378 
00379 bool add_annotations(SerializerBase *, AnnotatableSparse *, std::vector<ser_rec_t> &) {
00380    return false;
00381 }
00382 
00383 bool add_annotations(SerializerBase *, AnnotatableDense *, std::vector<ser_rec_t> &) {
00384    return false;
00385 }
00386 #endif
00387 
00388 }
00389 bool dummy_bs()
00390 {
00391    fprintf(stderr, "%s[%d]:  \n", FILE__, __LINE__);
00392    return true;
00393 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1