1/*
2 * Copyright 2010-2012, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "bcc/Linker.h"
18#include "bcc/Support/LinkerConfig.h"
19#include "bcc/Support/MemoryFactory.h"
20#include "bcc/Support/Log.h"
21
22#include <llvm/Support/ELF.h>
23
24#include <mcld/MC/MCLDDriver.h>
25#include <mcld/MC/InputTree.h>
26#include <mcld/MC/MCLinker.h>
27#include <mcld/MC/InputTree.h>
28#include <mcld/LD/LDSection.h>
29#include <mcld/LD/LDContext.h>
30#include <mcld/Target/TargetLDBackend.h>
31#include <mcld/Support/Path.h>
32#include <mcld/Support/MemoryArea.h>
33#include <mcld/Support/FileHandle.h>
34#include <mcld/Support/MemoryAreaFactory.h>
35#include <mcld/Support/TargetRegistry.h>
36
37using namespace bcc;
38
39const char* Linker::GetErrorString(enum Linker::ErrorCode pErrCode) {
40  static const char* ErrorString[] = {
41    /* kSuccess */
42    "Successfully compiled.",
43    /* kDoubleConfig */
44    "Configure Linker twice.",
45    /* kCreateBackend */
46    "Cannot create backend.",
47    /* kDelegateLDInfo */
48    "Cannot get linker information",
49    /* kFindNameSpec */
50    "Cannot find -lnamespec",
51    /* kOpenNameSpec */
52    "Cannot open -lnamespec",
53    /* kOpenObjectFile */
54    "Cannot open object file",
55    /* kNotConfig */
56    "Linker::config() is not called",
57    /* kNotSetUpOutput */
58    "Linker::setOutput() is not called before add input files",
59    /* kOpenOutput */
60    "Cannot open output file",
61    /* kReadSections */
62    "Cannot read sections",
63    /* kReadSymbols */
64    "Cannot read symbols",
65    /* kAddAdditionalSymbols */
66    "Cannot add standard and target symbols",
67    /* kMaxErrorCode */
68    "(Unknown error code)"
69  };
70
71  if (pErrCode > kMaxErrorCode) {
72    pErrCode = kMaxErrorCode;
73  }
74
75  return ErrorString[ static_cast<size_t>(pErrCode) ];
76}
77
78//===----------------------------------------------------------------------===//
79// Linker
80//===----------------------------------------------------------------------===//
81Linker::Linker()
82  : mBackend(NULL), mDriver(NULL), mMemAreaFactory(NULL), mLDInfo(NULL),
83    mRoot(NULL), mShared(false) {
84}
85
86Linker::Linker(const LinkerConfig& pConfig)
87  : mBackend(NULL), mDriver(NULL), mMemAreaFactory(NULL), mLDInfo(NULL),
88    mRoot(NULL), mShared(false) {
89
90  const std::string &triple = pConfig.getTriple();
91
92  enum ErrorCode err = config(pConfig);
93  if (kSuccess != err) {
94    ALOGE("%s (%s)", GetErrorString(err), triple.c_str());
95    return;
96  }
97
98  return;
99}
100
101Linker::~Linker() {
102  delete mDriver;
103  delete mBackend;
104  delete mMemAreaFactory;
105  delete mRoot;
106}
107
108enum Linker::ErrorCode Linker::extractFiles(const LinkerConfig& pConfig) {
109  mLDInfo = const_cast<mcld::MCLDInfo*>(pConfig.getLDInfo());
110  if (mLDInfo == NULL) {
111    return kDelegateLDInfo;
112  }
113
114  mRoot = new mcld::InputTree::iterator(mLDInfo->inputs().root());
115  mShared = pConfig.isShared();
116  mSOName = pConfig.getSOName();
117
118  return kSuccess;
119}
120
121enum Linker::ErrorCode Linker::config(const LinkerConfig& pConfig) {
122  if (mLDInfo != NULL) {
123    return kDoubleConfig;
124  }
125
126  extractFiles(pConfig);
127
128  mBackend = pConfig.getTarget()->createLDBackend(pConfig.getTriple());
129  if (mBackend == NULL) {
130    return kCreateBackend;
131  }
132
133  mMemAreaFactory = new MemoryFactory();
134
135  mDriver = new mcld::MCLDDriver(*mLDInfo, *mBackend, *mMemAreaFactory);
136
137  mDriver->initMCLinker();
138
139  return kSuccess;
140}
141
142void Linker::advanceRoot() {
143  if (mRoot->isRoot()) {
144    mRoot->move<mcld::TreeIteratorBase::Leftward>();
145  } else {
146    mRoot->move<mcld::TreeIteratorBase::Rightward>();
147  }
148  return;
149}
150
151enum Linker::ErrorCode Linker::openFile(const mcld::sys::fs::Path& pPath,
152                                        enum Linker::ErrorCode pCode,
153                                        mcld::Input& pInput) {
154  mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pPath,
155                                                    mcld::FileHandle::ReadOnly);
156
157  if (input_memory->handler()->isGood()) {
158    pInput.setMemArea(input_memory);
159  } else {
160    return pCode;
161  }
162
163  mcld::LDContext *input_context = mLDInfo->contextFactory().produce(pPath);
164  pInput.setContext(input_context);
165  return kSuccess;
166}
167
168enum Linker::ErrorCode Linker::addNameSpec(const std::string &pNameSpec) {
169  mcld::sys::fs::Path* path = NULL;
170  // find out the real path of the namespec.
171  if (mLDInfo->attrFactory().constraint().isSharedSystem()) {
172    // In the system with shared object support, we can find both archive
173    // and shared object.
174
175    if (mLDInfo->attrFactory().last().isStatic()) {
176      // with --static, we must search an archive.
177      path = mLDInfo->options().directories().find(pNameSpec,
178                                                   mcld::Input::Archive);
179    }
180    else {
181      // otherwise, with --Bdynamic, we can find either an archive or a
182      // shared object.
183      path = mLDInfo->options().directories().find(pNameSpec,
184                                                   mcld::Input::DynObj);
185    }
186  }
187  else {
188    // In the system without shared object support, we only look for an
189    // archive.
190    path = mLDInfo->options().directories().find(pNameSpec,
191                                                 mcld::Input::Archive);
192  }
193
194  if (NULL == path)
195    return kFindNameSpec;
196
197  mcld::Input* input = mLDInfo->inputFactory().produce(pNameSpec, *path,
198                                                       mcld::Input::Unknown);
199  mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input);
200
201  advanceRoot();
202
203  return openFile(*path, kOpenNameSpec, *input);
204}
205
206/// addObject - Add a object file by the filename.
207enum Linker::ErrorCode Linker::addObject(const std::string &pObjectPath) {
208  mcld::Input* input = mLDInfo->inputFactory().produce(pObjectPath,
209                                                       pObjectPath,
210                                                       mcld::Input::Unknown);
211
212  mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input);
213
214  advanceRoot();
215
216  return openFile(pObjectPath, kOpenObjectFile, *input);
217}
218
219/// addObject - Add a piece of memory. The memory is of ELF format.
220enum Linker::ErrorCode Linker::addObject(void* pMemory, size_t pSize) {
221
222  mcld::Input* input = mLDInfo->inputFactory().produce("memory object",
223                                                       "NAN",
224                                                       mcld::Input::Unknown);
225
226  mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input);
227
228  advanceRoot();
229
230  mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pMemory, pSize);
231  input->setMemArea(input_memory);
232
233  mcld::LDContext *input_context = mLDInfo->contextFactory().produce();
234  input->setContext(input_context);
235
236  return kSuccess;
237}
238
239enum Linker::ErrorCode Linker::addCode(void* pMemory, size_t pSize) {
240  mcld::Input* input = mLDInfo->inputFactory().produce("code object",
241                                                       "NAN",
242                                                       mcld::Input::External);
243
244  mLDInfo->inputs().insert<mcld::InputTree::Positional>(*mRoot, *input);
245
246  advanceRoot();
247
248  mcld::MemoryArea *input_memory = mMemAreaFactory->produce(pMemory, pSize);
249  input->setMemArea(input_memory);
250
251  mcld::LDContext *input_context = mLDInfo->contextFactory().produce();
252  input->setContext(input_context);
253
254  // FIXME: So far, MCLinker must set up output before add input files.
255  // set up LDContext
256  if (mDriver->hasInitLinker()) {
257    return kNotConfig;
258  }
259
260  if (!mLDInfo->output().hasContext()) {
261    return kNotSetUpOutput;
262  }
263
264  // create NULL section
265  mcld::LDSection& null =
266      mDriver->getLinker()->createSectHdr("",
267                                          mcld::LDFileFormat::Null,
268                                          llvm::ELF::SHT_NULL,
269                                          0);
270
271  null.setSize(0);
272  null.setOffset(0);
273  null.setIndex(0);
274  null.setInfo(0);
275  null.setAlign(0);
276
277  input_context->getSectionTable().push_back(&null);
278
279  // create .text section
280  mcld::LDSection& text = mDriver->getLinker()->createSectHdr(".text",
281                              mcld::LDFileFormat::Regular,
282                              llvm::ELF::SHT_PROGBITS,
283                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR);
284
285  text.setSize(pSize);
286  text.setOffset(0x0);
287  text.setIndex(1);
288  text.setInfo(0);
289  text.setAlign(1);
290
291  input_context->getSectionTable().push_back(&text);
292
293  return kSuccess;
294}
295
296enum Linker::ErrorCode Linker::setOutput(const std::string &pPath) {
297  if (mLDInfo->output().hasContext()) {
298    return kDoubleConfig;
299  }
300
301  // -----  initialize output file  ----- //
302
303  mcld::FileHandle::Permission perm = 0755;
304
305  mcld::MemoryArea* out_area = mMemAreaFactory->produce(
306                      pPath,
307                      mcld::FileHandle::ReadWrite |
308                        mcld::FileHandle::Truncate |
309                        mcld::FileHandle::Create,
310                      perm);
311
312  if (!out_area->handler()->isGood()) {
313    return kOpenOutput;
314  }
315
316  if (mShared) {
317    mLDInfo->output().setType(mcld::Output::DynObj);
318  } else {
319    mLDInfo->output().setType(mcld::Output::Exec);
320  }
321
322  mLDInfo->output().setSOName(mSOName);
323  mLDInfo->output().setMemArea(out_area);
324  mLDInfo->output().setContext(mLDInfo->contextFactory().produce(pPath));
325
326  // FIXME: We must initialize MCLinker before setOutput, and initialize
327  // standard sections here. This is because we have to build the section
328  // map before input files using it.
329  if (!mDriver->hasInitLinker()) {
330    return kNotConfig;
331  }
332
333  mDriver->initStdSections();
334
335  return kSuccess;
336}
337
338enum Linker::ErrorCode Linker::setOutput(int pFileHandler) {
339  if (mLDInfo->output().hasContext()) {
340    return kDoubleConfig;
341  }
342
343  // -----  initialize output file  ----- //
344  mcld::MemoryArea* out_area = mMemAreaFactory->produce(pFileHandler);
345
346  mLDInfo->output().setType(mcld::Output::DynObj);
347  mLDInfo->output().setMemArea(out_area);
348  mLDInfo->output().setContext(mLDInfo->contextFactory().produce());
349
350  // FIXME: We must initialize MCLinker before setOutput, and initialize
351  // standard sections here. This is because we have to build the section
352  // map before input files using it.
353  if (!mDriver->hasInitLinker()) {
354    return kNotConfig;
355  }
356
357  mDriver->initStdSections();
358
359  return kSuccess;
360}
361
362enum Linker::ErrorCode Linker::link() {
363  mDriver->normalize();
364
365  if (!mDriver->mergeSections()) {
366    return kReadSections;
367  }
368
369  if (!mDriver->addStandardSymbols() || !mDriver->addTargetSymbols()) {
370    return kAddAdditionalSymbols;
371  }
372
373  mDriver->readRelocations();
374  mDriver->prelayout();
375  mDriver->layout();
376  mDriver->postlayout();
377  mDriver->finalizeSymbolValue();
378  mDriver->relocation();
379  mDriver->emitOutput();
380  mDriver->postProcessing();
381
382  return kSuccess;
383}
384
385