1cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===- MCLinker.cpp -------------------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file implements the MCLinker class 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h> 14cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 15cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Host.h> 16cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/raw_ostream.h> 17cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInput.h> 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h> 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/Resolver.h> 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDContext.h> 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDSymbol.h> 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDSectionFactory.h> 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/SectionMap.h> 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/RelocationFactory.h> 26cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/FillFragment.h> 27cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/RegionFragment.h> 28affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/EhFrame.h> 29affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/EhFrameHdr.h> 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 31affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/TargetLDBackend.h> 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Constructor 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMCLinker::MCLinker(TargetLDBackend& pBackend, 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MCLDInfo& pInfo, 39affc150dc44fab1911775a49636d0ce85333b634Zonr Chang SectionMap& pSectionMap) 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao: m_Backend(pBackend), 41affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_LDInfo(pInfo), 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_SectionMap(pSectionMap), 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_LDSymbolFactory(128), 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_LDSectHdrFactory(10), // the average number of sections. (assuming 10.) 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_LDSectDataFactory(10), 46affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pSectionMerger(NULL) 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Destructor 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMCLinker::~MCLinker() 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 53affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL != m_pSectionMerger) 54affc150dc44fab1911775a49636d0ce85333b634Zonr Chang delete m_pSectionMerger; 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 57cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 58cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// Symbol Operations 59cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// addSymbolFromObject - add a symbol from object file and resolve it 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// immediately 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::addSymbolFromObject(const llvm::StringRef& pName, 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Type pType, 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Desc pDesc, 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Binding pBinding, 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::SizeType pSize, 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol::ValueType pValue, 68cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* pFragmentRef, 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Visibility pVisibility) 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // resolved_result is a triple <resolved_info, existent, override> 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Resolver::Result resolved_result; 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo old_info; // used for arrange output symbols 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pBinding == ResolveInfo::Local) { 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if the symbol is a local symbol, create a LDSymbol for input, but do not 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // resolve them. 79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang resolved_result.info = m_LDInfo.getNamePool().createSymbol(pName, 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao false, 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pType, 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pDesc, 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pBinding, 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pSize, 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pVisibility); 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // No matter if there is a symbol with the same name, insert the symbol 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // into output symbol table. So, we let the existent false. 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao resolved_result.existent = false; 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao resolved_result.overriden = true; 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if the symbol is not local, insert and resolve it immediately 94affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_LDInfo.getNamePool().insertSymbol(pName, false, pType, pDesc, pBinding, 95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSize, pVisibility, 96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &old_info, resolved_result); 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // the return ResolveInfo should not NULL 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != resolved_result.info); 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create a LDSymbol for the input file. 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol* input_sym = m_LDSymbolFactory.allocate(); 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao new (input_sym) LDSymbol(); 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set the relation between input LDSymbol and its ResolveInfo 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao input_sym->setResolveInfo(*resolved_result.info); 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up input LDSymbol 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao input_sym->setFragmentRef(pFragmentRef); 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao input_sym->setValue(pValue); 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol* output_sym = resolved_result.info->outSymbol(); 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool has_output_sym = (NULL != output_sym); 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!resolved_result.existent || !has_output_sym) { 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // it is a new symbol, the output_sym should be NULL. 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL == output_sym); 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if it is a new symbol, create a LDSymbol for the output 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym = m_LDSymbolFactory.allocate(); 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao new (output_sym) LDSymbol(); 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up the relation between output LDSymbol and its ResolveInfo 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym->setResolveInfo(*resolved_result.info); 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao resolved_result.info->setSymPtr(output_sym); 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (resolved_result.overriden || !has_output_sym) { 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // symbol can be overriden only if it exists. 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(output_sym != NULL); 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // should override output LDSymbol 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym->setFragmentRef(pFragmentRef); 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym->setValue(pValue); 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // After symbol resolution, visibility is changed to the most restrict one. 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // we need to arrange its position in the output symbol . 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pType != ResolveInfo::Section) { 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!has_output_sym) { 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We merge sections when reading them. So we do not need to output symbols 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // with section type 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // No matter the symbol is already in the output or not, add it if it 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // should be forcefully set local. 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (shouldForceLocal(*resolved_result.info)) 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_OutputSymbols.forceLocal(*output_sym); 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // the symbol should not be forcefully local. 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_OutputSymbols.add(*output_sym); 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (resolved_result.overriden) { 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!shouldForceLocal(old_info) || 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao !shouldForceLocal(*resolved_result.info)) { 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If the old info and the new info are both forcefully local, then 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // we should keep the output_sym in forcefully local category. Else, 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // we should re-sort the output_sym 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_OutputSymbols.arrange(*output_sym, old_info); 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return input_sym; 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// addSymbolFromDynObj - add a symbol from object file and resolve it 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// immediately 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::addSymbolFromDynObj(const llvm::StringRef& pName, 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Type pType, 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Desc pDesc, 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Binding pBinding, 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::SizeType pSize, 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol::ValueType pValue, 175cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* pFragmentRef, 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Visibility pVisibility) 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We merge sections when reading them. So we do not need symbols with 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // section type 1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pType == ResolveInfo::Section) 1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return NULL; 1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // ignore symbols with local binding or that have internal or hidden 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // visibility 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pBinding == ResolveInfo::Local || 1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pVisibility == ResolveInfo::Internal || 1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pVisibility == ResolveInfo::Hidden) 1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return NULL; 1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // A protected symbol in a shared library must be treated as a 1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // normal symbol when viewed from outside the shared library. 1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pVisibility == ResolveInfo::Protected) 1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pVisibility = ResolveInfo::Default; 1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // insert symbol and resolve it immediately 1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // resolved_result is a triple <resolved_info, existent, override> 1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Resolver::Result resolved_result; 198affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_LDInfo.getNamePool().insertSymbol(pName, true, pType, pDesc, 199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pBinding, pSize, pVisibility, 2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao NULL, resolved_result); 2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // the return ResolveInfo should not NULL 2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != resolved_result.info); 2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create a LDSymbol for the input file. 2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol* input_sym = m_LDSymbolFactory.allocate(); 2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao new (input_sym) LDSymbol(); 2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up the relation between input LDSymbol and its ResolveInfo 2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao input_sym->setResolveInfo(*resolved_result.info); 2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // set up input LDSymbol 2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao input_sym->setFragmentRef(pFragmentRef); 2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao input_sym->setValue(pValue); 2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol* output_sym = NULL; 2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!resolved_result.existent) { 2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // we get a new symbol, leave it as NULL 2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao resolved_result.info->setSymPtr(NULL); 2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // we saw the symbol before, but the output_sym still may be NULL. 2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym = resolved_result.info->outSymbol(); 2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (output_sym != NULL) { 2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // After symbol resolution, visibility is changed to the most restrict one. 2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // If we are not doing incremental linking, then any symbol with hidden 2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // or internal visibility is forcefully set as a local symbol. 2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (shouldForceLocal(*resolved_result.info)) { 2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_OutputSymbols.forceLocal(*output_sym); 2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return input_sym; 2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// defineSymbolForcefully - define an output symbol and override it immediately 2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::defineSymbolForcefully(const llvm::StringRef& pName, 2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool pIsDyn, 2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Type pType, 2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Desc pDesc, 2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Binding pBinding, 2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::SizeType pSize, 2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol::ValueType pValue, 246cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* pFragmentRef, 2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Visibility pVisibility) 2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 249affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo* info = m_LDInfo.getNamePool().findInfo(pName); 2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol* output_sym = NULL; 2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == info) { 2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // the symbol is not in the pool, create a new one. 2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create a ResolveInfo 2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Resolver::Result result; 255affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_LDInfo.getNamePool().insertSymbol(pName, pIsDyn, pType, pDesc, 256affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pBinding, pSize, pVisibility, 257affc150dc44fab1911775a49636d0ce85333b634Zonr Chang NULL, result); 2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(!result.existent); 2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create a output LDSymbol 2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym = m_LDSymbolFactory.allocate(); 2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao new (output_sym) LDSymbol(); 2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym->setResolveInfo(*result.info); 2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result.info->setSymPtr(output_sym); 2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (shouldForceLocal(*result.info)) 2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_OutputSymbols.forceLocal(*output_sym); 2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_OutputSymbols.add(*output_sym); 2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // the symbol is already in the pool, override it 2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo old_info; 2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao old_info.override(*info); 2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setSource(pIsDyn); 2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setType(pType); 2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setDesc(pDesc); 2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setBinding(pBinding); 2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setVisibility(pVisibility); 2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setIsSymbol(true); 2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setSize(pSize); 2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym = info->outSymbol(); 2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != output_sym) 2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_OutputSymbols.arrange(*output_sym, old_info); 2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create a output LDSymbol 2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym = m_LDSymbolFactory.allocate(); 2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao new (output_sym) LDSymbol(); 2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym->setResolveInfo(*info); 2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setSymPtr(output_sym); 2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_OutputSymbols.add(*output_sym); 2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != output_sym) { 3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym->setFragmentRef(pFragmentRef); 3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym->setValue(pValue); 3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return output_sym; 3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// defineSymbolAsRefered - define an output symbol and override it immediately 3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::defineSymbolAsRefered(const llvm::StringRef& pName, 3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool pIsDyn, 3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Type pType, 3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Desc pDesc, 3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Binding pBinding, 3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::SizeType pSize, 3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol::ValueType pValue, 316cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* pFragmentRef, 3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Visibility pVisibility) 3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 319affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo* info = m_LDInfo.getNamePool().findInfo(pName); 3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 321cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (NULL == info || !(info->isUndef() || info->isDyn())) { 322cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // only undefined symbol and dynamic symbol can make a reference. 3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return NULL; 3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // the symbol is already in the pool, override it 3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo old_info; 3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao old_info.override(*info); 3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setSource(pIsDyn); 3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setType(pType); 3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setDesc(pDesc); 3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setBinding(pBinding); 3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setVisibility(pVisibility); 3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setIsSymbol(true); 3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setSize(pSize); 3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol* output_sym = info->outSymbol(); 3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != output_sym) { 3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym->setFragmentRef(pFragmentRef); 3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym->setValue(pValue); 3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_OutputSymbols.arrange(*output_sym, old_info); 3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create a output LDSymbol 3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym = m_LDSymbolFactory.allocate(); 3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao new (output_sym) LDSymbol(); 3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym->setResolveInfo(*info); 3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao info->setSymPtr(output_sym); 3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_OutputSymbols.add(*output_sym); 3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return output_sym; 3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// defineAndResolveSymbolForcefully - define an output symbol and resolve it 3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// immediately 3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::defineAndResolveSymbolForcefully(const llvm::StringRef& pName, 3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool pIsDyn, 3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Type pType, 3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Desc pDesc, 3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Binding pBinding, 3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::SizeType pSize, 3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol::ValueType pValue, 367cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* pFragmentRef, 3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Visibility pVisibility) 3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Result is <info, existent, override> 3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Resolver::Result result; 3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo old_info; 373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_LDInfo.getNamePool().insertSymbol(pName, pIsDyn, pType, pDesc, pBinding, 374affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSize, pVisibility, 375affc150dc44fab1911775a49636d0ce85333b634Zonr Chang &old_info, result); 3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol* output_sym = result.info->outSymbol(); 3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool has_output_sym = (NULL != output_sym); 3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!result.existent || !has_output_sym) { 3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym = m_LDSymbolFactory.allocate(); 3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao new (output_sym) LDSymbol(); 3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym->setResolveInfo(*result.info); 3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result.info->setSymPtr(output_sym); 3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (result.overriden || !has_output_sym) { 3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym->setFragmentRef(pFragmentRef); 3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sym->setValue(pValue); 3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // After symbol resolution, the visibility is changed to the most restrict. 3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // arrange the output position 3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (shouldForceLocal(*result.info)) 3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_OutputSymbols.forceLocal(*output_sym); 3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (has_output_sym) 3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_OutputSymbols.arrange(*output_sym, old_info); 3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_OutputSymbols.add(*output_sym); 4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return output_sym; 4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// defineAndResolveSymbolAsRefered - define an output symbol and resolve it 4055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// immediately. 4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::defineAndResolveSymbolAsRefered(const llvm::StringRef& pName, 4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool pIsDyn, 4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Type pType, 4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Desc pDesc, 4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Binding pBinding, 4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::SizeType pSize, 4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSymbol::ValueType pValue, 413cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* pFragmentRef, 4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo::Visibility pVisibility) 4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 416affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ResolveInfo* info = m_LDInfo.getNamePool().findInfo(pName); 4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 418cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (NULL == info || !(info->isUndef() || info->isDyn())) { 419cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // only undefined symbol and dynamic symbol can make a reference. 4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return NULL; 4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return defineAndResolveSymbolForcefully(pName, 4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pIsDyn, 4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pType, 4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pDesc, 4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pBinding, 4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pSize, 4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pValue, 4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFragmentRef, 4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pVisibility); 4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 434cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool MCLinker::finalizeSymbols() 435cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 436cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao SymbolCategory::iterator symbol, symEnd = m_OutputSymbols.end(); 437cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao for (symbol = m_OutputSymbols.begin(); symbol != symEnd; ++symbol) { 438cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 439cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if ((*symbol)->resolveInfo()->isAbsolute() || 440cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao (*symbol)->resolveInfo()->type() == ResolveInfo::File) { 441cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // absolute symbols or symbols with function type should have 442cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // zero value 443cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao (*symbol)->setValue(0x0); 444cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao continue; 445cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 446cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 447cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if ((*symbol)->hasFragRef()) { 448cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // set the virtual address of the symbol. If the output file is 449cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // relocatable object file, the section's virtual address becomes zero. 450cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // And the symbol's value become section relative offset. 451cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao uint64_t value = getLayout().getOutputOffset(*(*symbol)->fragRef()); 452cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao assert(NULL != (*symbol)->fragRef()->frag()); 453cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao uint64_t addr = getLayout().getOutputLDSection(*(*symbol)->fragRef()->frag())->addr(); 454cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao (*symbol)->setValue(value + addr); 455cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao continue; 456cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 457cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 458cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 459cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // finialize target-dependent symbols 460cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return m_Backend.finalizeSymbols(*this, m_LDInfo.output()); 461cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 462cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 463cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool MCLinker::shouldForceLocal(const ResolveInfo& pInfo) const 464cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 465cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // forced local symbol matches all rules: 466cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // 1. We are not doing incremental linking. 467cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // 2. The symbol is with Hidden or Internal visibility. 468cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // 3. The symbol should be global or weak. Otherwise, local symbol is local. 469cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // 4. The symbol is defined or common 470cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (m_LDInfo.output().type() != Output::Object && 471cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao (pInfo.visibility() == ResolveInfo::Hidden || 472cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pInfo.visibility() == ResolveInfo::Internal) && 473cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao (pInfo.isGlobal() || pInfo.isWeak()) && 474cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao (pInfo.isDefine() || pInfo.isCommon())) 475cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return true; 476cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return false; 477cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 478cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 479cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 480cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// Section Operations 481cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createSectHdr - create the input section header 4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSection& MCLinker::createSectHdr(const std::string& pName, 4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDFileFormat::Kind pKind, 4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t pType, 4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t pFlag) 4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(m_LDInfo.output().hasContext()); 489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // for user such as reader, standard/target fromat 4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection* result = 4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_LDSectHdrFactory.produce(pName, pKind, pType, pFlag); 4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // check if we need to create a output section for output LDContext 4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao std::string sect_name = m_SectionMap.getOutputSectName(pName); 496affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection* output_sect = m_LDInfo.output().context()->getSection(sect_name); 4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == output_sect) { 4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create a output section and push it into output LDContext 5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sect = 5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_LDSectHdrFactory.produce(sect_name, pKind, pType, pFlag); 502affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_LDInfo.output().context()->getSectionTable().push_back(output_sect); 503affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pSectionMerger->addMapping(pName, output_sect); 5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *result; 5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getOrCreateOutputSectHdr - for reader and standard/target format to get 5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// or create the output's section header 5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSection& MCLinker::getOrCreateOutputSectHdr(const std::string& pName, 5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDFileFormat::Kind pKind, 5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t pType, 5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t pFlag, 5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t pAlign) 5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(m_LDInfo.output().hasContext()); 517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // check if we need to create a output section for output LDContext 5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao std::string sect_name = m_SectionMap.getOutputSectName(pName); 520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection* output_sect = m_LDInfo.output().context()->getSection(sect_name); 5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == output_sect) { 5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // create a output section and push it into output LDContext 5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sect = 5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_LDSectHdrFactory.produce(sect_name, pKind, pType, pFlag); 5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sect->setAlign(pAlign); 527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_LDInfo.output().context()->getSectionTable().push_back(output_sect); 528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pSectionMerger->addMapping(pName, output_sect); 5295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *output_sect; 5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 533cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// getOrCreateSectData - get or create SectionData 5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// pSection is input LDSection 535cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoSectionData& MCLinker::getOrCreateSectData(LDSection& pSection) 5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if there is already a section data pointed by section, return it. 538cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao SectionData* sect_data = pSection.getSectionData(); 5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != sect_data) { 5405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Layout.addInputRange(*sect_data, pSection); 5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *sect_data; 5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // try to get one from output LDSection 5455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection* output_sect = 546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_pSectionMerger->getOutputSectHdr(pSection.name()); 5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != output_sect); 5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sect_data = output_sect->getSectionData(); 5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != sect_data) { 5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pSection.setSectionData(sect_data); 5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Layout.addInputRange(*sect_data, pSection); 5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *sect_data; 5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 558cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // if the output LDSection also has no SectionData, then create one. 5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sect_data = m_LDSectDataFactory.allocate(); 560cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao new (sect_data) SectionData(*output_sect); 5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pSection.setSectionData(sect_data); 5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao output_sect->setSectionData(sect_data); 5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Layout.addInputRange(*sect_data, pSection); 5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return *sect_data; 5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 567cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaovoid MCLinker::initSectionMap() 568cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 569cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao assert(m_LDInfo.output().hasContext()); 570cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (NULL == m_pSectionMerger) 571cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao m_pSectionMerger = new SectionMerger(m_SectionMap, *m_LDInfo.output().context()); 572cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 573cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 574cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool MCLinker::layout() 575cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 576cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return m_Layout.layout(m_LDInfo.output(), m_Backend, m_LDInfo); 577cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 578cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 579cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 580cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// Relocation Operations 581cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// addRelocation - add a relocation entry in MCLinker (only for object file) 5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// All symbols should be read and resolved before calling this function. 5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocation* MCLinker::addRelocation(Relocation::Type pType, 5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSymbol& pSym, 5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ResolveInfo& pResolveInfo, 588cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef& pFragmentRef, 589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const LDSection& pSection, 5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Relocation::Address pAddend) 5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: we should dicard sections and symbols first instead 593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // if the symbol is in the discarded input section, then we also need to 594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // discard this relocation. 595affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pSym.fragRef() == NULL && 596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pResolveInfo.type() == ResolveInfo::Section && 597affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pResolveInfo.desc() == ResolveInfo::Undefined) 598affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return NULL; 599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Relocation* relocation = m_Backend.getRelocFactory()->produce(pType, 6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFragmentRef, 6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pAddend); 6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao relocation->setSymInfo(&pResolveInfo); 6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_RelocationList.push_back(relocation); 6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 608affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Backend.scanRelocation(*relocation, pSym, *this, m_LDInfo, 609affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_LDInfo.output(), pSection); 6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 611affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (pResolveInfo.isUndef() && !pResolveInfo.isDyn() && !pResolveInfo.isWeak()) 612affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::undefined_reference) << pResolveInfo.name(); 6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return relocation; 6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLinker::applyRelocations() 6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao RelocationListType::iterator relocIter, relocEnd = m_RelocationList.end(); 6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (relocIter = m_RelocationList.begin(); relocIter != relocEnd; ++relocIter) { 621cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = (Fragment*)relocIter; 622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang static_cast<Relocation*>(frag)->apply(*m_Backend.getRelocFactory(), m_LDInfo); 6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MCLinker::syncRelocationResult() 6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 630affc150dc44fab1911775a49636d0ce85333b634Zonr Chang MemoryRegion* region = m_LDInfo.output().memArea()->request(0, 631affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_LDInfo.output().memArea()->handler()->size()); 6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint8_t* data = region->getBuffer(); 6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao RelocationListType::iterator relocIter, relocEnd = m_RelocationList.end(); 6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (relocIter = m_RelocationList.begin(); relocIter != relocEnd; ++relocIter) { 6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 638cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = (Fragment*)relocIter; 6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Relocation* reloc = static_cast<Relocation*>(frag); 6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get output file offset 6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t out_offset = m_Layout.getOutputLDSection(*reloc->targetRef().frag())->offset() + 6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Layout.getOutputOffset(reloc->targetRef()); 6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint8_t* target_addr = data + out_offset; 6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // byte swapping if target and host has different endian, and then write back 6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(llvm::sys::isLittleEndianHost() != m_Backend.isLittleEndian()) { 6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t tmp_data = 0; 6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(m_Backend.bitclass()) { 6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case 32u: 6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao tmp_data = bswap32(reloc->target()); 6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao std::memcpy(target_addr, &tmp_data, 4); 6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case 64u: 6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao tmp_data = bswap64(reloc->target()); 6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao std::memcpy(target_addr, &tmp_data, 8); 6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao std::memcpy(target_addr, &reloc->target(), m_Backend.bitclass()/8); 6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } // end of for 6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 670affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_LDInfo.output().memArea()->clear(); 6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 673cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 674cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// Exception Handling Operations 675cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 676affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// addEhFrame - add an exception handling section 677affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @param pSection - the input section 678affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @param pArea - the memory area which pSection is within. 67967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaouint64_t MCLinker::addEhFrame(const Input& pInput, 68067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao LDSection& pSection, 68167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao MemoryArea& pArea) 682affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 683affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint64_t size = 0; 684affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 685affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // get the SectionData of this eh_frame 686cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao SectionData& sect_data = getOrCreateSectData(pSection); 687affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 688affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // parse the eh_frame if the option --eh-frame-hdr is given 689affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (m_LDInfo.options().hasEhFrameHdr()) { 690affc150dc44fab1911775a49636d0ce85333b634Zonr Chang EhFrame* ehframe = m_Backend.getEhFrame(); 691affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(NULL != ehframe); 692affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (ehframe->canRecognizeAllEhFrame()) { 69367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao size = ehframe->readEhFrame(m_Layout, m_Backend, sect_data, pInput, 69467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao pSection, pArea); 695affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // zero size indicate that this is an empty section or we can't recognize 696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // this eh_frame, handle it as a regular section. 697affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (0 != size) 698affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return size; 699affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 700affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 701affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 702affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // handle eh_frame as a regular section 70367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao MemoryRegion* region = pArea.request(pInput.fileOffset() + pSection.offset(), 704affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSection.size()); 705affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 706cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Fragment* frag = NULL; 707affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == region) { 708affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // If the input section's size is zero, we got a NULL region. 709affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // use a virtual fill fragment 710cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao frag = new FillFragment(0x0, 0, 0); 711affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 712affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 713cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao frag = new RegionFragment(*region); 714affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 715affc150dc44fab1911775a49636d0ce85333b634Zonr Chang size = m_Layout.appendFragment(*frag, sect_data, pSection.align()); 716affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return size; 717affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 718affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 719