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//===----------------------------------------------------------------------===// 9affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/GNUArchiveReader.h> 1022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h> 1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/InputTree.h> 1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/MC/Attribute.h> 1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/MC/MCLDInput.h> 15cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/ResolveInfo.h> 16cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/ELFObjectReader.h> 17affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/FileSystem.h> 18cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/Support/FileHandle.h> 19affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MemoryArea.h> 20affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MemoryRegion.h> 21affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 22cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/Support/Path.h> 23affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/ADT/SizeTraits.h> 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 25cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/ADT/StringRef.h> 26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/Host.h> 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 28cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cstring> 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstdlib> 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoGNUArchiveReader::GNUArchiveReader(Module& pModule, 34cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao ELFObjectReader& pELFObjectReader) 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao : m_Module(pModule), 36cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao m_ELFObjectReader(pELFObjectReader) 37cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 38cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 40cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoGNUArchiveReader::~GNUArchiveReader() 41cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 42cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 44cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// isMyFormat 45cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool GNUArchiveReader::isMyFormat(Input& pInput) const 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 47cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao assert(pInput.hasMemArea()); 48cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(), 49cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Archive::MAGIC_LEN); 50cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao const char* str = reinterpret_cast<const char*>(region->getBuffer()); 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 52cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao bool result = false; 53cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao assert(NULL != str); 54cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (isArchive(str) || isThinArchive(str)) 55cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao result = true; 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 57cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pInput.memArea()->release(region); 58cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return result; 59cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 61cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// isArchive 62cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool GNUArchiveReader::isArchive(const char* pStr) const 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 64cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return (0 == memcmp(pStr, Archive::MAGIC, Archive::MAGIC_LEN)); 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 67cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// isThinArchive 68cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool GNUArchiveReader::isThinArchive(const char* pStr) const 69cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 70cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return (0 == memcmp(pStr, Archive::THIN_MAGIC, Archive::MAGIC_LEN)); 71cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 73cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// isThinArchive 74cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool GNUArchiveReader::isThinArchive(Input& pInput) const 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(pInput.hasMemArea()); 77cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(), 78cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Archive::MAGIC_LEN); 79cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao const char* str = reinterpret_cast<const char*>(region->getBuffer()); 80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 81cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao bool result = false; 82cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao assert(NULL != str); 83cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (isThinArchive(str)) 84cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao result = true; 85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 86cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pInput.memArea()->release(region); 87cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return result; 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 90cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool GNUArchiveReader::readArchive(Archive& pArchive) 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // bypass the empty archive 936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (Archive::MAGIC_LEN == pArchive.getARFile().memArea()->handler()->size()) 946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pArchive.getARFile().attribute()->isWholeArchive()) 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return includeAllMembers(pArchive); 9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if this is the first time read this archive, setup symtab and strtab 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pArchive.getSymbolTable().empty()) { 101cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // read the symtab of the archive 102cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao readSymbolTable(pArchive); 103cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 104cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // read the strtab of the archive 105cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao readStringTable(pArchive); 106cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 107cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // add root archive to ArchiveMemberMap 108cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchive.addArchiveMember(pArchive.getARFile().name(), 109cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchive.inputs().root(), 110cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao &InputTree::Downward); 11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 112cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 113cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // include the needed members in the archive and build up the input tree 114cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao bool willSymResolved; 115cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao do { 116cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao willSymResolved = false; 117cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao for (size_t idx = 0; idx < pArchive.numOfSymbols(); ++idx) { 118cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // bypass if we already decided to include this symbol or not 119cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (Archive::Symbol::Unknown != pArchive.getSymbolStatus(idx)) 120cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao continue; 121cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 122cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // bypass if another symbol with the same object file offset is included 123cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (pArchive.hasObjectMember(pArchive.getObjFileOffset(idx))) { 124cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchive.setSymbolStatus(idx, Archive::Symbol::Include); 125cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao continue; 126cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 127cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 128cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // check if we should include this defined symbol 129cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Archive::Symbol::Status status = 130cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao shouldIncludeSymbol(pArchive.getSymbolName(idx)); 131cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (Archive::Symbol::Unknown != status) 132cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchive.setSymbolStatus(idx, status); 133cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 134cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (Archive::Symbol::Include == status) { 13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // include the object member from the given offset 13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao includeMember(pArchive, pArchive.getObjFileOffset(idx)); 137cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao willSymResolved = true; 138cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } // end of if 139cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } // end of for 140cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } while (willSymResolved); 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 142cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return true; 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 145cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// readMemberHeader - read the header of a member in a archive file and then 146cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// return the corresponding archive member (it may be an input object or 147cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// another archive) 148cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// @param pArchiveRoot - the archive root that holds the strtab (extended 149cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// name table) 150cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// @param pArchiveFile - the archive that contains the needed object 151cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// @param pFileOffset - file offset of the member header in the archive 152cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// @param pNestedOffset - used when we find a nested archive 15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @param pMemberSize - the file size of this member 154cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoInput* GNUArchiveReader::readMemberHeader(Archive& pArchiveRoot, 155cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Input& pArchiveFile, 156cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao uint32_t pFileOffset, 15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t& pNestedOffset, 15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t& pMemberSize) 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 160cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao assert(pArchiveFile.hasMemArea()); 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 162cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao MemoryRegion* header_region = 163cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchiveFile.memArea()->request((pArchiveFile.fileOffset() + pFileOffset), 164cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao sizeof(Archive::MemberHeader)); 165cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao const Archive::MemberHeader* header = 166cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao reinterpret_cast<const Archive::MemberHeader*>(header_region->getBuffer()); 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(0 == memcmp(header->fmag, Archive::MEMBER_MAGIC, sizeof(header->fmag))); 169cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 17022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pMemberSize = atoi(header->size); 171cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 172cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // parse the member name and nested offset if any 173cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao std::string member_name; 17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::StringRef name_field(header->name, sizeof(header->name)); 175cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if ('/' != header->name[0]) { 176cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // this is an object file in an archive 177cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao size_t pos = name_field.find_first_of('/'); 178cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao member_name.assign(name_field.substr(0, pos).str()); 179cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 180cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao else { 181cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // this is an object/archive file in a thin archive 182cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao size_t begin = 1; 183cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao size_t end = name_field.find_first_of(" :"); 184cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao uint32_t name_offset = 0; 185cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // parse the name offset 186cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao name_field.substr(begin, end - begin).getAsInteger(10, name_offset); 187cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 188cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (':' == name_field[end]) { 189cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // there is a nested offset 190cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao begin = end + 1; 191cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao end = name_field.find_first_of(' ', begin); 192cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao name_field.substr(begin, end - begin).getAsInteger(10, pNestedOffset); 193cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 194cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 195cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get the member name from the extended name table 19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(pArchiveRoot.hasStrTable()); 197cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao begin = name_offset; 198cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao end = pArchiveRoot.getStrTable().find_first_of('\n', begin); 199cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao member_name.assign(pArchiveRoot.getStrTable().substr(begin, end - begin -1)); 200cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 202cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Input* member = NULL; 20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool isThinAR = isThinArchive(pArchiveFile); 20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!isThinAR) { 205cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // this is an object file in an archive 20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao member = pArchiveRoot.getMemberFile(pArchiveFile, 20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao isThinAR, 20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao member_name, 20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchiveFile.path(), 21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (pFileOffset + 21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sizeof(Archive::MemberHeader))); 2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 213cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao else { 214cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // this is a member in a thin archive 215cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // try to find if this is a archive already in the map first 216cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Archive::ArchiveMember* ar_member = 217cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchiveRoot.getArchiveMember(member_name); 218cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (NULL != ar_member) { 219cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return ar_member->file; 220cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 222cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // get nested file path, the nested file's member name is the relative 223cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // path to the archive containing it. 224cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao sys::fs::Path input_path(pArchiveFile.path().parent_path()); 225cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (!input_path.empty()) 226cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao input_path.append(member_name); 2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 228cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao input_path.assign(member_name); 229cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao member = pArchiveRoot.getMemberFile(pArchiveFile, 23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao isThinAR, 23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao member_name, 23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao input_path); 2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 235cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 236cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchiveFile.memArea()->release(header_region); 237cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return member; 2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 240cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// readSymbolTable - read the archive symbol map (armap) 241cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool GNUArchiveReader::readSymbolTable(Archive& pArchive) 242cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 243cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao assert(pArchive.getARFile().hasMemArea()); 244cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 245cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao MemoryRegion* header_region = 246cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchive.getARFile().memArea()->request((pArchive.getARFile().fileOffset() + 247cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Archive::MAGIC_LEN), 248cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao sizeof(Archive::MemberHeader)); 249cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao const Archive::MemberHeader* header = 250cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao reinterpret_cast<const Archive::MemberHeader*>(header_region->getBuffer()); 25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(0 == memcmp(header->fmag, Archive::MEMBER_MAGIC, sizeof(header->fmag))); 252cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 253cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao int symtab_size = atoi(header->size); 254cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchive.setSymTabSize(symtab_size); 255cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!pArchive.getARFile().attribute()->isWholeArchive()) { 25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* symtab_region = 25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.getARFile().memArea()->request( 25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (pArchive.getARFile().fileOffset() + 260cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Archive::MAGIC_LEN + 261cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao sizeof(Archive::MemberHeader)), 262cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao symtab_size); 26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const uint32_t* data = 26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<const uint32_t*>(symtab_region->getBuffer()); 26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // read the number of symbols 26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t number = 0; 26821433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) 269d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao number = mcld::bswap32(*data); 270cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao else 27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao number = *data; 27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 27322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set up the pointers for file offset and name offset 274cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao ++data; 27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const char* name = reinterpret_cast<const char*>(data + number); 27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // add the archive symbols 27822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (uint32_t i = 0; i < number; ++i) { 27921433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) 280d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pArchive.addSymbol(name, mcld::bswap32(*data)); 28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.addSymbol(name, *data); 28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao name += strlen(name) + 1; 28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++data; 28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.getARFile().memArea()->release(symtab_region); 2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 288cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchive.getARFile().memArea()->release(header_region); 289cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return true; 290cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 292cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// readStringTable - read the strtab for long file name of the archive 293cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool GNUArchiveReader::readStringTable(Archive& pArchive) 294cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 295cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao size_t offset = Archive::MAGIC_LEN + 296cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao sizeof(Archive::MemberHeader) + 297cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchive.getSymTabSize(); 2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 299cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (0x0 != (offset & 1)) 300cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao ++offset; 3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 302cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao assert(pArchive.getARFile().hasMemArea()); 303cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 304cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao MemoryRegion* header_region = 305cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchive.getARFile().memArea()->request((pArchive.getARFile().fileOffset() + 306cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao offset), 307cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao sizeof(Archive::MemberHeader)); 308cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao const Archive::MemberHeader* header = 309cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao reinterpret_cast<const Archive::MemberHeader*>(header_region->getBuffer()); 3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(0 == memcmp(header->fmag, Archive::MEMBER_MAGIC, sizeof(header->fmag))); 31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 == memcmp(header->name, Archive::STRTAB_NAME, sizeof(header->name))) { 31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // read the extended name table 31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao int strtab_size = atoi(header->size); 31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* strtab_region = 31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.getARFile().memArea()->request( 31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (pArchive.getARFile().fileOffset() + 31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao offset + sizeof(Archive::MemberHeader)), 32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao strtab_size); 32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const char* strtab = 32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<const char*>(strtab_region->getBuffer()); 32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.getStrTable().assign(strtab, strtab_size); 32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.getARFile().memArea()->release(strtab_region); 32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 326cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pArchive.getARFile().memArea()->release(header_region); 327cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return true; 3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 330cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// shouldIncludeStatus - given a sym name from armap and check if including 331cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// the corresponding archive member, and then return the decision 332cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaoenum Archive::Symbol::Status 333cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoGNUArchiveReader::shouldIncludeSymbol(const llvm::StringRef& pSymName) const 3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 335cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // TODO: handle symbol version issue and user defined symbols 33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ResolveInfo* info = m_Module.getNamePool().findInfo(pSymName); 337cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (NULL != info) { 338cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (!info->isUndef()) 339cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return Archive::Symbol::Exclude; 340cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (info->isWeak()) 341cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return Archive::Symbol::Unknown; 342cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return Archive::Symbol::Include; 3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 344cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return Archive::Symbol::Unknown; 3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 346cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// includeMember - include the object member in the given file offset, and 34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// return the size of the object 34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @param pArchiveRoot - the archive root 35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @param pFileOffset - file offset of the member header in the archive 35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaosize_t GNUArchiveReader::includeMember(Archive& pArchive, uint32_t pFileOffset) 35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Input* cur_archive = &(pArchive.getARFile()); 35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Input* member = NULL; 35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t file_offset = pFileOffset; 35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t size = 0; 35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao do { 35822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t nested_offset = 0; 35922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // use the file offset in current archive to find out the member we 36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // want to include 36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao member = readMemberHeader(pArchive, 36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *cur_archive, 36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_offset, 36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao nested_offset, 36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size); 36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(member != NULL); 36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // bypass if we get an archive that is already in the map 36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (Input::Archive == member->type()) { 36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao cur_archive = member; 37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_offset = nested_offset; 37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 37422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // insert a node into the subtree of current archive. 37522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Archive::ArchiveMember* parent = 37622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.getArchiveMember(cur_archive->name()); 37722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 37822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != parent); 37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.inputs().insert(parent->lastPos, *(parent->move), *member); 38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // move the iterator to new created node, and also adjust the 38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // direction to Afterward for next insertion in this subtree 38322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao parent->move->move(parent->lastPos); 38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao parent->move = &InputTree::Afterward; 38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_ELFObjectReader.isMyFormat(*member)) { 38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao member->setType(Input::Object); 38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.addObjectMember(pFileOffset, parent->lastPos); 38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_ELFObjectReader.readHeader(*member); 39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_ELFObjectReader.readSections(*member); 39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_ELFObjectReader.readSymbols(*member); 39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Module.getObjectList().push_back(member); 39322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 39422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (isMyFormat(*member)) { 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 39822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.addArchiveMember(member->name(), 39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao parent->lastPos, 40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao &InputTree::Downward); 40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao cur_archive = member; 40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao file_offset = nested_offset; 40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } while (Input::Object != member->type()); 40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return size; 40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// includeAllMembers - include all object members. This is called if 40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// --whole-archive is the attribute for this archive file. 41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool GNUArchiveReader::includeAllMembers(Archive& pArchive) 41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // read the symtab of the archive 41322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao readSymbolTable(pArchive); 41422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 41522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // read the strtab of the archive 41622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao readStringTable(pArchive); 41722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 41822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // add root archive to ArchiveMemberMap 41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.addArchiveMember(pArchive.getARFile().name(), 42022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.inputs().root(), 42122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao &InputTree::Downward); 42222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 42322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool isThinAR = isThinArchive(pArchive.getARFile()); 42422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t begin_offset = pArchive.getARFile().fileOffset() + 42522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Archive::MAGIC_LEN + 42622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sizeof(Archive::MemberHeader) + 42722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.getSymTabSize(); 42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pArchive.hasStrTable()) { 42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0x0 != (begin_offset & 1)) 43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++begin_offset; 43122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao begin_offset += sizeof(Archive::MemberHeader) + 43222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pArchive.getStrTable().size(); 43322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 43422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t end_offset = pArchive.getARFile().memArea()->handler()->size(); 43522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (uint32_t offset = begin_offset; 43622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao offset < end_offset; 43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao offset += sizeof(Archive::MemberHeader)) { 43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t size = includeMember(pArchive, offset); 44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!isThinAR) { 44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao offset += size; 44322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 44422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 44522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0x0 != (offset & 1)) 44622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++offset; 44722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 44822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 44922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 45022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 451