//===- LinkerTest.cpp -----------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "LinkerTest.h"

#include <mcld/Environment.h>
#include <mcld/Module.h>
#include <mcld/InputTree.h>
#include <mcld/IRBuilder.h>
#include <mcld/Linker.h>
#include <mcld/LinkerConfig.h>

#include <mcld/Support/Path.h>

#include <llvm/Support/ELF.h>

using namespace mcld;
using namespace mcld::test;
using namespace mcld::sys::fs;


// Constructor can do set-up work for all test here.
LinkerTest::LinkerTest()
{
}

// Destructor can do clean-up work that doesn't throw exceptions here.
LinkerTest::~LinkerTest()
{
}

// SetUp() will be called immediately before each test.
void LinkerTest::SetUp()
{
}

// TearDown() will be called immediately after each test.
void LinkerTest::TearDown()
{
}

//===----------------------------------------------------------------------===//
// Testcases
//===----------------------------------------------------------------------===//
TEST_F( LinkerTest, set_up_n_clean_up) {

  Initialize();
  LinkerConfig config("arm-none-linux-gnueabi");

  Module module("test");
  config.setCodeGenType(LinkerConfig::DynObj);

  Linker linker;
  linker.config(config);

  IRBuilder builder(module, config);
  // create inputs here
  //   builder.CreateInput("./test.o");

  if (linker.link(module, builder))
    linker.emit("./test.so");

  Finalize();
}

// %MCLinker --shared -soname=libplasma.so -Bsymbolic
// -mtriple="armv7-none-linux-gnueabi"
// -L=%p/../../../libs/ARM/Android/android-14
// %p/../../../libs/ARM/Android/android-14/crtbegin_so.o
// %p/plasma.o
// -lm -llog -ljnigraphics -lc
// %p/../../../libs/ARM/Android/android-14/crtend_so.o
// -o libplasma.so
TEST_F( LinkerTest, plasma) {

  Initialize();
  Linker linker;

  ///< --mtriple="armv7-none-linux-gnueabi"
  LinkerConfig config("armv7-none-linux-gnueabi");

  /// To configure linker before setting options. Linker::config sets up
  /// default target-dependent configuration to LinkerConfig.
  linker.config(config);

  config.setCodeGenType(LinkerConfig::DynObj);  ///< --shared
  config.options().setSOName("libplasma.so");   ///< --soname=libplasma.so
  config.options().setBsymbolic();              ///< -Bsymbolic

  /// -L=${TOPDIR}/test/libs/ARM/Android/android-14
  Path search_dir(TOPDIR);
  search_dir.append("test/libs/ARM/Android/android-14");
  config.options().directories().insert(search_dir);

  Module module("libplasma.so");
  IRBuilder builder(module, config);

  /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtbegin_so.o
  Path crtbegin(search_dir);
  crtbegin.append("crtbegin_so.o");
  builder.ReadInput("crtbegin", crtbegin);

  /// ${TOPDIR}/test/Android/Plasma/ARM/plasma.o
  Path plasma(TOPDIR);
  plasma.append("test/Android/Plasma/ARM/plasma.o");
  builder.ReadInput("plasma", plasma);

  // -lm -llog -ljnigraphics -lc
  builder.ReadInput("m");
  builder.ReadInput("log");
  builder.ReadInput("jnigraphics");
  builder.ReadInput("c");

  /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtend_so.o
  Path crtend(search_dir);
  crtend.append("crtend_so.o");
  builder.ReadInput("crtend", crtend);

  if (linker.link(module, builder)) {
    linker.emit("libplasma.so"); ///< -o libplasma.so
  }

  Finalize();
}

