]> git.saurik.com Git - apple/libc.git/blobdiff - gmon/gmon.c
Libc-1044.1.2.tar.gz
[apple/libc.git] / gmon / gmon.c
index 69d7822a8a1120dab0f8ec3a20bd10829f2fe8b8..ff2f4edc43aeadba15e1efee2b62f2455d6ce0f3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999, 2003, 2004, 2007, 2008 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *     Added support for dynamic shared libraries.  Also removed the code that
  *     had been ifdef'ed out for profiling fixed shared libraries and
  *     objective-C.
+ * 
+ *  29-Aug-11 Vishal Patel (vishal_patel) at Apple
+ *     Removed code that made calls to deprecated syscalls profil() and 
+ *     add_profil(). The syscalls are not supported since 2008 and planned
+ *     to be completely removed soon. Similarly the monitor apis are also
+ *     deprecated.
+ *
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
@@ -103,9 +110,6 @@ static char sccsid[] = "@(#)gmon.c  5.2 (Berkeley) 6/21/85";
 
 #include <stdio.h>
 #include <libc.h>
-extern const struct section *getsectbyname(
-       const char *segname, 
-       const char *sectname);
 #include <monitor.h>
 #include <sys/types.h>
 #include <sys/gmon.h>
@@ -114,6 +118,7 @@ extern const struct section *getsectbyname(
 #include <mach/mach.h>
 #include <mach-o/loader.h>
 #include <mach-o/dyld.h>
+#include <mach-o/getsect.h>
 
 /*
  * These are defined in here and these declarations need to be moved to libc.h
@@ -137,82 +142,28 @@ static char init = 0;             /* set while moninit() is being serviced */
 
 static unsigned long order = 0;        /* call order */
 
-struct mon_t {
+typedef struct {
     /* the address range and size this mon struct refers to */
     char               *lowpc;
     char               *highpc;
     unsigned long      textsize;
     /* the data structures to support the arc's and their counts */
     unsigned short     *froms; /* froms is unsigned shorts indexing into tos */
-    struct tostruct    *tos;
+    tostruct_t         *tos;
     long               tolimit;
     /* the pc-sample buffer, it's size and scale */
     char               *sbuf;
-    int                        ssiz;   /* includes the gmonhdr struct */
-    int                        scale;
-};
-static struct mon_t *mon = NULL;
+    long               ssiz;   /* includes the gmonhdr_t */
+    long               scale;
+} mon_t;
+static mon_t *mon = NULL;
 static unsigned long nmon = 0;
 
-static void monsetup(
-    struct mon_t *m,
-    char *lowpc,
-    char *highpc);
-static int getprofhz(
-    void);
-
 void
 moninit(
 void)
 {
-    const struct section *section;
-    char *lowpc, *highpc;
-    unsigned long i;
-
-       monreset();
-       init = 1;
-
-       section = getsectbyname ("__TEXT", "__text");
-       lowpc = (char *)section->addr,
-       highpc = (char *)(section->addr + section->size);
-
-       if(mon == NULL){
-           if((mon = malloc(sizeof(struct mon_t))) == NULL){
-               write(2, MSG, sizeof(MSG) - 1);
-               return;
-           }
-           nmon = 1;
-           memset(mon, '\0', sizeof(struct mon_t));
-       }
-       /*
-        * To continue to make monstartup() and the functions that existed
-        * before adding multiple profiling areas working correctly the new
-        * calls to get the dyld loaded code profiled are made after
-        * the first mon_t struct is allocated so that they will not use the 
-        * first mon_t and the old calls will always use the first mon_t struct
-        * in the list.
-        */
-       monsetup(mon, lowpc, highpc);
-
-       profil(mon->sbuf + sizeof(struct gmonhdr),
-              mon->ssiz - sizeof(struct gmonhdr),
-              (int)mon->lowpc, mon->scale);
-       for(i = 1; i < nmon; i++)
-           add_profil(mon[i].sbuf + sizeof(struct gmonhdr),
-                      mon[i].ssiz - sizeof(struct gmonhdr),
-                      (int)mon[i].lowpc, mon[i].scale);
-       init = 0;
-       profiling = 0;
-
-#if defined(__DYNAMIC__)
-        /*
-        * Call _dyld_moninit() if the dyld is present.  This is done after the
-        * above calls so the dynamic libraries will be added after the
-        * executable.
-        */
-       if(_dyld_present())
-           _dyld_moninit(monaddition);
-#endif
+       return; // Deprecated api. do nothing
 }
 
 void
@@ -220,16 +171,7 @@ monstartup(
 char *lowpc,
 char *highpc)
 {
-       monreset();
-       if(mon == NULL){
-           if((mon = malloc(sizeof(struct mon_t))) == NULL){
-               write(2, MSG, sizeof(MSG) - 1);
-               return;
-           }
-           nmon = 1;
-           memset(mon, '\0', sizeof(struct mon_t));
-       }
-       monsetup(mon, lowpc, highpc);
+       return; // Deprecated api. do nothing
 }
 
 /*
@@ -241,302 +183,21 @@ monaddition(
 char *lowpc,
 char *highpc)
 {
-    char save_profiling;
-    struct mon_t *m;
-
-       if(mon == NULL){
-           monstartup(lowpc, highpc);
-           return;
-       }
-       save_profiling = profiling;
-       profiling = -1;
-       if((mon = realloc(mon, (nmon + 1) * sizeof(struct mon_t))) == NULL){
-           write(2, MSG, sizeof(MSG) - 1);
-           return;
-       }
-       m = mon + nmon;
-       memset(m, '\0', sizeof(struct mon_t));
-       nmon++;
-       monsetup(m, lowpc, highpc);
-       profiling = save_profiling;
-}
-
-static
-void
-monsetup(
-struct mon_t *m,
-char *lowpc,
-char *highpc)
-{
-    int monsize;
-    char *buffer;
-    kern_return_t ret;
-    struct gmonhdr *p;
-    unsigned int o;
-
-       /*
-        * round lowpc and highpc to multiples of the density we're using
-        * so the rest of the scaling (here and in gprof) stays in ints.
-        */
-       lowpc = (char *)ROUNDDOWN((unsigned)lowpc,
-                                 HISTFRACTION * sizeof(HISTCOUNTER));
-       m->lowpc = lowpc;
-       highpc = (char *)ROUNDUP((unsigned)highpc,
-                                HISTFRACTION * sizeof(HISTCOUNTER));
-       m->highpc = highpc;
-
-       if(m->froms)
-           vm_deallocate(mach_task_self(),
-                         (vm_address_t)m->froms,
-                         (vm_size_t)(m->textsize / HASHFRACTION));
-       m->textsize = highpc - lowpc;
-       ret = vm_allocate(mach_task_self(),
-                         (vm_address_t *)&m->froms,
-                         (vm_size_t)(m->textsize / HASHFRACTION),
-                          TRUE);
-       if(ret != KERN_SUCCESS){
-           write(2, MSG, sizeof(MSG) - 1);
-           m->froms = 0;
-           return;
-       }
-
-       if(m->sbuf)
-           vm_deallocate(mach_task_self(),
-                         (vm_address_t)m->sbuf,
-                         (vm_size_t)m->ssiz);
-       monsize = (m->textsize / HISTFRACTION) + sizeof(struct gmonhdr);
-       ret = vm_allocate(mach_task_self(),
-                         (vm_address_t *)&buffer,
-                         (vm_size_t)monsize,
-                          TRUE);
-       if(ret != KERN_SUCCESS){
-           write(2, MSG, sizeof(MSG) - 1);
-           m->sbuf = 0;
-           return;
-       }
-
-       if(m->tos)
-           vm_deallocate(mach_task_self(),
-                         (vm_address_t)m->tos,
-                         (vm_size_t)(m->tolimit * sizeof(struct tostruct)));
-       m->tolimit = m->textsize * ARCDENSITY / 100;
-       if(m->tolimit < MINARCS){
-           m->tolimit = MINARCS;
-       }
-       else if(m->tolimit > 65534){
-           m->tolimit = 65534;
-       }
-       ret =  vm_allocate(mach_task_self(), 
-                          (vm_address_t *)&m->tos,
-                          (vm_size_t)(m->tolimit * sizeof(struct tostruct)),
-                           TRUE);
-       if(ret != KERN_SUCCESS){
-           write(2, MSG, sizeof(MSG) - 1);
-           m->tos = 0;
-           return;
-       }
-       m->tos[0].link = 0; /* a nop since tos was vm_allocated and is zero */
-
-       /*
-        * If this is call to monsetup() was via monstartup() (m == mon) then
-        * it is using or reusing the first pc range and then the pc sample 
-        * buffer can be setup by the system call profil() via monitor() via
-        * a moncontrol(1) call.
-        *
-        * Otherwise this is call to monsetup() was via monaddition() and a
-        * new system call is needed to add an additional pc sample buffer in
-        * the kernel.
-        */
-       if(m == mon && !init){
-           monitor(lowpc, highpc, buffer, monsize, m->tolimit);
-       }
-       else{
-           /* monitor() functionality */
-           m->sbuf = buffer;
-           m->ssiz = monsize;
-           p = (struct gmonhdr *)m->sbuf;
-           memset(p, '\0', sizeof(struct gmonhdr));
-           p->lpc = (unsigned long)m->lowpc;
-           p->hpc = (unsigned long)m->highpc;
-           p->ncnt = m->ssiz;
-           p->version = GMONVERSION;
-           p->profrate = getprofhz();
-           o = highpc - lowpc;
-           if((monsize - sizeof(struct gmonhdr)) < o)
-/* POSSIBLE BUG, if "(float) (monsize - sizeof(struct gmonhdr))/ o)" is zero
- * then m->scale will be set to zero and the add_profil() call will disable
- * profiling */
-               m->scale = ((float) (monsize - sizeof(struct gmonhdr))/ o) *
-                          SCALE_1_TO_1;
-           else
-               m->scale = SCALE_1_TO_1;
-
-            /* moncontrol(mode == 1) functionality */
-           if(!init)
-               add_profil(m->sbuf + sizeof(struct gmonhdr),
-                          m->ssiz - sizeof(struct gmonhdr),
-                          (int)m->lowpc, m->scale);
-       }
+       return; // Deprecated api. do nothing
 }
 
 void
 monreset(
 void)
 {
-    unsigned long i;
-    struct mon_t *m;
-    struct gmonhdr *p;
-
-       moncontrol(0);
-       if(mon == NULL)
-           return;
-       for(i = 0; i < nmon; i++){
-           m = mon + i;
-           if(m->sbuf != NULL){
-               memset(m->sbuf, '\0', m->ssiz);
-               p = (struct gmonhdr *)m->sbuf;
-               p->lpc = (unsigned long)m->lowpc;
-               p->hpc = (unsigned long)m->highpc;
-               p->ncnt = m->ssiz;
-               p->version = GMONVERSION;
-               p->profrate = getprofhz();
-           }
-           if(m->froms != NULL)
-               memset(m->froms, '\0', m->textsize / HASHFRACTION);
-           if(m->tos != NULL)
-               memset(m->tos, '\0', m->tolimit * sizeof (struct tostruct));
-       }
-       order = 0;
-       moncontrol(1);
+       return; // Deprecated api. do nothing
 }
 
 void
 monoutput(
 const char *filename)
 {
-    int fd;
-    unsigned long magic, i, fromindex, endfrom, toindex;
-    struct gmon_data sample_data, arc_data, dyld_data;
-    char *frompc;
-    struct rawarc_order rawarc_order;
-    struct mon_t *m;
-    unsigned long image_count, vmaddr_slide;
-    char *image_name;
-
-       moncontrol(0);
-       m = mon;
-       if(m == NULL)
-           return;
-       fd = creat(filename, 0666);
-       if(fd < 0){
-           perror("mcount: gmon.out");
-           return;
-       }
-
-       magic = GMON_MAGIC;
-       write(fd, &magic, sizeof(unsigned long));
-
-#if defined(__DYNAMIC__)
-        if(_dyld_present()){
-           image_count = _dyld_image_count();
-           if(image_count > 1){
-#ifdef DYLD_DEBUG
-               printf("image_count = %lu\n", image_count - 1);
-               for(i = 1; i < image_count; i++){
-                   vmaddr_slide = _dyld_get_image_vmaddr_slide(i);
-                   printf("\tvmaddr_slide 0x%x\n", (unsigned int)vmaddr_slide);
-                   image_name = _dyld_get_image_name(i);
-                   printf("\timage_name %s\n", image_name);
-               }
-#endif
-               /*
-                * Calculate the dyld_data.size.
-                */
-               dyld_data.type = GMONTYPE_DYLD_STATE;
-               dyld_data.size = sizeof(unsigned long) +
-                   sizeof(unsigned long) * (image_count - 1);
-               for(i = 1; i < image_count; i++){
-                   image_name = _dyld_get_image_name(i);
-                   dyld_data.size += strlen(image_name) + 1;
-               }
-
-               /*
-                * Write the dyld_data.
-                */
-               write(fd, &dyld_data, sizeof(struct gmon_data));
-               image_count--;
-               write(fd, &image_count, sizeof(unsigned long));
-               image_count++;
-               for(i = 1; i < image_count; i++){
-                   vmaddr_slide = _dyld_get_image_vmaddr_slide(i);
-                   write(fd, &vmaddr_slide, sizeof(unsigned long));
-                   image_name = _dyld_get_image_name(i);
-                   write(fd, image_name, strlen(image_name) + 1);
-               }
-           }
-       }
-#endif
-       for(i = 0; i < nmon; i++){
-           m = mon + i;
-#ifdef DEBUG
-           fprintf(stderr, "[monoutput] sbuf 0x%x ssiz %d\n",
-                   m->sbuf, m->ssiz);
-#endif
-           sample_data.type = GMONTYPE_SAMPLES;
-           sample_data.size = m->ssiz;
-           write(fd, &sample_data, sizeof(struct gmon_data));
-           /*
-            * Write the gmonhdr struct and the pc-sample buffer.  Note the
-            * gmonhdr struct is in sbuf at the beginning of sbuf already
-            * filled in.
-            */
-           write(fd, m->sbuf, m->ssiz);
-
-           /*
-            * Now write out the raw arcs.
-            */
-           endfrom = m->textsize / (HASHFRACTION * sizeof(*m->froms));
-           arc_data.type = GMONTYPE_ARCS_ORDERS;
-           arc_data.size = 0;
-           for(fromindex = 0; fromindex < endfrom; fromindex++){
-               if(m->froms[fromindex] == 0){
-                   continue;
-               }
-               frompc = m->lowpc +
-                        (fromindex * HASHFRACTION * sizeof(*m->froms));
-               for(toindex = m->froms[fromindex];
-                   toindex != 0;
-                   toindex = m->tos[toindex].link){
-                   arc_data.size += sizeof(struct rawarc_order);
-               }
-           }
-           write(fd, &arc_data, sizeof(struct gmon_data));
-
-           for(fromindex = 0; fromindex < endfrom; fromindex++){
-               if(m->froms[fromindex] == 0){
-                   continue;
-               }
-               frompc = m->lowpc +
-                        (fromindex * HASHFRACTION * sizeof(*m->froms));
-               for(toindex = m->froms[fromindex];
-                   toindex != 0;
-                   toindex = m->tos[toindex].link){
-#ifdef DEBUG
-                   fprintf(stderr, "[monoutput] frompc 0x%x selfpc 0x%x "
-                           "count %ld order %lu\n", (unsigned int)frompc,
-                           (unsigned int)m->tos[toindex].selfpc,
-                           m->tos[toindex].count, m->tos[toindex].order);
-#endif
-                   rawarc_order.raw_frompc = (unsigned long)frompc;
-                   rawarc_order.raw_selfpc = (unsigned long)
-                                              m->tos[toindex].selfpc;
-                   rawarc_order.raw_count = m->tos[toindex].count;
-                   rawarc_order.raw_order = m->tos[toindex].order;
-                   write(fd, &rawarc_order, sizeof(struct rawarc_order));
-               }
-           }
-       }
-       close(fd);
+       return; // Deprecated api. do nothing
 }
 
 void
