Update mclinker for LLVM rebase to r222494. This corresponds to the following upstream mclinker change: commit b2f1691276052c4215abf36715d43248d6337cf8 Author: Diana Chen <[email protected]> Date: Tue Nov 25 14:03:29 2014 +0800 option: Allow `-hash-style' can be specified zero or more times Change-Id: I332546680bb45cf9692adfa2c2d3dcdc84361afc
diff --git a/lib/Object/ObjectLinker.cpp b/lib/Object/ObjectLinker.cpp index dfc7f37..f32ebfc 100644 --- a/lib/Object/ObjectLinker.cpp +++ b/lib/Object/ObjectLinker.cpp
@@ -6,68 +6,68 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#include <mcld/Object/ObjectLinker.h> +#include "mcld/Object/ObjectLinker.h" -#include <mcld/LinkerConfig.h> -#include <mcld/LinkerScript.h> -#include <mcld/Module.h> -#include <mcld/InputTree.h> -#include <mcld/IRBuilder.h> -#include <mcld/LD/LDSection.h> -#include <mcld/LD/LDContext.h> -#include <mcld/LD/Archive.h> -#include <mcld/LD/ArchiveReader.h> -#include <mcld/LD/ObjectReader.h> -#include <mcld/LD/DynObjReader.h> -#include <mcld/LD/GroupReader.h> -#include <mcld/LD/BinaryReader.h> -#include <mcld/LD/GarbageCollection.h> -#include <mcld/LD/IdenticalCodeFolding.h> -#include <mcld/LD/ObjectWriter.h> -#include <mcld/LD/ResolveInfo.h> -#include <mcld/LD/RelocData.h> -#include <mcld/LD/Relocator.h> -#include <mcld/LD/SectionData.h> -#include <mcld/LD/BranchIslandFactory.h> -#include <mcld/Script/ScriptFile.h> -#include <mcld/Script/ScriptReader.h> -#include <mcld/Script/Assignment.h> -#include <mcld/Script/Operand.h> -#include <mcld/Script/RpnEvaluator.h> -#include <mcld/Support/RealPath.h> -#include <mcld/Support/FileOutputBuffer.h> -#include <mcld/Support/MsgHandling.h> -#include <mcld/Target/TargetLDBackend.h> -#include <mcld/Fragment/Relocation.h> -#include <mcld/Object/ObjectBuilder.h> +#include "mcld/InputTree.h" +#include "mcld/IRBuilder.h" +#include "mcld/LinkerConfig.h" +#include "mcld/LinkerScript.h" +#include "mcld/Module.h" +#include "mcld/Fragment/Relocation.h" +#include "mcld/LD/Archive.h" +#include "mcld/LD/ArchiveReader.h" +#include "mcld/LD/BinaryReader.h" +#include "mcld/LD/BranchIslandFactory.h" +#include "mcld/LD/DebugString.h" +#include "mcld/LD/DynObjReader.h" +#include "mcld/LD/GarbageCollection.h" +#include "mcld/LD/GroupReader.h" +#include "mcld/LD/IdenticalCodeFolding.h" +#include "mcld/LD/LDContext.h" +#include "mcld/LD/LDSection.h" +#include "mcld/LD/ObjectReader.h" +#include "mcld/LD/ObjectWriter.h" +#include "mcld/LD/Relocator.h" +#include "mcld/LD/RelocData.h" +#include "mcld/LD/ResolveInfo.h" +#include "mcld/LD/SectionData.h" +#include "mcld/Object/ObjectBuilder.h" +#include "mcld/Script/Assignment.h" +#include "mcld/Script/Operand.h" +#include "mcld/Script/RpnEvaluator.h" +#include "mcld/Script/ScriptFile.h" +#include "mcld/Script/ScriptReader.h" +#include "mcld/Support/FileOutputBuffer.h" +#include "mcld/Support/MsgHandling.h" +#include "mcld/Support/RealPath.h" +#include "mcld/Target/TargetLDBackend.h" #include <llvm/Support/Casting.h> #include <llvm/Support/Host.h> + #include <system_error> -using namespace llvm; -using namespace mcld; +namespace mcld { //===----------------------------------------------------------------------===// // ObjectLinker //===----------------------------------------------------------------------===// ObjectLinker::ObjectLinker(const LinkerConfig& pConfig, TargetLDBackend& pLDBackend) - : m_Config(pConfig), - m_pModule(NULL), - m_pBuilder(NULL), - m_LDBackend(pLDBackend), - m_pObjectReader(NULL), - m_pDynObjReader(NULL), - m_pArchiveReader(NULL), - m_pGroupReader(NULL), - m_pBinaryReader(NULL), - m_pScriptReader(NULL), - m_pWriter(NULL) { + : m_Config(pConfig), + m_pModule(NULL), + m_pBuilder(NULL), + m_LDBackend(pLDBackend), + m_pObjectReader(NULL), + m_pDynObjReader(NULL), + m_pArchiveReader(NULL), + m_pGroupReader(NULL), + m_pBinaryReader(NULL), + m_pScriptReader(NULL), + m_pWriter(NULL) { } -ObjectLinker::~ObjectLinker() -{ +ObjectLinker::~ObjectLinker() { delete m_pObjectReader; delete m_pDynObjReader; delete m_pArchiveReader; @@ -77,20 +77,23 @@ delete m_pWriter; } -bool ObjectLinker::initialize(Module& pModule, IRBuilder& pBuilder) -{ +bool ObjectLinker::initialize(Module& pModule, IRBuilder& pBuilder) { m_pModule = &pModule; m_pBuilder = &pBuilder; // initialize the readers and writers - m_pObjectReader = m_LDBackend.createObjectReader(*m_pBuilder); + m_pObjectReader = m_LDBackend.createObjectReader(*m_pBuilder); m_pArchiveReader = m_LDBackend.createArchiveReader(*m_pModule); - m_pDynObjReader = m_LDBackend.createDynObjReader(*m_pBuilder); - m_pBinaryReader = m_LDBackend.createBinaryReader(*m_pBuilder); - m_pGroupReader = new GroupReader(*m_pModule, *m_pObjectReader, - *m_pDynObjReader, *m_pArchiveReader, *m_pBinaryReader); - m_pScriptReader = new ScriptReader(*m_pGroupReader); - m_pWriter = m_LDBackend.createWriter(); + m_pDynObjReader = m_LDBackend.createDynObjReader(*m_pBuilder); + m_pBinaryReader = m_LDBackend.createBinaryReader(*m_pBuilder); + m_pGroupReader = new GroupReader(*m_pModule, + *m_pObjectReader, + *m_pDynObjReader, + *m_pArchiveReader, + *m_pBinaryReader); + m_pScriptReader = new ScriptReader( + *m_pObjectReader, *m_pArchiveReader, *m_pDynObjReader, *m_pGroupReader); + m_pWriter = m_LDBackend.createWriter(); // initialize Relocator m_LDBackend.initRelocator(); @@ -99,8 +102,7 @@ } /// initStdSections - initialize standard sections -bool ObjectLinker::initStdSections() -{ +bool ObjectLinker::initStdSections() { ObjectBuilder builder(*m_pModule); // initialize standard sections @@ -113,30 +115,27 @@ return true; } -void ObjectLinker::addUndefinedSymbols() -{ +void ObjectLinker::addUndefinedSymbols() { // Add the symbol set by -u as an undefind global symbol into symbol pool GeneralOptions::const_undef_sym_iterator usym; GeneralOptions::const_undef_sym_iterator usymEnd = - m_Config.options().undef_sym_end(); + m_Config.options().undef_sym_end(); for (usym = m_Config.options().undef_sym_begin(); usym != usymEnd; ++usym) { Resolver::Result result; - m_pModule->getNamePool().insertSymbol(*usym, // name - false, // isDyn + m_pModule->getNamePool().insertSymbol(*usym, // name + false, // isDyn ResolveInfo::NoType, ResolveInfo::Undefined, ResolveInfo::Global, - 0x0, // size - 0x0, // value + 0x0, // size + 0x0, // value ResolveInfo::Default, NULL, result); LDSymbol* output_sym = result.info->outSymbol(); - bool has_output_sym = (NULL != output_sym); - // create the output symbol if it dose not have one - if (!result.existent || !has_output_sym) { + if (!result.existent || (output_sym != NULL)) { output_sym = LDSymbol::Create(*result.info); result.info->setSymPtr(output_sym); output_sym->setFragmentRef(FragmentRef::Null()); @@ -144,15 +143,14 @@ } } -void ObjectLinker::normalize() -{ +void ObjectLinker::normalize() { // ----- set up inputs ----- // Module::input_iterator input, inEnd = m_pModule->input_end(); - for (input = m_pModule->input_begin(); input!=inEnd; ++input) { + for (input = m_pModule->input_begin(); input != inEnd; ++input) { // is a group node if (isGroup(input)) { - getGroupReader()->readGroup(input, inEnd, m_pBuilder->getInputBuilder(), - m_Config); + getGroupReader()->readGroup( + input, inEnd, m_pBuilder->getInputBuilder(), m_Config); continue; } @@ -179,58 +177,56 @@ (*input)->setType(Input::Object); getBinaryReader()->readBinary(**input); m_pModule->getObjectList().push_back(*input); - } - // is a relocatable object file - else if (doContinue && getObjectReader()->isMyFormat(**input, doContinue)) { + } else if (doContinue && + getObjectReader()->isMyFormat(**input, doContinue)) { + // is a relocatable object file (*input)->setType(Input::Object); getObjectReader()->readHeader(**input); getObjectReader()->readSections(**input); getObjectReader()->readSymbols(**input); m_pModule->getObjectList().push_back(*input); - } - // is a shared object file - else if (doContinue && getDynObjReader()->isMyFormat(**input, doContinue)) { + } else if (doContinue && + getDynObjReader()->isMyFormat(**input, doContinue)) { + // is a shared object file (*input)->setType(Input::DynObj); getDynObjReader()->readHeader(**input); getDynObjReader()->readSymbols(**input); m_pModule->getLibraryList().push_back(*input); - } - // is an archive - else if (doContinue && getArchiveReader()->isMyFormat(**input, doContinue)) { + } else if (doContinue && + getArchiveReader()->isMyFormat(**input, doContinue)) { + // is an archive (*input)->setType(Input::Archive); if (m_Config.options().isInExcludeLIBS(**input)) { (*input)->setNoExport(); } Archive archive(**input, m_pBuilder->getInputBuilder()); getArchiveReader()->readArchive(m_Config, archive); - if(archive.numOfObjectMember() > 0) { + if (archive.numOfObjectMember() > 0) { m_pModule->getInputTree().merge<InputTree::Inclusive>(input, archive.inputs()); } - } - // try to parse input as a linker script - else if (doContinue && getScriptReader()->isMyFormat(**input, doContinue)) { - ScriptFile script(ScriptFile::LDScript, **input, - m_pBuilder->getInputBuilder()); + } else if (doContinue && + getScriptReader()->isMyFormat(**input, doContinue)) { + // try to parse input as a linker script + ScriptFile script( + ScriptFile::LDScript, **input, m_pBuilder->getInputBuilder()); if (getScriptReader()->readScript(m_Config, script)) { (*input)->setType(Input::Script); script.activate(*m_pModule); if (script.inputs().size() > 0) { - m_pModule->getInputTree().merge<InputTree::Inclusive>(input, - script.inputs()); + m_pModule->getInputTree().merge<InputTree::Inclusive>( + input, script.inputs()); } } - } - else { + } else { if (m_Config.options().warnMismatch()) - warning(diag::warn_unrecognized_input_file) << (*input)->path() - << m_Config.targets().triple().str(); + warning(diag::warn_unrecognized_input_file) + << (*input)->path() << m_Config.targets().triple().str(); } - } // end of for + } // end of for } -bool ObjectLinker::linkable() const -{ +bool ObjectLinker::linkable() const { // check we have input and output files if (m_pModule->getInputTree().empty()) { error(diag::err_no_inputs); @@ -240,9 +236,9 @@ // can not mix -static with shared objects Module::const_lib_iterator lib, libEnd = m_pModule->lib_end(); for (lib = m_pModule->lib_begin(); lib != libEnd; ++lib) { - if((*lib)->attribute()->isStatic()) { - error(diag::err_mixed_shared_static_objects) - << (*lib)->name() << (*lib)->path(); + if ((*lib)->attribute()->isStatic()) { + error(diag::err_mixed_shared_static_objects) << (*lib)->name() + << (*lib)->path(); return false; } } @@ -265,8 +261,11 @@ return true; } -void ObjectLinker::dataStrippingOpt() -{ +void ObjectLinker::dataStrippingOpt() { + if (m_Config.codeGenType() == LinkerConfig::Object) { + return; + } + // Garbege collection if (m_Config.options().GCSections()) { GarbageCollection GC(m_Config, m_LDBackend, *m_pModule); @@ -284,12 +283,12 @@ /// readRelocations - read all relocation entries /// /// All symbols should be read and resolved before this function. -bool ObjectLinker::readRelocations() -{ +bool ObjectLinker::readRelocations() { // Bitcode is read by the other path. This function reads relocation sections // in object files. - mcld::InputTree::bfs_iterator input, inEnd = m_pModule->getInputTree().bfs_end(); - for (input=m_pModule->getInputTree().bfs_begin(); input!=inEnd; ++input) { + mcld::InputTree::bfs_iterator input, + inEnd = m_pModule->getInputTree().bfs_end(); + for (input = m_pModule->getInputTree().bfs_begin(); input != inEnd; ++input) { if ((*input)->type() == Input::Object && (*input)->hasMemArea()) { if (!getObjectReader()->readRelocations(**input)) return false; @@ -300,8 +299,39 @@ } /// mergeSections - put allinput sections into output sections -bool ObjectLinker::mergeSections() -{ +bool ObjectLinker::mergeSections() { + // Set up input/output from ldscript requirement if any + { + RpnEvaluator evaluator(*m_pModule, m_LDBackend); + SectionMap::iterator out, outBegin, outEnd; + outBegin = m_pModule->getScript().sectionMap().begin(); + outEnd = m_pModule->getScript().sectionMap().end(); + for (out = outBegin; out != outEnd; ++out) { + uint64_t out_align = 0x0, in_align = 0x0; + LDSection* out_sect = (*out)->getSection(); + SectionMap::Output::iterator in, inBegin, inEnd; + inBegin = (*out)->begin(); + inEnd = (*out)->end(); + + // force input alignment from ldscript if any + if ((*out)->prolog().hasSubAlign()) { + evaluator.eval((*out)->prolog().subAlign(), in_align); + } + + for (in = inBegin; in != inEnd; ++in) { + LDSection* in_sect = (*in)->getSection(); + if ((*out)->prolog().hasSubAlign()) + in_sect->setAlign(in_align); + } // for each input section description + + // force output alignment from ldscript if any + if ((*out)->prolog().hasAlign()) { + evaluator.eval((*out)->prolog().align(), out_align); + out_sect->setAlign(out_align); + } + } // for each output section description + } + ObjectBuilder builder(*m_pModule); Module::obj_iterator obj, objEnd = m_pModule->obj_end(); for (obj = m_pModule->obj_begin(); obj != objEnd; ++obj) { @@ -317,15 +347,14 @@ case LDFileFormat::StackNote: // skip continue; - case LDFileFormat::Relocation: { + case LDFileFormat::Relocation: if (!(*sect)->hasRelocData()) - continue; // skip + continue; // skip if ((*sect)->getLink()->kind() == LDFileFormat::Ignore || (*sect)->getLink()->kind() == LDFileFormat::Folded) (*sect)->setKind(LDFileFormat::Ignore); break; - } case LDFileFormat::Target: if (!m_LDBackend.mergeSection(*m_pModule, **obj, **sect)) { error(diag::err_cannot_merge_section) << (*sect)->name() @@ -335,10 +364,10 @@ break; case LDFileFormat::EhFrame: { if (!(*sect)->hasEhFrame()) - continue; // skip + continue; // skip LDSection* out_sect = NULL; - if (NULL != (out_sect = builder.MergeSection(**obj, **sect))) { + if ((out_sect = builder.MergeSection(**obj, **sect)) != NULL) { if (!m_LDBackend.updateSectionFlags(*out_sect, **sect)) { error(diag::err_cannot_merge_section) << (*sect)->name() << (*obj)->name(); @@ -347,12 +376,17 @@ } break; } + case LDFileFormat::DebugString: { + // FIXME: disable debug string merge when doing partial link. + if (LinkerConfig::Object == m_Config.codeGenType()) + (*sect)->setKind(LDFileFormat::Debug); + } // Fall through default: { if (!(*sect)->hasSectionData()) - continue; // skip + continue; // skip LDSection* out_sect = NULL; - if (NULL != (out_sect = builder.MergeSection(**obj, **sect))) { + if ((out_sect = builder.MergeSection(**obj, **sect)) != NULL) { if (!m_LDBackend.updateSectionFlags(*out_sect, **sect)) { error(diag::err_cannot_merge_section) << (*sect)->name() << (*obj)->name(); @@ -361,69 +395,72 @@ } break; } - } // end of switch - } // for each section - } // for each obj + } // end of switch + } // for each section + } // for each obj - RpnEvaluator evaluator(*m_pModule, m_LDBackend); - SectionMap::iterator out, outBegin, outEnd; - outBegin = m_pModule->getScript().sectionMap().begin(); - outEnd = m_pModule->getScript().sectionMap().end(); - for (out = outBegin; out != outEnd; ++out) { - uint64_t out_align = 0x0, in_align = 0x0; - LDSection* out_sect = (*out)->getSection(); - SectionMap::Output::iterator in, inBegin, inEnd; - inBegin = (*out)->begin(); - inEnd = (*out)->end(); + { + SectionMap::iterator out, outBegin, outEnd; + outBegin = m_pModule->getScript().sectionMap().begin(); + outEnd = m_pModule->getScript().sectionMap().end(); + for (out = outBegin; out != outEnd; ++out) { + LDSection* out_sect = (*out)->getSection(); + SectionMap::Output::iterator in, inBegin, inEnd; + inBegin = (*out)->begin(); + inEnd = (*out)->end(); - // force input alignment from ldscript if any - if ((*out)->prolog().hasSubAlign()) { - evaluator.eval((*out)->prolog().subAlign(), in_align); - } + for (in = inBegin; in != inEnd; ++in) { + LDSection* in_sect = (*in)->getSection(); + if (builder.MoveSectionData(*in_sect->getSectionData(), + *out_sect->getSectionData())) { + builder.UpdateSectionAlign(*out_sect, *in_sect); + m_LDBackend.updateSectionFlags(*out_sect, *in_sect); + } + } // for each input section description - for (in = inBegin; in != inEnd; ++in) { - LDSection* in_sect = (*in)->getSection(); - if ((*out)->prolog().hasSubAlign()) - in_sect->setAlign(in_align); - - if (builder.MoveSectionData(*in_sect->getSectionData(), - *out_sect->getSectionData())) { - builder.UpdateSectionAlign(*out_sect, *in_sect); - m_LDBackend.updateSectionFlags(*out_sect, *in_sect); + if ((*out)->hasContent()) { + LDSection* target = m_pModule->getSection((*out)->name()); + assert(target != NULL && target->hasSectionData()); + if (builder.MoveSectionData(*out_sect->getSectionData(), + *target->getSectionData())) { + builder.UpdateSectionAlign(*target, *out_sect); + m_LDBackend.updateSectionFlags(*target, *out_sect); + } } - } // for each input section description - - // force output alignment from ldscript if any - if ((*out)->prolog().hasAlign()) { - evaluator.eval((*out)->prolog().align(), out_align); - out_sect->setAlign(out_align); - } - - if ((*out)->hasContent()) { - LDSection* target = m_pModule->getSection((*out)->name()); - assert(target != NULL && target->hasSectionData()); - if (builder.MoveSectionData(*out_sect->getSectionData(), - *target->getSectionData())) { - builder.UpdateSectionAlign(*target, *out_sect); - m_LDBackend.updateSectionFlags(*target, *out_sect); - } - } - } // for each output section description + } // for each output section description + } return true; } -void ObjectLinker::addSymbolToOutput(ResolveInfo& pInfo, Module& pModule) -{ +void ObjectLinker::addSymbolToOutput(ResolveInfo& pInfo, Module& pModule) { // section symbols will be defined by linker later, we should not add section // symbols to output here - if (ResolveInfo::Section == pInfo.type() || NULL == pInfo.outSymbol()) + if (ResolveInfo::Section == pInfo.type() || pInfo.outSymbol() == NULL) return; // if the symbols defined in the Ignore sections (e.g. discared by GC), then // not to put them to output - if (pInfo.outSymbol()->hasFragRef() && LDFileFormat::Ignore == - pInfo.outSymbol()->fragRef()->frag()->getParent()->getSection().kind()) + // make sure that symbols defined in .debug_str won't add into output + // symbol table. Since these symbols has fragRef to input fragments, which + // will refer to input LDSection and has bad result when emitting their + // section index. However, .debug_str actually does not need symobl in + // shrad/executable objects, so it's fine to do so. + if (pInfo.outSymbol()->hasFragRef() && + (LDFileFormat::Ignore == + pInfo.outSymbol() + ->fragRef() + ->frag() + ->getParent() + ->getSection() + .kind() || + LDFileFormat::DebugString == + pInfo.outSymbol() + ->fragRef() + ->frag() + ->getParent() + ->getSection() + .kind())) return; if (pInfo.shouldForceLocal(m_Config)) @@ -432,31 +469,27 @@ pModule.getSymbolTable().add(*pInfo.outSymbol()); } -void ObjectLinker::addSymbolsToOutput(Module& pModule) -{ +void ObjectLinker::addSymbolsToOutput(Module& pModule) { // Traverse all the free ResolveInfo and add the output symobols to output NamePool::freeinfo_iterator free_it, - free_end = pModule.getNamePool().freeinfo_end(); + free_end = pModule.getNamePool().freeinfo_end(); for (free_it = pModule.getNamePool().freeinfo_begin(); free_it != free_end; - ++free_it) + ++free_it) addSymbolToOutput(**free_it, pModule); - // Traverse all the resolveInfo and add the output symbol to output NamePool::syminfo_iterator info_it, - info_end = pModule.getNamePool().syminfo_end(); + info_end = pModule.getNamePool().syminfo_end(); for (info_it = pModule.getNamePool().syminfo_begin(); info_it != info_end; - ++info_it) + ++info_it) addSymbolToOutput(*info_it.getEntry(), pModule); } - /// addStandardSymbols - shared object and executable files need some /// standard symbols /// @return if there are some input symbols with the same name to the /// standard symbols, return false -bool ObjectLinker::addStandardSymbols() -{ +bool ObjectLinker::addStandardSymbols() { // create and add section symbols for each output section Module::iterator iter, iterEnd = m_pModule->end(); for (iter = m_pModule->begin(); iter != iterEnd; ++iter) { @@ -470,25 +503,23 @@ /// target-dependent symbols /// @return if there are some input symbols with the same name to the /// target symbols, return false -bool ObjectLinker::addTargetSymbols() -{ +bool ObjectLinker::addTargetSymbols() { m_LDBackend.initTargetSymbols(*m_pBuilder, *m_pModule); return true; } /// addScriptSymbols - define symbols from the command line option or linker /// scripts. -bool ObjectLinker::addScriptSymbols() -{ +bool ObjectLinker::addScriptSymbols() { LinkerScript& script = m_pModule->getScript(); LinkerScript::Assignments::iterator it, ie = script.assignments().end(); // go through the entire symbol assignments for (it = script.assignments().begin(); it != ie; ++it) { LDSymbol* symbol = NULL; assert((*it).second.symbol().type() == Operand::SYMBOL); - const llvm::StringRef symName = (*it).second.symbol().name(); - ResolveInfo::Type type = ResolveInfo::NoType; - ResolveInfo::Visibility vis = ResolveInfo::Default; + const llvm::StringRef symName = (*it).second.symbol().name(); + ResolveInfo::Type type = ResolveInfo::NoType; + ResolveInfo::Visibility vis = ResolveInfo::Default; size_t size = 0; ResolveInfo* old_info = m_pModule->getNamePool().findInfo(symName); // if the symbol does not exist, we can set type to NOTYPE @@ -504,36 +535,35 @@ // FIXME: bfd linker would change the binding instead, but currently // ABS is also a kind of Binding in ResolveInfo. switch ((*it).second.type()) { - case Assignment::HIDDEN: - vis = ResolveInfo::Hidden; + case Assignment::HIDDEN: + vis = ResolveInfo::Hidden; // Fall through - case Assignment::DEFAULT: - symbol = - m_pBuilder->AddSymbol<IRBuilder::Force, - IRBuilder::Unresolve>(symName, - type, - ResolveInfo::Define, - ResolveInfo::Absolute, - size, - 0x0, - FragmentRef::Null(), - vis); - break; - case Assignment::PROVIDE_HIDDEN: - vis = ResolveInfo::Hidden; + case Assignment::DEFAULT: + symbol = m_pBuilder->AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( + symName, + type, + ResolveInfo::Define, + ResolveInfo::Absolute, + size, + 0x0, + FragmentRef::Null(), + vis); + break; + case Assignment::PROVIDE_HIDDEN: + vis = ResolveInfo::Hidden; // Fall through - case Assignment::PROVIDE: - symbol = - m_pBuilder->AddSymbol<IRBuilder::AsReferred, - IRBuilder::Unresolve>(symName, - type, - ResolveInfo::Define, - ResolveInfo::Absolute, - size, - 0x0, - FragmentRef::Null(), - vis); - break; + case Assignment::PROVIDE: + symbol = + m_pBuilder->AddSymbol<IRBuilder::AsReferred, IRBuilder::Unresolve>( + symName, + type, + ResolveInfo::Define, + ResolveInfo::Absolute, + size, + 0x0, + FragmentRef::Null(), + vis); + break; } // Set symbol of this assignment. (*it).first = symbol; @@ -541,8 +571,7 @@ return true; } -bool ObjectLinker::scanRelocations() -{ +bool ObjectLinker::scanRelocations() { // apply all relocations of all inputs Module::obj_iterator input, inEnd = m_pModule->obj_end(); for (input = m_pModule->obj_begin(); input != inEnd; ++input) { @@ -565,25 +594,25 @@ if (!info->outSymbol()->hasFragRef() && ResolveInfo::Section == info->type() && ResolveInfo::Undefined == info->desc()) - continue; + continue; // scan relocation - if (LinkerConfig::Object != m_Config.codeGenType()) + if (LinkerConfig::Object != m_Config.codeGenType()) { m_LDBackend.getRelocator()->scanRelocation( - *relocation, *m_pBuilder, *m_pModule, **rs, **input); - else + *relocation, *m_pBuilder, *m_pModule, **rs, **input); + } else { m_LDBackend.getRelocator()->partialScanRelocation( - *relocation, *m_pModule, **rs); - } // for all relocations - } // for all relocation section + *relocation, *m_pModule); + } + } // for all relocations + } // for all relocation section m_LDBackend.getRelocator()->finalizeScan(**input); - } // for all inputs + } // for all inputs return true; } /// initStubs - initialize stub-related stuff. -bool ObjectLinker::initStubs() -{ +bool ObjectLinker::initStubs() { // initialize BranchIslandFactory m_LDBackend.initBRIslandFactory(); @@ -597,8 +626,7 @@ /// allocateCommonSymobols - allocate fragments for common symbols to the /// corresponding sections -bool ObjectLinker::allocateCommonSymbols() -{ +bool ObjectLinker::allocateCommonSymbols() { if (LinkerConfig::Object != m_Config.codeGenType() || m_Config.options().isDefineCommon()) return m_LDBackend.allocateCommonSymbols(*m_pModule); @@ -606,13 +634,13 @@ } /// prelayout - help backend to do some modification before layout -bool ObjectLinker::prelayout() -{ +bool ObjectLinker::prelayout() { // finalize the section symbols, set their fragment reference and push them // into output symbol table Module::iterator sect, sEnd = m_pModule->end(); for (sect = m_pModule->begin(); sect != sEnd; ++sect) { - m_pModule->getSectionSymbolSet().finalize(**sect, + m_pModule->getSectionSymbolSet().finalize( + **sect, m_pModule->getSymbolTable(), m_Config.codeGenType() == LinkerConfig::Object); } @@ -622,15 +650,15 @@ /// check program interpreter - computer the name size of the runtime dyld if (!m_Config.isCodeStatic() && (LinkerConfig::Exec == m_Config.codeGenType() || - m_Config.options().isPIE() || - m_Config.options().hasDyld())) + m_Config.options().isPIE() || m_Config.options().hasDyld())) m_LDBackend.sizeInterp(); /// measure NamePools - compute the size of name pool sections /// In ELF, will compute the size of.symtab, .strtab, .dynsym, .dynstr, /// .hash and .shstrtab sections. /// - /// dump all symbols and strings from ObjectLinker and build the format-dependent + /// dump all symbols and strings from ObjectLinker and build the + /// format-dependent /// hash table. /// @note sizeNamePools replies on LinkerConfig::CodePosition. Must determine /// code position model before calling GNULDBackend::sizeNamePools() @@ -642,6 +670,16 @@ eh_frame_sect->getEhFrame()->computeOffsetSize(); m_LDBackend.createAndSizeEhFrameHdr(*m_pModule); + // size debug string table and set up the debug string offset + // we set the .debug_str size here so that there won't be a section symbol for + // .debug_str. While actually it doesn't matter that .debug_str has section + // symbol or not. + // FIXME: disable debug string merge when doing partial link. + if (LinkerConfig::Object != m_Config.codeGenType()) { + LDSection* debug_str_sect = m_pModule->getSection(".debug_str"); + if (debug_str_sect && debug_str_sect->hasDebugString()) + debug_str_sect->getDebugString()->computeOffsetSize(); + } return true; } @@ -650,27 +688,24 @@ /// Because we do not support instruction relaxing in this early version, /// if there is a branch can not jump to its target, we return false /// directly -bool ObjectLinker::layout() -{ +bool ObjectLinker::layout() { m_LDBackend.layout(*m_pModule); return true; } /// prelayout - help backend to do some modification after layout -bool ObjectLinker::postlayout() -{ +bool ObjectLinker::postlayout() { m_LDBackend.postLayout(*m_pModule, *m_pBuilder); return true; } /// finalizeSymbolValue - finalize the resolved symbol value. -/// Before relocate(), after layout(), ObjectLinker should correct value of all +/// Before relocate(), after layout(), ObjectLinker should correct value of +/// all /// symbol. -bool ObjectLinker::finalizeSymbolValue() -{ +bool ObjectLinker::finalizeSymbolValue() { Module::sym_iterator symbol, symEnd = m_pModule->sym_end(); for (symbol = m_pModule->sym_begin(); symbol != symEnd; ++symbol) { - if ((*symbol)->resolveInfo()->isAbsolute() || (*symbol)->resolveInfo()->type() == ResolveInfo::File) { // absolute symbols should just use its value directly (i.e., the result @@ -688,9 +723,9 @@ // relocatable object file, the section's virtual address becomes zero. // And the symbol's value become section relative offset. uint64_t value = (*symbol)->fragRef()->getOutputOffset(); - assert(NULL != (*symbol)->fragRef()->frag()); + assert((*symbol)->fragRef()->frag() != NULL); uint64_t addr = - (*symbol)->fragRef()->frag()->getParent()->getSection().addr(); + (*symbol)->fragRef()->frag()->getParent()->getSection().addr(); (*symbol)->setValue(value + addr); continue; } @@ -714,7 +749,7 @@ break; symbol->setValue(assignment.symbol().value()); - } // for each script symbol assignment + } // for each script symbol assignment bool assertionsPassed = true; LinkerScript::Assertions::iterator assert, assertEnd; @@ -724,7 +759,7 @@ evaluator.eval((*assert).getRpnExpr(), res); if (res == 0x0) fatal(diag::err_assert_failed) << (*assert).message(); - } // for each assertion in ldscript + } // for each assertion in ldscript return finalized && scriptSymsFinalized && assertionsPassed; } @@ -734,12 +769,13 @@ /// Create relocation section, asking TargetLDBackend to /// read the relocation information into RelocationEntry /// and push_back into the relocation section -bool ObjectLinker::relocation() -{ +bool ObjectLinker::relocation() { // when producing relocatables, no need to apply relocation if (LinkerConfig::Object == m_Config.codeGenType()) return true; + LDSection* debug_str_sect = m_pModule->getSection(".debug_str"); + // apply all relocations of all inputs Module::obj_iterator input, inEnd = m_pModule->obj_end(); for (input = m_pModule->obj_begin(); input != inEnd; ++input) { @@ -764,11 +800,24 @@ ResolveInfo::Undefined == info->desc()) continue; + // apply the relocation aginst symbol on DebugString + if (info->outSymbol()->hasFragRef() && + info->outSymbol()->fragRef()->frag()->getKind() + == Fragment::Region && + info->outSymbol()->fragRef()->frag()->getParent()->getSection() + .kind() == LDFileFormat::DebugString) { + assert(debug_str_sect != NULL); + assert(debug_str_sect->hasDebugString()); + debug_str_sect->getDebugString()->applyOffset(*relocation, + m_LDBackend); + continue; + } + relocation->apply(*m_LDBackend.getRelocator()); - } // for all relocations - } // for all relocation section + } // for all relocations + } // for all relocation section m_LDBackend.getRelocator()->finalizeApply(**input); - } // for all inputs + } // for all inputs // apply relocations created by relaxation BranchIslandFactory* br_factory = m_LDBackend.getBRIslandFactory(); @@ -779,19 +828,17 @@ for (iter = island.reloc_begin(); iter != iterEnd; ++iter) (*iter)->apply(*m_LDBackend.getRelocator()); } + return true; } /// emitOutput - emit the output file. -bool ObjectLinker::emitOutput(FileOutputBuffer& pOutput) -{ +bool ObjectLinker::emitOutput(FileOutputBuffer& pOutput) { return std::error_code() == getWriter()->writeObject(*m_pModule, pOutput); } - /// postProcessing - do modification after all processes -bool ObjectLinker::postProcessing(FileOutputBuffer& pOutput) -{ +bool ObjectLinker::postProcessing(FileOutputBuffer& pOutput) { if (LinkerConfig::Object != m_Config.codeGenType()) normalSyncRelocationResult(pOutput); else @@ -804,8 +851,7 @@ return true; } -void ObjectLinker::normalSyncRelocationResult(FileOutputBuffer& pOutput) -{ +void ObjectLinker::normalSyncRelocationResult(FileOutputBuffer& pOutput) { uint8_t* data = pOutput.getBufferStart(); // sync all relocations of all inputs @@ -837,12 +883,12 @@ // we want is the value of the other relocation result. For example, // in .exidx, there are usually an R_ARM_NONE and R_ARM_PREL31 apply to // the same place - if (0x0 == relocation->type()) + if (relocation->type() == 0x0) continue; writeRelocationResult(*relocation, data); - } // for all relocations - } // for all relocation section - } // for all inputs + } // for all relocations + } // for all relocation section + } // for all inputs // sync relocations created by relaxation BranchIslandFactory* br_factory = m_LDBackend.getBRIslandFactory(); @@ -857,8 +903,7 @@ } } -void ObjectLinker::partialSyncRelocationResult(FileOutputBuffer& pOutput) -{ +void ObjectLinker::partialSyncRelocationResult(FileOutputBuffer& pOutput) { uint8_t* data = pOutput.getBufferStart(); // traverse outputs' LDSection to get RelocData @@ -878,51 +923,52 @@ // we want is the value of the other relocation result. For example, // in .exidx, there are usually an R_ARM_NONE and R_ARM_PREL31 apply to // the same place - if (0x0 == reloc->type()) + if (reloc->type() == 0x0) continue; writeRelocationResult(*reloc, data); } } } -void ObjectLinker::writeRelocationResult(Relocation& pReloc, uint8_t* pOutput) -{ +void ObjectLinker::writeRelocationResult(Relocation& pReloc, uint8_t* pOutput) { // get output file offset size_t out_offset = - pReloc.targetRef().frag()->getParent()->getSection().offset() + - pReloc.targetRef().getOutputOffset(); + pReloc.targetRef().frag()->getParent()->getSection().offset() + + pReloc.targetRef().getOutputOffset(); uint8_t* target_addr = pOutput + out_offset; // byte swapping if target and host has different endian, and then write back - if(llvm::sys::IsLittleEndianHost != m_Config.targets().isLittleEndian()) { - uint64_t tmp_data = 0; + if (llvm::sys::IsLittleEndianHost != m_Config.targets().isLittleEndian()) { + uint64_t tmp_data = 0; - switch(pReloc.size(*m_LDBackend.getRelocator())) { - case 8u: - std::memcpy(target_addr, &pReloc.target(), 1); - break; + switch (pReloc.size(*m_LDBackend.getRelocator())) { + case 8u: + std::memcpy(target_addr, &pReloc.target(), 1); + break; - case 16u: - tmp_data = mcld::bswap16(pReloc.target()); - std::memcpy(target_addr, &tmp_data, 2); - break; + case 16u: + tmp_data = mcld::bswap16(pReloc.target()); + std::memcpy(target_addr, &tmp_data, 2); + break; - case 32u: - tmp_data = mcld::bswap32(pReloc.target()); - std::memcpy(target_addr, &tmp_data, 4); - break; + case 32u: + tmp_data = mcld::bswap32(pReloc.target()); + std::memcpy(target_addr, &tmp_data, 4); + break; - case 64u: - tmp_data = mcld::bswap64(pReloc.target()); - std::memcpy(target_addr, &tmp_data, 8); - break; + case 64u: + tmp_data = mcld::bswap64(pReloc.target()); + std::memcpy(target_addr, &tmp_data, 8); + break; - default: - break; + default: + break; } + } else { + std::memcpy(target_addr, + &pReloc.target(), + pReloc.size(*m_LDBackend.getRelocator()) / 8); } - else - std::memcpy(target_addr, &pReloc.target(), - pReloc.size(*m_LDBackend.getRelocator())/8); } +} // namespace mcld