// The outputs generated without -Bsymbolic usually have more relocation
// entries than the outputs generated with -Bsymbolic. This testcase generates
// output with -Bsymbolic first, then generate the same output without -Bsymbolic.
// By this way, we can make sure symbols and relocations are cleaned between
// two linkings.
TEST_F( LinkerTest, plasma_twice) {

  Initialize();
  Linker linker;

  ///< --mtriple="armv7-none-linux-gnueabi"
  LinkerConfig config1("armv7-none-linux-gnueabi");

  /// To configure linker before setting options. Linker::config sets up
  /// default target-dependent configuration to LinkerConfig.
  linker.config(config1);

  config1.setCodeGenType(LinkerConfig::DynObj);  ///< --shared
  config1.options().setSOName("libplasma.once.so");   ///< --soname=libplasma.twice.so
  config1.options().setBsymbolic(false);              ///< -Bsymbolic

  /// -L=${TOPDIR}/test/libs/ARM/Android/android-14
  Path search_dir(TOPDIR);
  search_dir.append("test/libs/ARM/Android/android-14");
  config1.options().directories().insert(search_dir);

  Module module1("libplasma.once.so");
  IRBuilder builder1(module1, config1);

  /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtbegin_so.o
  Path crtbegin(search_dir);
  crtbegin.append("crtbegin_so.o");
  builder1.ReadInput("crtbegin", crtbegin);

  /// ${TOPDIR}/test/Android/Plasma/ARM/plasma.o
  Path plasma(TOPDIR);
  plasma.append("test/Android/Plasma/ARM/plasma.o");
  builder1.ReadInput("plasma", plasma);

  // -lm -llog -ljnigraphics -lc
  builder1.ReadInput("m");
  builder1.ReadInput("log");
  builder1.ReadInput("jnigraphics");
  builder1.ReadInput("c");

  /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtend_so.o
  Path crtend(search_dir);
  crtend.append("crtend_so.o");
  builder1.ReadInput("crtend", crtend);

  if (linker.link(module1, builder1)) {
    linker.emit("libplasma.once.so"); ///< -o libplasma.so
  }

  Finalize();

  linker.reset();

  Initialize();

  ///< --mtriple="armv7-none-linux-gnueabi"
  LinkerConfig config2("armv7-none-linux-gnueabi");

  /// To configure linker before setting options. Linker::config sets up
  /// default target-dependent configuration to LinkerConfig.
  linker.config(config2);

  config2.setCodeGenType(LinkerConfig::DynObj);  ///< --shared
  config2.options().setSOName("libplasma.twice.so");   ///< --soname=libplasma.twice.exe
  config2.options().setBsymbolic();              ///< -Bsymbolic

  /// -L=${TOPDIR}/test/libs/ARM/Android/android-14
  config2.options().directories().insert(search_dir);

  Module module2("libplasma.so");
  IRBuilder builder2(module2, config2);

  /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtbegin_so.o
  builder2.ReadInput("crtbegin", crtbegin);

  /// ${TOPDIR}/test/Android/Plasma/ARM/plasma.o
  builder2.ReadInput("plasma", plasma);

  // -lm -llog -ljnigraphics -lc
  builder2.ReadInput("m");
  builder2.ReadInput("log");
  builder2.ReadInput("jnigraphics");
  builder2.ReadInput("c");

  /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtend_so.o
  builder2.ReadInput("crtend", crtend);

  if (linker.link(module2, builder2)) {
    linker.emit("libplasma.twice.so"); ///< -o libplasma.exe
  }

  Finalize();
}

