about summary refs log tree commit diff
path: root/elf/dl-profile.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-profile.c')
-rw-r--r--elf/dl-profile.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/elf/dl-profile.c b/elf/dl-profile.c
index f67b5d08b5..40c4757307 100644
--- a/elf/dl-profile.c
+++ b/elf/dl-profile.c
@@ -22,6 +22,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
+#include <limits.h>
 #include <link.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -403,13 +404,20 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
   /* Setup counting data.  */
   if (kcountsize < highpc - lowpc)
     {
-      /* XXX I've not yet verified that the second expression is really
-	 well suited but something like this is in any case necessary
-	 for targets without hardware FP support.  --drepper  */
 #if 0
       s_scale = ((double) kcountsize / (highpc - lowpc)) * SCALE_1_TO_1;
 #else
-      s_scale = (kcountsize * SCALE_1_TO_1) / (highpc - lowpc);
+      size_t range = highpc - lowpc;
+      size_t quot = range / kcountsize;
+
+      if (quot >= SCALE_1_TO_1)
+	s_scale = 1;
+      else if (quot >= SCALE_1_TO_1 / 256)
+	s_scale = SCALE_1_TO_1 / quot;
+      else if (range > ULONG_MAX / 256)
+	s_scale = (SCALE_1_TO_1 * 256) / (range / (kcountsize / 256));
+      else
+	s_scale = (SCALE_1_TO_1 * 256) / ((range * 256) / kcountsize);
 #endif
     }
   else