/* Copyright 2013-2021 Free Software Foundation, Inc.

   This file is part of GDB.

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

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <errno.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct
{
  unsigned char	e_ident[16];
  uint16_t	e_type;
  uint16_t	e_machine;
  uint32_t	e_version;
  uint32_t	e_entry;
  uint32_t	e_phoff;
  uint32_t	e_shoff;
  uint32_t	e_flags;
  uint16_t	e_ehsize;
  uint16_t	e_phentsize;
  uint16_t	e_phnum;
  uint16_t	e_shentsize;
  uint16_t	e_shnum;
  uint16_t	e_shstrndx;
} Elf32_Ehdr;

typedef struct
{
  unsigned char	e_ident[16];
  uint16_t	e_type;
  uint16_t	e_machine;
  uint32_t	e_version;
  uint64_t	e_entry;
  uint64_t	e_phoff;
  uint64_t	e_shoff;
  uint32_t	e_flags;
  uint16_t	e_ehsize;
  uint16_t	e_phentsize;
  uint16_t	e_phnum;
  uint16_t	e_shentsize;
  uint16_t	e_shnum;
  uint16_t	e_shstrndx;
} Elf64_Ehdr;

typedef struct
{
  uint32_t	p_type;
  uint32_t	p_offset;
  uint32_t	p_vaddr;
  uint32_t	p_paddr;
  uint32_t	p_filesz;
  uint32_t	p_memsz;
  uint32_t	p_flags;
  uint32_t	p_align;
} Elf32_Phdr;

typedef struct
{
  uint32_t	p_type;
  uint32_t	p_flags;
  uint64_t	p_offset;
  uint64_t	p_vaddr;
  uint64_t	p_paddr;
  uint64_t	p_filesz;
  uint64_t	p_memsz;
  uint64_t	p_align;
} Elf64_Phdr;

struct elfbuf
{
  const char *path;
  unsigned char *buf;
  size_t len;
  enum { ELFCLASS32 = 1,
	 ELFCLASS64 = 2 } ei_class;
};

#define ELFBUF_EHDR_LEN(elf)					\
  ((elf)->ei_class == ELFCLASS32 ? sizeof (Elf32_Ehdr) :	\
   sizeof (Elf64_Ehdr))

#define ELFBUF_EHDR(elf, memb)			\
  ((elf)->ei_class == ELFCLASS32 ?		\
   ((Elf32_Ehdr *) (elf)->buf)->memb		\
   : ((Elf64_Ehdr *) (elf)->buf)->memb)

#define ELFBUF_PHDR_LEN(elf)					\
  ((elf)->ei_class == ELFCLASS32 ? sizeof (Elf32_Phdr) :	\
   sizeof (Elf64_Phdr))

#define ELFBUF_PHDR(elf, idx, memb)				\
  ((elf)->ei_class == ELFCLASS32 ?				\
   ((Elf32_Phdr *) &(elf)->buf[((Elf32_Ehdr *)(elf)->buf)	\
			       ->e_phoff])[idx].memb		\
   : ((Elf64_Phdr *) &(elf)->buf[((Elf64_Ehdr *)(elf)->buf)	\
				 ->e_phoff])[idx].memb)

static void
exit_with_msg(const char *fmt, ...)
{
  va_list ap;

  fflush (stdout);
  va_start (ap, fmt);
  vfprintf (stderr, fmt, ap);
  va_end (ap);

  if (errno)
    {
      fputs (": ", stderr);
      perror (NULL);
    }
  else
    fputc ('\n', stderr);
  exit (1);
}

static void
read_file (unsigned char **buf_ptr, size_t *len_ptr, FILE *fp)
{
  size_t len = 0;
  size_t size = 1024;
  size_t chunk;
  unsigned char *buf = malloc (size);

  while ((chunk = fread (buf + len, 1, size - len, fp)) == size - len)
    {
      len = size;
      size *= 2;
      buf = realloc (buf, size);
    }
  len += chunk;
  *buf_ptr = buf;
  *len_ptr = len;
}

static void
write_file (unsigned char *buf, size_t len, FILE *fp)
{
  fwrite (buf, 1, len, fp);
}

static void
elfbuf_init_from_file (struct elfbuf *elf, const char *path)
{
  FILE *fp = fopen (path, "rb");
  unsigned char *buf;
  size_t len;

  if (fp == NULL)
    exit_with_msg ("%s", path);

  read_file (&buf, &len, fp);
  fclose (fp);

  /* Validate ELF identification. */
  if (len < 16
      || buf[0] != 0x7f || buf[1] != 0x45 || buf[2] != 0x4c || buf[3] != 0x46
      || buf[4] < 1 || buf[4] > 2 || buf[5] < 1 || buf[5] > 2)
    exit_with_msg ("%s: unsupported or invalid ELF file", path);

  elf->path = path;
  elf->buf = buf;
  elf->len = len;
  elf->ei_class = buf[4];

  if (ELFBUF_EHDR_LEN (elf) > len
      || ELFBUF_EHDR (elf, e_phoff) > len
      || ELFBUF_EHDR (elf, e_phnum) > ((len - ELFBUF_EHDR (elf, e_phoff))
				       / ELFBUF_PHDR_LEN (elf)) )
    exit_with_msg ("%s: unexpected end of data", path);

  if (ELFBUF_EHDR (elf, e_phentsize) != ELFBUF_PHDR_LEN (elf))
    exit_with_msg ("%s: inconsistent ELF header", path);
}

