llvm.org GIT mirror llvm / e36c14f
This removes the eating of the error in Archive::Child::getSize() when the characters in the size field in the archive header for the member is not a number. To do this we have all of the needed methods return ErrorOr to push them up until we get out of lib. Then the tools and can handle the error in whatever way is appropriate for that tool. So the solution is to plumb all the ErrorOr stuff through everything that touches archives. This include its iterators as one can create an Archive object but the first or any other Child object may fail to be created due to a bad size field in its header. Thanks to Lang Hames on the changes making child_iterator contain an ErrorOr<Child> instead of a Child and the needed changes to ErrorOr.h to add operator overloading for * and -> . We don’t want to use llvm_unreachable() as it calls abort() and is produces a “crash” and using report_fatal_error() to move the error checking will cause the program to stop, neither of which are really correct in library code. There are still some uses of these that should be cleaned up in this library code for other than the size field. Also corrected the code where the size gets us to the “at the end of the archive” which is OK but past the end of the archive will return object_error::parse_failed now. The test cases use archives with text files so one can see the non-digit character, in this case a ‘%’, in the size field. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@250906 91177308-0d34-0410-b5e6-96231b3b80d8 Kevin Enderby 3 years ago
18 changed file(s) with 357 addition(s) and 100 deletion(s). Raw diff Collapse all Expand all
6464 bool isThinMember() const;
6565
6666 public:
67 Child(const Archive *Parent, const char *Start);
67 Child(const Archive *Parent, const char *Start,
68 std::error_code *EC);
69 static ErrorOr> create(const Archive *Parent,
70 const char *Start);
6871
6972 bool operator ==(const Child &other) const {
7073 assert(Parent == other.Parent);
7679 }
7780
7881 const Archive *getParent() const { return Parent; }
79 Child getNext() const;
82 ErrorOr getNext() const;
8083
8184 ErrorOr getName() const;
8285 StringRef getRawName() const { return getHeader()->getName(); }
9295 return getHeader()->getAccessMode();
9396 }
9497 /// \return the size of the archive member without the header or padding.
95 uint64_t getSize() const;
98 ErrorOr getSize() const;
9699 /// \return the size in the archive header for this member.
97 uint64_t getRawSize() const;
100 ErrorOr getRawSize() const;
98101
99102 ErrorOr getBuffer() const;
100103 uint64_t getChildOffset() const;
106109 };
107110
108111 class child_iterator {
109 Child child;
110
111 public:
112 child_iterator() : child(Child(nullptr, nullptr)) {}
112 ErrorOr child;
113
114 public:
115 child_iterator() : child(Child(nullptr, nullptr, nullptr)) {}
113116 child_iterator(const Child &c) : child(c) {}
114 const Child *operator->() const { return &child; }
115 const Child &operator*() const { return child; }
117 child_iterator(std::error_code EC) : child(EC) {}
118 const ErrorOr *operator->() const { return &child; }
119 const ErrorOr &operator*() const { return child; }
116120
117121 bool operator==(const child_iterator &other) const {
118 return child == other.child;
122 if ((*this)->getError())
123 return false;
124 if (other->getError())
125 return false;
126 return (*this)->get() == other->get();
119127 }
120128
121129 bool operator!=(const child_iterator &other) const {
122130 return !(*this == other);
123131 }
124132
125 bool operator<(const child_iterator &other) const {
126 return child < other.child;
127 }
128
133 // No operator< as we can't do less than compares with iterators that
134 // contain errors.
135
136 // Code in loops with child_iterators must check for errors on each loop
137 // iteration. And if there is an error break out of the loop.
129138 child_iterator &operator++() { // Preincrement
130 child = child.getNext();
139 assert(child && "Can't increment iterator with error");
140 child = child->getNext();
131141 return *this;
132142 }
133143 };
211221 StringRef getSymbolTable() const {
212222 // We know that the symbol table is not an external file,
213223 // so we just assert there is no error.
214 return *SymbolTable->getBuffer();
224 return *(*SymbolTable)->getBuffer();
215225 }
216226 uint32_t getNumberOfSymbols() const;
217227
9090 typedef typename std::remove_reference::type &reference;
9191 typedef const typename std::remove_reference::type &const_reference;
9292 typedef typename std::remove_reference::type *pointer;
93 typedef const typename std::remove_reference::type *const_pointer;
9394
9495 public:
9596 template
182183 return toPointer(getStorage());
183184 }
184185
186 const_pointer operator ->() const {
187 return toPointer(getStorage());
188 }
189
185190 reference operator *() {
191 return *getStorage();
192 }
193
194 const_reference operator *() const {
186195 return *getStorage();
187196 }
188197
245254 return Val;
246255 }
247256
257 const_pointer toPointer(const_pointer Val) const {
258 return Val;
259 }
260
248261 pointer toPointer(wrap *Val) {
249262 return &Val->get();
250263 }
264
265 const_pointer toPointer(const wrap *Val) const {
266 return &Val->get();
267 }
268
251269
252270 storage_type *getStorage() {
253271 assert(!HasError && "Cannot get value when an error exists!");
317317 object::Archive *A = OB.getBinary();
318318 // Look for our symbols in each Archive
319319 object::Archive::child_iterator ChildIt = A->findSym(Name);
320 if (ChildIt != A->child_end()) {
320 if (*ChildIt && ChildIt != A->child_end()) {
321321 // FIXME: Support nested archives?
322322 ErrorOr> ChildBinOrErr =
323 ChildIt->getAsBinary();
323 (*ChildIt)->getAsBinary();
324324 if (ChildBinOrErr.getError())
325325 continue;
326326 std::unique_ptr &ChildBin = ChildBinOrErr.get();
252252 object::Archive *A = OB.getBinary();
253253 // Look for our symbols in each Archive
254254 object::Archive::child_iterator ChildIt = A->findSym(Name);
255 if (ChildIt != A->child_end()) {
255 if (*ChildIt && ChildIt != A->child_end()) {
256256 // FIXME: Support nested archives?
257257 ErrorOr> ChildBinOrErr =
258 ChildIt->getAsBinary();
258 (*ChildIt)->getAsBinary();
259259 if (ChildBinOrErr.getError())
260260 continue;
261261 std::unique_ptr &ChildBin = ChildBinOrErr.get();
4545 ErrorOr ArchiveMemberHeader::getSize() const {
4646 uint32_t Ret;
4747 if (llvm::StringRef(Size, sizeof(Size)).rtrim(" ").getAsInteger(10, Ret))
48 return object_error::parse_failed;
48 return object_error::parse_failed; // Size is not a decimal number.
4949 return Ret;
5050 }
5151
8181 return Ret;
8282 }
8383
84 Archive::Child::Child(const Archive *Parent, const char *Start)
84 Archive::Child::Child(const Archive *Parent, const char *Start,
85 std::error_code *EC)
8586 : Parent(Parent) {
8687 if (!Start)
8788 return;
8990 uint64_t Size = sizeof(ArchiveMemberHeader);
9091 Data = StringRef(Start, Size);
9192 if (!isThinMember()) {
92 Size += getRawSize();
93 ErrorOr MemberSize = getRawSize();
94 if (MemberSize.getError()) {
95 assert (EC && "Error must be caught");
96 *EC = MemberSize.getError();
97 return;
98 }
99 Size += MemberSize.get();
93100 Data = StringRef(Start, Size);
94101 }
95102
99106 StringRef Name = getRawName();
100107 if (Name.startswith("#1/")) {
101108 uint64_t NameSize;
102 if (Name.substr(3).rtrim(" ").getAsInteger(10, NameSize))
103 llvm_unreachable("Long name length is not an integer");
109 if (Name.substr(3).rtrim(" ").getAsInteger(10, NameSize)) {
110 if (EC)
111 *EC = object_error::parse_failed; // Long name offset is not an integer.
112 return;
113 }
104114 StartOfFile += NameSize;
105115 }
106116 }
107117
108 uint64_t Archive::Child::getSize() const {
118 ErrorOr> Archive::Child::create(
119 const Archive *Parent, const char *Start) {
120 std::error_code EC;
121 std::unique_ptr Ret(new Archive::Child(Parent, Start, &EC));
122 if (EC)
123 return EC;
124 return std::move(Ret);
125 }
126
127 ErrorOr Archive::Child::getSize() const {
109128 if (Parent->IsThin) {
110129 ErrorOr Size = getHeader()->getSize();
111 if (Size.getError())
112 return 0;
130 if (std::error_code EC = Size.getError())
131 return EC;
113132 return Size.get();
114133 }
115134 return Data.size() - StartOfFile;
116135 }
117136
118 uint64_t Archive::Child::getRawSize() const {
137 ErrorOr Archive::Child::getRawSize() const {
119138 ErrorOr Size = getHeader()->getSize();
120 if (Size.getError())
121 return 0;
139 if (std::error_code EC = Size.getError())
140 return EC;
122141 return Size.get();
123142 }
124143
128147 }
129148
130149 ErrorOr Archive::Child::getBuffer() const {
131 if (!isThinMember())
132 return StringRef(Data.data() + StartOfFile, getSize());
150 if (!isThinMember()) {
151 ErrorOr Size = getSize();
152 if (std::error_code EC = Size.getError())
153 return EC;
154 return StringRef(Data.data() + StartOfFile, Size.get());
155 }
133156 ErrorOr Name = getName();
134157 if (std::error_code EC = Name.getError())
135158 return EC;
143166 return Parent->ThinBuffers.back()->getBuffer();
144167 }
145168
146 Archive::Child Archive::Child::getNext() const {
169 ErrorOr Archive::Child::getNext() const {
147170 size_t SpaceToSkip = Data.size();
148171 // If it's odd, add 1 to make it even.
172 size_t Pad = 0;
149173 if (SpaceToSkip & 1)
150 ++SpaceToSkip;
151
152 const char *NextLoc = Data.data() + SpaceToSkip;
174 Pad++;
175
176 const char *NextLoc = Data.data() + SpaceToSkip + Pad;
177
178 // Check to see if this is at the end of the archive.
179 if (NextLoc == Parent->Data.getBufferEnd() ||
180 NextLoc == Parent->Data.getBufferEnd() - Pad )
181 return Child(Parent, nullptr, nullptr);
153182
154183 // Check to see if this is past the end of the archive.
155 if (NextLoc >= Parent->Data.getBufferEnd())
156 return Child(Parent, nullptr);
157
158 return Child(Parent, NextLoc);
184 if (NextLoc > Parent->Data.getBufferEnd())
185 return object_error::parse_failed;
186
187 auto ChildOrErr = Child::create(Parent, NextLoc);
188 if (std::error_code EC = ChildOrErr.getError())
189 return EC;
190 return std::move(*ChildOrErr.get());
159191 }
160192
161193 uint64_t Archive::Child::getChildOffset() const {
177209 // Get the offset.
178210 std::size_t offset;
179211 if (name.substr(1).rtrim(" ").getAsInteger(10, offset))
180 llvm_unreachable("Long name offset is not an integer");
181 const char *addr = Parent->StringTable->Data.begin()
212 return object_error::parse_failed; // Long name offset is not an integer.
213 // Check for bad stringtable iterator.
214 if (std::error_code EC = Parent->StringTable->getError())
215 return EC;
216 const char *addr = (*Parent->StringTable)->Data.begin()
182217 + sizeof(ArchiveMemberHeader)
183218 + offset;
184219 // Verify it.
220 auto Size = (*Parent->StringTable)->getSize();
221 if (std::error_code EC = Size.getError())
222 return EC;
185223 if (Parent->StringTable == Parent->child_end()
186 || addr < (Parent->StringTable->Data.begin()
224 || addr < ((*Parent->StringTable)->Data.begin()
187225 + sizeof(ArchiveMemberHeader))
188 || addr > (Parent->StringTable->Data.begin()
226 || addr > ((*Parent->StringTable)->Data.begin()
189227 + sizeof(ArchiveMemberHeader)
190 + Parent->StringTable->getSize()))
228 + Size.get()))
191229 return object_error::parse_failed;
192230
193231 // GNU long file names end with a "/\n".
199237 } else if (name.startswith("#1/")) {
200238 uint64_t name_size;
201239 if (name.substr(3).rtrim(" ").getAsInteger(10, name_size))
202 llvm_unreachable("Long name length is not an ingeter");
240 return object_error::parse_failed; // Long name offset is not an integer.
203241 return Data.substr(sizeof(ArchiveMemberHeader), name_size)
204242 .rtrim(StringRef("\0", 1));
205243 }
255293 child_iterator i = child_begin(false);
256294 child_iterator e = child_end();
257295
258 if (i == e) {
259 ec = std::error_code();
260 return;
261 }
262
263 StringRef Name = i->getRawName();
296 if (!*i || i == e) {
297 ec = i->getError();
298 return;
299 }
300
301 StringRef Name = (*i)->getRawName();
264302
265303 // Below is the pattern that is used to figure out the archive format
266304 // GNU archive format
285323 Format = K_BSD;
286324 SymbolTable = i;
287325 ++i;
326 if (!*i) {
327 ec = i->getError();
328 return;
329 }
330
288331 FirstRegular = i;
289332 ec = std::error_code();
290333 return;
293336 if (Name.startswith("#1/")) {
294337 Format = K_BSD;
295338 // We know this is BSD, so getName will work since there is no string table.
296 ErrorOr NameOrErr = i->getName();
339 ErrorOr NameOrErr = (*i)->getName();
297340 ec = NameOrErr.getError();
298341 if (ec)
299342 return;
301344 if (Name == "__.SYMDEF SORTED" || Name == "__.SYMDEF") {
302345 SymbolTable = i;
303346 ++i;
347 if (!*i) {
348 ec = i->getError();
349 return;
350 }
304351 }
305352 FirstRegular = i;
306353 return;
318365 has64SymTable = true;
319366
320367 ++i;
321 if (i == e) {
322 ec = std::error_code();
368 if (!*i || i == e) {
369 ec = i->getError();
323370 return;
324371 }
325 Name = i->getRawName();
372 Name = (*i)->getRawName();
326373 }
327374
328375 if (Name == "//") {
329376 Format = has64SymTable ? K_MIPS64 : K_GNU;
330377 StringTable = i;
331378 ++i;
379 if (!*i) {
380 ec = i->getError();
381 return;
382 }
332383 FirstRegular = i;
333384 ec = std::error_code();
334385 return;
350401 SymbolTable = i;
351402
352403 ++i;
404 if (!*i) {
405 ec = i->getError();
406 return;
407 }
353408 if (i == e) {
354409 FirstRegular = i;
355410 ec = std::error_code();
356411 return;
357412 }
358413
359 Name = i->getRawName();
414 Name = (*i)->getRawName();
360415
361416 if (Name == "//") {
362417 StringTable = i;
363418 ++i;
419 if (!*i) {
420 ec = i->getError();
421 return;
422 }
364423 }
365424
366425 FirstRegular = i;
375434 return FirstRegular;
376435
377436 const char *Loc = Data.getBufferStart() + strlen(Magic);
378 Child c(this, Loc);
379 return c;
437 auto ChildOrErr = Child::create(this, Loc);
438 if (std::error_code EC = ChildOrErr.getError())
439 return child_iterator(EC);
440 Child c = *(ChildOrErr.get());
441 return child_iterator(c);
380442 }
381443
382444 Archive::child_iterator Archive::child_end() const {
383 return Child(this, nullptr);
445 // This with a second argument of nullptr can't return an Error.
446 auto ChildOrErr = Child::create(this, nullptr);
447 if (ChildOrErr.getError())
448 llvm_unreachable("Can't create Archive::child_end().");
449 Child c = *(ChildOrErr.get());
450 return child_iterator(c);
384451 }
385452
386453 StringRef Archive::Symbol::getName() const {
432499 }
433500
434501 const char *Loc = Parent->getData().begin() + Offset;
435 child_iterator Iter(Child(Parent, Loc));
502 auto ChildOrErr = Child::create(Parent, Loc);
503 if (std::error_code EC = ChildOrErr.getError())
504 return EC;
505 child_iterator Iter(std::move(*ChildOrErr.get()));
436506 return Iter;
437507 }
438508
346346 MemberRef = Buffers.back()->getMemBufferRef();
347347 } else {
348348 object::Archive::child_iterator OldMember = Member.getOld();
349 assert((!Thin || OldMember->getParent()->isThin()) &&
349 assert((!Thin || (*OldMember && (*OldMember)->getParent()->isThin())) &&
350350 "Thin archives cannot refers to member of other archives");
351351 ErrorOr MemberBufferOrErr =
352 OldMember->getMemoryBufferRef();
352 (*OldMember)->getMemoryBufferRef();
353353 if (auto EC = MemberBufferOrErr.getError())
354354 return std::make_pair("", EC);
355355 MemberRef = MemberBufferOrErr.get();
397397 Perms = Status.permissions();
398398 } else {
399399 object::Archive::child_iterator OldMember = I.getOld();
400 ModTime = OldMember->getLastModified();
401 UID = OldMember->getUID();
402 GID = OldMember->getGID();
403 Perms = OldMember->getAccessMode();
400 ModTime = (*OldMember)->getLastModified();
401 UID = (*OldMember)->getUID();
402 GID = (*OldMember)->getGID();
403 Perms = (*OldMember)->getAccessMode();
404404 }
405405
406406 if (I.isNewMember()) {
411411 Status.getSize());
412412 } else {
413413 object::Archive::child_iterator OldMember = I.getOld();
414 ErrorOr Size = (*OldMember)->getSize();
415 if (std::error_code EC = Size.getError())
416 return std::make_pair("", EC);
414417 printMemberHeader(Out, Kind, Thin, I.getName(), StringMapIndexIter,
415 ModTime, UID, GID, Perms, OldMember->getSize());
418 ModTime, UID, GID, Perms, Size.get());
416419 }
417420
418421 if (!Thin)
0 !
1 hello.c 1444941273 124 0 100644 10% `
2 #include
3 #include
4 int
5 main()
6 {
7 printf("Hello World\n");
8 return EXIT_SUCCESS;
9 }
10 foo.c 1444941645 124 0 100644 1% `
11 void foo(void){}
12
0 !
1 hello.c 1444941273 124 0 100644 102 `
2 #include
3 #include
4 int
5 main()
6 {
7 printf("Hello World\n");
8 return EXIT_SUCCESS;
9 }
10 foo.c 1444941645 124 0 100644 1% `
11 void foo(void){}
12
0 !
1 hello.c 1444941273 124 0 100644 102 `
2 #include
3 #include
4 int
5 main()
6 {
7 printf("Hello World\n");
8 return EXIT_SUCCESS;
9 }
10 foo.c 1444941645 124 0 100644 171 `
11 void foo(void){}
12
13 bar.c 1445026190 124 0 100644 17 `
14 void foo(void){}
15
0 // These test checks that llvm-objdump will not crash with malformed Archive
1 // files. So the check line is not all that important but the bug fixes to
2 // make sure llvm-objdump is robust is what matters.
3 # RUN: llvm-objdump -macho -archive-headers \
4 # RUN: %p/Inputs/malformed-archives/libbogus1.a \
5 # RUN: 2>&1 | FileCheck -check-prefix=bogus1 %s
6
7 # bogus1: Invalid data was encountered while parsing the file
8
9 # RUN: llvm-objdump -macho -archive-headers \
10 # RUN: %p/Inputs/malformed-archives/libbogus2.a \
11 # RUN: 2>&1 | FileCheck -check-prefix=bogus2 %s
12
13 # bogus2: hello.c
14
15 # RUN: llvm-objdump -macho -archive-headers \
16 # RUN: %p/Inputs/malformed-archives/libbogus3.a \
17 # RUN: 2>&1 | FileCheck -check-prefix=bogus3 %s
18
19 # bogus3: foo.c
108108 Buffers.reserve(CurrentArchives.size());
109109
110110 for (const auto &CurrentArchive : CurrentArchives) {
111 for (const auto &Child : CurrentArchive->children()) {
111 for (auto ChildOrErr : CurrentArchive->children()) {
112 if (auto Err = ChildOrErr.getError())
113 return Err;
114 const auto &Child = *ChildOrErr;
112115 if (auto NameOrErr = Child.getName()) {
113116 if (*NameOrErr == Filename) {
114117 if (Timestamp != sys::TimeValue::PosixZeroTime() &&
337337 printMode(Mode & 007);
338338 outs() << ' ' << C.getUID();
339339 outs() << '/' << C.getGID();
340 outs() << ' ' << format("%6llu", C.getSize());
340 ErrorOr Size = C.getSize();
341 if (Size.getError())
342 outs() << ' ' << "bad size";
343 else
344 outs() << ' ' << format("%6llu", Size.get());
341345 outs() << ' ' << C.getLastModified().str();
342346 outs() << ' ';
343347 }
402406 }
403407
404408 bool Filter = !Members.empty();
405 for (const object::Archive::Child &C : OldArchive->children()) {
409 for (auto &ChildOrErr : OldArchive->children()) {
410 if (ChildOrErr.getError()) {
411 errs() << ToolName << ": error reading '" << ArchiveName
412 << "': " << ChildOrErr.getError().message() << "!\n";
413 return;
414 }
415 const object::Archive::Child &C = *ChildOrErr;
416
406417 ErrorOr NameOrErr = C.getName();
407418 failIfError(NameOrErr.getError());
408419 StringRef Name = NameOrErr.get();
447458 void addMember(std::vector &Members,
448459 object::Archive::child_iterator I, StringRef Name,
449460 int Pos = -1) {
450 if (Thin && !I->getParent()->isThin())
461 if (I->getError())
462 fail("New member is not valid: " + I->getError().message());
463 if (Thin && !(*I)->getParent()->isThin())
451464 fail("Cannot convert a regular archive to a thin one");
452465 NewArchiveIterator NI(I, Name);
453466 if (Pos == -1)
468481 object::Archive::child_iterator I,
469482 StringRef Name,
470483 std::vector::iterator &Pos) {
484 if (I->getError())
485 fail("Invalid member: " + I->getError().message());
486
471487 if (Operation == QuickAppend || Members.empty())
472488 return IA_AddOldMember;
473489
499515 // operation.
500516 sys::fs::file_status Status;
501517 failIfError(sys::fs::status(*MI, Status), *MI);
502 if (Status.getLastModificationTime() < I->getLastModified()) {
518 if (Status.getLastModificationTime() < (*I)->getLastModified()) {
503519 if (PosName.empty())
504520 return IA_AddOldMember;
505521 return IA_MoveOldMember;
522538 int InsertPos = -1;
523539 StringRef PosName = sys::path::filename(RelPos);
524540 if (OldArchive) {
525 for (auto &Child : OldArchive->children()) {
541 for (auto &ChildOrErr : OldArchive->children()) {
542 failIfError(ChildOrErr.getError());
543 auto &Child = ChildOrErr.get();
526544 int Pos = Ret.size();
527545 ErrorOr NameOrErr = Child.getName();
528546 failIfError(NameOrErr.getError());
725743 failIfError(LibOrErr.getError(), "Could not parse library");
726744 Archives.push_back(std::move(*LibOrErr));
727745 object::Archive &Lib = *Archives.back();
728 for (auto &Member : Lib.children()) {
746 for (auto &MemberOrErr : Lib.children()) {
747 failIfError(MemberOrErr.getError());
748 auto &Member = MemberOrErr.get();
729749 ErrorOr NameOrErr = Member.getName();
730750 failIfError(NameOrErr.getError());
731751 addMember(NewMembers, Member, *NameOrErr);
481481 }
482482
483483 static void dumpArchive(const Archive *Arc) {
484 for (const Archive::Child &ArcC : Arc->children()) {
484 for (auto &ErrorOrChild : Arc->children()) {
485 if (std::error_code EC = ErrorOrChild.getError()) {
486 reportError(Arc->getFileName(), EC.message());
487 break;
488 }
489 const Archive::Child &ArcC = *ErrorOrChild;
485490 ErrorOr> ChildOrErr = ArcC.getAsBinary();
486491 if (std::error_code EC = ChildOrErr.getError()) {
487492 // Ignore non-object files.
944944 if (I != E) {
945945 outs() << "Archive map\n";
946946 for (; I != E; ++I) {
947 ErrorOr C = I->getMember();
948 if (error(C.getError()))
947 ErrorOr ErrorOrChild = I->getMember();
948 if (error(ErrorOrChild.getError()))
949949 return;
950 ErrorOr FileNameOrErr = C.get()->getName();
950 auto &C = *(ErrorOrChild.get());
951 ErrorOr FileNameOrErr = C.get().getName();
951952 if (error(FileNameOrErr.getError()))
952953 return;
953954 StringRef SymName = I->getName();
959960
960961 for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
961962 I != E; ++I) {
962 ErrorOr> ChildOrErr = I->getAsBinary(&Context);
963 if (I->getError())
964 break;
965 auto &C = I->get();
966 ErrorOr> ChildOrErr = C.getAsBinary(&Context);
963967 if (ChildOrErr.getError())
964968 continue;
965969 if (SymbolicFile *O = dyn_cast(&*ChildOrErr.get())) {
10141018 for (Archive::child_iterator AI = A->child_begin(),
10151019 AE = A->child_end();
10161020 AI != AE; ++AI) {
1021 if(AI->getError())
1022 break;
1023 auto &C = AI->get();
10171024 ErrorOr> ChildOrErr =
1018 AI->getAsBinary(&Context);
1025 C.getAsBinary(&Context);
10191026 if (ChildOrErr.getError())
10201027 continue;
10211028 if (SymbolicFile *O =
10681075 for (Archive::child_iterator AI = A->child_begin(),
10691076 AE = A->child_end();
10701077 AI != AE; ++AI) {
1078 if(AI->getError())
1079 break;
1080 auto &C = AI->get();
10711081 ErrorOr> ChildOrErr =
1072 AI->getAsBinary(&Context);
1082 C.getAsBinary(&Context);
10731083 if (ChildOrErr.getError())
10741084 continue;
10751085 if (SymbolicFile *O =
11171127 std::unique_ptr &A = *AOrErr;
11181128 for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
11191129 AI != AE; ++AI) {
1130 if(AI->getError())
1131 continue;
1132 auto &C = AI->get();
11201133 ErrorOr> ChildOrErr =
1121 AI->getAsBinary(&Context);
1134 C.getAsBinary(&Context);
11221135 if (ChildOrErr.getError())
11231136 continue;
11241137 if (SymbolicFile *O = dyn_cast(&*ChildOrErr.get())) {
14161416 outs() << format("%3d/", UID);
14171417 unsigned GID = C.getGID();
14181418 outs() << format("%-3d ", GID);
1419 uint64_t Size = C.getRawSize();
1420 outs() << format("%5" PRId64, Size) << " ";
1419 ErrorOr Size = C.getRawSize();
1420 if (Size.getError())
1421 outs() << "bad size" << " ";
1422 else
1423 outs() << format("%5" PRId64, Size.get()) << " ";
14211424
14221425 StringRef RawLastModified = C.getRawLastModified();
14231426 if (verbose) {
14531456 static void printArchiveHeaders(Archive *A, bool verbose, bool print_offset) {
14541457 if (A->hasSymbolTable()) {
14551458 Archive::child_iterator S = A->getSymbolTableChild();
1456 Archive::Child C = *S;
1457 printArchiveChild(C, verbose, print_offset);
1459 if (!S->getError()) {
1460 Archive::Child C = S->get();
1461 printArchiveChild(C, verbose, print_offset);
1462 }
14581463 }
14591464 for (Archive::child_iterator I = A->child_begin(), E = A->child_end(); I != E;
14601465 ++I) {
1461 Archive::Child C = *I;
1466 if(I->getError())
1467 break;
1468 Archive::Child C = I->get();
14621469 printArchiveChild(C, verbose, print_offset);
14631470 }
14641471 }
14951502 printArchiveHeaders(A, !NonVerbose, ArchiveMemberOffsets);
14961503 for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
14971504 I != E; ++I) {
1498 ErrorOr> ChildOrErr = I->getAsBinary();
1505 if (I->getError())
1506 break;
1507 auto &C = I->get();
1508 ErrorOr> ChildOrErr = C.getAsBinary();
14991509 if (ChildOrErr.getError())
15001510 continue;
15011511 if (MachOObjectFile *O = dyn_cast(&*ChildOrErr.get())) {
15431553 for (Archive::child_iterator AI = A->child_begin(),
15441554 AE = A->child_end();
15451555 AI != AE; ++AI) {
1546 ErrorOr> ChildOrErr = AI->getAsBinary();
1556 if (AI->getError())
1557 break;
1558 auto &C = AI->get();
1559 ErrorOr> ChildOrErr = C.getAsBinary();
15471560 if (ChildOrErr.getError())
15481561 continue;
15491562 if (MachOObjectFile *O =
15851598 for (Archive::child_iterator AI = A->child_begin(),
15861599 AE = A->child_end();
15871600 AI != AE; ++AI) {
1588 ErrorOr> ChildOrErr = AI->getAsBinary();
1601 if (AI->getError())
1602 break;
1603 auto &C = AI->get();
1604 ErrorOr> ChildOrErr = C.getAsBinary();
15891605 if (ChildOrErr.getError())
15901606 continue;
15911607 if (MachOObjectFile *O =
16211637 printArchiveHeaders(A.get(), !NonVerbose, ArchiveMemberOffsets);
16221638 for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
16231639 AI != AE; ++AI) {
1624 ErrorOr> ChildOrErr = AI->getAsBinary();
1640 if (AI->getError())
1641 break;
1642 auto &C = AI->get();
1643 ErrorOr> ChildOrErr = C.getAsBinary();
16251644 if (ChildOrErr.getError())
16261645 continue;
16271646 if (MachOObjectFile *O =
15351535
15361536 /// @brief Dump each object file in \a a;
15371537 static void DumpArchive(const Archive *a) {
1538 for (const Archive::Child &C : a->children()) {
1538 for (auto &ErrorOrChild : a->children()) {
1539 if (std::error_code EC = ErrorOrChild.getError()) {
1540 report_error(a->getFileName(), EC);
1541 break;
1542 }
1543 const Archive::Child &C = *ErrorOrChild;
15391544 ErrorOr> ChildOrErr = C.getAsBinary();
15401545 if (std::error_code EC = ChildOrErr.getError())
15411546 if (EC != object_error::invalid_file_type)
376376
377377 /// @brief Dumps each object file in \a Arc;
378378 static void dumpArchive(const Archive *Arc) {
379 for (const auto &Child : Arc->children()) {
379 for (auto &ErrorOrChild : Arc->children()) {
380 if (std::error_code EC = ErrorOrChild.getError()) {
381 reportError(Arc->getFileName(), EC.message());
382 break;
383 }
384 const auto &Child = *ErrorOrChild;
380385 ErrorOr> ChildOrErr = Child.getAsBinary();
381386 if (std::error_code EC = ChildOrErr.getError()) {
382387 // Ignore non-object files.
426426 for (object::Archive::child_iterator i = a->child_begin(),
427427 e = a->child_end();
428428 i != e; ++i) {
429 ErrorOr> ChildOrErr = i->getAsBinary();
429 if (i->getError()) {
430 errs() << ToolName << ": " << file << ": " << i->getError().message()
431 << ".\n";
432 break;
433 }
434 auto &c = i->get();
435 ErrorOr> ChildOrErr = c.getAsBinary();
430436 if (std::error_code EC = ChildOrErr.getError()) {
431437 errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
432438 continue;
488494 for (object::Archive::child_iterator i = UA->child_begin(),
489495 e = UA->child_end();
490496 i != e; ++i) {
491 ErrorOr> ChildOrErr = i->getAsBinary();
497 if (std::error_code EC = i->getError()) {
498 errs() << ToolName << ": " << file << ": " << EC.message()
499 << ".\n";
500 break;
501 }
502 auto &c = i->get();
503 ErrorOr> ChildOrErr = c.getAsBinary();
492504 if (std::error_code EC = ChildOrErr.getError()) {
493505 errs() << ToolName << ": " << file << ": " << EC.message()
494506 << ".\n";
565577 for (object::Archive::child_iterator i = UA->child_begin(),
566578 e = UA->child_end();
567579 i != e; ++i) {
568 ErrorOr> ChildOrErr = i->getAsBinary();
580 if (std::error_code EC = i->getError()) {
581 errs() << ToolName << ": " << file << ": " << EC.message()
582 << ".\n";
583 break;
584 }
585 auto &c = i->get();
586 ErrorOr> ChildOrErr = c.getAsBinary();
569587 if (std::error_code EC = ChildOrErr.getError()) {
570588 errs() << ToolName << ": " << file << ": " << EC.message()
571589 << ".\n";
629647 for (object::Archive::child_iterator i = UA->child_begin(),
630648 e = UA->child_end();
631649 i != e; ++i) {
632 ErrorOr> ChildOrErr = i->getAsBinary();
650 if (std::error_code EC = i->getError()) {
651 errs() << ToolName << ": " << file << ": " << EC.message()
652 << ".\n";
653 break;
654 }
655 auto &c = i->get();
656 ErrorOr> ChildOrErr = c.getAsBinary();
633657 if (std::error_code EC = ChildOrErr.getError()) {
634658 errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
635659 continue;