/// includeMember - include the object member in the given file offset, and /// return the size of the object /// @param pConfig - LinkerConfig /// @param pArchiveRoot - the archive root /// @param pFileOffset - file offset of the member header in the archive size_t GNUArchiveReader::includeMember(const LinkerConfig& pConfig, Archive& pArchive, uint32_t pFileOffset) { Input* cur_archive = &(pArchive.getARFile()); Input* member = NULL; uint32_t file_offset = pFileOffset; size_t size = 0; do { uint32_t nested_offset = 0; // use the file offset in current archive to find out the member we // want to include member = readMemberHeader(pArchive, *cur_archive, file_offset, nested_offset, size); assert(member != NULL); // bypass if we get an archive that is already in the map if (Input::Archive == member->type()) { cur_archive = member; file_offset = nested_offset; continue; } // insert a node into the subtree of current archive. Archive::ArchiveMember* parent = pArchive.getArchiveMember(cur_archive->name()); assert(NULL != parent); pArchive.inputs().insert(parent->lastPos, *(parent->move), *member); // move the iterator to new created node, and also adjust the // direction to Afterward for next insertion in this subtree parent->move->move(parent->lastPos); parent->move = &InputTree::Afterward; bool doContinue = false; if (m_ELFObjectReader.isMyFormat(*member, doContinue)) { member->setType(Input::Object); pArchive.addObjectMember(pFileOffset, parent->lastPos); m_ELFObjectReader.readHeader(*member); m_ELFObjectReader.readSections(*member); m_ELFObjectReader.readSymbols(*member); m_Module.getObjectList().push_back(member); } else if (doContinue && isMyFormat(*member, doContinue)) { member->setType(Input::Archive); // when adding a new archive node, set the iterator to archive // itself, and set the direction to Downward pArchive.addArchiveMember(member->name(), parent->lastPos, &InputTree::Downward); cur_archive = member; file_offset = nested_offset; } else { warning(diag::warn_unrecognized_input_file) << member->path() << pConfig.targets().triple().str(); } } while (Input::Object != member->type()); return size; }