1//===- ReadStageTest.cpp --------------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include "ReadStageTest.h"
10#include <mcld/LD/LDContext.h>
11#include <mcld/LD/LDSection.h>
12#include <mcld/LD/SectionData.h>
13#include <mcld/LD/Fragment.h>
14#include <mcld/LD/FragmentRef.h>
15#include <mcld/LD/LDSymbol.h>
16#include <mcld/LD/ResolveInfo.h>
17
18#include <sstream>
19#include <iostream>
20
21using namespace std;
22
23using namespace mcld;
24using namespace mcld::test;
25
26
27// Constructor can do set-up work for all test here.
28ReadStageTest::ReadStageTest()
29  : m_pLinker(NULL) {
30}
31
32// Destructor can do clean-up work that doesn't throw exceptions here.
33ReadStageTest::~ReadStageTest()
34{
35}
36
37// SetUp() will be called immediately before each test.
38void ReadStageTest::SetUp()
39{
40  m_pLinker = new mcld::test::TestLinker();
41  m_pLinker->initialize("arm-none-linux-gnueabi");
42
43  // set up target-dependent constraints of attributes
44  m_pLinker->config()->attrFactory().constraint().enableWholeArchive();
45  m_pLinker->config()->attrFactory().constraint().disableAsNeeded();
46  m_pLinker->config()->attrFactory().constraint().setSharedSystem();
47
48  // set up the predefined attributes
49  m_pLinker->config()->attrFactory().predefined().setWholeArchive();
50  m_pLinker->config()->attrFactory().predefined().setDynamic();
51
52  // set up target dependent options
53  mcld::sys::fs::Path path = TOPDIR;
54  path.append("test/libs/ARM/Android/android-14");
55  m_pLinker->setSysRoot(path);
56  m_pLinker->addSearchDir("=/");
57
58  m_pLinker->config()->options().setDyld("/usr/lib/ld.so.1");
59  m_pLinker->config()->options().setBsymbolic(true);
60}
61
62// TearDown() will be called immediately after each test.
63void ReadStageTest::TearDown()
64{
65  delete m_pLinker;
66}
67
68void ReadStageTest::dumpInput(const mcld::Input &pInput, mcld::FileHandle &pFile, size_t pIdent)
69{
70  stringstream sstream;
71  for (int i=0; i < pIdent; ++i)
72    sstream << " ";
73  sstream << "<input name=\"" << pInput.name() << "\">\n";
74
75  LDContext::const_sect_iterator sect, sectEnd = pInput.context()->sectEnd();
76  for (sect = pInput.context()->sectBegin(); sect != sectEnd; ++sect) {
77    for (int i=0; i < (pIdent+1); ++i)
78      sstream << " ";
79    sstream << "<section name=\"" << (*sect)->name() << "\"/>\n";
80  }
81  for (int i=0; i < pIdent; ++i)
82    sstream << " ";
83  sstream << "</input>\n";
84
85  size_t org_size = pFile.size();
86  pFile.truncate(sstream.str().size() + org_size);
87  pFile.write(sstream.str().data(), org_size, sstream.str().size());
88}
89
90void ReadStageTest::dumpOutput(const mcld::Output &pOutput, mcld::FileHandle &pFile, size_t pIdent)
91{
92  stringstream sstream;
93  for (int i=0; i < pIdent; ++i)
94    sstream << " ";
95  sstream << "<output name=\"" << pOutput.name() << "\">\n";
96
97  LDContext::const_sect_iterator sect, sectEnd = pOutput.context()->sectEnd();
98  for (sect = pOutput.context()->sectBegin(); sect != sectEnd; ++sect) {
99    for (int i=0; i < (pIdent+1); ++i)
100      sstream << " ";
101    sstream << "<section name=\"" << (*sect)->name() << "\"/>\n";
102  }
103  for (int i=0; i < pIdent; ++i)
104    sstream << " ";
105  sstream << "</output>\n";
106
107  size_t org_size = pFile.size();
108  pFile.truncate(sstream.str().size() + org_size);
109  pFile.write(sstream.str().data(), org_size, sstream.str().size());
110}
111//===----------------------------------------------------------------------===//
112// Testcases
113//===----------------------------------------------------------------------===//
114TEST_F(ReadStageTest, quake) {
115  mcld::sys::fs::Path top_level = TOPDIR;
116
117  // set up output
118  m_pLinker->config()->output().setType(mcld::Output::DynObj);
119  m_pLinker->setOutput(top_level + "unittests/plasma.so");
120
121
122  // set up input
123  m_pLinker->addObject(top_level + "test/libs/ARM/Android/android-14/crtbegin_so.o");
124  m_pLinker->addObject(top_level + "test/Android/Plasma/ARM/plasma.o");
125  m_pLinker->addNameSpec("m");
126  m_pLinker->addNameSpec("log");
127  m_pLinker->addNameSpec("jnigraphics");
128  m_pLinker->addNameSpec("c");
129  m_pLinker->addObject(top_level + "test/libs/ARM/Android/android-14/crtend_so.o");
130
131  // dump status
132  m_pLinker->getDriver()->normalize();
133
134  FileHandle file;
135  file.open(top_level + "unittests/read_stage.xml",
136     FileHandle::ReadWrite | FileHandle::Create | FileHandle::Truncate, 0644);
137
138  InputTree::iterator input, inEnd = m_pLinker->config()->inputs().end();
139  for (input = m_pLinker->config()->inputs().begin(); input != inEnd; ++input) {
140    dumpInput(**input, file, 1);
141  }
142
143  dumpOutput(m_pLinker->config()->output(), file, 1);
144  // dump status
145  ASSERT_TRUE(m_pLinker->getDriver()->mergeSections());
146}
147
148