Update perl asm scripts include paths for perlasm.
[openssl.git] / crypto / mem_dbg.c
1 /* crypto/mem_dbg.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  * 
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  * 
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  * 
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from 
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  * 
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * 
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 /* ====================================================================
59  * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
60  *
61  * Redistribution and use in source and binary forms, with or without
62  * modification, are permitted provided that the following conditions
63  * are met:
64  *
65  * 1. Redistributions of source code must retain the above copyright
66  *    notice, this list of conditions and the following disclaimer. 
67  *
68  * 2. Redistributions in binary form must reproduce the above copyright
69  *    notice, this list of conditions and the following disclaimer in
70  *    the documentation and/or other materials provided with the
71  *    distribution.
72  *
73  * 3. All advertising materials mentioning features or use of this
74  *    software must display the following acknowledgment:
75  *    "This product includes software developed by the OpenSSL Project
76  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77  *
78  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79  *    endorse or promote products derived from this software without
80  *    prior written permission. For written permission, please contact
81  *    openssl-core@openssl.org.
82  *
83  * 5. Products derived from this software may not be called "OpenSSL"
84  *    nor may "OpenSSL" appear in their names without prior written
85  *    permission of the OpenSSL Project.
86  *
87  * 6. Redistributions of any form whatsoever must retain the following
88  *    acknowledgment:
89  *    "This product includes software developed by the OpenSSL Project
90  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91  *
92  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103  * OF THE POSSIBILITY OF SUCH DAMAGE.
104  * ====================================================================
105  *
106  * This product includes cryptographic software written by Eric Young
107  * (eay@cryptsoft.com).  This product includes software written by Tim
108  * Hudson (tjh@cryptsoft.com).
109  *
110  */
111
112 #include <stdio.h>
113 #include <stdlib.h>
114 #include <time.h>       
115 #include "cryptlib.h"
116 #include <openssl/crypto.h>
117 #include <openssl/buffer.h>
118 #include <openssl/bio.h>
119 #include <openssl/lhash.h>
120
121 static int mh_mode=CRYPTO_MEM_CHECK_OFF;
122 /* The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE
123  * when the application asks for it (usually after library initialisation
124  * for which no book-keeping is desired).
125  *
126  * State CRYPTO_MEM_CHECK_ON exists only temporarily when the library
127  * thinks that certain allocations should not be checked (e.g. the data
128  * structures used for memory checking).  It is not suitable as an initial
129  * state: the library will unexpectedly enable memory checking when it
130  * executes one of those sections that want to disable checking
131  * temporarily.
132  *
133  * State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes no sense whatsoever.
134  */
135
136 static unsigned long order = 0; /* number of memory requests */
137 static LHASH *mh=NULL; /* hash-table of memory requests (address as key);
138                         * access requires MALLOC2 lock */
139
140
141 typedef struct app_mem_info_st
142 /* For application-defined information (static C-string `info')
143  * to be displayed in memory leak list.
144  * Each thread has its own stack.  For applications, there is
145  *   CRYPTO_push_info("...")     to push an entry,
146  *   CRYPTO_pop_info()           to pop an entry,
147  *   CRYPTO_remove_all_info()    to pop all entries.
148  */
149         {       
150         unsigned long thread_id;
151         void *thread_idptr;
152         const char *file;
153         int line;
154         const char *info;
155         struct app_mem_info_st *next; /* tail of thread's stack */
156         int references;
157         } APP_INFO;
158
159 static void app_info_free(APP_INFO *);
160
161 static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's
162                           * that are at the top of their thread's stack
163                           * (with `thread' as key);
164                           * access requires MALLOC2 lock */
165
166 typedef struct mem_st
167 /* memory-block description */
168         {
169         void *addr;
170         int num;
171         const char *file;
172         int line;
173         unsigned long thread_id;
174         void *thread_idptr;
175         unsigned long order;
176         time_t time;
177         APP_INFO *app_info;
178         } MEM;
179
180 static long options =             /* extra information to be recorded */
181 #if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL)
182         V_CRYPTO_MDEBUG_TIME |
183 #endif
184 #if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL)
185         V_CRYPTO_MDEBUG_THREAD |
186 #endif
187         0;
188
189
190 static unsigned int num_disable = 0; /* num_disable > 0
191                                       *     iff
192                                       * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
193                                       */
194
195 /* The following two variables, disabling_thread_id and disabling_thread_idptr,
196  * are valid iff num_disable > 0.  CRYPTO_LOCK_MALLOC2 is locked exactly in
197  * this case (by the thread named in disabling_thread_id / disabling_thread_idptr).
198  */
199 static unsigned long disabling_thread_id = 0;
200 static void *disabling_thread_idptr = NULL;
201
202 static void app_info_free(APP_INFO *inf)
203         {
204         if (--(inf->references) <= 0)
205                 {
206                 if (inf->next != NULL)
207                         {
208                         app_info_free(inf->next);
209                         }
210                 OPENSSL_free(inf);
211                 }
212         }
213
214 int CRYPTO_mem_ctrl(int mode)
215         {
216         int ret=mh_mode;
217
218         CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
219         switch (mode)
220                 {
221         /* for applications (not to be called while multiple threads
222          * use the library): */
223         case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
224                 mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE;
225                 num_disable = 0;
226                 break;
227         case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
228                 mh_mode = 0;
229                 num_disable = 0; /* should be true *before* MemCheck_stop is used,
230                                     or there'll be a lot of confusion */
231                 break;
232
233         /* switch off temporarily (for library-internal use): */
234         case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
235                 if (mh_mode & CRYPTO_MEM_CHECK_ON)
236                         {
237                         if (!num_disable
238                             || (disabling_thread_id != CRYPTO_thread_id())
239                             || (disabling_thread_idptr != CRYPTO_thread_idptr())) /* otherwise we already have the MALLOC2 lock */
240                                 {
241                                 /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
242                                  * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
243                                  * somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot release
244                                  * it because we block entry to this function).
245                                  * Give them a chance, first, and then claim the locks in
246                                  * appropriate order (long-time lock first).
247                                  */
248                                 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
249                                 /* Note that after we have waited for CRYPTO_LOCK_MALLOC2
250                                  * and CRYPTO_LOCK_MALLOC, we'll still be in the right
251                                  * "case" and "if" branch because MemCheck_start and
252                                  * MemCheck_stop may never be used while there are multiple
253                                  * OpenSSL threads. */
254                                 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
255                                 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
256                                 mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
257                                 disabling_thread_id=CRYPTO_thread_id();
258                                 disabling_thread_idptr=CRYPTO_thread_idptr();
259                                 }
260                         num_disable++;
261                         }
262                 break;
263         case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
264                 if (mh_mode & CRYPTO_MEM_CHECK_ON)
265                         {
266                         if (num_disable) /* always true, or something is going wrong */
267                                 {
268                                 num_disable--;
269                                 if (num_disable == 0)
270                                         {
271                                         mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
272                                         CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
273                                         }
274                                 }
275                         }
276                 break;
277
278         default:
279                 break;
280                 }
281         CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
282         return(ret);
283         }
284
285 int CRYPTO_is_mem_check_on(void)
286         {
287         int ret = 0;
288
289         if (mh_mode & CRYPTO_MEM_CHECK_ON)
290                 {
291                 CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
292
293                 ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
294                         || (disabling_thread_id != CRYPTO_thread_id())
295                         || (disabling_thread_idptr != CRYPTO_thread_idptr());
296
297                 CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
298                 }
299         return(ret);
300         }       
301
302
303 void CRYPTO_dbg_set_options(long bits)
304         {
305         options = bits;
306         }
307
308 long CRYPTO_dbg_get_options(void)
309         {
310         return options;
311         }
312
313 /* static int mem_cmp(MEM *a, MEM *b) */
314 static int mem_cmp(const void *a_void, const void *b_void)
315         {
316 #ifdef _WIN64
317         const char *a=(const char *)((const MEM *)a_void)->addr,
318                    *b=(const char *)((const MEM *)b_void)->addr;
319         if (a==b)       return 0;
320         else if (a>b)   return 1;
321         else            return -1;
322 #else
323         return((const char *)((const MEM *)a_void)->addr
324                 - (const char *)((const MEM *)b_void)->addr);
325 #endif
326         }
327
328 /* static unsigned long mem_hash(MEM *a) */
329 static unsigned long mem_hash(const void *a_void)
330         {
331         unsigned long ret;
332
333         ret=(unsigned long)((const MEM *)a_void)->addr;
334
335         ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
336         return(ret);
337         }
338
339 /* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
340 static int app_info_cmp(const void *a_void, const void *b_void)
341         {
342         return (((const APP_INFO *)a_void)->thread_id != ((const APP_INFO *)b_void)->thread_id)
343                || (((const APP_INFO *)a_void)->thread_idptr != ((const APP_INFO *)b_void)->thread_idptr);
344         }
345
346 /* static unsigned long app_info_hash(APP_INFO *a) */
347 static unsigned long app_info_hash(const void *a_void)
348         {
349         unsigned long id1, id2;
350         unsigned long ret;
351
352         id1=(unsigned long)((const APP_INFO *)a_void)->thread_id;
353         id2=(unsigned long)((const APP_INFO *)a_void)->thread_idptr;
354         ret = id1 + id2;
355
356         ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
357         return(ret);
358         }
359
360 static APP_INFO *pop_info(void)
361         {
362         APP_INFO tmp;
363         APP_INFO *ret = NULL;
364
365         if (amih != NULL)
366                 {
367                 tmp.thread_id=CRYPTO_thread_id();
368                 tmp.thread_idptr=CRYPTO_thread_idptr();
369                 if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL)
370                         {
371                         APP_INFO *next=ret->next;
372
373                         if (next != NULL)
374                                 {
375                                 next->references++;
376                                 lh_insert(amih,(char *)next);
377                                 }
378 #ifdef LEVITTE_DEBUG_MEM
379                         if (ret->thread_id != tmp.thread_id || ret->thread_idptr != tmp.thread_idptr)
380                                 {
381                                 fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu/%p) than the current thread (%lu/%p)!!!!\n",
382                                         ret->thread_id, ret->thread_idptr, tmp.thread_id, tmp.thread_idptr);
383                                 abort();
384                                 }
385 #endif
386                         if (--(ret->references) <= 0)
387                                 {
388                                 ret->next = NULL;
389                                 if (next != NULL)
390                                         next->references--;
391                                 OPENSSL_free(ret);
392                                 }
393                         }
394                 }
395         return(ret);
396         }
397
398 int CRYPTO_push_info_(const char *info, const char *file, int line)
399         {
400         APP_INFO *ami, *amim;
401         int ret=0;
402
403         if (is_MemCheck_on())
404                 {
405                 MemCheck_off(); /* obtain MALLOC2 lock */
406
407                 if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL)
408                         {
409                         ret=0;
410                         goto err;
411                         }
412                 if (amih == NULL)
413                         {
414                         if ((amih=lh_new(app_info_hash, app_info_cmp)) == NULL)
415                                 {
416                                 OPENSSL_free(ami);
417                                 ret=0;
418                                 goto err;
419                                 }
420                         }
421
422                 ami->thread_id=CRYPTO_thread_id();
423                 ami->thread_idptr=CRYPTO_thread_idptr();
424                 ami->file=file;
425                 ami->line=line;
426                 ami->info=info;
427                 ami->references=1;
428                 ami->next=NULL;
429
430                 if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL)
431                         {
432 #ifdef LEVITTE_DEBUG_MEM
433                         if (ami->thread_id != amim->thread_id || ami->thread_idptr != amim->thread_idptr)
434                                 {
435                                 fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu/%p) than the current thread (%lu/%p)!!!!\n",
436                                         amim->thread_id, amim->thread_idptr, ami->thread_id, ami->thread_idptr);
437                                 abort();
438                                 }
439 #endif
440                         ami->next=amim;
441                         }
442  err:
443                 MemCheck_on(); /* release MALLOC2 lock */
444                 }
445
446         return(ret);
447         }
448
449 int CRYPTO_pop_info(void)
450         {
451         int ret=0;
452
453         if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */
454                 {
455                 MemCheck_off(); /* obtain MALLOC2 lock */
456
457                 ret=(pop_info() != NULL);
458
459                 MemCheck_on(); /* release MALLOC2 lock */
460                 }
461         return(ret);
462         }
463
464 int CRYPTO_remove_all_info(void)
465         {
466         int ret=0;
467
468         if (is_MemCheck_on()) /* _must_ be true */
469                 {
470                 MemCheck_off(); /* obtain MALLOC2 lock */
471
472                 while(pop_info() != NULL)
473                         ret++;
474
475                 MemCheck_on(); /* release MALLOC2 lock */
476                 }
477         return(ret);
478         }
479
480
481 static unsigned long break_order_num=0;
482 void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
483         int before_p)
484         {
485         MEM *m,*mm;
486         APP_INFO tmp,*amim;
487
488         switch(before_p & 127)
489                 {
490         case 0:
491                 break;
492         case 1:
493                 if (addr == NULL)
494                         break;
495
496                 if (is_MemCheck_on())
497                         {
498                         MemCheck_off(); /* make sure we hold MALLOC2 lock */
499                         if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL)
500                                 {
501                                 OPENSSL_free(addr);
502                                 MemCheck_on(); /* release MALLOC2 lock
503                                                 * if num_disabled drops to 0 */
504                                 return;
505                                 }
506                         if (mh == NULL)
507                                 {
508                                 if ((mh=lh_new(mem_hash, mem_cmp)) == NULL)
509                                         {
510                                         OPENSSL_free(addr);
511                                         OPENSSL_free(m);
512                                         addr=NULL;
513                                         goto err;
514                                         }
515                                 }
516
517                         m->addr=addr;
518                         m->file=file;
519                         m->line=line;
520                         m->num=num;
521                         if (options & V_CRYPTO_MDEBUG_THREAD)
522                                 {
523                                 m->thread_id=CRYPTO_thread_id();
524                                 m->thread_idptr=CRYPTO_thread_idptr();
525                                 }
526                         else
527                                 {
528                                 m->thread_id=0;
529                                 m->thread_idptr=NULL;
530                                 }
531
532                         if (order == break_order_num)
533                                 {
534                                 /* BREAK HERE */
535                                 m->order=order;
536                                 }
537                         m->order=order++;
538 #ifdef LEVITTE_DEBUG_MEM
539                         fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n",
540                                 m->order,
541                                 (before_p & 128) ? '*' : '+',
542                                 m->addr, m->num);
543 #endif
544                         if (options & V_CRYPTO_MDEBUG_TIME)
545                                 m->time=time(NULL);
546                         else
547                                 m->time=0;
548
549                         tmp.thread_id=CRYPTO_thread_id();
550                         tmp.thread_idptr=CRYPTO_thread_idptr();
551                         m->app_info=NULL;
552                         if (amih != NULL
553                                 && (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL)
554                                 {
555                                 m->app_info = amim;
556                                 amim->references++;
557                                 }
558
559                         if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL)
560                                 {
561                                 /* Not good, but don't sweat it */
562                                 if (mm->app_info != NULL)
563                                         {
564                                         mm->app_info->references--;
565                                         }
566                                 OPENSSL_free(mm);
567                                 }
568                 err:
569                         MemCheck_on(); /* release MALLOC2 lock
570                                         * if num_disabled drops to 0 */
571                         }
572                 break;
573                 }
574         return;
575         }
576
577 void CRYPTO_dbg_free(void *addr, int before_p)
578         {
579         MEM m,*mp;
580
581         switch(before_p)
582                 {
583         case 0:
584                 if (addr == NULL)
585                         break;
586
587                 if (is_MemCheck_on() && (mh != NULL))
588                         {
589                         MemCheck_off(); /* make sure we hold MALLOC2 lock */
590
591                         m.addr=addr;
592                         mp=(MEM *)lh_delete(mh,(char *)&m);
593                         if (mp != NULL)
594                                 {
595 #ifdef LEVITTE_DEBUG_MEM
596                         fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n",
597                                 mp->order, mp->addr, mp->num);
598 #endif
599                                 if (mp->app_info != NULL)
600                                         app_info_free(mp->app_info);
601                                 OPENSSL_free(mp);
602                                 }
603
604                         MemCheck_on(); /* release MALLOC2 lock
605                                         * if num_disabled drops to 0 */
606                         }
607                 break;
608         case 1:
609                 break;
610                 }
611         }
612
613 void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
614         const char *file, int line, int before_p)
615         {
616         MEM m,*mp;
617
618 #ifdef LEVITTE_DEBUG_MEM
619         fprintf(stderr, "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
620                 addr1, addr2, num, file, line, before_p);
621 #endif
622
623         switch(before_p)
624                 {
625         case 0:
626                 break;
627         case 1:
628                 if (addr2 == NULL)
629                         break;
630
631                 if (addr1 == NULL)
632                         {
633                         CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
634                         break;
635                         }
636
637                 if (is_MemCheck_on())
638                         {
639                         MemCheck_off(); /* make sure we hold MALLOC2 lock */
640
641                         m.addr=addr1;
642                         mp=(MEM *)lh_delete(mh,(char *)&m);
643                         if (mp != NULL)
644                                 {
645 #ifdef LEVITTE_DEBUG_MEM
646                                 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n",
647                                         mp->order,
648                                         mp->addr, mp->num,
649                                         addr2, num);
650 #endif
651                                 mp->addr=addr2;
652                                 mp->num=num;
653                                 lh_insert(mh,(char *)mp);
654                                 }
655
656                         MemCheck_on(); /* release MALLOC2 lock
657                                         * if num_disabled drops to 0 */
658                         }
659                 break;
660                 }
661         return;
662         }
663
664
665 typedef struct mem_leak_st
666         {
667         BIO *bio;
668         int chunks;
669         long bytes;
670         } MEM_LEAK;
671
672 static void print_leak(const MEM *m, MEM_LEAK *l)
673         {
674         char buf[1024];
675         char *bufp = buf;
676         APP_INFO *amip;
677         int ami_cnt;
678         struct tm *lcl = NULL;
679         unsigned long ti;
680         void *tip;
681
682 #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
683
684         if(m->addr == (char *)l->bio)
685             return;
686
687         if (options & V_CRYPTO_MDEBUG_TIME)
688                 {
689                 lcl = localtime(&m->time);
690         
691                 BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
692                         lcl->tm_hour,lcl->tm_min,lcl->tm_sec);
693                 bufp += strlen(bufp);
694                 }
695
696         BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
697                 m->order,m->file,m->line);
698         bufp += strlen(bufp);
699
700         if (options & V_CRYPTO_MDEBUG_THREAD)
701                 {
702                 BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu/%p, ", m->thread_id, m->thread_idptr);
703                 bufp += strlen(bufp);
704                 }
705
706         BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n",
707                 m->num,(unsigned long)m->addr);
708         bufp += strlen(bufp);
709
710         BIO_puts(l->bio,buf);
711         
712         l->chunks++;
713         l->bytes+=m->num;
714
715         amip=m->app_info;
716         ami_cnt=0;
717         if (!amip)
718                 return;
719         ti=amip->thread_id;
720         tip=amip->thread_idptr;
721         
722         do
723                 {
724                 int buf_len;
725                 int info_len;
726
727                 ami_cnt++;
728                 memset(buf,'>',ami_cnt);
729                 BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
730                         " thread=%lu/%p, file=%s, line=%d, info=\"",
731                         amip->thread_id, amip->thread_idptr, amip->file, amip->line);
732                 buf_len=strlen(buf);
733                 info_len=strlen(amip->info);
734                 if (128 - buf_len - 3 < info_len)
735                         {
736                         memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
737                         buf_len = 128 - 3;
738                         }
739                 else
740                         {
741                         BUF_strlcpy(buf + buf_len, amip->info,
742                                     sizeof buf - buf_len);
743                         buf_len = strlen(buf);
744                         }
745                 BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
746                 
747                 BIO_puts(l->bio,buf);
748
749                 amip = amip->next;
750                 }
751         while(amip && amip->thread_id == ti && amip->thread_idptr == tip);
752                 
753 #ifdef LEVITTE_DEBUG_MEM
754         if (amip)
755                 {
756                 fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
757                 abort();
758                 }
759 #endif
760         }
761
762 static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM *, MEM_LEAK *)
763
764 void CRYPTO_mem_leaks(BIO *b)
765         {
766         MEM_LEAK ml;
767
768         if (mh == NULL && amih == NULL)
769                 return;
770
771         MemCheck_off(); /* obtain MALLOC2 lock */
772
773         ml.bio=b;
774         ml.bytes=0;
775         ml.chunks=0;
776         if (mh != NULL)
777                 lh_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak),
778                                 (char *)&ml);
779         if (ml.chunks != 0)
780                 {
781                 BIO_printf(b,"%ld bytes leaked in %d chunks\n",
782                            ml.bytes,ml.chunks);
783                 }
784         else
785                 {
786                 /* Make sure that, if we found no leaks, memory-leak debugging itself
787                  * does not introduce memory leaks (which might irritate
788                  * external debugging tools).
789                  * (When someone enables leak checking, but does not call
790                  * this function, we declare it to be their fault.)
791                  *
792                  * XXX    This should be in CRYPTO_mem_leaks_cb,
793                  * and CRYPTO_mem_leaks should be implemented by
794                  * using CRYPTO_mem_leaks_cb.
795                  * (Also their should be a variant of lh_doall_arg
796                  * that takes a function pointer instead of a void *;
797                  * this would obviate the ugly and illegal
798                  * void_fn_to_char kludge in CRYPTO_mem_leaks_cb.
799                  * Otherwise the code police will come and get us.)
800                  */
801                 int old_mh_mode;
802
803                 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
804
805                 /* avoid deadlock when lh_free() uses CRYPTO_dbg_free(),
806                  * which uses CRYPTO_is_mem_check_on */
807                 old_mh_mode = mh_mode;
808                 mh_mode = CRYPTO_MEM_CHECK_OFF;
809
810                 if (mh != NULL)
811                         {
812                         lh_free(mh);
813                         mh = NULL;
814                         }
815                 if (amih != NULL)
816                         {
817                         if (lh_num_items(amih) == 0) 
818                                 {
819                                 lh_free(amih);
820                                 amih = NULL;
821                                 }
822                         }
823
824                 mh_mode = old_mh_mode;
825                 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
826                 }
827         MemCheck_on(); /* release MALLOC2 lock */
828         }
829
830 #ifndef OPENSSL_NO_FP_API
831 void CRYPTO_mem_leaks_fp(FILE *fp)
832         {
833         BIO *b;
834
835         if (mh == NULL) return;
836         /* Need to turn off memory checking when allocated BIOs ... especially
837          * as we're creating them at a time when we're trying to check we've not
838          * left anything un-free()'d!! */
839         MemCheck_off();
840         b = BIO_new(BIO_s_file());
841         MemCheck_on();
842         if(!b) return;
843         BIO_set_fp(b,fp,BIO_NOCLOSE);
844         CRYPTO_mem_leaks(b);
845         BIO_free(b);
846         }
847 #endif
848
849
850
851 /* FIXME: We really don't allow much to the callback.  For example, it has
852    no chance of reaching the info stack for the item it processes.  Should
853    it really be this way?  -- Richard Levitte */
854 /* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h
855  * If this code is restructured, remove the callback type if it is no longer
856  * needed. -- Geoff Thorpe */
857 static void cb_leak(const MEM *m, CRYPTO_MEM_LEAK_CB **cb)
858         {
859         (**cb)(m->order,m->file,m->line,m->num,m->addr);
860         }
861
862 static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM *, CRYPTO_MEM_LEAK_CB **)
863
864 void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
865         {
866         if (mh == NULL) return;
867         CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
868         lh_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), &cb);
869         CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
870         }