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/ErrorHandling.h" 17 #include "llvm/Support/Endian.h" 18 #include "llvm/Support/MemoryBuffer.h" 19 20 using namespace llvm; 21 using namespace object; 22 23 static const char *Magic = "!<arch>\n"; 24 25 namespace { 26 struct ArchiveMemberHeader { 27 char Name[16]; 28 char LastModified[12]; 29 char UID[6]; 30 char GID[6]; 31 char AccessMode[8]; 32 char Size[10]; ///< Size of data, not including header or padding. 33 char Terminator[2]; 34 35 ///! Get the name without looking up long names. 36 StringRef getName() const { 37 char EndCond; 38 if (Name[0] == '/' || Name[0] == '#') 39 EndCond = ' '; 40 else 41 EndCond = '/'; 42 StringRef::size_type end = StringRef(Name, sizeof(Name)).find(EndCond); 43 if (end == StringRef::npos) 44 end = sizeof(Name); 45 assert(end <= sizeof(Name) && end > 0); 46 // Don't include the EndCond if there is one. 47 return StringRef(Name, end); 48 } 49 50 uint64_t getSize() const { 51 APInt ret; 52 StringRef(Size, sizeof(Size)).getAsInteger(10, ret); 53 return ret.getZExtValue(); 54 } 55 }; 56 } 57 58 static const ArchiveMemberHeader *ToHeader(const char *base) { 59 return reinterpret_cast<const ArchiveMemberHeader *>(base); 60 } 61 62 63 static bool isInternalMember(const ArchiveMemberHeader &amh) { 64 static const char *const internals[] = { 65 "/", 66 "//", 67 "#_LLVM_SYM_TAB_#" 68 }; 69 70 StringRef name = amh.getName(); 71 for (std::size_t i = 0; i < sizeof(internals) / sizeof(*internals); ++i) { 72 if (name == internals[i]) 73 return true; 74 } 75 return false; 76 } 77 78 void Archive::anchor() { } 79 80 Archive::Child Archive::Child::getNext() const { 81 size_t SpaceToSkip = sizeof(ArchiveMemberHeader) + 82 ToHeader(Data.data())->getSize(); 83 // If it's odd, add 1 to make it even. 84 if (SpaceToSkip & 1) 85 ++SpaceToSkip; 86 87 const char *NextLoc = Data.data() + SpaceToSkip; 88 89 // Check to see if this is past the end of the archive. 90 if (NextLoc >= Parent->Data->getBufferEnd()) 91 return Child(Parent, StringRef(0, 0)); 92 93 size_t NextSize = sizeof(ArchiveMemberHeader) + 94 ToHeader(NextLoc)->getSize(); 95 96 return Child(Parent, StringRef(NextLoc, NextSize)); 97 } 98 99 error_code Archive::Child::getName(StringRef &Result) const { 100 StringRef name = ToHeader(Data.data())->getName(); 101 // Check if it's a special name. 102 if (name[0] == '/') { 103 if (name.size() == 1) { // Linker member. 104 Result = name; 105 return object_error::success; 106 } 107 if (name.size() == 2 && name[1] == '/') { // String table. 108 Result = name; 109 return object_error::success; 110 } 111 // It's a long name. 112 // Get the offset. 113 APInt offset; 114 name.substr(1).getAsInteger(10, offset); 115 const char *addr = Parent->StringTable->Data.begin() 116 + sizeof(ArchiveMemberHeader) 117 + offset.getZExtValue(); 118 // Verify it. 119 if (Parent->StringTable == Parent->end_children() 120 || addr < (Parent->StringTable->Data.begin() 121 + sizeof(ArchiveMemberHeader)) 122 || addr > (Parent->StringTable->Data.begin() 123 + sizeof(ArchiveMemberHeader) 124 + Parent->StringTable->getSize())) 125 return object_error::parse_failed; 126 127 // GNU long file names end with a /. 128 if (Parent->kind() == K_GNU) { 129 StringRef::size_type End = StringRef(addr).find('/'); 130 Result = StringRef(addr, End); 131 } else { 132 Result = addr; 133 } 134 return object_error::success; 135 } else if (name.startswith("#1/")) { 136 APInt name_size; 137 name.substr(3).getAsInteger(10, name_size); 138 Result = Data.substr(0, name_size.getZExtValue()); 139 return object_error::success; 140 } 141 // It's a simple name. 142 if (name[name.size() - 1] == '/') 143 Result = name.substr(0, name.size() - 1); 144 else 145 Result = name; 146 return object_error::success; 147 } 148 149 uint64_t Archive::Child::getSize() const { 150 uint64_t size = ToHeader(Data.data())->getSize(); 151 // Don't include attached name. 152 StringRef name = ToHeader(Data.data())->getName(); 153 if (name.startswith("#1/")) { 154 APInt name_size; 155 name.substr(3).getAsInteger(10, name_size); 156 size -= name_size.getZExtValue(); 157 } 158 return size; 159 } 160 161 MemoryBuffer *Archive::Child::getBuffer() const { 162 StringRef name; 163 if (getName(name)) return NULL; 164 int size = sizeof(ArchiveMemberHeader); 165 if (name.startswith("#1/")) { 166 APInt name_size; 167 name.substr(3).getAsInteger(10, name_size); 168 size += name_size.getZExtValue(); 169 } 170 return MemoryBuffer::getMemBuffer(Data.substr(size, getSize()), 171 name, 172 false); 173 } 174 175 error_code Archive::Child::getAsBinary(OwningPtr<Binary> &Result) const { 176 OwningPtr<Binary> ret; 177 if (error_code ec = 178 createBinary(getBuffer(), ret)) 179 return ec; 180 Result.swap(ret); 181 return object_error::success; 182 } 183 184 Archive::Archive(MemoryBuffer *source, error_code &ec) 185 : Binary(Binary::ID_Archive, source) { 186 // Check for sufficient magic. 187 if (!source || source->getBufferSize() 188 < (8 + sizeof(ArchiveMemberHeader) + 2) // Smallest archive. 189 || StringRef(source->getBufferStart(), 8) != Magic) { 190 ec = object_error::invalid_file_type; 191 return; 192 } 193 194 // Get the special members. 195 child_iterator i = begin_children(false); 196 child_iterator e = end_children(); 197 198 StringRef name; 199 if ((ec = i->getName(name))) 200 return; 201 202 // Below is the pattern that is used to figure out the archive format 203 // GNU archive format 204 // First member : / (points to the symbol table ) 205 // Second member : // (may exist, if it exists, points to the string table) 206 // Note : The string table is used if the filename exceeds 15 characters 207 // BSD archive format 208 // First member : __.SYMDEF (points to the symbol table) 209 // There is no string table, if the filename exceeds 15 characters or has a 210 // embedded space, the filename has #1/<size>, The size represents the size 211 // of the filename that needs to be read after the archive header 212 // COFF archive format 213 // First member : / 214 // Second member : / (provides a directory of symbols) 215 // Third member : // contains the string table, this is present even if the 216 // string table is empty 217 if (name == "/") { 218 SymbolTable = i; 219 StringTable = e; 220 if (i != e) ++i; 221 if ((ec = i->getName(name))) 222 return; 223 if (name[0] != '/') { 224 Format = K_GNU; 225 } else if ((name.size() > 1) && (name == "//")) { 226 Format = K_GNU; 227 StringTable = i; 228 ++i; 229 } else { 230 Format = K_COFF; 231 if (i != e) { 232 SymbolTable = i; 233 ++i; 234 } 235 if (i != e) { 236 StringTable = i; 237 } 238 } 239 } else if (name == "__.SYMDEF") { 240 Format = K_BSD; 241 SymbolTable = i; 242 StringTable = e; 243 } 244 ec = object_error::success; 245 } 246 247 Archive::child_iterator Archive::begin_children(bool skip_internal) const { 248 const char *Loc = Data->getBufferStart() + strlen(Magic); 249 size_t Size = sizeof(ArchiveMemberHeader) + 250 ToHeader(Loc)->getSize(); 251 Child c(this, StringRef(Loc, Size)); 252 // Skip internals at the beginning of an archive. 253 if (skip_internal && isInternalMember(*ToHeader(Loc))) 254 return c.getNext(); 255 return c; 256 } 257 258 Archive::child_iterator Archive::end_children() const { 259 return Child(this, StringRef(0, 0)); 260 } 261 262 error_code Archive::Symbol::getName(StringRef &Result) const { 263 Result = 264 StringRef(Parent->SymbolTable->getBuffer()->getBufferStart() + StringIndex); 265 return object_error::success; 266 } 267 268 error_code Archive::Symbol::getMember(child_iterator &Result) const { 269 const char *Buf = Parent->SymbolTable->getBuffer()->getBufferStart(); 270 const char *Offsets = Buf + 4; 271 uint32_t Offset = 0; 272 if (Parent->kind() == K_GNU) { 273 Offset = *(reinterpret_cast<const support::ubig32_t*>(Offsets) 274 + SymbolIndex); 275 } else if (Parent->kind() == K_BSD) { 276 llvm_unreachable("BSD format is not supported"); 277 } else { 278 uint32_t MemberCount = *reinterpret_cast<const support::ulittle32_t*>(Buf); 279 280 // Skip offsets. 281 Buf += sizeof(support::ulittle32_t) 282 + (MemberCount * sizeof(support::ulittle32_t)); 283 284 uint32_t SymbolCount = *reinterpret_cast<const support::ulittle32_t*>(Buf); 285 286 if (SymbolIndex >= SymbolCount) 287 return object_error::parse_failed; 288 289 // Skip SymbolCount to get to the indices table. 290 const char *Indices = Buf + sizeof(support::ulittle32_t); 291 292 // Get the index of the offset in the file member offset table for this 293 // symbol. 294 uint16_t OffsetIndex = 295 *(reinterpret_cast<const support::ulittle16_t*>(Indices) 296 + SymbolIndex); 297 // Subtract 1 since OffsetIndex is 1 based. 298 --OffsetIndex; 299 300 if (OffsetIndex >= MemberCount) 301 return object_error::parse_failed; 302 303 Offset = *(reinterpret_cast<const support::ulittle32_t*>(Offsets) 304 + OffsetIndex); 305 } 306 307 const char *Loc = Parent->getData().begin() + Offset; 308 size_t Size = sizeof(ArchiveMemberHeader) + 309 ToHeader(Loc)->getSize(); 310 Result = Child(Parent, StringRef(Loc, Size)); 311 312 return object_error::success; 313 } 314 315 Archive::Symbol Archive::Symbol::getNext() const { 316 Symbol t(*this); 317 // Go to one past next null. 318 t.StringIndex = 319 Parent->SymbolTable->getBuffer()->getBuffer().find('\0', t.StringIndex) + 1; 320 ++t.SymbolIndex; 321 return t; 322 } 323 324 Archive::symbol_iterator Archive::begin_symbols() const { 325 const char *buf = SymbolTable->getBuffer()->getBufferStart(); 326 if (kind() == K_GNU) { 327 uint32_t symbol_count = 0; 328 symbol_count = *reinterpret_cast<const support::ubig32_t*>(buf); 329 buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t))); 330 } else if (kind() == K_BSD) { 331 llvm_unreachable("BSD archive format is not supported"); 332 } else { 333 uint32_t member_count = 0; 334 uint32_t symbol_count = 0; 335 member_count = *reinterpret_cast<const support::ulittle32_t*>(buf); 336 buf += 4 + (member_count * 4); // Skip offsets. 337 symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf); 338 buf += 4 + (symbol_count * 2); // Skip indices. 339 } 340 uint32_t string_start_offset = 341 buf - SymbolTable->getBuffer()->getBufferStart(); 342 return symbol_iterator(Symbol(this, 0, string_start_offset)); 343 } 344 345 Archive::symbol_iterator Archive::end_symbols() const { 346 const char *buf = SymbolTable->getBuffer()->getBufferStart(); 347 uint32_t symbol_count = 0; 348 if (kind() == K_GNU) { 349 symbol_count = *reinterpret_cast<const support::ubig32_t*>(buf); 350 buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t))); 351 } else if (kind() == K_BSD) { 352 llvm_unreachable("BSD archive format is not supported"); 353 } else { 354 uint32_t member_count = 0; 355 member_count = *reinterpret_cast<const support::ulittle32_t*>(buf); 356 buf += 4 + (member_count * 4); // Skip offsets. 357 symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf); 358 } 359 return symbol_iterator( 360 Symbol(this, symbol_count, 0)); 361 } 362 363 Archive::child_iterator Archive::findSym(StringRef name) const { 364 Archive::symbol_iterator bs = begin_symbols(); 365 Archive::symbol_iterator es = end_symbols(); 366 Archive::child_iterator result; 367 368 StringRef symname; 369 for (; bs != es; ++bs) { 370 if (bs->getName(symname)) 371 return end_children(); 372 if (symname == name) { 373 if (bs->getMember(result)) 374 return end_children(); 375 return result; 376 } 377 } 378 return end_children(); 379 } 380