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 char *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 void Archive::anchor() { } 78 79 Archive::Child Archive::Child::getNext() const { 80 size_t SpaceToSkip = sizeof(ArchiveMemberHeader) + 81 ToHeader(Data.data())->getSize(); 82 // If it's odd, add 1 to make it even. 83 if (SpaceToSkip & 1) 84 ++SpaceToSkip; 85 86 const char *NextLoc = Data.data() + SpaceToSkip; 87 88 // Check to see if this is past the end of the archive. 89 if (NextLoc >= Parent->Data->getBufferEnd()) 90 return Child(Parent, StringRef(0, 0)); 91 92 size_t NextSize = sizeof(ArchiveMemberHeader) + 93 ToHeader(NextLoc)->getSize(); 94 95 return Child(Parent, StringRef(NextLoc, NextSize)); 96 } 97 98 error_code Archive::Child::getName(StringRef &Result) const { 99 StringRef name = ToHeader(Data.data())->getName(); 100 // Check if it's a special name. 101 if (name[0] == '/') { 102 if (name.size() == 1) { // Linker member. 103 Result = name; 104 return object_error::success; 105 } 106 if (name.size() == 2 && name[1] == '/') { // String table. 107 Result = name; 108 return object_error::success; 109 } 110 // It's a long name. 111 // Get the offset. 112 APInt offset; 113 name.substr(1).getAsInteger(10, offset); 114 const char *addr = Parent->StringTable->Data.begin() 115 + sizeof(ArchiveMemberHeader) 116 + offset.getZExtValue(); 117 // Verify it. 118 if (Parent->StringTable == Parent->end_children() 119 || addr < (Parent->StringTable->Data.begin() 120 + sizeof(ArchiveMemberHeader)) 121 || addr > (Parent->StringTable->Data.begin() 122 + sizeof(ArchiveMemberHeader) 123 + Parent->StringTable->getSize())) 124 return object_error::parse_failed; 125 Result = addr; 126 return object_error::success; 127 } else if (name.startswith("#1/")) { 128 APInt name_size; 129 name.substr(3).getAsInteger(10, name_size); 130 Result = Data.substr(0, name_size.getZExtValue()); 131 return object_error::success; 132 } 133 // It's a simple name. 134 if (name[name.size() - 1] == '/') 135 Result = name.substr(0, name.size() - 1); 136 else 137 Result = name; 138 return object_error::success; 139 } 140 141 uint64_t Archive::Child::getSize() const { 142 uint64_t size = ToHeader(Data.data())->getSize(); 143 // Don't include attached name. 144 StringRef name = ToHeader(Data.data())->getName(); 145 if (name.startswith("#1/")) { 146 APInt name_size; 147 name.substr(3).getAsInteger(10, name_size); 148 size -= name_size.getZExtValue(); 149 } 150 return size; 151 } 152 153 MemoryBuffer *Archive::Child::getBuffer() const { 154 StringRef name; 155 if (getName(name)) return NULL; 156 int size = sizeof(ArchiveMemberHeader); 157 if (name.startswith("#1/")) { 158 APInt name_size; 159 name.substr(3).getAsInteger(10, name_size); 160 size += name_size.getZExtValue(); 161 } 162 return MemoryBuffer::getMemBuffer(Data.substr(size, getSize()), 163 name, 164 false); 165 } 166 167 error_code Archive::Child::getAsBinary(OwningPtr<Binary> &Result) const { 168 OwningPtr<Binary> ret; 169 if (error_code ec = 170 createBinary(getBuffer(), ret)) 171 return ec; 172 Result.swap(ret); 173 return object_error::success; 174 } 175 176 Archive::Archive(MemoryBuffer *source, error_code &ec) 177 : Binary(Binary::ID_Archive, source) { 178 // Check for sufficient magic. 179 if (!source || source->getBufferSize() 180 < (8 + sizeof(ArchiveMemberHeader) + 2) // Smallest archive. 181 || StringRef(source->getBufferStart(), 8) != Magic) { 182 ec = object_error::invalid_file_type; 183 return; 184 } 185 186 // Get the special members. 187 child_iterator i = begin_children(false); 188 child_iterator e = end_children(); 189 190 if (i != e) ++i; // Nobody cares about the first member. 191 if (i != e) { 192 SymbolTable = i; 193 ++i; 194 } 195 if (i != e) { 196 StringTable = i; 197 } 198 199 ec = object_error::success; 200 } 201 202 Archive::child_iterator Archive::begin_children(bool skip_internal) const { 203 const char *Loc = Data->getBufferStart() + strlen(Magic); 204 size_t Size = sizeof(ArchiveMemberHeader) + 205 ToHeader(Loc)->getSize(); 206 Child c(this, StringRef(Loc, Size)); 207 // Skip internals at the beginning of an archive. 208 if (skip_internal && isInternalMember(*ToHeader(Loc))) 209 return c.getNext(); 210 return c; 211 } 212 213 Archive::child_iterator Archive::end_children() const { 214 return Child(this, StringRef(0, 0)); 215 } 216 217 error_code Archive::Symbol::getName(StringRef &Result) const { 218 Result = 219 StringRef(Parent->SymbolTable->getBuffer()->getBufferStart() + StringIndex); 220 return object_error::success; 221 } 222 223 error_code Archive::Symbol::getMember(child_iterator &Result) const { 224 const char *buf = Parent->SymbolTable->getBuffer()->getBufferStart(); 225 uint32_t member_count = *reinterpret_cast<const support::ulittle32_t*>(buf); 226 const char *offsets = buf + 4; 227 buf += 4 + (member_count * 4); // Skip offsets. 228 const char *indicies = buf + 4; 229 230 uint16_t offsetindex = 231 *(reinterpret_cast<const support::ulittle16_t*>(indicies) 232 + SymbolIndex); 233 234 uint32_t offset = *(reinterpret_cast<const support::ulittle32_t*>(offsets) 235 + (offsetindex - 1)); 236 237 const char *Loc = Parent->getData().begin() + offset; 238 size_t Size = sizeof(ArchiveMemberHeader) + 239 ToHeader(Loc)->getSize(); 240 Result = Child(Parent, StringRef(Loc, Size)); 241 242 return object_error::success; 243 } 244 245 Archive::Symbol Archive::Symbol::getNext() const { 246 Symbol t(*this); 247 // Go to one past next null. 248 t.StringIndex = 249 Parent->SymbolTable->getBuffer()->getBuffer().find('\0', t.StringIndex) + 1; 250 ++t.SymbolIndex; 251 return t; 252 } 253 254 Archive::symbol_iterator Archive::begin_symbols() const { 255 const char *buf = SymbolTable->getBuffer()->getBufferStart(); 256 uint32_t member_count = *reinterpret_cast<const support::ulittle32_t*>(buf); 257 buf += 4 + (member_count * 4); // Skip offsets. 258 uint32_t symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf); 259 buf += 4 + (symbol_count * 2); // Skip indices. 260 uint32_t string_start_offset = 261 buf - SymbolTable->getBuffer()->getBufferStart(); 262 return symbol_iterator(Symbol(this, 0, string_start_offset)); 263 } 264 265 Archive::symbol_iterator Archive::end_symbols() const { 266 const char *buf = SymbolTable->getBuffer()->getBufferStart(); 267 uint32_t member_count = *reinterpret_cast<const support::ulittle32_t*>(buf); 268 buf += 4 + (member_count * 4); // Skip offsets. 269 uint32_t symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf); 270 return symbol_iterator( 271 Symbol(this, symbol_count, 0)); 272 } 273