122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===- SectionMap.cpp -----------------------------------------------------===//
222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//                     The MCLinker Project
422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// This file is distributed under the University of Illinois Open Source
622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// License. See LICENSE.TXT for details.
722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Object/SectionMap.h"
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/NullFragment.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSection.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/SectionData.h"
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/Assignment.h"
1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/Operand.h"
1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/Operator.h"
1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/RpnExpr.h"
1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/StringList.h"
1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/WildcardPattern.h"
2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
2187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/Casting.h>
2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines
2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <cassert>
2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <cstring>
2587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <climits>
2687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#if !defined(MCLD_ON_WIN32)
2787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <fnmatch.h>
2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define fnmatch0(pattern, string) (fnmatch(pattern, string, 0) == 0)
2987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#else
3087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <windows.h>
3187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <shlwapi.h>
3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define fnmatch0(pattern, string) (PathMatchSpec(string, pattern) == true)
3387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#endif
3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines
3787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===//
3887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// SectionMap::Input
3987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===//
4087f34658dec9097d987d254a990ea7f311bfc95fStephen HinesSectionMap::Input::Input(const std::string& pName,
4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                         InputSectDesc::KeepPolicy pPolicy)
4237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : m_Policy(pPolicy) {
4387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Spec.m_pWildcardFile =
4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      WildcardPattern::create("*", WildcardPattern::SORT_NONE);
4587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Spec.m_pExcludeFiles = NULL;
4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  StringList* sections = StringList::create();
4887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  sections->push_back(
4937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      WildcardPattern::create(pName, WildcardPattern::SORT_NONE));
5087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Spec.m_pWildcardSections = sections;
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
520dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  m_pSection = LDSection::Create(pName, LDFileFormat::TEXT, 0, 0);
5387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionData* sd = SectionData::Create(*m_pSection);
5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_pSection->setSectionData(sd);
5587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  new NullFragment(sd);
5687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  new NullFragment(sd);
5787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
5887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
5987f34658dec9097d987d254a990ea7f311bfc95fStephen HinesSectionMap::Input::Input(const InputSectDesc& pInputDesc)
6037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : m_Policy(pInputDesc.policy()) {
6187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Spec.m_pWildcardFile = pInputDesc.spec().m_pWildcardFile;
6287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Spec.m_pExcludeFiles = pInputDesc.spec().m_pExcludeFiles;
6387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Spec.m_pWildcardSections = pInputDesc.spec().m_pWildcardSections;
640dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  m_pSection = LDSection::Create("", LDFileFormat::TEXT, 0, 0);
6587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionData* sd = SectionData::Create(*m_pSection);
6687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_pSection->setSectionData(sd);
6787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  new NullFragment(sd);
6887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  new NullFragment(sd);
6987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
7287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// SectionMap::Output
7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
7487f34658dec9097d987d254a990ea7f311bfc95fStephen HinesSectionMap::Output::Output(const std::string& pName)
7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : m_Name(pName), m_Order(UINT_MAX) {
7687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Prolog.m_pVMA = NULL;
7787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Prolog.m_Type = OutputSectDesc::LOAD;
7887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Prolog.m_pLMA = NULL;
7987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Prolog.m_pAlign = NULL;
8087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Prolog.m_pSubAlign = NULL;
8187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Prolog.m_Constraint = OutputSectDesc::NO_CONSTRAINT;
8287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
8387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Epilog.m_pRegion = NULL;
8487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Epilog.m_pLMARegion = NULL;
8587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Epilog.m_pPhdrs = NULL;
8687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Epilog.m_pFillExp = NULL;
8787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
880dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  m_pSection = LDSection::Create(pName, LDFileFormat::TEXT, 0, 0);
8987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionData* sd = SectionData::Create(*m_pSection);
9087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_pSection->setSectionData(sd);
9187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
9287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_bIsDiscard = pName.compare("/DISCARD/") == 0;
9387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
9487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
9587f34658dec9097d987d254a990ea7f311bfc95fStephen HinesSectionMap::Output::Output(const OutputSectDesc& pOutputDesc)
9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : m_Name(pOutputDesc.name()),
9737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_Prolog(pOutputDesc.prolog()),
9837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_Epilog(pOutputDesc.epilog()),
9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_Order(UINT_MAX) {
1000dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  m_pSection = LDSection::Create(m_Name, LDFileFormat::TEXT, 0, 0);
10187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionData* sd = SectionData::Create(*m_pSection);
10287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_pSection->setSectionData(sd);
10387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
10487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_bIsDiscard = m_Name.compare("/DISCARD/") == 0;
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool SectionMap::Output::hasContent() const {
10887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return m_pSection != NULL && m_pSection->size() != 0;
10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11187f34658dec9097d987d254a990ea7f311bfc95fStephen HinesSectionMap::Output::const_dot_iterator
11237b74a387bb3993387029859c2d9d051c41c724eStephen HinesSectionMap::Output::find_first_explicit_dot() const {
11387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (const_dot_iterator it = dot_begin(), ie = dot_end(); it != ie; ++it) {
11487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*it).type() == Assignment::DEFAULT)
11587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return it;
11687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
11787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return dot_end();
11887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
11987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
12037b74a387bb3993387029859c2d9d051c41c724eStephen HinesSectionMap::Output::dot_iterator SectionMap::Output::find_first_explicit_dot() {
12187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (dot_iterator it = dot_begin(), ie = dot_end(); it != ie; ++it) {
12287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*it).type() == Assignment::DEFAULT)
12387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return it;
12487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
12587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return dot_end();
12687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
12787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
12887f34658dec9097d987d254a990ea7f311bfc95fStephen HinesSectionMap::Output::const_dot_iterator
12937b74a387bb3993387029859c2d9d051c41c724eStephen HinesSectionMap::Output::find_last_explicit_dot() const {
13087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  typedef DotAssignments::const_reverse_iterator CONST_RIT;
13187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (CONST_RIT rit = dotAssignments().rbegin(), rie = dotAssignments().rend();
13237b74a387bb3993387029859c2d9d051c41c724eStephen Hines       rit != rie;
13337b74a387bb3993387029859c2d9d051c41c724eStephen Hines       ++rit) {
13487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*rit).type() == Assignment::DEFAULT) {
13587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return dot_begin() +
13687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines             (dotAssignments().size() - (rit - dotAssignments().rbegin()) - 1);
13787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
13887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
13987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return dot_end();
14087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
14187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
14237b74a387bb3993387029859c2d9d051c41c724eStephen HinesSectionMap::Output::dot_iterator SectionMap::Output::find_last_explicit_dot() {
14387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  typedef DotAssignments::reverse_iterator RIT;
14487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (RIT rit = dotAssignments().rbegin(), rie = dotAssignments().rend();
14537b74a387bb3993387029859c2d9d051c41c724eStephen Hines       rit != rie;
14637b74a387bb3993387029859c2d9d051c41c724eStephen Hines       ++rit) {
14787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*rit).type() == Assignment::DEFAULT) {
14887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return dot_begin() +
14987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines             (dotAssignments().size() - (rit - dotAssignments().rbegin()) - 1);
15087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
15187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
15287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return dot_end();
15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
15422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// SectionMap
15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
15837b74a387bb3993387029859c2d9d051c41c724eStephen HinesSectionMap::~SectionMap() {
15987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  iterator out, outBegin = begin(), outEnd = end();
16087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (out = outBegin; out != outEnd; ++out) {
16187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (*out != NULL) {
16287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      Output::iterator in, inBegin = (*out)->begin(), inEnd = (*out)->end();
16387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      for (in = inBegin; in != inEnd; ++in) {
16487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (*in != NULL)
16587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          delete *in;
16687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
16787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      delete *out;
16887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
16987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
17022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
17237b74a387bb3993387029859c2d9d051c41c724eStephen HinesSectionMap::const_mapping SectionMap::find(
17337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const std::string& pInputFile,
17437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const std::string& pInputSection) const {
17587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const_iterator out, outBegin = begin(), outEnd = end();
17687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (out = outBegin; out != outEnd; ++out) {
17787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    Output::const_iterator in, inBegin = (*out)->begin(), inEnd = (*out)->end();
17887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (in = inBegin; in != inEnd; ++in) {
17987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (matched(**in, pInputFile, pInputSection))
18087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        return std::make_pair(*out, *in);
18187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
18287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
18387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return std::make_pair((const Output*)NULL, (const Input*)NULL);
18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18687f34658dec9097d987d254a990ea7f311bfc95fStephen HinesSectionMap::mapping SectionMap::find(const std::string& pInputFile,
18737b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                     const std::string& pInputSection) {
18887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  iterator out, outBegin = begin(), outEnd = end();
18987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (out = outBegin; out != outEnd; ++out) {
19087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    Output::iterator in, inBegin = (*out)->begin(), inEnd = (*out)->end();
19187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (in = inBegin; in != inEnd; ++in) {
19287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (matched(**in, pInputFile, pInputSection))
19387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        return std::make_pair(*out, *in);
19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
19637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return std::make_pair(reinterpret_cast<Output*>(NULL),
19737b74a387bb3993387029859c2d9d051c41c724eStephen Hines                        reinterpret_cast<Input*>(NULL));
19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
20037b74a387bb3993387029859c2d9d051c41c724eStephen HinesSectionMap::const_iterator SectionMap::find(
20137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const std::string& pOutputSection) const {
20287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const_iterator out, outBegin = begin(), outEnd = end();
20387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (out = outBegin; out != outEnd; ++out) {
20487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*out)->name().compare(pOutputSection) == 0)
20587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return out;
20687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
20787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return outEnd;
20887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
20987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
21037b74a387bb3993387029859c2d9d051c41c724eStephen HinesSectionMap::iterator SectionMap::find(const std::string& pOutputSection) {
21187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  iterator out, outBegin = begin(), outEnd = end();
21287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (out = outBegin; out != outEnd; ++out) {
21387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*out)->name().compare(pOutputSection) == 0)
21487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return out;
21587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
21687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return outEnd;
21787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
21887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
21937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstd::pair<SectionMap::mapping, bool> SectionMap::insert(
22037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const std::string& pInputSection,
22137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const std::string& pOutputSection,
22237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    InputSectDesc::KeepPolicy pPolicy) {
22387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  iterator out, outBegin = begin(), outEnd = end();
22487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (out = outBegin; out != outEnd; ++out) {
22587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*out)->name().compare(pOutputSection) == 0)
22687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
22787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
22887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (out != end()) {
22987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    Output::iterator in, inBegin = (*out)->begin(), inEnd = (*out)->end();
23087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (in = inBegin; in != inEnd; ++in) {
23187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if ((*in)->getSection()->name().compare(pInputSection) == 0)
23287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        break;
23387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
23487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
23587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (in != (*out)->end()) {
23687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return std::make_pair(std::make_pair(*out, *in), false);
23787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else {
23887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      Input* input = new Input(pInputSection, pPolicy);
23987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*out)->append(input);
24087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return std::make_pair(std::make_pair(*out, input), true);
24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
24387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
24487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Output* output = new Output(pOutputSection);
24587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_OutputDescList.push_back(output);
24687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Input* input = new Input(pInputSection, pPolicy);
24787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  output->append(input);
24887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
24987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return std::make_pair(std::make_pair(output, input), true);
25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstd::pair<SectionMap::mapping, bool> SectionMap::insert(
25337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const InputSectDesc& pInputDesc,
25437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const OutputSectDesc& pOutputDesc) {
25587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  iterator out, outBegin = begin(), outEnd = end();
25687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (out = outBegin; out != outEnd; ++out) {
25787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*out)->name().compare(pOutputDesc.name()) == 0 &&
25887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->prolog() == pOutputDesc.prolog() &&
25987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        (*out)->epilog() == pOutputDesc.epilog())
26087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      break;
26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (out != end()) {
26487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    Output::iterator in, inBegin = (*out)->begin(), inEnd = (*out)->end();
26587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (in = inBegin; in != inEnd; ++in) {
26687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if ((*in)->policy() == pInputDesc.policy() &&
26787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          (*in)->spec() == pInputDesc.spec())
26887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        break;
26987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
27087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
27187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (in != (*out)->end()) {
27287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return std::make_pair(std::make_pair(*out, *in), false);
27387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    } else {
27487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      Input* input = new Input(pInputDesc);
27587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      (*out)->append(input);
27687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return std::make_pair(std::make_pair(*out, input), true);
27787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
27887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
27987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
28087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Output* output = new Output(pOutputDesc);
28187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_OutputDescList.push_back(output);
28287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Input* input = new Input(pInputDesc);
28387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  output->append(input);
28487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
28587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return std::make_pair(std::make_pair(output, input), true);
28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
28837b74a387bb3993387029859c2d9d051c41c724eStephen HinesSectionMap::iterator SectionMap::insert(iterator pPosition,
28937b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        LDSection* pSection) {
29087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Output* output = new Output(pSection->name());
29187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  output->append(new Input(pSection->name(), InputSectDesc::NoKeep));
29287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  output->setSection(pSection);
29387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return m_OutputDescList.insert(pPosition, output);
29487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool SectionMap::matched(const SectionMap::Input& pInput,
29787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                         const std::string& pInputFile,
29837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                         const std::string& pInputSection) const {
29987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (pInput.spec().hasFile() && !matched(pInput.spec().file(), pInputFile))
30037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    return false;
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (pInput.spec().hasExcludeFiles()) {
30387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    StringList::const_iterator file, fileEnd;
30487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    fileEnd = pInput.spec().excludeFiles().end();
30587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (file = pInput.spec().excludeFiles().begin(); file != fileEnd; ++file) {
30687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (matched(llvm::cast<WildcardPattern>(**file), pInputFile)) {
30787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        return false;
30887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
30987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
31087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (pInput.spec().hasSections()) {
31387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    StringList::const_iterator sect, sectEnd = pInput.spec().sections().end();
31487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (sect = pInput.spec().sections().begin(); sect != sectEnd; ++sect) {
31587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (matched(llvm::cast<WildcardPattern>(**sect), pInputSection)) {
31687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        return true;
31787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
31887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return false;
32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool SectionMap::matched(const WildcardPattern& pPattern,
32537b74a387bb3993387029859c2d9d051c41c724eStephen Hines                         const std::string& pName) const {
32687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (pPattern.isPrefix()) {
32787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    llvm::StringRef name(pName);
32887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return name.startswith(pPattern.prefix());
32987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } else {
33087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return fnmatch0(pPattern.name().c_str(), pName.c_str());
33187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// fixupDotSymbols - ensure the dot symbols are valid
33537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid SectionMap::fixupDotSymbols() {
33687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (iterator it = begin() + 1, ie = end(); it != ie; ++it) {
33787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // fixup the 1st explicit dot assignment if needed
33887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (!(*it)->dotAssignments().empty()) {
33987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      Output::dot_iterator dot = (*it)->find_first_explicit_dot();
34037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (dot != (*it)->dot_end() && (*dot).symbol().isDot() &&
34187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          (*dot).getRpnExpr().hasDot()) {
34287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        Assignment assign(Assignment::OUTPUT_SECTION,
34387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                          Assignment::DEFAULT,
34487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                          *SymOperand::create("."),
34587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                          *RpnExpr::buildHelperExpr(it - 1));
34687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        Output::dot_iterator ref = (*it)->dotAssignments().insert(dot, assign);
34787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        for (RpnExpr::iterator tok = (*dot).getRpnExpr().begin(),
34837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                               tokEnd = (*dot).getRpnExpr().end();
34937b74a387bb3993387029859c2d9d051c41c724eStephen Hines             tok != tokEnd;
35037b74a387bb3993387029859c2d9d051c41c724eStephen Hines             ++tok) {
35187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          if ((*tok)->kind() == ExprToken::OPERAND &&
35287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines              llvm::cast<Operand>(*tok)->isDot())
35387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            *tok = &((*ref).symbol());
35437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        }  // for each token in the RHS expr of the dot assignment
35587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
35687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
35787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
35887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    // fixup dot in output VMA if needed
35987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if ((*it)->prolog().hasVMA() && (*it)->prolog().vma().hasDot()) {
36087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      Output::dot_iterator dot = (*it)->find_last_explicit_dot();
36187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      if (dot == (*it)->dot_end()) {
36287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        Assignment assign(Assignment::OUTPUT_SECTION,
36387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                          Assignment::DEFAULT,
36487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                          *SymOperand::create("."),
36587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                          *RpnExpr::buildHelperExpr(it - 1));
36687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        dot = (*it)->dotAssignments().insert(dot, assign);
36787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
36887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      for (RpnExpr::iterator tok = (*it)->prolog().vma().begin(),
36937b74a387bb3993387029859c2d9d051c41c724eStephen Hines                             tokEnd = (*it)->prolog().vma().end();
37037b74a387bb3993387029859c2d9d051c41c724eStephen Hines           tok != tokEnd;
37137b74a387bb3993387029859c2d9d051c41c724eStephen Hines           ++tok) {
37287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if ((*tok)->kind() == ExprToken::OPERAND &&
37387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines            llvm::cast<Operand>(*tok)->isDot())
37487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          *tok = &((*dot).symbol());
37537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      }  // for each token in the RHS expr of the dot assignment
37687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
37737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }  // for each output section
37887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
37937b74a387bb3993387029859c2d9d051c41c724eStephen Hines
38037b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
381