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