/* 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.
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>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <stdint.h>
#include <ldsodefs.h>
#include <sys/gmon.h>
#include <sys/gmon_out.h>
#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
{
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;
/* 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;
*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];
print_error:
errnum = errno;
if (fd != -1)
- __close (fd);
+ __close_nocancel (fd);
_dl_error_printf (errstr, filename,
__strerror_r (errnum, buf, sizeof buf));
return;
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)
}
/* We don't need the file descriptor anymore. */
- __close (fd);
+ __close_nocancel (fd);
/* Pointer to data after the header. */
hist = (char *) (addr + 1);
done:
;
}
-INTDEF(_dl_mcount)
+rtld_hidden_def (_dl_mcount)