// -*- mode: C++ -*-

// Copyright (c) 2011, 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.

// Original author: Ted Mielczarek <ted.mielczarek@gmail.com>

// synth_elf.h: Interface to synth_elf::ELF: fake ELF generator.

#ifndef COMMON_LINUX_SYNTH_ELF_H_
#define COMMON_LINUX_SYNTH_ELF_H_

#include "common/test_assembler.h"

#include <list>
#include <vector>
#include <map>
#include <string>
#include <utility>

#include "common/using_std_string.h"

namespace google_breakpad {
namespace synth_elf {

using std::list;
using std::vector;
using std::map;
using std::pair;
using test_assembler::Endianness;
using test_assembler::kLittleEndian;
using test_assembler::kUnsetEndian;
using test_assembler::Label;
using test_assembler::Section;

// String tables are common in ELF headers, so subclass Section
// to make them easy to generate.
class StringTable : public Section {
public:
  StringTable(Endianness endianness = kUnsetEndian)
  : Section(endianness) {
    start() = 0;
    empty_string = Add("");
  }

  // Add the string s to the string table, and return
  // a label containing the offset into the string table
  // at which it was added.
  Label Add(const string& s) {
    if (strings_.find(s) != strings_.end())
      return strings_[s];

    Label string_label(Here());
    AppendCString(s);
    strings_[s] = string_label;
    return string_label;
  }

  // All StringTables contain an empty string as their first
  // entry.
  Label empty_string;

  // Avoid inserting duplicate strings.
  map<string,Label> strings_;
};

// A Section representing an entire ELF file.
class ELF : public Section {
 public:
  ELF(uint16_t machine,    // EM_386, etc
      uint8_t file_class,  // ELFCLASS{32,64}
      Endianness endianness = kLittleEndian);

  // Add the Section section to the section header table and append it
  // to the file. Returns the index of the section in the section
  // header table.
  int AddSection(const string& name, const Section& section,
                 uint32_t type, uint32_t flags = 0, uint64_t addr = 0,
                 uint32_t link = 0, uint64_t entsize = 0, uint64_t offset = 0);
                  
  // Add a segment containing from section index start to section index end.
  // The indexes must have been gotten from AddSection.
  void AddSegment(int start, int end, uint32_t type, uint32_t flags = 0);

  // Write out all data. GetContents may be used after this.
  void Finish();

 private:
  // Size of an address, in bytes.
  const size_t addr_size_;

  // Offset to the program header table.
  Label program_header_label_;
  // Number of entries in the program header table.
  int program_count_;
  Label program_count_label_;
  // The program header table itself.
  Section program_header_table_;

  // Offset to the section header table.
  Label section_header_label_;
  // Number of entries in the section header table.
  int section_count_;
  Label section_count_label_;
  // The section header table itself.
  Section section_header_table_;

  // Index of the section header string table in the section
  // header table.
  Label section_header_string_index_;
  // Section containing the names of section header table entries.
  StringTable section_header_strings_;

  // Record of an added section
  struct ElfSection : public Section {
    ElfSection(const Section& section, uint32_t type, uint32_t addr,
               uint32_t offset, Label offset_label, uint32_t size)
    : Section(section), type_(type), addr_(addr), offset_(offset)
    , offset_label_(offset_label), size_(size) {
    }

    uint32_t type_;
    uint32_t addr_;
    uint32_t offset_;
    Label offset_label_;
    uint32_t size_;
  };

  vector<ElfSection> sections_;

  void AppendSection(ElfSection &section);
};

// A class to build .symtab or .dynsym sections.
class SymbolTable : public Section {
 public:
  // table is the StringTable that contains symbol names. The caller
  // must ensure that it remains alive for the life of the
  // SymbolTable.
  SymbolTable(Endianness endianness, size_t addr_size, StringTable& table);

  // Add an Elf32_Sym.
  void AddSymbol(const string& name, uint32_t value,
                 uint32_t size, unsigned info, uint16_t shndx);
  // Add an Elf64_Sym.
  void AddSymbol(const string& name, uint64_t value,
                 uint64_t size, unsigned info, uint16_t shndx);

 private:
  size_t addr_size_;
  StringTable& table_;
};

// A class for note sections
class Notes : public Section {
public:
  Notes(Endianness endianness)
  : Section(endianness) {
  }

  // Add a note.
  void AddNote(int type, const string &name, const uint8_t* desc_bytes,
               size_t desc_size);
};

}  // namespace synth_elf
}  // namespace google_breakpad

#endif  // COMMON_LINUX_SYNTH_ELF_H_
