/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
  Copyright (c) 2008 Eliot Dresselhaus

  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
  "Software"), to deal in the Software without restriction, including
  without limitation the rights to use, copy, modify, merge, publish,
  distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so, subject to
  the following conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <vppinfra/elf.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#ifndef CLIB_UNIX
#error "unix only"
#endif

typedef struct {
  elf_main_t elf_main;
  char * input_file;
  char * output_file;
  char * set_interpreter;
  char * set_rpath;
  int unset_rpath;
  int verbose;
  int quiet;
  int allow_elf_shared;
  /* for use in the optimized / simplified case */
  u64 file_size;
  u64 interpreter_offset;
  u64 rpath_offset;
} elf_tool_main_t;

static clib_error_t * elf_set_interpreter (elf_main_t * em, 
                                           elf_tool_main_t * tm)
{
  elf_segment_t * g;
  elf_section_t * s;
  clib_error_t * error;
  char * interp = tm->set_interpreter;

  switch (em->first_header.file_type)
    {
    case ELF_EXEC:
      break;

    case ELF_SHARED:
      if (tm->allow_elf_shared)
        break;
      /* Note flowthrough */
    default:
      return clib_error_return (0, "unacceptable file_type");    
    }

  vec_foreach (g, em->segments)
    {
      if (g->header.type == ELF_SEGMENT_INTERP)
	break;
    }

  if (g >= vec_end (em->segments))
    return clib_error_return (0, "interpreter not found");

  if (g->header.memory_size < 1 + strlen (interp))
    return clib_error_return (0, "given interpreter does not fit; must be less than %d bytes (`%s' given)",
			      g->header.memory_size, interp);

  error = elf_get_section_by_start_address (em, g->header.virtual_address, &s);
  if (error)
    return error;

  /* Put in new null terminated string. */
  memset (s->contents, 0, vec_len (s->contents));
  memcpy (s->contents, interp, strlen (interp));

  return 0;
}

static void
delete_rpath_for_section (elf_main_t * em, elf_section_t * s)
{
  elf64_dynamic_entry_t * e;
  elf64_dynamic_entry_t * new_es = 0;

  vec_foreach (e, em->dynamic_entries)
    {
      switch (e->type)
	{
	case ELF_DYNAMIC_ENTRY_RPATH:
	case ELF_DYNAMIC_ENTRY_RUN_PATH:
	  break;

	default:
	  vec_add1 (new_es, e[0]);
	  break;
	}
    }

  /* Pad so as to keep section size constant. */
  {
    elf64_dynamic_entry_t e_end;
    e_end.type = ELF_DYNAMIC_ENTRY_END;
    e_end.data = 0;
    while (vec_len (new_es) < vec_len (em->dynamic_entries))
      vec_add1 (new_es, e_end);
  }

  vec_free (em->dynamic_entries);
  em->dynamic_entries = new_es;

  elf_set_dynamic_entries (em);
}

static void delete_rpath (elf_main_t * em)
{
  elf_section_t * s;

  vec_foreach (s, em->sections)
    {
      switch (s->header.type)
	{
	case ELF_SECTION_DYNAMIC:
	  delete_rpath_for_section (em, s);
	  break;

	default:
	  break;
	}
    }
}

static clib_error_t *
set_rpath_for_section (elf_main_t * em, elf_section_t * s, char * new_rpath)
{
  elf64_dynamic_entry_t * e;
  char * old_rpath;
  int old_len, new_len = strlen (new_rpath);
  u8 * new_string_table = vec_dup (em->dynamic_string_table);

  vec_foreach (e, em->dynamic_entries)
    {
      switch (e->type)
	{
	case ELF_DYNAMIC_ENTRY_RPATH:
	case ELF_DYNAMIC_ENTRY_RUN_PATH:
	  old_rpath = (char *) new_string_table + e->data;
	  old_len = strlen (old_rpath);
	  if (old_len < new_len)
	    return clib_error_return (0, "rpath of `%s' does not fit (old rpath `%s')",
				      new_rpath, old_rpath);
	  strcpy (old_rpath, new_rpath);
	  break;

	default:
	  break;
	}
    }

  elf_set_section_contents (em, em->dynamic_string_table_section_index,
			    new_string_table,
			    vec_bytes (new_string_table));

  return 0;
}

static clib_error_t *
set_rpath (elf_main_t * em, char * rpath)
{
  clib_error_t * error = 0;
  elf_section_t * s;

  vec_foreach (s, em->sections)
    {
      switch (s->header.type)
	{
	case ELF_SECTION_DYNAMIC:
	  error = set_rpath_for_section (em, s, rpath);
	  if (error)
	    return error;
	  break;

	default:
	  break;
	}
    }

  return error;
}

