// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// file_id.cc: Return a unique identifier for a file
//
// See file_id.h for documentation
//
// Author: Alfred Peng

#include <elf.h>
#include <fcntl.h>
#include <gelf.h>
#include <sys/mman.h>
#include <sys/ksyms.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include <cassert>
#include <cstdio>

#include "common/md5.h"
#include "common/solaris/file_id.h"
#include "common/solaris/message_output.h"
#include "google_breakpad/common/minidump_format.h"

namespace google_breakpad {

class AutoElfEnder {
 public:
  AutoElfEnder(Elf* elf) : elf_(elf) {}
  ~AutoElfEnder() { if (elf_) elf_end(elf_); }
 private:
  Elf* elf_;
};

// Find the text section in elf object file.
// Return the section start address and the size.
static bool FindElfTextSection(int fd, const void* elf_base,
                               const void** text_start,
                               int* text_size) {
  assert(text_start);
  assert(text_size);

  *text_start = NULL;
  *text_size = 0;

  if (elf_version(EV_CURRENT) == EV_NONE) {
    print_message2(2, "elf_version() failed: %s\n", elf_errmsg(0));
    return false;
  }

  GElf_Ehdr elf_header;
  lseek(fd, 0L, 0);
  Elf* elf = elf_begin(fd, ELF_C_READ, NULL);
  AutoElfEnder elfEnder(elf);

  if (gelf_getehdr(elf, &elf_header) == (GElf_Ehdr*)NULL) {
    print_message2(2, "failed to read elf header: %s\n", elf_errmsg(-1));
    return false;
  }

  if (elf_header.e_ident[EI_MAG0] != ELFMAG0 ||
      elf_header.e_ident[EI_MAG1] != ELFMAG1 ||
      elf_header.e_ident[EI_MAG2] != ELFMAG2 ||
      elf_header.e_ident[EI_MAG3] != ELFMAG3) {
    print_message1(2, "header magic doesn't match\n");
    return false;
  }

  static const char kTextSectionName[] = ".text";
  const GElf_Shdr* text_section = NULL;
  Elf_Scn* scn = NULL;
  GElf_Shdr shdr;

  while ((scn = elf_nextscn(elf, scn)) != NULL) {
    if (gelf_getshdr(scn, &shdr) == (GElf_Shdr*)0) {
      print_message2(2, "failed to read section header: %s\n", elf_errmsg(0));
      return false;
    }

    if (shdr.sh_type == SHT_PROGBITS) {
      const char* section_name = elf_strptr(elf, elf_header.e_shstrndx,
                                            shdr.sh_name);
      if (!section_name) {
        print_message2(2, "Section name error: %s\n", elf_errmsg(-1));
        continue;
      }

      if (strcmp(section_name, kTextSectionName) == 0) {
        text_section = &shdr;
        break;
      }
    }
  }
  if (text_section != NULL && text_section->sh_size > 0) {
    *text_start = (char*)elf_base + text_section->sh_offset;
    *text_size = text_section->sh_size;
    return true;
  }

  return false;
}

FileID::FileID(const char* path) {
  strcpy(path_, path);
}

class AutoCloser {
 public:
  AutoCloser(int fd) : fd_(fd) {}
  ~AutoCloser() { if (fd_) close(fd_); }
 private:
  int fd_;
};

bool FileID::ElfFileIdentifier(unsigned char identifier[16]) {
  int fd = 0;
  if ((fd = open(path_, O_RDONLY)) < 0)
    return false;

  AutoCloser autocloser(fd);
  struct stat st;
  if (fstat(fd, &st) != 0 || st.st_size <= 0)
    return false;

  void* base = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  if (base == MAP_FAILED)
    return false;

  bool success = false;
  const void* text_section = NULL;
  int text_size = 0;

  if (FindElfTextSection(fd, base, &text_section, &text_size)) {
    MD5Context md5;
    MD5Init(&md5);
    MD5Update(&md5, (const unsigned char*)text_section, text_size);
    MD5Final(identifier, &md5);
    success = true;
  }

  munmap((char*)base, st.st_size);
  return success;
}

// static
bool FileID::ConvertIdentifierToString(const unsigned char identifier[16],
                                       char* buffer, int buffer_length) {
  if (buffer_length < 34)
    return false;

  int buffer_idx = 0;
  for (int idx = 0; idx < 16; ++idx) {
    int hi = (identifier[idx] >> 4) & 0x0F;
    int lo = (identifier[idx]) & 0x0F;

    buffer[buffer_idx++] = (hi >= 10) ? 'A' + hi - 10 : '0' + hi;
    buffer[buffer_idx++] = (lo >= 10) ? 'A' + lo - 10 : '0' + lo;
  }

  // Add an extra "0" by the end.
  buffer[buffer_idx++] = '0';

  // NULL terminate
  buffer[buffer_idx] = 0;

  return true;
}

}  // namespace google_breakpad
