/* Dynamic linker system dependencies for Linux.
   Copyright (C) 1995-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   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/>.  */

/* Linux needs some special initialization, but otherwise uses
   the generic dynamic linker system interface code.  */

#include <assert.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/utsname.h>
#include <ldsodefs.h>
#include <kernel-features.h>

#ifdef SHARED
# define DL_SYSDEP_INIT frob_brk ()

static inline void
frob_brk (void)
{
  __brk (0);			/* Initialize the break.  */
}

# include <elf/dl-sysdep.c>
#endif


int
attribute_hidden
_dl_discover_osversion (void)
{
#if defined NEED_DL_SYSINFO_DSO && defined SHARED
  if (GLRO(dl_sysinfo_map) != NULL)
    {
      /* If the kernel-supplied DSO contains a note indicating the kernel's
	 version, we don't need to call uname or parse any strings.  */

      static const struct
      {
	ElfW(Nhdr) hdr;
	char vendor[8];
      } expected_note = { { sizeof "Linux", sizeof (ElfW(Word)), 0 }, "Linux" };
      const ElfW(Phdr) *const phdr = GLRO(dl_sysinfo_map)->l_phdr;
      const ElfW(Word) phnum = GLRO(dl_sysinfo_map)->l_phnum;
      for (uint_fast16_t i = 0; i < phnum; ++i)
	if (phdr[i].p_type == PT_NOTE)
	  {
	    const ElfW(Addr) start = (phdr[i].p_vaddr
				      + GLRO(dl_sysinfo_map)->l_addr);
	    const ElfW(Nhdr) *note = (const void *) start;
	    while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz)
	      {
		if (!memcmp (note, &expected_note, sizeof expected_note))
		  return *(const ElfW(Word) *) ((const void *) note
						+ sizeof expected_note);
#define ROUND(len) (((len) + sizeof note->n_type - 1) & -sizeof note->n_type)
		note = ((const void *) (note + 1)
			+ ROUND (note->n_namesz) + ROUND (note->n_descsz));
#undef ROUND
	      }
	  }
    }
#endif

  char bufmem[64];
  char *buf = bufmem;
  unsigned int version;
  int parts;
  char *cp;
  struct utsname uts;

  /* Try the uname system call.  */
  if (__uname (&uts))
    {
      /* This was not successful.  Now try reading the /proc filesystem.  */
      int fd = __open ("/proc/sys/kernel/osrelease", O_RDONLY);
      if (fd < 0)
	return -1;
      ssize_t reslen = __read (fd, bufmem, sizeof (bufmem));
      __close (fd);
      if (reslen <= 0)
	/* This also didn't work.  We give up since we cannot
	   make sure the library can actually work.  */
	return -1;
      buf[MIN (reslen, (ssize_t) sizeof (bufmem) - 1)] = '\0';
    }
  else
    buf = uts.release;

  /* Now convert it into a number.  The string consists of at most
     three parts.  */
  version = 0;
  parts = 0;
  cp = buf;
  while ((*cp >= '0') && (*cp <= '9'))
    {
      unsigned int here = *cp++ - '0';

      while ((*cp >= '0') && (*cp <= '9'))
	{
	  here *= 10;
	  here += *cp++ - '0';
	}

      ++parts;
      version <<= 8;
      version |= here;

      if (*cp++ != '.' || parts == 3)
	/* Another part following?  */
	break;
    }

  if (parts < 3)
    version <<= 8 * (3 - parts);

  return version;
}

/* Mask every signal, returning the previous sigmask in OLD.  */
void
internal_function
_dl_mask_all_signals (sigset_t *old)
{
  int ret;
  sigset_t new;

  sigfillset (&new);

  /* This function serves as a replacement to pthread_sigmask, which
     isn't available from within the dynamic linker since it would require
     linking with libpthread. We duplicate some of the functionality here
     to avoid requiring libpthread.  This isn't quite identical to
     pthread_sigmask in that we do not mask internal signals used for
     cancellation and setxid handling. This disables asynchronous
     cancellation for the duration the signals are disabled, but it's a
     small window, and prevents any problems with the use of TLS variables
     in the signal handlers that would have executed.  */

  /* It's very important we don't touch errno here, as that's TLS; since this
     gets called from get_tls_addr we might end up recursing.  */

  INTERNAL_SYSCALL_DECL (err);

  ret = INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &new, old,
			  _NSIG / 8);

  assert (ret == 0);
}

/* Return sigmask to what it was before a call to _dl_mask_all_signals.  */
void
internal_function
_dl_unmask_signals (sigset_t *old)
{
  int ret;
  INTERNAL_SYSCALL_DECL (err);

  ret = INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, old, NULL,
			  _NSIG / 8);

  assert (ret == 0);
}