static clib_error_t *
set_interpreter_rpath (elf_tool_main_t * tm)
{
  int ifd = -1, ofd = -1;
  struct stat fd_stat;
  u8 *idp = 0;                  /* warning be gone */
  u64 mmap_length = 0, i;
  u32 run_length;
  u8 in_run;
  u64 offset0 = 0, offset1 = 0;
  clib_error_t * error = 0;
  int fix_in_place = 0;

  if (!strcmp (tm->input_file, tm->output_file))
    fix_in_place = 1;

  ifd = open (tm->input_file, O_RDWR);
  if (ifd < 0)
    {
      error = clib_error_return_unix (0, "open `%s'", tm->input_file);
      goto done;
    }

  if (fstat (ifd, &fd_stat) < 0)
    {
      error = clib_error_return_unix (0, "fstat `%s'", tm->input_file);
      goto done;
    }

  if (!(fd_stat.st_mode & S_IFREG)) 
    {
      error = clib_error_return (0, "%s is not a regular file", tm->input_file);
      goto done;
    }

  mmap_length = fd_stat.st_size;
  if (mmap_length < 4)
    {
      error = clib_error_return (0, "%s too short", tm->input_file);
      goto done;
    }

  /* COW-mapping, since we intend to write the fixups */
  if (fix_in_place)
    idp = mmap (0, mmap_length, PROT_READ | PROT_WRITE, MAP_SHARED, 
              ifd, /* offset */ 0);
  else
    idp = mmap (0, mmap_length, PROT_READ | PROT_WRITE, MAP_PRIVATE, 
              ifd, /* offset */ 0);
  if (~pointer_to_uword (idp) == 0)
    {
      mmap_length = 0;
      error = clib_error_return_unix (0, "mmap `%s'", tm->input_file);
      goto done;
    }
  
  if (idp[0] != 0x7f || idp[1] != 'E' || idp[2] != 'L' || idp[3] != 'F')
    {
      error = clib_error_return (0, "not an ELF file '%s'", tm->input_file);
      goto done;
    }

  in_run = 0;
  run_length = 0;

  for (i = 0; i < mmap_length; i++)
    {
      if (idp[i] == '/')
        {
          if (in_run)
            run_length++;
          else
            {
              in_run = 1;
              run_length = 1;
            }
        }
      else
        {
          if (in_run && run_length >= 16)
            {
              if (offset0 == 0)
                  offset0 = (i - run_length);
              else if (offset1 == 0)
                {
                  offset1 = (i - run_length);
                  goto found_both;
                }
            }
          in_run = 0;
          run_length = 0;
        }
    }

  if (offset0 == 0)
    {
      error = clib_error_return (0, "no fixup markers in %s", 
                                 tm->input_file);
      goto done;
    }

 found_both:
  if (0)
    clib_warning ("offset0 %lld (0x%llx), offset1 %lld (0x%llx)", 
                  offset0, offset0, offset1, offset1);

  /* Executable file case */
  if (offset0 && offset1)
    {
      tm->interpreter_offset = offset0;
      tm->rpath_offset = offset1;
    }
  else /* shared library case */                         
    {
      tm->interpreter_offset = 0;
      tm->rpath_offset = offset0;
    }
  
  if (tm->interpreter_offset)
    memcpy (&idp[tm->interpreter_offset], tm->set_interpreter, 
            strlen (tm->set_interpreter)+1);

  if (tm->rpath_offset)
    memcpy (&idp[tm->rpath_offset], tm->set_rpath, 
            strlen (tm->set_rpath)+1);

  /* Write the output file... */
  if (fix_in_place == 0)
    {
      ofd = open (tm->output_file, O_RDWR | O_CREAT | O_TRUNC, 0644);
      if (ofd < 0)
        {
          error = clib_error_return_unix (0, "create `%s'", tm->output_file);
          goto done;
        }

      if (write (ofd, idp, mmap_length) != mmap_length)
        error = clib_error_return_unix (0, "write `%s'", tm->output_file);
    }

 done:
  if (mmap_length > 0)
    munmap (idp, mmap_length);
  close (ifd);
  close (ofd);
  return error;
}


int main (int argc, char * argv[])
{
  elf_tool_main_t _tm, * tm = &_tm;
  elf_main_t * em = &tm->elf_main;
  unformat_input_t i;
  clib_error_t * error = 0;

  memset (tm, 0, sizeof (tm[0]));
  unformat_init_command_line (&i, argv);

  while (unformat_check_input (&i) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (&i, "in %s", &tm->input_file))
	;
      else if (unformat (&i, "out %s", &tm->output_file))
	;
      else if (unformat (&i, "set-interpreter %s", &tm->set_interpreter))
	;
      else if (unformat (&i, "set-rpath %s", &tm->set_rpath))
	;
      else if (unformat (&i, "unset-rpath"))
	tm->unset_rpath = 1;
      else if (unformat (&i, "verbose"))
	tm->verbose = ~0;
      else if (unformat (&i, "verbose-symbols"))
	tm->verbose |= FORMAT_ELF_MAIN_SYMBOLS;
      else if (unformat (&i, "verbose-relocations"))
	tm->verbose |= FORMAT_ELF_MAIN_RELOCATIONS;
      else if (unformat (&i, "verbose-dynamic"))
	tm->verbose |= FORMAT_ELF_MAIN_DYNAMIC;
      else if (unformat (&i, "quiet"))
	tm->quiet = 1;
      else if (unformat (&i, "allow-elf-shared"))
        tm->allow_elf_shared = 1;
      else
	{
	  error = unformat_parse_error (&i);
	  goto done;
	}
    }

  if (! tm->input_file)
    clib_error ("no input file");

  /* Do the typical case a stone-simple way... */
  if (tm->quiet && tm->set_interpreter && tm->set_rpath && tm->output_file)
    {
      error = set_interpreter_rpath (tm);
      goto done;
    }

  error = elf_read_file (em, tm->input_file);

  if (error)
    goto done;

  if (tm->verbose)
    fformat (stdout, "%U", format_elf_main, em, tm->verbose);

  if (tm->set_interpreter)
    {
      error = elf_set_interpreter (em, tm);
      if (error)
	goto done;
    }

  if (tm->set_rpath)
    {
      error = set_rpath (em, tm->set_rpath);
      if (error)
	goto done;
    }

  if (tm->unset_rpath)
    delete_rpath (em);

  if (tm->output_file)
    error = elf_write_file (em, tm->output_file);

  elf_main_free (em);

 done:
  if (error)
    {
      if (tm->quiet == 0)
        clib_error_report (error);
      return 1;
    }
  else
    return 0;
}
