llvm.org GIT mirror llvm / 96b7967
Start adding thin archive support. This is just sufficient for 'ar t' to work. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@224307 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 5 years ago
4 changed file(s) with 29 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
8383 return getHeader()->getAccessMode();
8484 }
8585 /// \return the size of the archive member without the header or padding.
86 uint64_t getSize() const { return Data.size() - StartOfFile; }
86 uint64_t getSize() const;
8787
8888 StringRef getBuffer() const {
8989 return StringRef(Data.data() + StartOfFile, getSize());
172172 K_COFF
173173 };
174174
175 Kind kind() const {
176 return Format;
177 }
175 Kind kind() const { return (Kind)Format; }
178176
179177 child_iterator child_begin(bool SkipInternal = true) const;
180178 child_iterator child_end() const;
200198 child_iterator SymbolTable;
201199 child_iterator StringTable;
202200 child_iterator FirstRegular;
203 Kind Format;
201 unsigned Format : 2;
202 unsigned IsThin : 1;
204203 };
205204
206205 }
2121 using namespace object;
2222
2323 static const char *const Magic = "!\n";
24 static const char *const ThinMagic = "!\n";
2425
2526 void Archive::anchor() { }
2627
8586
8687 const ArchiveMemberHeader *Header =
8788 reinterpret_cast(Start);
88 Data = StringRef(Start, sizeof(ArchiveMemberHeader) + Header->getSize());
89 uint64_t Size = sizeof(ArchiveMemberHeader);
90 if (!Parent->IsThin || Header->getName() == "/" || Header->getName() == "//")
91 Size += Header->getSize();
92 Data = StringRef(Start, Size);
8993
9094 // Setup StartOfFile and PaddingBytes.
9195 StartOfFile = sizeof(ArchiveMemberHeader);
97101 llvm_unreachable("Long name length is not an integer");
98102 StartOfFile += NameSize;
99103 }
104 }
105
106 uint64_t Archive::Child::getSize() const {
107 if (Parent->IsThin)
108 return getHeader()->getSize();
109 return Data.size() - StartOfFile;
100110 }
101111
102112 Archive::Child Archive::Child::getNext() const {
185195
186196 Archive::Archive(MemoryBufferRef Source, std::error_code &ec)
187197 : Binary(Binary::ID_Archive, Source), SymbolTable(child_end()) {
198 StringRef Buffer = Data.getBuffer();
188199 // Check for sufficient magic.
189 if (Data.getBufferSize() < 8 ||
190 StringRef(Data.getBufferStart(), 8) != Magic) {
200 if (Buffer.startswith(ThinMagic)) {
201 IsThin = true;
202 } else if (Buffer.startswith(Magic)) {
203 IsThin = false;
204 } else {
191205 ec = object_error::invalid_file_type;
192206 return;
193207 }
Binary diff not shown
2525 CHECK-NEXT: rw-r--r-- 1002/102 7 2004-11-19 03:24:02.000000000 oddlen
2626 CHECK-NEXT: rwxr-xr-x 1002/102 1465 2004-11-19 03:24:02.000000000 very_long_bytecode_file_name.bc
2727 CHECK-NEXT: rw-r--r-- 1002/102 2280 2004-11-19 03:24:02.000000000 IsNAN.o
28
29 Test reading a thin archive created by gnu ar
30 RUN: env TZ=GMT llvm-ar tv %p/Inputs/thin.a | FileCheck %s --check-prefix=THIN -strict-whitespace
31
32 THIN: rw-r--r-- 1000/1000 8 2014-12-16 00:56:27.000000000 evenlen
33 THIN-NEXT: rw-r--r-- 1000/1000 7 2014-12-16 00:56:27.000000000 oddlen
34 THIN-NEXT: rwxr-xr-x 1000/1000 1465 2014-12-16 00:56:27.000000000 very_long_bytecode_file_name.bc
35 THIN-NEXT: rw-r--r-- 1000/1000 2280 2014-12-16 00:56:27.000000000 IsNAN.o