// This testcase put IRBuilder in the heap
TEST_F( LinkerTest, plasma_twice_irbuilder_heap) {

  Initialize();
  Linker linker;

  ///< --mtriple="armv7-none-linux-gnueabi"
  LinkerConfig config1("armv7-none-linux-gnueabi");

  /// To configure linker before setting options. Linker::config sets up
  /// default target-dependent configuration to LinkerConfig.
  linker.config(config1);

  config1.setCodeGenType(LinkerConfig::DynObj);  ///< --shared
  config1.options().setSOName("libplasma.once.so");   ///< --soname=libplasma.twice.so
  config1.options().setBsymbolic(false);              ///< -Bsymbolic

  /// -L=${TOPDIR}/test/libs/ARM/Android/android-14
  Path search_dir(TOPDIR);
  search_dir.append("test/libs/ARM/Android/android-14");
  config1.options().directories().insert(search_dir);

  Module module1("libplasma.once.so");
  IRBuilder *builder1 = new IRBuilder(module1, config1);

  /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtbegin_so.o
  Path crtbegin(search_dir);
  crtbegin.append("crtbegin_so.o");
  builder1->ReadInput("crtbegin", crtbegin);

  /// ${TOPDIR}/test/Android/Plasma/ARM/plasma.o
  Path plasma(TOPDIR);
  plasma.append("test/Android/Plasma/ARM/plasma.o");
  builder1->ReadInput("plasma", plasma);

  // -lm -llog -ljnigraphics -lc
  builder1->ReadInput("m");
  builder1->ReadInput("log");
  builder1->ReadInput("jnigraphics");
  builder1->ReadInput("c");

  /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtend_so.o
  Path crtend(search_dir);
  crtend.append("crtend_so.o");
  builder1->ReadInput("crtend", crtend);

  if (linker.link(module1, *builder1)) {
    linker.emit("libplasma.once.so"); ///< -o libplasma.so
  }

  // Can not delete builder until emit the output. Dynamic string table
  // needs the file name of the input files, and the inputs' life is
  // controlled by IRBuilder
  delete builder1;

  Finalize();

  linker.reset();

  Initialize();

  ///< --mtriple="armv7-none-linux-gnueabi"
  LinkerConfig config2("armv7-none-linux-gnueabi");

  /// To configure linker before setting options. Linker::config sets up
  /// default target-dependent configuration to LinkerConfig.
  linker.config(config2);

  config2.setCodeGenType(LinkerConfig::DynObj);  ///< --shared
  config2.options().setSOName("libplasma.twice.so");   ///< --soname=libplasma.twice.exe
  config2.options().setBsymbolic();              ///< -Bsymbolic

  /// -L=${TOPDIR}/test/libs/ARM/Android/android-14
  config2.options().directories().insert(search_dir);

  Module module2("libplasma.so");
  IRBuilder* builder2 = new IRBuilder(module2, config2);

  /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtbegin_so.o
  builder2->ReadInput("crtbegin", crtbegin);

  /// ${TOPDIR}/test/Android/Plasma/ARM/plasma.o
  builder2->ReadInput("plasma", plasma);

  // -lm -llog -ljnigraphics -lc
  builder2->ReadInput("m");
  builder2->ReadInput("log");
  builder2->ReadInput("jnigraphics");
  builder2->ReadInput("c");

  /// ${TOPDIR}/test/libs/ARM/Android/android-14/crtend_so.o
  builder2->ReadInput("crtend", crtend);

  if (linker.link(module2, *builder2)) {
    linker.emit("libplasma.twice.so"); ///< -o libplasma.exe
  }

  delete builder2;
  Finalize();
}

