]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - elf/dl-profile.c
Sync "language", "lang_name", "territory", "country_name" with CLDR/langtable
[thirdparty/glibc.git] / elf / dl-profile.c
index f7e99a09e96ccfe303145c4a3bf362948d18e276..d243a15cf9f92380217370718250ec73138cc3d8 100644 (file)
@@ -1,5 +1,5 @@
 /* Profiling of shared libraries.
-   Copyright (C) 1997-2004, 2006, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
    Based on the BSD mcount implementation.
@@ -16,7 +16,7 @@
 
    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
+   <https://www.gnu.org/licenses/>.  */
 
 #include <assert.h>
 #include <errno.h>
@@ -27,6 +27,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <stdint.h>
 #include <ldsodefs.h>
 #include <sys/gmon.h>
 #include <sys/gmon_out.h>
@@ -34,6 +35,7 @@
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <atomic.h>
+#include <not-cancel.h>
 
 /* The LD_PROFILE feature has to be implemented different to the
    normal profiling using the gmon/ functions.  The problem is that an
@@ -130,7 +132,18 @@ struct here_cg_arc_record
   {
     uintptr_t from_pc;
     uintptr_t self_pc;
-    uint32_t count;
+    /* The count field is atomically incremented in _dl_mcount, which
+       requires it to be properly aligned for its type, and for this
+       alignment to be visible to the compiler.  The amount of data
+       before an array of this structure is calculated as
+       expected_size in _dl_start_profile.  Everything in that
+       calculation is a multiple of 4 bytes (in the case of
+       kcountsize, because it is derived from a subtraction of
+       page-aligned values, and the corresponding calculation in
+       __monstartup also ensures it is at least a multiple of the size
+       of u_long), so all copies of this field do in fact have the
+       appropriate alignment.  */
+    uint32_t count __attribute__ ((aligned (__alignof__ (uint32_t))));
   } __attribute__ ((packed));
 
 static struct here_cg_arc_record *data;
@@ -168,7 +181,6 @@ static unsigned int log_hashfraction;
 /* Set up profiling data to profile object desribed by MAP.  The output
    file is found (or created) in OUTPUT_DIR.  */
 void
-internal_function
 _dl_start_profile (void)
 {
   char *filename;
@@ -313,12 +325,7 @@ _dl_start_profile (void)
   *cp++ = '/';
   __stpcpy (__stpcpy (cp, GLRO(dl_profile)), ".profile");
 
-#ifdef O_NOFOLLOW
-# define EXTRA_FLAGS | O_NOFOLLOW
-#else
-# define EXTRA_FLAGS
-#endif
-  fd = __open (filename, O_RDWR | O_CREAT EXTRA_FLAGS, DEFFILEMODE);
+  fd = __open64_nocancel (filename, O_RDWR|O_CREAT|O_NOFOLLOW, DEFFILEMODE);
   if (fd == -1)
     {
       char buf[400];
@@ -329,7 +336,7 @@ _dl_start_profile (void)
     print_error:
       errnum = errno;
       if (fd != -1)
-       __close (fd);
+       __close_nocancel (fd);
       _dl_error_printf (errstr, filename,
                        __strerror_r (errnum, buf, sizeof buf));
       return;
@@ -358,15 +365,14 @@ _dl_start_profile (void)
          goto print_error;
        }
 
-      if (TEMP_FAILURE_RETRY (__libc_write (fd, buf, (expected_size
-                                                     & (GLRO(dl_pagesize)
-                                                        - 1))))
+      if (TEMP_FAILURE_RETRY
+         (__write_nocancel (fd, buf, (expected_size & (GLRO(dl_pagesize) - 1))))
          < 0)
        goto cannot_create;
     }
   else if (st.st_size != expected_size)
     {
-      __close (fd);
+      __close_nocancel (fd);
     wrong_format:
 
       if (addr != NULL)
@@ -386,7 +392,7 @@ _dl_start_profile (void)
     }
 
   /* We don't need the file descriptor anymore.  */
-  __close (fd);
+  __close_nocancel (fd);
 
   /* Pointer to data after the header.  */
   hist = (char *) (addr + 1);
@@ -586,4 +592,4 @@ _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc)
  done:
   ;
 }
-INTDEF(_dl_mcount)
+rtld_hidden_def (_dl_mcount)