1a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer//===- Archive.cpp - ar File Format implementation --------------*- C++ -*-===// 2a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer// 3a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer// The LLVM Compiler Infrastructure 4a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer// 5a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer// This file is distributed under the University of Illinois Open Source 6a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer// License. See LICENSE.TXT for details. 7a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer// 8a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer//===----------------------------------------------------------------------===// 9a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer// 10a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer// This file defines the ArchiveObjectFile class. 11a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer// 12a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer//===----------------------------------------------------------------------===// 13a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 14a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer#include "llvm/Object/Archive.h" 15a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer#include "llvm/ADT/APInt.h" 16c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer#include "llvm/Support/Endian.h" 17a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer#include "llvm/Support/MemoryBuffer.h" 18a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 19a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencerusing namespace llvm; 20a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencerusing namespace object; 21a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 22e1a4427ccb6e29e63c11e63224460a92ee66de37Benjamin Kramerstatic const char *Magic = "!<arch>\n"; 23a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 24fe944e8cd03701b699c07590b4ec5203928b2b11Michael J. Spencernamespace { 25a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencerstruct ArchiveMemberHeader { 26a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer char Name[16]; 27a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer char LastModified[12]; 28a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer char UID[6]; 29a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer char GID[6]; 30a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer char AccessMode[8]; 3177592fe39c404f3c48b06fae48b965058b3a5ee8Dmitri Gribenko char Size[10]; ///< Size of data, not including header or padding. 32a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer char Terminator[2]; 33a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 34a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer ///! Get the name without looking up long names. 35a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer StringRef getName() const { 36aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer char EndCond; 37aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer if (Name[0] == '/' || Name[0] == '#') 38aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer EndCond = ' '; 39aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer else 40aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer EndCond = '/'; 41a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer StringRef::size_type end = StringRef(Name, sizeof(Name)).find(EndCond); 42a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer if (end == StringRef::npos) 43a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer end = sizeof(Name); 44a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer assert(end <= sizeof(Name) && end > 0); 45a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer // Don't include the EndCond if there is one. 46a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer return StringRef(Name, end); 47a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer } 48a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 49a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer uint64_t getSize() const { 50a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer APInt ret; 51a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer StringRef(Size, sizeof(Size)).getAsInteger(10, ret); 52a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer return ret.getZExtValue(); 53a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer } 54a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer}; 55fe944e8cd03701b699c07590b4ec5203928b2b11Michael J. Spencer} 56a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 57fe944e8cd03701b699c07590b4ec5203928b2b11Michael J. Spencerstatic const ArchiveMemberHeader *ToHeader(const char *base) { 58a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer return reinterpret_cast<const ArchiveMemberHeader *>(base); 59a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer} 60fe944e8cd03701b699c07590b4ec5203928b2b11Michael J. Spencer 61a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 62aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencerstatic bool isInternalMember(const ArchiveMemberHeader &amh) { 63e32981048244ecfa67d0bdc211af1bac2020a555Craig Topper static const char *const internals[] = { 64aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer "/", 65aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer "//", 66aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer "#_LLVM_SYM_TAB_#" 67e32981048244ecfa67d0bdc211af1bac2020a555Craig Topper }; 68aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer 69aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer StringRef name = amh.getName(); 70aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer for (std::size_t i = 0; i < sizeof(internals) / sizeof(*internals); ++i) { 71aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer if (name == internals[i]) 72aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer return true; 73aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer } 74aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer return false; 75aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer} 76aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer 772d24e2a396a1d211baaeedf32148a3b657240170David Blaikievoid Archive::anchor() { } 782d24e2a396a1d211baaeedf32148a3b657240170David Blaikie 79a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. SpencerArchive::Child Archive::Child::getNext() const { 80a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer size_t SpaceToSkip = sizeof(ArchiveMemberHeader) + 81a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer ToHeader(Data.data())->getSize(); 82a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer // If it's odd, add 1 to make it even. 83a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer if (SpaceToSkip & 1) 84a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer ++SpaceToSkip; 85a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 86a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer const char *NextLoc = Data.data() + SpaceToSkip; 87a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 88a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer // Check to see if this is past the end of the archive. 89a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer if (NextLoc >= Parent->Data->getBufferEnd()) 90a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer return Child(Parent, StringRef(0, 0)); 91a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 92a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer size_t NextSize = sizeof(ArchiveMemberHeader) + 93a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer ToHeader(NextLoc)->getSize(); 94a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 95a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer return Child(Parent, StringRef(NextLoc, NextSize)); 96a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer} 97a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 98a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencererror_code Archive::Child::getName(StringRef &Result) const { 99a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer StringRef name = ToHeader(Data.data())->getName(); 100a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer // Check if it's a special name. 101a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer if (name[0] == '/') { 102a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer if (name.size() == 1) { // Linker member. 103a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer Result = name; 104a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer return object_error::success; 105a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer } 106a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer if (name.size() == 2 && name[1] == '/') { // String table. 107a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer Result = name; 108a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer return object_error::success; 109a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer } 110a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer // It's a long name. 111a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer // Get the offset. 112a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer APInt offset; 113a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer name.substr(1).getAsInteger(10, offset); 114a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer const char *addr = Parent->StringTable->Data.begin() 115a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer + sizeof(ArchiveMemberHeader) 116a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer + offset.getZExtValue(); 117a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer // Verify it. 118a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer if (Parent->StringTable == Parent->end_children() 119a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer || addr < (Parent->StringTable->Data.begin() 120a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer + sizeof(ArchiveMemberHeader)) 121a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer || addr > (Parent->StringTable->Data.begin() 122a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer + sizeof(ArchiveMemberHeader) 123a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer + Parent->StringTable->getSize())) 124a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer return object_error::parse_failed; 125a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer Result = addr; 126a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer return object_error::success; 127aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer } else if (name.startswith("#1/")) { 128aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer APInt name_size; 129aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer name.substr(3).getAsInteger(10, name_size); 130aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer Result = Data.substr(0, name_size.getZExtValue()); 131aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer return object_error::success; 132a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer } 133a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer // It's a simple name. 134a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer if (name[name.size() - 1] == '/') 135a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer Result = name.substr(0, name.size() - 1); 136a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer else 137a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer Result = name; 138a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer return object_error::success; 139a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer} 140a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 141a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spenceruint64_t Archive::Child::getSize() const { 142aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer uint64_t size = ToHeader(Data.data())->getSize(); 143aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer // Don't include attached name. 144aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer StringRef name = ToHeader(Data.data())->getName(); 145aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer if (name.startswith("#1/")) { 146aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer APInt name_size; 147aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer name.substr(3).getAsInteger(10, name_size); 148aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer size -= name_size.getZExtValue(); 149aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer } 150aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer return size; 151a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer} 152a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 153a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. SpencerMemoryBuffer *Archive::Child::getBuffer() const { 154a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer StringRef name; 155a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer if (getName(name)) return NULL; 156aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer int size = sizeof(ArchiveMemberHeader); 157aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer if (name.startswith("#1/")) { 158aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer APInt name_size; 159aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer name.substr(3).getAsInteger(10, name_size); 160aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer size += name_size.getZExtValue(); 161aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer } 162aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer return MemoryBuffer::getMemBuffer(Data.substr(size, getSize()), 163a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer name, 164a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer false); 165a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer} 166a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 167a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencererror_code Archive::Child::getAsBinary(OwningPtr<Binary> &Result) const { 168a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer OwningPtr<Binary> ret; 169a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer if (error_code ec = 170a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer createBinary(getBuffer(), ret)) 171a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer return ec; 172a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer Result.swap(ret); 173a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer return object_error::success; 174a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer} 175a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 176a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. SpencerArchive::Archive(MemoryBuffer *source, error_code &ec) 1776f9489a86f33624f9ff5388411d12359ce9cef20David Meyer : Binary(Binary::ID_Archive, source) { 178a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer // Check for sufficient magic. 179a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer if (!source || source->getBufferSize() 180a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer < (8 + sizeof(ArchiveMemberHeader) + 2) // Smallest archive. 181a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer || StringRef(source->getBufferStart(), 8) != Magic) { 182a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer ec = object_error::invalid_file_type; 183a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer return; 184a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer } 185a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 186c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer // Get the special members. 187c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer child_iterator i = begin_children(false); 188a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer child_iterator e = end_children(); 189a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 190c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer if (i != e) ++i; // Nobody cares about the first member. 191c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer if (i != e) { 192c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer SymbolTable = i; 193c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer ++i; 194c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer } 195c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer if (i != e) { 196c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer StringTable = i; 197c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer } 198a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 199a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer ec = object_error::success; 200a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer} 201a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 202aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. SpencerArchive::child_iterator Archive::begin_children(bool skip_internal) const { 203e1a4427ccb6e29e63c11e63224460a92ee66de37Benjamin Kramer const char *Loc = Data->getBufferStart() + strlen(Magic); 204a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer size_t Size = sizeof(ArchiveMemberHeader) + 205a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer ToHeader(Loc)->getSize(); 206aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer Child c(this, StringRef(Loc, Size)); 207aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer // Skip internals at the beginning of an archive. 208aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer if (skip_internal && isInternalMember(*ToHeader(Loc))) 209aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer return c.getNext(); 210aaf98ead114bcd51cd2479badfe28b8d0e4895c2Michael J. Spencer return c; 211a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer} 212a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer 2135861893c25ee9ee6bb2991057169c0cb1e1331e0Michael J. SpencerArchive::child_iterator Archive::end_children() const { 214a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer return Child(this, StringRef(0, 0)); 215a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer} 216c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer 217c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencererror_code Archive::Symbol::getName(StringRef &Result) const { 218c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer Result = 219c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer StringRef(Parent->SymbolTable->getBuffer()->getBufferStart() + StringIndex); 220c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer return object_error::success; 221c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer} 222c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer 223c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencererror_code Archive::Symbol::getMember(child_iterator &Result) const { 224c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer const char *buf = Parent->SymbolTable->getBuffer()->getBufferStart(); 225c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer uint32_t member_count = *reinterpret_cast<const support::ulittle32_t*>(buf); 226c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer const char *offsets = buf + 4; 227c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer buf += 4 + (member_count * 4); // Skip offsets. 228c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer const char *indicies = buf + 4; 229c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer 230c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer uint16_t offsetindex = 231c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer *(reinterpret_cast<const support::ulittle16_t*>(indicies) 232c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer + SymbolIndex); 233c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer 234c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer uint32_t offset = *(reinterpret_cast<const support::ulittle32_t*>(offsets) 235c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer + (offsetindex - 1)); 236c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer 237c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer const char *Loc = Parent->getData().begin() + offset; 238c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer size_t Size = sizeof(ArchiveMemberHeader) + 239c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer ToHeader(Loc)->getSize(); 240c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer Result = Child(Parent, StringRef(Loc, Size)); 241c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer 242c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer return object_error::success; 243c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer} 244c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer 245c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. SpencerArchive::Symbol Archive::Symbol::getNext() const { 246c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer Symbol t(*this); 247efd2d5e1c48e9e530d2323123d28120f50dfed76Benjamin Kramer // Go to one past next null. 248efd2d5e1c48e9e530d2323123d28120f50dfed76Benjamin Kramer t.StringIndex = 249efd2d5e1c48e9e530d2323123d28120f50dfed76Benjamin Kramer Parent->SymbolTable->getBuffer()->getBuffer().find('\0', t.StringIndex) + 1; 250c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer ++t.SymbolIndex; 251c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer return t; 252c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer} 253c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer 254c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. SpencerArchive::symbol_iterator Archive::begin_symbols() const { 255c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer const char *buf = SymbolTable->getBuffer()->getBufferStart(); 256c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer uint32_t member_count = *reinterpret_cast<const support::ulittle32_t*>(buf); 257c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer buf += 4 + (member_count * 4); // Skip offsets. 258c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer uint32_t symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf); 259c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer buf += 4 + (symbol_count * 2); // Skip indices. 260c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer uint32_t string_start_offset = 261c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer buf - SymbolTable->getBuffer()->getBufferStart(); 262c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer return symbol_iterator(Symbol(this, 0, string_start_offset)); 263c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer} 264c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer 265c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. SpencerArchive::symbol_iterator Archive::end_symbols() const { 266c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer const char *buf = SymbolTable->getBuffer()->getBufferStart(); 267c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer uint32_t member_count = *reinterpret_cast<const support::ulittle32_t*>(buf); 268c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer buf += 4 + (member_count * 4); // Skip offsets. 269c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer uint32_t symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf); 270c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer return symbol_iterator( 271c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer Symbol(this, symbol_count, 0)); 272c8a55a660e93bb7a4854969b4c5814bf7bb0101bMichael J. Spencer} 273