Archive.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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. #include "llvm/Object/Archive.h"
  14. #include "llvm/ADT/APInt.h"
  15. #include "llvm/Support/Endian.h"
  16. #include "llvm/Support/MemoryBuffer.h"
  17. using namespace llvm;
  18. using namespace object;
  19. static const char *Magic = "!<arch>\n";
  20. static bool isInternalMember(const ArchiveMemberHeader &amh) {
  21. static const char *const internals[] = {
  22. "/",
  23. "//"
  24. };
  25. StringRef name = amh.getName();
  26. for (std::size_t i = 0; i < sizeof(internals) / sizeof(*internals); ++i) {
  27. if (name == internals[i])
  28. return true;
  29. }
  30. return false;
  31. }
  32. void Archive::anchor() { }
  33. error_code Archive::Child::getName(StringRef &Result) const {
  34. StringRef name = ToHeader(Data.data())->getName();
  35. // Check if it's a special name.
  36. if (name[0] == '/') {
  37. if (name.size() == 1) { // Linker member.
  38. Result = name;
  39. return object_error::success;
  40. }
  41. if (name.size() == 2 && name[1] == '/') { // String table.
  42. Result = name;
  43. return object_error::success;
  44. }
  45. // It's a long name.
  46. // Get the offset.
  47. std::size_t offset;
  48. if (name.substr(1).rtrim(" ").getAsInteger(10, offset))
  49. llvm_unreachable("Long name offset is not an integer");
  50. const char *addr = Parent->StringTable->Data.begin()
  51. + sizeof(ArchiveMemberHeader)
  52. + offset;
  53. // Verify it.
  54. if (Parent->StringTable == Parent->end_children()
  55. || addr < (Parent->StringTable->Data.begin()
  56. + sizeof(ArchiveMemberHeader))
  57. || addr > (Parent->StringTable->Data.begin()
  58. + sizeof(ArchiveMemberHeader)
  59. + Parent->StringTable->getSize()))
  60. return object_error::parse_failed;
  61. // GNU long file names end with a /.
  62. if (Parent->kind() == K_GNU) {
  63. StringRef::size_type End = StringRef(addr).find('/');
  64. Result = StringRef(addr, End);
  65. } else {
  66. Result = addr;
  67. }
  68. return object_error::success;
  69. } else if (name.startswith("#1/")) {
  70. uint64_t name_size;
  71. if (name.substr(3).rtrim(" ").getAsInteger(10, name_size))
  72. llvm_unreachable("Long name length is not an ingeter");
  73. Result = Data.substr(sizeof(ArchiveMemberHeader), name_size);
  74. return object_error::success;
  75. }
  76. // It's a simple name.
  77. if (name[name.size() - 1] == '/')
  78. Result = name.substr(0, name.size() - 1);
  79. else
  80. Result = name;
  81. return object_error::success;
  82. }
  83. error_code Archive::Child::getAsBinary(OwningPtr<Binary> &Result) const {
  84. OwningPtr<Binary> ret;
  85. OwningPtr<MemoryBuffer> Buff;
  86. if (error_code ec = getMemoryBuffer(Buff))
  87. return ec;
  88. if (error_code ec = createBinary(Buff.take(), ret))
  89. return ec;
  90. Result.swap(ret);
  91. return object_error::success;
  92. }
  93. Archive::Archive(MemoryBuffer *source, error_code &ec)
  94. : Binary(Binary::ID_Archive, source) {
  95. // Check for sufficient magic.
  96. if (!source || source->getBufferSize()
  97. < (8 + sizeof(ArchiveMemberHeader) + 2) // Smallest archive.
  98. || StringRef(source->getBufferStart(), 8) != Magic) {
  99. ec = object_error::invalid_file_type;
  100. return;
  101. }
  102. // Get the special members.
  103. child_iterator i = begin_children(false);
  104. child_iterator e = end_children();
  105. StringRef name;
  106. if ((ec = i->getName(name)))
  107. return;
  108. // Below is the pattern that is used to figure out the archive format
  109. // GNU archive format
  110. // First member : / (points to the symbol table )
  111. // Second member : // (may exist, if it exists, points to the string table)
  112. // Note : The string table is used if the filename exceeds 15 characters
  113. // BSD archive format
  114. // First member : __.SYMDEF (points to the symbol table)
  115. // There is no string table, if the filename exceeds 15 characters or has a
  116. // embedded space, the filename has #1/<size>, The size represents the size
  117. // of the filename that needs to be read after the archive header
  118. // COFF archive format
  119. // First member : /
  120. // Second member : / (provides a directory of symbols)
  121. // Third member : // (may exist, if it exists, contains the string table)
  122. // Note: Microsoft PE/COFF Spec 8.3 says that the third member is present
  123. // even if the string table is empty. However, lib.exe does not in fact
  124. // seem to create the third member if there's no member whose filename
  125. // exceeds 15 characters. So the third member is optional.
  126. if (name == "/") {
  127. SymbolTable = i;
  128. StringTable = e;
  129. if (i != e) ++i;
  130. if (i == e) {
  131. ec = object_error::parse_failed;
  132. return;
  133. }
  134. if ((ec = i->getName(name)))
  135. return;
  136. if (name[0] != '/') {
  137. Format = K_GNU;
  138. } else if ((name.size() > 1) && (name == "//")) {
  139. Format = K_GNU;
  140. StringTable = i;
  141. ++i;
  142. } else {
  143. Format = K_COFF;
  144. if (i != e) {
  145. SymbolTable = i;
  146. ++i;
  147. }
  148. if (i != e) {
  149. if ((ec = i->getName(name)))
  150. return;
  151. if (name == "//")
  152. StringTable = i;
  153. }
  154. }
  155. } else if (name == "__.SYMDEF") {
  156. Format = K_BSD;
  157. SymbolTable = i;
  158. StringTable = e;
  159. }
  160. ec = object_error::success;
  161. }
  162. Archive::child_iterator Archive::begin_children(bool skip_internal) const {
  163. const char *Loc = Data->getBufferStart() + strlen(Magic);
  164. size_t Size = sizeof(ArchiveMemberHeader) +
  165. ToHeader(Loc)->getSize();
  166. Child c(this, StringRef(Loc, Size));
  167. // Skip internals at the beginning of an archive.
  168. if (skip_internal && isInternalMember(*ToHeader(Loc)))
  169. return c.getNext();
  170. return c;
  171. }
  172. Archive::child_iterator Archive::end_children() const {
  173. return Child(this, StringRef(0, 0));
  174. }
  175. error_code Archive::Symbol::getName(StringRef &Result) const {
  176. Result = StringRef(Parent->SymbolTable->getBuffer().begin() + StringIndex);
  177. return object_error::success;
  178. }
  179. error_code Archive::Symbol::getMember(child_iterator &Result) const {
  180. const char *Buf = Parent->SymbolTable->getBuffer().begin();
  181. const char *Offsets = Buf + 4;
  182. uint32_t Offset = 0;
  183. if (Parent->kind() == K_GNU) {
  184. Offset = *(reinterpret_cast<const support::ubig32_t*>(Offsets)
  185. + SymbolIndex);
  186. } else if (Parent->kind() == K_BSD) {
  187. llvm_unreachable("BSD format is not supported");
  188. } else {
  189. uint32_t MemberCount = *reinterpret_cast<const support::ulittle32_t*>(Buf);
  190. // Skip offsets.
  191. Buf += sizeof(support::ulittle32_t)
  192. + (MemberCount * sizeof(support::ulittle32_t));
  193. uint32_t SymbolCount = *reinterpret_cast<const support::ulittle32_t*>(Buf);
  194. if (SymbolIndex >= SymbolCount)
  195. return object_error::parse_failed;
  196. // Skip SymbolCount to get to the indices table.
  197. const char *Indices = Buf + sizeof(support::ulittle32_t);
  198. // Get the index of the offset in the file member offset table for this
  199. // symbol.
  200. uint16_t OffsetIndex =
  201. *(reinterpret_cast<const support::ulittle16_t*>(Indices)
  202. + SymbolIndex);
  203. // Subtract 1 since OffsetIndex is 1 based.
  204. --OffsetIndex;
  205. if (OffsetIndex >= MemberCount)
  206. return object_error::parse_failed;
  207. Offset = *(reinterpret_cast<const support::ulittle32_t*>(Offsets)
  208. + OffsetIndex);
  209. }
  210. const char *Loc = Parent->getData().begin() + Offset;
  211. size_t Size = sizeof(ArchiveMemberHeader) +
  212. ToHeader(Loc)->getSize();
  213. Result = Child(Parent, StringRef(Loc, Size));
  214. return object_error::success;
  215. }
  216. Archive::Symbol Archive::Symbol::getNext() const {
  217. Symbol t(*this);
  218. // Go to one past next null.
  219. t.StringIndex =
  220. Parent->SymbolTable->getBuffer().find('\0', t.StringIndex) + 1;
  221. ++t.SymbolIndex;
  222. return t;
  223. }
  224. Archive::symbol_iterator Archive::begin_symbols() const {
  225. const char *buf = SymbolTable->getBuffer().begin();
  226. if (kind() == K_GNU) {
  227. uint32_t symbol_count = 0;
  228. symbol_count = *reinterpret_cast<const support::ubig32_t*>(buf);
  229. buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t)));
  230. } else if (kind() == K_BSD) {
  231. llvm_unreachable("BSD archive format is not supported");
  232. } else {
  233. uint32_t member_count = 0;
  234. uint32_t symbol_count = 0;
  235. member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
  236. buf += 4 + (member_count * 4); // Skip offsets.
  237. symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
  238. buf += 4 + (symbol_count * 2); // Skip indices.
  239. }
  240. uint32_t string_start_offset = buf - SymbolTable->getBuffer().begin();
  241. return symbol_iterator(Symbol(this, 0, string_start_offset));
  242. }
  243. Archive::symbol_iterator Archive::end_symbols() const {
  244. const char *buf = SymbolTable->getBuffer().begin();
  245. uint32_t symbol_count = 0;
  246. if (kind() == K_GNU) {
  247. symbol_count = *reinterpret_cast<const support::ubig32_t*>(buf);
  248. buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t)));
  249. } else if (kind() == K_BSD) {
  250. llvm_unreachable("BSD archive format is not supported");
  251. } else {
  252. uint32_t member_count = 0;
  253. member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
  254. buf += 4 + (member_count * 4); // Skip offsets.
  255. symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
  256. }
  257. return symbol_iterator(
  258. Symbol(this, symbol_count, 0));
  259. }
  260. Archive::child_iterator Archive::findSym(StringRef name) const {
  261. Archive::symbol_iterator bs = begin_symbols();
  262. Archive::symbol_iterator es = end_symbols();
  263. Archive::child_iterator result;
  264. StringRef symname;
  265. for (; bs != es; ++bs) {
  266. if (bs->getName(symname))
  267. return end_children();
  268. if (symname == name) {
  269. if (bs->getMember(result))
  270. return end_children();
  271. return result;
  272. }
  273. }
  274. return end_children();
  275. }