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
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
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
00097
00098
00099
00100
00101
00102 va_list va;
00103 va_start(va, format);
00104 int ret = vfprintf(stderr, format, va);
00105 va_end(va);
00106
00107
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
00131
00132
00133
00134
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
00169 #if 0
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 if (!annotation_types) return;
00180 if (id >= annotation_types->size()) return;
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
00186
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
00299
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
00332
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 }