// %MCLinker --shared -soname=libgotplt.so -mtriple arm-none-linux-gnueabi
// gotplt.o -o libgotplt.so
TEST_F( LinkerTest, plasma_object) {

  Initialize();
  Linker linker;

  ///< --mtriple="armv7-none-linux-gnueabi"
  LinkerConfig config("armv7-none-linux-gnueabi");

  /// To configure linker before setting options. Linker::config sets up
  /// default target-dependent configuration to LinkerConfig.
  linker.config(config);

  config.setCodeGenType(LinkerConfig::DynObj);  ///< --shared
  config.options().setSOName("libgotplt.so");   ///< --soname=libgotplt.so

  Module module;
  IRBuilder builder(module, config);

  Path gotplt_o(TOPDIR);
  gotplt_o.append("test/PLT/gotplt.o");
  Input* input = builder.CreateInput("gotplt.o", gotplt_o, Input::Object);

  /// Sections
  /// [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  builder.CreateELFHeader(*input,
                          "",
                          LDFileFormat::Null,
                          llvm::ELF::SHT_NULL,
                          0x0);

  /// [ 1] .text             PROGBITS        00000000 000034 000010 00  AX  0   0  4
  LDSection* text = builder.CreateELFHeader(*input,
                              ".text",
                              llvm::ELF::SHT_PROGBITS,
                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
                              4);

  SectionData* text_data = builder.CreateSectionData(*text);
  static uint8_t text_content[] = { 0x00, 0x48, 0x2d, 0xe9,
                                    0xfe, 0xff, 0xff, 0xeb,
                                    0x00, 0x48, 0xbd, 0xe8,
                                    0x0e, 0xf0, 0xa0, 0xe1 };
  Fragment* text_frag = builder.CreateRegion(text_content, 0x10);
  builder.AppendFragment(*text_frag, *text_data);

  /// [ 2] .rel.text         REL             00000000 0002ac 000008 08      7   1  4
  LDSection* rel_text = builder.CreateELFHeader(*input,
                          ".rel.text",
                          llvm::ELF::SHT_REL,
                          0x0, 4);
  rel_text->setLink(text);
  builder.CreateRelocData(*rel_text);

  /// [ 3] .data             PROGBITS        00000000 000044 000000 00  WA  0   0  4
  LDSection* data = builder.CreateELFHeader(*input,
                          ".data",
                          llvm::ELF::SHT_PROGBITS,
                          llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
                          4);

  /// [ 4] .bss              NOBITS          00000000 000044 000000 00  WA  0   0  4
  LDSection* bss = builder.CreateELFHeader(*input,
                          ".bss",
                          llvm::ELF::SHT_NOBITS,
                          llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
                          4);
  builder.CreateBSS(*bss);

  /// [ 5] .ARM.attributes   ARM_ATTRIBUTES  00000000 000044 000020 00      0   0  1
  LDSection* attr = builder.CreateELFHeader(*input,
                              ".ARM.attributes",
                              llvm::ELF::SHT_ARM_ATTRIBUTES,
                              0x0,
                              1);

  SectionData* attr_data = builder.CreateSectionData(*attr);
  static uint8_t attr_content[] = {
                      0x41, 0x1f, 0x00, 0x00,
                      0x00, 0x61, 0x65, 0x61,
                      0x62, 0x69, 0x00, 0x01,
                      0x15, 0x00, 0x00, 0x00,
                      0x06, 0x02, 0x08, 0x01,
                      0x09, 0x01, 0x14, 0x01,
                      0x15, 0x01, 0x17, 0x03,
                      0x18, 0x01, 0x19, 0x01 };
  Fragment* attr_frag = builder.CreateRegion(attr_content, 0x20);
  builder.AppendFragment(*attr_frag, *attr_data);

  /// Symbols
  /// 1: 00000000     0 FILE    LOCAL  DEFAULT  ABS Output/gotplt.bc
  builder.AddSymbol(*input,
                    "Output/gotplt.bc", ResolveInfo::File,
                    ResolveInfo::Define, ResolveInfo::Local, 0);
  /// 2: 00000000     0 SECTION LOCAL  DEFAULT    1 
  builder.AddSymbol(*input,
                    ".text", ResolveInfo::Section,
                    ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, text);
  /// 3: 00000000     0 SECTION LOCAL  DEFAULT    3
  builder.AddSymbol(*input,
                    ".data", ResolveInfo::Section,
                    ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, data);
  /// 4: 00000000     0 SECTION LOCAL  DEFAULT    4 
  builder.AddSymbol(*input,
                    ".bss", ResolveInfo::Section,
                    ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, bss);
  /// 5: 00000000     0 SECTION LOCAL  DEFAULT    5 
  builder.AddSymbol(*input,
                    ".ARM.attributes", ResolveInfo::Section,
                    ResolveInfo::Define, ResolveInfo::Local, 0, 0x0, attr);
  /// 6: 00000000    16 FUNC    GLOBAL DEFAULT    1 _Z1fv
  builder.AddSymbol(*input,
                    "_Z1fv", ResolveInfo::Function,
                    ResolveInfo::Define, ResolveInfo::Global,
                    16,
                    0x0,
                    text);

  /// 7: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _Z1gv
  LDSymbol* z1gv = builder.AddSymbol(*input,
                                     "_Z1gv",
                                     ResolveInfo::NoType,
                                     ResolveInfo::Undefined,
                                     ResolveInfo::Global,
                                     0);

 /// Relocations
 /// Offset     Info    Type            Sym.Value  Sym. Name
 /// 00000004  0000071b R_ARM_PLT32       00000000   _Z1gv
 builder.AddRelocation(*rel_text, llvm::ELF::R_ARM_PLT32, *z1gv, 0x4);

  if (linker.link(module, builder)) {
    linker.emit("libgotplt.so"); ///< -o libgotplt.so
  }

  Finalize();
}