static void
elfbuf_write_to_file (struct elfbuf *elf, const char *path)
{
  FILE *fp = fopen (path, "wb");

  if (fp == NULL)
    exit_with_msg ("%s", path);

  write_file (elf->buf, elf->len, fp);
  fclose (fp);
}

/* In the auxv note starting at OFFSET with size LEN, mask the hwcap
   field using the HWCAP_MASK. */

static void
elfbuf_handle_auxv (struct elfbuf *elf, size_t offset, size_t len,
		    unsigned long hwcap_mask)
{
  size_t i;
  uint32_t *auxv32 = (uint32_t *) (elf->buf + offset);
  uint64_t *auxv64 = (uint64_t *) auxv32;
  size_t entry_size = elf->ei_class == ELFCLASS32 ?
    sizeof (auxv32[0]) : sizeof (auxv64[0]);

  for (i = 0; i < len / entry_size; i++)
    {
      uint64_t auxv_type = elf->ei_class == ELFCLASS32 ?
	auxv32[2 * i] : auxv64[2 * i];

      if (auxv_type == 0)
	break;
      if (auxv_type != 16)
	continue;

      if (elf->ei_class == ELFCLASS32)
	auxv32[2 * i + 1] &= (uint32_t) hwcap_mask;
      else
	auxv64[2 * i + 1] &= (uint64_t) hwcap_mask;
    }
}

/* In the note segment starting at OFFSET with size LEN, make notes
   with type NOTE_TYPE unrecognizable by GDB.  Also, mask the hwcap
   field of any auxv notes using the HWCAP_MASK. */

static void
elfbuf_handle_note_segment (struct elfbuf *elf, size_t offset, size_t len,
			    unsigned note_type, unsigned long hwcap_mask)
{
  size_t pos = 0;

  while (pos + 12 < len)
    {
      uint32_t *note = (uint32_t *) (elf->buf + offset + pos);
      size_t desc_pos = pos + 12 + ((note[0] + 3) & ~3);
      size_t next_pos = desc_pos + ((note[1] + 3) & ~3);

      if (desc_pos > len || next_pos > len)
	exit_with_msg ("%s: corrupt notes data", elf->path);

      if (note[2] == note_type)
	note[2] |= 0xff000000;
      else if (note[2] == 6 && hwcap_mask != 0)
	elfbuf_handle_auxv (elf, offset + desc_pos, note[1],
			    hwcap_mask);
      pos = next_pos;
    }
}

static void
elfbuf_handle_core_notes (struct elfbuf *elf, unsigned note_type,
			  unsigned long hwcap_mask)
{
  unsigned ph_idx;

  if (ELFBUF_EHDR (elf, e_type) != 4)
    exit_with_msg ("%s: not a core file", elf->path);

  /* Iterate over program headers. */
  for (ph_idx = 0; ph_idx != ELFBUF_EHDR (elf, e_phnum); ph_idx++)
    {
      size_t offset = ELFBUF_PHDR (elf, ph_idx, p_offset);
      size_t filesz = ELFBUF_PHDR (elf, ph_idx, p_filesz);

      if (offset > elf->len || filesz > elf->len - offset)
	exit_with_msg ("%s: unexpected end of data", elf->path);

      /* Deal with NOTE segments only. */
      if (ELFBUF_PHDR (elf, ph_idx, p_type) != 4)
	continue;
      elfbuf_handle_note_segment (elf, offset, filesz, note_type,
				  hwcap_mask);
    }
}

int
main (int argc, char *argv[])
{
  unsigned note_type;
  unsigned long hwcap_mask = 0;
  struct elfbuf elf;

  if (argc < 4)
    {
      abort ();
    }

  if (sscanf (argv[3], "%u", &note_type) != 1)
    exit_with_msg ("%s: bad command line arguments\n", argv[0]);

  if (argc >= 5)
    {
      if (sscanf (argv[4], "%lu", &hwcap_mask) != 1)
	exit_with_msg ("%s: bad command line arguments\n", argv[0]);
    }

  elfbuf_init_from_file (&elf, argv[1]);
  elfbuf_handle_core_notes (&elf, note_type, hwcap_mask);
  elfbuf_write_to_file (&elf, argv[2]);

  return 0;
}