@@ -547,37 +208,7 @@ char *buf,
 int bufsiz,
 int nfunc) /* nfunc is not used; available for compatability only. */
 {
-    unsigned int o;
-    struct gmonhdr *p;
-    struct mon_t *m;
-
-       moncontrol(0);
-       m = mon;
-       if(m == NULL)
-           return;
-       if(lowpc == 0){
-           moncontrol(0);
-           monoutput("gmon.out");
-           return;
-       }
-       m->sbuf = buf;
-       m->ssiz = bufsiz;
-       p = (struct gmonhdr *)buf;
-       memset(p, '\0', sizeof(struct gmonhdr));
-       p->lpc = (unsigned long)lowpc;
-       p->hpc = (unsigned long)highpc;
-       p->ncnt = m->ssiz;
-       p->version = GMONVERSION;
-       p->profrate = getprofhz();
-       bufsiz -= sizeof(struct gmonhdr);
-       if(bufsiz <= 0)
-           return;
-       o = highpc - lowpc;
-       if(bufsiz < o)
-           m->scale = ((float) bufsiz / o) * SCALE_1_TO_1;
-       else
-           m->scale = SCALE_1_TO_1;
-       moncontrol(1);
+       return; // Deprecated api. do nothing
 }
 
 /*
@@ -589,28 +220,7 @@ void
 moncontrol(
 int mode)
 {
-    struct mon_t *m;
-    unsigned long i;
-
-       if(mode){
-           /* start */
-           m = mon;
-           if(m != NULL){
-               profil(m->sbuf + sizeof(struct gmonhdr),
-                      m->ssiz - sizeof(struct gmonhdr),
-                      (int)m->lowpc, m->scale);
-               for(i = 1; i < nmon; i++)
-                   add_profil(mon[i].sbuf + sizeof(struct gmonhdr),
-                              mon[i].ssiz - sizeof(struct gmonhdr),
-                              (int)mon[i].lowpc, mon[i].scale);
-               profiling = 0;
-           }
-       }
-       else{
-           /* stop */
-           profil((char *)0, 0, 0, 0);
-           profiling = -1;
-       }
+       return; // Deprecated api. do nothing
 }
 
 void
