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