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