@@ -618,146 +228,5 @@ moncount(
 char *frompc,
 char *selfpc)
 {
-    unsigned short *frompcindex;
-    struct tostruct *top, *prevtop;
-    unsigned long i, toindex;
-    struct mon_t *m;
-
-       m = mon;
-       if(m == NULL)
-           return;
-       /*
-        * Check that we are profiling and that we aren't recursively invoked.
-        * This should really be a test and set instruction in changing the
-        * value of profiling.
-        */
-       if(profiling)
-           return;
-       profiling++;
-
-
-#ifdef DEBUG
-       fprintf(stderr, "[moncount] frompc 0x%x selfpc 0x%x\n",
-               (unsigned int)frompc, (unsigned int)selfpc);
-#endif
-       frompcindex = (unsigned short *)frompc;
-
-       /*
-        * check that frompcindex is a reasonable pc value.
-        * for example: signal catchers get called from the stack,
-        *              not from text space.  too bad.
-        */
-       for(i = 0; i < nmon; i++){
-           m = mon + i;
-           if((unsigned long)frompcindex >= (unsigned long)m->lowpc &&
-              (unsigned long)frompcindex <  (unsigned long)m->highpc)
-               break;
-       }
-       if(i == nmon){
-           goto done;
-       }
-       else{
-           frompcindex = (unsigned short *)
-                 ((unsigned long)frompcindex - (unsigned long)m->lowpc);
-       }
-       frompcindex =
-           &m->froms[((long)frompcindex) / (HASHFRACTION * sizeof(*m->froms))];
-       toindex = *frompcindex;
-       if(toindex == 0){
-           /*
-            *  first time traversing this arc
-            */
-           toindex = ++m->tos[0].link;
-           if(toindex >= m->tolimit){
-               goto overflow;
-           }
-           *frompcindex = toindex;
-           top = &m->tos[toindex];
-           top->selfpc = (unsigned long)selfpc;
-           top->count = 1;
-           top->link = 0;
-           top->order = ++order;
-           goto done;
-       }
-       top = &m->tos[toindex];
-       if(top->selfpc == (unsigned long)selfpc){
-           /*
-            * arc at front of chain; usual case.
-            */
-           top->count++;
-           goto done;
-       }
-       /*
-        * have to go looking down chain for it.
-        * top points to what we are looking at,
-        * prevtop points to previous top.
-        * we know it is not at the head of the chain.
-        */
-       for(; /* goto done */; ){
-           if(top->link == 0){
-               /*
-                * top is end of the chain and none of the chain
-                * had top->selfpc == selfpc.
-                * so we allocate a new tostruct
-                * and link it to the head of the chain.
-                */
-               toindex = ++m->tos[0].link;
-               if(toindex >= m->tolimit){
-                   goto overflow;
-               }
-               top = &m->tos[toindex];
-               top->selfpc = (unsigned long)selfpc;
-               top->count = 1;
-               top->link = *frompcindex;
-               top->order = ++order;
-               *frompcindex = toindex;
-               goto done;
-           }
-           /*
-            * otherwise, check the next arc on the chain.
-            */
-           prevtop = top;
-           top = &m->tos[top->link];
-           if(top->selfpc == (unsigned long)selfpc){
-               /*
-                * there it is.
-                * increment its count
-                * move it to the head of the chain.
-                */
-               top->count++;
-               toindex = prevtop->link;
-               prevtop->link = top->link;
-               top->link = *frompcindex;
-               *frompcindex = toindex;
-               goto done;
-           }
-       }
-done:
-       profiling--;
-       return;
-
-overflow:
-       profiling++; /* halt further profiling */
-#define        TOLIMIT "mcount: tos overflow\n"
-       write(2, TOLIMIT, sizeof(TOLIMIT) - 1);
-}
-
-/*
- * Get the profiling rate.
- */
-static
-int
-getprofhz(void)
-{
-    int mib[2];
-    size_t size;
-    struct clockinfo clockrate;
-
-        mib[0] = CTL_KERN;
-        mib[1] = KERN_CLOCKRATE;
-        clockrate.profhz = 1;
-        size = sizeof(clockrate);
-        if(sysctl(mib, 2, &clockrate, &size, NULL, 0) < 0)
-               ;
-        return(clockrate.profhz);
+       return; //Deprecated api. do nothing
 }