15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- GNUArchiveReader.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//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/GNUArchiveReader.h" 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/InputTree.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Module.h" 1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/ADT/SizeTraits.h" 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/Attribute.h" 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/Input.h" 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFObjectReader.h" 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ResolveInfo.h" 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileHandle.h" 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileSystem.h" 2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MemoryArea.h" 2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/Path.h" 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 25cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/ADT/StringRef.h> 26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/Host.h> 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstdlib> 2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <cstring> 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNUArchiveReader::GNUArchiveReader(Module& pModule, 34cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao ELFObjectReader& pELFObjectReader) 3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines : m_Module(pModule), m_ELFObjectReader(pELFObjectReader) { 36cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3837b74a387bb3993387029859c2d9d051c41c724eStephen HinesGNUArchiveReader::~GNUArchiveReader() { 39cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 41cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// isMyFormat 4237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNUArchiveReader::isMyFormat(Input& pInput, bool& pContinue) const { 43cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao assert(pInput.hasMemArea()); 4487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pInput.memArea()->size() < Archive::MAGIC_LEN) 4587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 4687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 4787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef region = 4887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pInput.memArea()->request(pInput.fileOffset(), Archive::MAGIC_LEN); 4987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const char* str = region.begin(); 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 51cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao bool result = false; 5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(str != NULL); 5387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pContinue = true; 54cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (isArchive(str) || isThinArchive(str)) 55cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao result = true; 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 57cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return result; 58cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 60cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// isArchive 6137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNUArchiveReader::isArchive(const char* pStr) const { 6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines return (memcmp(pStr, Archive::MAGIC, Archive::MAGIC_LEN) == 0); 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 65cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// isThinArchive 6637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNUArchiveReader::isThinArchive(const char* pStr) const { 6737b74a387bb3993387029859c2d9d051c41c724eStephen Hines return (memcmp(pStr, Archive::THIN_MAGIC, Archive::MAGIC_LEN) == 0); 68cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 70cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// isThinArchive 7137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNUArchiveReader::isThinArchive(Input& pInput) const { 72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(pInput.hasMemArea()); 7387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef region = 7487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pInput.memArea()->request(pInput.fileOffset(), Archive::MAGIC_LEN); 7587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const char* str = region.begin(); 76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 77cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao bool result = false; 7837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(str != NULL); 79cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (isThinArchive(str)) 80cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao result = true; 81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 82cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return result; 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNUArchiveReader::readArchive(const LinkerConfig& pConfig, 8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines Archive& pArchive) { 876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // bypass the empty archive 8887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (Archive::MAGIC_LEN == pArchive.getARFile().memArea()->size()) 896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pArchive.getARFile().attribute()->isWholeArchive()) 9287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return includeAllMembers(pConfig, pArchive); 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if this is the first time read this archive, setup symtab and strtab 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pArchive.getSymbolTable().empty()) { 9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines // read the symtab of the archive 9737b74a387bb3993387029859c2d9d051c41c724eStephen Hines readSymbolTable(pArchive); 98cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines // read the strtab of the archive 10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines readStringTable(pArchive); 101cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 10237b74a387bb3993387029859c2d9d051c41c724eStephen Hines // add root archive to ArchiveMemberMap 10337b74a387bb3993387029859c2d9d051c41c724eStephen Hines pArchive.addArchiveMember(pArchive.getARFile().name(), 10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines pArchive.inputs().root(), 10537b74a387bb3993387029859c2d9d051c41c724eStephen Hines &InputTree::Downward); 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 107cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 108cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // include the needed members in the archive and build up the input tree 109cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao bool willSymResolved; 110cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao do { 111cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao willSymResolved = false; 112cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao for (size_t idx = 0; idx < pArchive.numOfSymbols(); ++idx) { 113cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // bypass if we already decided to include this symbol or not 114cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (Archive::Symbol::Unknown != pArchive.getSymbolStatus(idx)) 115cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao continue; 116cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 117cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // bypass if another symbol with the same object file offset is included 118cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (pArchive.hasObjectMember(pArchive.getObjFileOffset(idx))) { 119cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchive.setSymbolStatus(idx, Archive::Symbol::Include); 120cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao continue; 121cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 122cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 123cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // check if we should include this defined symbol 124cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Archive::Symbol::Status status = 12537b74a387bb3993387029859c2d9d051c41c724eStephen Hines shouldIncludeSymbol(pArchive.getSymbolName(idx)); 126cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (Archive::Symbol::Unknown != status) 127cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchive.setSymbolStatus(idx, status); 128cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 129cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (Archive::Symbol::Include == status) { 13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // include the object member from the given offset 13187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines includeMember(pConfig, pArchive, pArchive.getObjFileOffset(idx)); 132cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao willSymResolved = true; 13337b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of if 13437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for 135cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } while (willSymResolved); 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 137cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return true; 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 140cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// readMemberHeader - read the header of a member in a archive file and then 141cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// return the corresponding archive member (it may be an input object or 142cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// another archive) 143cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// @param pArchiveRoot - the archive root that holds the strtab (extended 144cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// name table) 145cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// @param pArchiveFile - the archive that contains the needed object 146cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// @param pFileOffset - file offset of the member header in the archive 147cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// @param pNestedOffset - used when we find a nested archive 14822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @param pMemberSize - the file size of this member 149cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoInput* GNUArchiveReader::readMemberHeader(Archive& pArchiveRoot, 150cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Input& pArchiveFile, 151cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao uint32_t pFileOffset, 15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t& pNestedOffset, 15337b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t& pMemberSize) { 154cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao assert(pArchiveFile.hasMemArea()); 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15637b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::StringRef header_region = pArchiveFile.memArea()->request( 15737b74a387bb3993387029859c2d9d051c41c724eStephen Hines (pArchiveFile.fileOffset() + pFileOffset), sizeof(Archive::MemberHeader)); 158cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao const Archive::MemberHeader* header = 15937b74a387bb3993387029859c2d9d051c41c724eStephen Hines reinterpret_cast<const Archive::MemberHeader*>(header_region.begin()); 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(memcmp(header->fmag, Archive::MEMBER_MAGIC, sizeof(header->fmag)) == 16237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0); 163cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pMemberSize = atoi(header->size); 165cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 166cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // parse the member name and nested offset if any 167cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao std::string member_name; 16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::StringRef name_field(header->name, sizeof(header->name)); 16937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (header->name[0] != '/') { 170cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // this is an object file in an archive 171cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao size_t pos = name_field.find_first_of('/'); 172cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao member_name.assign(name_field.substr(0, pos).str()); 17337b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 174cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // this is an object/archive file in a thin archive 175cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao size_t begin = 1; 176cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao size_t end = name_field.find_first_of(" :"); 177cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao uint32_t name_offset = 0; 178cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // parse the name offset 179cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao name_field.substr(begin, end - begin).getAsInteger(10, name_offset); 180cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 18137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (name_field[end] == ':') { 182cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // there is a nested offset 183cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao begin = end + 1; 184cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao end = name_field.find_first_of(' ', begin); 185cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao name_field.substr(begin, end - begin).getAsInteger(10, pNestedOffset); 186cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 187cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 188cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get the member name from the extended name table 18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(pArchiveRoot.hasStrTable()); 190cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao begin = name_offset; 191cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao end = pArchiveRoot.getStrTable().find_first_of('\n', begin); 19237b74a387bb3993387029859c2d9d051c41c724eStephen Hines member_name.assign( 19337b74a387bb3993387029859c2d9d051c41c724eStephen Hines pArchiveRoot.getStrTable().substr(begin, end - begin - 1)); 194cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 195affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 196cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Input* member = NULL; 19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool isThinAR = isThinArchive(pArchiveFile); 19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!isThinAR) { 199cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // this is an object file in an archive 20037b74a387bb3993387029859c2d9d051c41c724eStephen Hines member = pArchiveRoot.getMemberFile( 20137b74a387bb3993387029859c2d9d051c41c724eStephen Hines pArchiveFile, 20237b74a387bb3993387029859c2d9d051c41c724eStephen Hines isThinAR, 20337b74a387bb3993387029859c2d9d051c41c724eStephen Hines member_name, 20437b74a387bb3993387029859c2d9d051c41c724eStephen Hines pArchiveFile.path(), 20537b74a387bb3993387029859c2d9d051c41c724eStephen Hines (pFileOffset + sizeof(Archive::MemberHeader))); 20637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 207cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // this is a member in a thin archive 208cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // try to find if this is a archive already in the map first 209cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Archive::ArchiveMember* ar_member = 21037b74a387bb3993387029859c2d9d051c41c724eStephen Hines pArchiveRoot.getArchiveMember(member_name); 21137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (ar_member != NULL) { 212cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return ar_member->file; 213cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 215cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get nested file path, the nested file's member name is the relative 216cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // path to the archive containing it. 217cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao sys::fs::Path input_path(pArchiveFile.path().parent_path()); 218cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (!input_path.empty()) 21937b74a387bb3993387029859c2d9d051c41c724eStephen Hines input_path.append(sys::fs::Path(member_name)); 2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 221cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao input_path.assign(member_name); 222cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 22337b74a387bb3993387029859c2d9d051c41c724eStephen Hines member = pArchiveRoot.getMemberFile( 22437b74a387bb3993387029859c2d9d051c41c724eStephen Hines pArchiveFile, isThinAR, member_name, input_path); 2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 226cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 227cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return member; 2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 23087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinestemplate <size_t SIZE> 23137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic void readSymbolTableEntries(Archive& pArchive, 23237b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::StringRef pMemRegion) { 23387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines typedef typename SizeTraits<SIZE>::Offset Offset; 23487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 23587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const Offset* data = reinterpret_cast<const Offset*>(pMemRegion.begin()); 23687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 23787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // read the number of symbols 23887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Offset number = 0; 23987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::sys::IsLittleEndianHost) 24087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines number = mcld::bswap<SIZE>(*data); 24187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else 24287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines number = *data; 24387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 24487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set up the pointers for file offset and name offset 24587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ++data; 24687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const char* name = reinterpret_cast<const char*>(data + number); 24787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 24887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // add the archive symbols 24987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (Offset i = 0; i < number; ++i) { 25087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::sys::IsLittleEndianHost) 25187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pArchive.addSymbol(name, mcld::bswap<SIZE>(*data)); 25287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else 25387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pArchive.addSymbol(name, *data); 25487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines name += strlen(name) + 1; 25587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ++data; 25687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 25787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 25887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 259cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// readSymbolTable - read the archive symbol map (armap) 26037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNUArchiveReader::readSymbolTable(Archive& pArchive) { 261cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao assert(pArchive.getARFile().hasMemArea()); 26237b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryArea* memory_area = pArchive.getARFile().memArea(); 263cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 26437b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::StringRef header_region = memory_area->request( 26537b74a387bb3993387029859c2d9d051c41c724eStephen Hines (pArchive.getARFile().fileOffset() + Archive::MAGIC_LEN), 26637b74a387bb3993387029859c2d9d051c41c724eStephen Hines sizeof(Archive::MemberHeader)); 267cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao const Archive::MemberHeader* header = 26837b74a387bb3993387029859c2d9d051c41c724eStephen Hines reinterpret_cast<const Archive::MemberHeader*>(header_region.begin()); 26937b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(memcmp(header->fmag, Archive::MEMBER_MAGIC, sizeof(header->fmag)) == 27037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0); 271cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 272cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao int symtab_size = atoi(header->size); 273cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchive.setSymTabSize(symtab_size); 274cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pArchive.getARFile().attribute()->isWholeArchive()) { 27637b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::StringRef symtab_region = memory_area->request( 27737b74a387bb3993387029859c2d9d051c41c724eStephen Hines (pArchive.getARFile().fileOffset() + Archive::MAGIC_LEN + 27887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sizeof(Archive::MemberHeader)), 27987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines symtab_size); 28087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 28137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (strncmp(header->name, 28237b74a387bb3993387029859c2d9d051c41c724eStephen Hines Archive::SVR4_SYMTAB_NAME, 28337b74a387bb3993387029859c2d9d051c41c724eStephen Hines strlen(Archive::SVR4_SYMTAB_NAME)) == 0) 28487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines readSymbolTableEntries<32>(pArchive, symtab_region); 28537b74a387bb3993387029859c2d9d051c41c724eStephen Hines else if (strncmp(header->name, 28637b74a387bb3993387029859c2d9d051c41c724eStephen Hines Archive::IRIX6_SYMTAB_NAME, 28737b74a387bb3993387029859c2d9d051c41c724eStephen Hines strlen(Archive::IRIX6_SYMTAB_NAME)) == 0) 28887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines readSymbolTableEntries<64>(pArchive, symtab_region); 289cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao else 29087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines unreachable(diag::err_unsupported_archive); 2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 292cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return true; 293cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 295cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// readStringTable - read the strtab for long file name of the archive 29637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool GNUArchiveReader::readStringTable(Archive& pArchive) { 29737b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t offset = Archive::MAGIC_LEN + sizeof(Archive::MemberHeader) + 298cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchive.getSymTabSize(); 2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 30037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if ((offset & 1) != 0x0) 301cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao ++offset; 3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 303cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao assert(pArchive.getARFile().hasMemArea()); 30437b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryArea* memory_area = pArchive.getARFile().memArea(); 305cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 30687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef header_region = 30737b74a387bb3993387029859c2d9d051c41c724eStephen Hines memory_area->request((pArchive.getARFile().fileOffset() + offset), 30837b74a387bb3993387029859c2d9d051c41c724eStephen Hines sizeof(Archive::MemberHeader)); 309cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao const Archive::MemberHeader* header = 31037b74a387bb3993387029859c2d9d051c41c724eStephen Hines reinterpret_cast<const Archive::MemberHeader*>(header_region.begin()); 3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 31237b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(memcmp(header->fmag, Archive::MEMBER_MAGIC, sizeof(header->fmag)) == 31337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0); 31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 31537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (memcmp(header->name, Archive::STRTAB_NAME, sizeof(header->name)) == 0) { 31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // read the extended name table 31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao int strtab_size = atoi(header->size); 31887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef strtab_region = 31937b74a387bb3993387029859c2d9d051c41c724eStephen Hines memory_area->request((pArchive.getARFile().fileOffset() + offset + 32037b74a387bb3993387029859c2d9d051c41c724eStephen Hines sizeof(Archive::MemberHeader)), 32137b74a387bb3993387029859c2d9d051c41c724eStephen Hines strtab_size); 32287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const char* strtab = strtab_region.begin(); 32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.getStrTable().assign(strtab, strtab_size); 32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 325cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return true; 3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 328cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// shouldIncludeStatus - given a sym name from armap and check if including 329cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// the corresponding archive member, and then return the decision 33037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesenum Archive::Symbol::Status GNUArchiveReader::shouldIncludeSymbol( 33137b74a387bb3993387029859c2d9d051c41c724eStephen Hines const llvm::StringRef& pSymName) const { 332cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // TODO: handle symbol version issue and user defined symbols 33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ResolveInfo* info = m_Module.getNamePool().findInfo(pSymName); 33437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (info != NULL) { 335cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (!info->isUndef()) 336cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return Archive::Symbol::Exclude; 337cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (info->isWeak()) 338cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return Archive::Symbol::Unknown; 339cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return Archive::Symbol::Include; 3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 341cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return Archive::Symbol::Unknown; 3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 343cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 34422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// includeMember - include the object member in the given file offset, and 34522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// return the size of the object 34687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// @param pConfig - LinkerConfig 34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @param pArchiveRoot - the archive root 34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @param pFileOffset - file offset of the member header in the archive 34987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinessize_t GNUArchiveReader::includeMember(const LinkerConfig& pConfig, 35087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines Archive& pArchive, 35137b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t pFileOffset) { 35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Input* cur_archive = &(pArchive.getARFile()); 35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Input* member = NULL; 35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t file_offset = pFileOffset; 35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t size = 0; 35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao do { 35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t nested_offset = 0; 35822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // use the file offset in current archive to find out the member we 35922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // want to include 36037b74a387bb3993387029859c2d9d051c41c724eStephen Hines member = readMemberHeader( 36137b74a387bb3993387029859c2d9d051c41c724eStephen Hines pArchive, *cur_archive, file_offset, nested_offset, size); 36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(member != NULL); 36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // bypass if we get an archive that is already in the map 36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (Input::Archive == member->type()) { 36537b74a387bb3993387029859c2d9d051c41c724eStephen Hines cur_archive = member; 36637b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_offset = nested_offset; 36737b74a387bb3993387029859c2d9d051c41c724eStephen Hines continue; 36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // insert a node into the subtree of current archive. 37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Archive::ArchiveMember* parent = 37237b74a387bb3993387029859c2d9d051c41c724eStephen Hines pArchive.getArchiveMember(cur_archive->name()); 37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 37437b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(parent != NULL); 37522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.inputs().insert(parent->lastPos, *(parent->move), *member); 37622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 37722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // move the iterator to new created node, and also adjust the 37822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // direction to Afterward for next insertion in this subtree 37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao parent->move->move(parent->lastPos); 38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao parent->move = &InputTree::Afterward; 38187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool doContinue = false; 38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 38387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_ELFObjectReader.isMyFormat(*member, doContinue)) { 38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao member->setType(Input::Object); 3850dea6bc96bb52346737966839ac68644f7939f58Stephen Hines // Set this object as no export if the archive is in the exclude libs. 3860dea6bc96bb52346737966839ac68644f7939f58Stephen Hines if (pArchive.getARFile().noExport()) { 3870dea6bc96bb52346737966839ac68644f7939f58Stephen Hines member->setNoExport(); 3880dea6bc96bb52346737966839ac68644f7939f58Stephen Hines } 38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.addObjectMember(pFileOffset, parent->lastPos); 39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_ELFObjectReader.readHeader(*member); 39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_ELFObjectReader.readSections(*member); 39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_ELFObjectReader.readSymbols(*member); 39322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Module.getObjectList().push_back(member); 39437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (doContinue && isMyFormat(*member, doContinue)) { 39522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao member->setType(Input::Archive); 39622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // when adding a new archive node, set the iterator to archive 39722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // itself, and set the direction to Downward 39837b74a387bb3993387029859c2d9d051c41c724eStephen Hines pArchive.addArchiveMember( 39937b74a387bb3993387029859c2d9d051c41c724eStephen Hines member->name(), parent->lastPos, &InputTree::Downward); 40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao cur_archive = member; 40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_offset = nested_offset; 40237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 40337b74a387bb3993387029859c2d9d051c41c724eStephen Hines warning(diag::warn_unrecognized_input_file) 40437b74a387bb3993387029859c2d9d051c41c724eStephen Hines << member->path() << pConfig.targets().triple().str(); 40587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } while (Input::Object != member->type()); 40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return size; 40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// includeAllMembers - include all object members. This is called if 41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// --whole-archive is the attribute for this archive file. 41287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool GNUArchiveReader::includeAllMembers(const LinkerConfig& pConfig, 41337b74a387bb3993387029859c2d9d051c41c724eStephen Hines Archive& pArchive) { 41422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // read the symtab of the archive 41522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao readSymbolTable(pArchive); 41622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 41722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // read the strtab of the archive 41822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao readStringTable(pArchive); 41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 42022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // add root archive to ArchiveMemberMap 42122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.addArchiveMember(pArchive.getARFile().name(), 42222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.inputs().root(), 42322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao &InputTree::Downward); 42422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 42522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool isThinAR = isThinArchive(pArchive.getARFile()); 42622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t begin_offset = pArchive.getARFile().fileOffset() + 42737b74a387bb3993387029859c2d9d051c41c724eStephen Hines Archive::MAGIC_LEN + sizeof(Archive::MemberHeader) + 42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.getSymTabSize(); 42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pArchive.hasStrTable()) { 43037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if ((begin_offset & 1) != 0x0) 43122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++begin_offset; 43237b74a387bb3993387029859c2d9d051c41c724eStephen Hines begin_offset += 43337b74a387bb3993387029859c2d9d051c41c724eStephen Hines sizeof(Archive::MemberHeader) + pArchive.getStrTable().size(); 43422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 43587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t end_offset = pArchive.getARFile().memArea()->size(); 43637b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (uint32_t offset = begin_offset; offset < end_offset; 43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao offset += sizeof(Archive::MemberHeader)) { 43887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines size_t size = includeMember(pConfig, pArchive, offset); 43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!isThinAR) { 44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao offset += size; 44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 44322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 44437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if ((offset & 1) != 0x0) 44522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++offset; 44622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 44722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 44822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 44937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 45037b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 451