llvm.org GIT mirror llvm / 2a71517
The next step along the way to getting good error messages for bad archives. As mentioned in commit log for r276686 this next step is adding a new method in the ArchiveMemberHeader class to get the full name that does proper error checking, and can be use for error messages. To do this the name of ArchiveMemberHeader::getName() is changed to ArchiveMemberHeader::getRawName() to be consistent with Archive::Child::getRawName(). Then the “new” method is the addition of a new implementation of ArchiveMemberHeader::getName() which gets the full name and provides proper error checking. Which is mostly a rewrite of what was Archive::Child::getName() and cleaning up incorrect uses of llvm_unreachable() in the code which were actually just cases of errors in the input Archives. Then Archive::Child::getName() is changed to return Expected<> and use the new implementation of ArchiveMemberHeader::getName() . Also needed to change Archive::getMemoryBufferRef() with these changes to return Expected<> as well to propagate Errors up. As well as changing Archive::isThinMember() to return Expected<> . git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277177 91177308-0d34-0410-b5e6-96231b3b80d8 Kevin Enderby 3 years ago
15 changed file(s) with 358 addition(s) and 124 deletion(s). Raw diff Collapse all Expand all
3535 // ArchiveMemberHeader() = default;
3636
3737 /// Get the name without looking up long names.
38 llvm::StringRef getName() const;
38 Expected getRawName() const;
39
40 /// Get the name looking up long names.
41 Expected getName(uint64_t Size) const;
3942
4043 /// Members are not larger than 4GB.
4144 Expected getSize() const;
8184 /// \brief Offset from Data to the start of the file.
8285 uint16_t StartOfFile;
8386
84 bool isThinMember() const;
87 Expected isThinMember() const;
8588
8689 public:
8790 Child(const Archive *Parent, const char *Start, Error *Err);
9598 const Archive *getParent() const { return Parent; }
9699 Expected getNext() const;
97100
98 ErrorOr getName() const;
101 Expected getName() const;
99102 ErrorOr getFullName() const;
100 StringRef getRawName() const { return Header.getName(); }
103 Expected getRawName() const { return Header.getRawName(); }
101104 sys::TimeValue getLastModified() const {
102105 return Header.getLastModified();
103106 }
117120 ErrorOr getBuffer() const;
118121 uint64_t getChildOffset() const;
119122
120 ErrorOr getMemoryBufferRef() const;
123 Expected getMemoryBufferRef() const;
121124
122125 Expected>
123126 getAsBinary(LLVMContext *Context = nullptr) const;
237240
238241 bool hasSymbolTable() const;
239242 StringRef getSymbolTable() const { return SymbolTable; }
243 StringRef getStringTable() const { return StringTable; }
240244 uint32_t getNumberOfSymbols() const;
241245
242246 std::vector> takeThinBuffers() {
4242 return;
4343 ErrorAsOutParameter ErrAsOutParam(Err);
4444
45 // TODO: For errors messages with the ArchiveMemberHeader class use the
46 // archive member name instead of the the offset to the archive member header.
47 // When there is also error getting the member name then use the offset to
48 // the member in the message.
49
5045 if (Size < sizeof(ArMemHdrType)) {
5146 if (Err) {
52 uint64_t Offset = RawHeaderPtr - Parent->getData().data();
53 *Err = malformedError("remaining size of archive too small for next "
54 "archive member header at offset " +
55 Twine(Offset));
47 Twine Msg("remaining size of archive too small for next archive member "
48 "header ");
49 Expected NameOrErr = getName(Size);
50 if (!NameOrErr) {
51 consumeError(NameOrErr.takeError());
52 uint64_t Offset = RawHeaderPtr - Parent->getData().data();
53 *Err = malformedError(Msg + "at offset " + Twine(Offset));
54 } else
55 *Err = malformedError(Msg + "for " + Twine(NameOrErr.get()));
5656 }
5757 return;
5858 }
6363 OS.write_escaped(llvm::StringRef(ArMemHdr->Terminator,
6464 sizeof(ArMemHdr->Terminator)));
6565 OS.flush();
66 uint64_t Offset = RawHeaderPtr - Parent->getData().data();
67 *Err = malformedError("terminator characters in archive member \"" + Buf +
68 "\" not the correct \"`\\n\" values for the "
69 "archive member header at offset " + Twine(Offset));
70 }
71 return;
72 }
73 }
74
75 StringRef ArchiveMemberHeader::getName() const {
66 Twine Msg("terminator characters in archive member \"" + Buf + "\" not "
67 "the correct \"`\\n\" values for the archive member header ");
68 Expected NameOrErr = getName(Size);
69 if (!NameOrErr) {
70 consumeError(NameOrErr.takeError());
71 uint64_t Offset = RawHeaderPtr - Parent->getData().data();
72 *Err = malformedError(Msg + "at offset " + Twine(Offset));
73 } else
74 *Err = malformedError(Msg + "for " + Twine(NameOrErr.get()));
75 }
76 return;
77 }
78 }
79
80 // This gets the raw name from the ArMemHdr->Name field and checks that it is
81 // valid for the kind of archive. If it is not valid it returns an Error.
82 Expected ArchiveMemberHeader::getRawName() const {
7683 char EndCond;
77 if (ArMemHdr->Name[0] == '/' || ArMemHdr->Name[0] == '#')
84 auto Kind = Parent->kind();
85 if (Kind == Archive::K_BSD || Kind == Archive::K_DARWIN64) {
86 if (ArMemHdr->Name[0] == ' ') {
87 uint64_t Offset = reinterpret_cast(ArMemHdr) -
88 Parent->getData().data();
89 return malformedError("name contains a leading space for archive member "
90 "header at offset " + Twine(Offset));
91 }
92 EndCond = ' ';
93 }
94 else if (ArMemHdr->Name[0] == '/' || ArMemHdr->Name[0] == '#')
7895 EndCond = ' ';
7996 else
8097 EndCond = '/';
85102 assert(end <= sizeof(ArMemHdr->Name) && end > 0);
86103 // Don't include the EndCond if there is one.
87104 return llvm::StringRef(ArMemHdr->Name, end);
105 }
106
107 // This gets the name looking up long names. Size is the size of the archive
108 // member including the header, so the size of any name following the header
109 // is checked to make sure it does not overflow.
110 Expected ArchiveMemberHeader::getName(uint64_t Size) const {
111
112 // This can be called from the ArchiveMemberHeader constructor when the
113 // archive header is truncated to produce an error message with the name.
114 // Make sure the name field is not truncated.
115 if (Size < offsetof(ArMemHdrType, Name) + sizeof(ArMemHdr->Name)) {
116 uint64_t ArchiveOffset = reinterpret_cast(ArMemHdr) -
117 Parent->getData().data();
118 return malformedError("archive header truncated before the name field "
119 "for archive member header at offset " +
120 Twine(ArchiveOffset));
121 }
122
123 // The raw name itself can be invalid.
124 Expected NameOrErr = getRawName();
125 if (!NameOrErr)
126 return NameOrErr.takeError();
127 StringRef Name = NameOrErr.get();
128
129 // Check if it's a special name.
130 if (Name[0] == '/') {
131 if (Name.size() == 1) // Linker member.
132 return Name;
133 if (Name.size() == 2 && Name[1] == '/') // String table.
134 return Name;
135 // It's a long name.
136 // Get the string table offset.
137 std::size_t StringOffset;
138 if (Name.substr(1).rtrim(' ').getAsInteger(10, StringOffset)) {
139 std::string Buf;
140 raw_string_ostream OS(Buf);
141 OS.write_escaped(Name.substr(1).rtrim(' '),
142 sizeof(Name.substr(1)).rtrim(' '));
143 OS.flush();
144 uint64_t ArchiveOffset = reinterpret_cast(ArMemHdr) -
145 Parent->getData().data();
146 return malformedError("long name offset characters after the '/' are "
147 "not all decimal numbers: '" + Buf + "' for "
148 "archive member header at offset " +
149 Twine(ArchiveOffset));
150 }
151
152 // Verify it.
153 if (StringOffset >= Parent->getStringTable().size()) {
154 uint64_t ArchiveOffset = reinterpret_cast(ArMemHdr) -
155 Parent->getData().data();
156 return malformedError("long name offset " + Twine(StringOffset) + " past "
157 "the end of the string table for archive member "
158 "header at offset " + Twine(ArchiveOffset));
159 }
160 const char *addr = Parent->getStringTable().begin() + StringOffset;
161
162 // GNU long file names end with a "/\n".
163 if (Parent->kind() == Archive::K_GNU ||
164 Parent->kind() == Archive::K_MIPS64) {
165 StringRef::size_type End = StringRef(addr).find('\n');
166 return StringRef(addr, End - 1);
167 }
168 return StringRef(addr);
169 } else if (Name.startswith("#1/")) {
170 uint64_t NameLength;
171 if (Name.substr(3).rtrim(' ').getAsInteger(10, NameLength)) {
172 std::string Buf;
173 raw_string_ostream OS(Buf);
174 OS.write_escaped(Name.substr(3).rtrim(' '),
175 sizeof(Name.substr(3)).rtrim(' '));
176 OS.flush();
177 uint64_t ArchiveOffset = reinterpret_cast(ArMemHdr) -
178 Parent->getData().data();
179 return malformedError("long name length characters after the #1/ are "
180 "not all decimal numbers: '" + Buf + "' for "
181 "archive member header at offset " +
182 Twine(ArchiveOffset));
183 }
184 if (getSizeOf() + NameLength > Size) {
185 uint64_t ArchiveOffset = reinterpret_cast(ArMemHdr) -
186 Parent->getData().data();
187 return malformedError("long name length: " + Twine(NameLength) +
188 " extends past the end of the member or archive "
189 "for archive member header at offset " +
190 Twine(ArchiveOffset));
191 }
192 return StringRef(reinterpret_cast(ArMemHdr) + getSizeOf(),
193 NameLength).rtrim('\0');
194 } else {
195 // It is not a long name so trim the blanks at the end of the name.
196 if (Name[Name.size() - 1] != '/') {
197 return Name.rtrim(' ');
198 }
199 }
200 // It's a simple name.
201 if (Name[Name.size() - 1] == '/')
202 return Name.substr(0, Name.size() - 1);
203 return Name;
88204 }
89205
90206 Expected ArchiveMemberHeader::getSize() const {
165281
166282 uint64_t Size = Header.getSizeOf();
167283 Data = StringRef(Start, Size);
168 if (!isThinMember()) {
284 Expected isThinOrErr = isThinMember();
285 if (!isThinOrErr) {
286 if (Err)
287 *Err = isThinOrErr.takeError();
288 return;
289 }
290 bool isThin = isThinOrErr.get();
291 if (!isThin) {
169292 Expected MemberSize = getRawSize();
170293 if (!MemberSize) {
171294 if (Err)
179302 // Setup StartOfFile and PaddingBytes.
180303 StartOfFile = Header.getSizeOf();
181304 // Don't include attached name.
182 StringRef Name = getRawName();
305 Expected NameOrErr = getRawName();
306 if (!NameOrErr){
307 if (Err)
308 *Err = NameOrErr.takeError();
309 return;
310 }
311 StringRef Name = NameOrErr.get();
183312 if (Name.startswith("#1/")) {
184313 uint64_t NameSize;
185 if (Name.substr(3).rtrim(' ').getAsInteger(10, NameSize))
186 llvm_unreachable("Long name length is not an integer");
314 if (Name.substr(3).rtrim(' ').getAsInteger(10, NameSize)) {
315 if (Err) {
316 std::string Buf;
317 raw_string_ostream OS(Buf);
318 OS.write_escaped(Name.substr(3).rtrim(' '),
319 sizeof(Name.substr(3)).rtrim(' '));
320 OS.flush();
321 uint64_t Offset = Start - Parent->getData().data();
322 *Err = malformedError("long name length characters after the #1/ are "
323 "not all decimal numbers: '" + Buf + "' for "
324 "archive member header at offset " +
325 Twine(Offset));
326 return;
327 }
328 }
187329 StartOfFile += NameSize;
188330 }
189331 }
202344 return Header.getSize();
203345 }
204346
205 bool Archive::Child::isThinMember() const {
206 StringRef Name = Header.getName();
347 Expected Archive::Child::isThinMember() const {
348 Expected NameOrErr = Header.getRawName();
349 if (!NameOrErr)
350 return NameOrErr.takeError();
351 StringRef Name = NameOrErr.get();
207352 return Parent->IsThin && Name != "/" && Name != "//";
208353 }
209354
210355 ErrorOr Archive::Child::getFullName() const {
211 assert(isThinMember());
212 ErrorOr NameOrErr = getName();
213 if (std::error_code EC = NameOrErr.getError())
214 return EC;
356 Expected isThin = isThinMember();
357 if (!isThin)
358 return errorToErrorCode(isThin.takeError());
359 assert(isThin.get());
360 Expected NameOrErr = getName();
361 if (!NameOrErr)
362 return errorToErrorCode(NameOrErr.takeError());
215363 StringRef Name = *NameOrErr;
216364 if (sys::path::is_absolute(Name))
217365 return Name;
223371 }
224372
225373 ErrorOr Archive::Child::getBuffer() const {
226 if (!isThinMember()) {
374 Expected isThinOrErr = isThinMember();
375 if (!isThinOrErr)
376 return errorToErrorCode(isThinOrErr.takeError());
377 bool isThin = isThinOrErr.get();
378 if (!isThin) {
227379 Expected Size = getSize();
228380 if (!Size)
229381 return errorToErrorCode(Size.takeError());
256408 if (NextLoc > Parent->Data.getBufferEnd()) {
257409 Twine Msg("offset to next archive member past the end of the archive after "
258410 "member ");
259 ErrorOr NameOrErr = getName();
260 if (NameOrErr.getError()) {
411 Expected NameOrErr = getName();
412 if (!NameOrErr) {
413 consumeError(NameOrErr.takeError());
261414 uint64_t Offset = Data.data() - Parent->getData().data();
262415 return malformedError(Msg + "at offset " + Twine(Offset));
263416 } else
278431 return offset;
279432 }
280433
281 ErrorOr Archive::Child::getName() const {
282 StringRef name = getRawName();
283 // Check if it's a special name.
284 if (name[0] == '/') {
285 if (name.size() == 1) // Linker member.
286 return name;
287 if (name.size() == 2 && name[1] == '/') // String table.
288 return name;
289 // It's a long name.
290 // Get the offset.
291 std::size_t offset;
292 if (name.substr(1).rtrim(' ').getAsInteger(10, offset))
293 llvm_unreachable("Long name offset is not an integer");
294
295 // Verify it.
296 if (offset >= Parent->StringTable.size())
297 return object_error::parse_failed;
298 const char *addr = Parent->StringTable.begin() + offset;
299
300 // GNU long file names end with a "/\n".
301 if (Parent->kind() == K_GNU || Parent->kind() == K_MIPS64) {
302 StringRef::size_type End = StringRef(addr).find('\n');
303 return StringRef(addr, End - 1);
304 }
305 return StringRef(addr);
306 } else if (name.startswith("#1/")) {
307 uint64_t name_size;
308 if (name.substr(3).rtrim(' ').getAsInteger(10, name_size))
309 llvm_unreachable("Long name length is not an ingeter");
310 return Data.substr(Header.getSizeOf(), name_size).rtrim('\0');
311 } else {
312 // It is not a long name so trim the blanks at the end of the name.
313 if (name[name.size() - 1] != '/') {
314 return name.rtrim(' ');
315 }
316 }
317 // It's a simple name.
318 if (name[name.size() - 1] == '/')
319 return name.substr(0, name.size() - 1);
320 return name;
321 }
322
323 ErrorOr Archive::Child::getMemoryBufferRef() const {
324 ErrorOr NameOrErr = getName();
325 if (std::error_code EC = NameOrErr.getError())
326 return EC;
434 Expected Archive::Child::getName() const {
435 Expected RawSizeOrErr = getRawSize();
436 if (!RawSizeOrErr)
437 return RawSizeOrErr.takeError();
438 uint64_t RawSize = RawSizeOrErr.get();
439 Expected NameOrErr = Header.getName(Header.getSizeOf() + RawSize);
440 if (!NameOrErr)
441 return NameOrErr.takeError();
442 StringRef Name = NameOrErr.get();
443 return Name;
444 }
445
446 Expected Archive::Child::getMemoryBufferRef() const {
447 Expected NameOrErr = getName();
448 if (!NameOrErr)
449 return NameOrErr.takeError();
327450 StringRef Name = NameOrErr.get();
328451 ErrorOr Buf = getBuffer();
329452 if (std::error_code EC = Buf.getError())
330 return EC;
453 return errorCodeToError(EC);
331454 return MemoryBufferRef(*Buf, Name);
332455 }
333456
334457 Expected>
335458 Archive::Child::getAsBinary(LLVMContext *Context) const {
336 ErrorOr BuffOrErr = getMemoryBufferRef();
337 if (std::error_code EC = BuffOrErr.getError())
338 return errorCodeToError(EC);
459 Expected BuffOrErr = getMemoryBufferRef();
460 if (!BuffOrErr)
461 return BuffOrErr.takeError();
339462
340463 auto BinaryOrErr = createBinary(BuffOrErr.get(), Context);
341464 if (BinaryOrErr)
371494 return;
372495 }
373496
497 // Make sure Format is initialized before any call to
498 // ArchiveMemberHeader::getName() is made. This could be a valid empty
499 // archive which is the same in all formats. So claiming it to be gnu to is
500 // fine if not totally correct before we look for a string table or table of
501 // contents.
502 Format = K_GNU;
503
374504 // Get the special members.
375505 child_iterator I = child_begin(Err, false);
376506 if (Err)
377507 return;
378508 child_iterator E = child_end();
379509
380 // This is at least a valid empty archive. Since an empty archive is the
381 // same in all formats, just claim it to be gnu to make sure Format is
382 // initialized.
383 Format = K_GNU;
384
510 // See if this is a valid empty archive and if so return.
385511 if (I == E) {
386512 Err = Error::success();
387513 return;
396522 return false;
397523 };
398524
399 StringRef Name = C->getRawName();
525 Expected NameOrErr = C->getRawName();
526 if (!NameOrErr) {
527 Err = NameOrErr.takeError();
528 return;
529 }
530 StringRef Name = NameOrErr.get();
400531
401532 // Below is the pattern that is used to figure out the archive format
402533 // GNU archive format
436567 if (Name.startswith("#1/")) {
437568 Format = K_BSD;
438569 // We know this is BSD, so getName will work since there is no string table.
439 ErrorOr NameOrErr = C->getName();
440 if (auto ec = NameOrErr.getError()) {
441 Err = errorCodeToError(ec);
570 Expected NameOrErr = C->getName();
571 if (!NameOrErr) {
572 Err = NameOrErr.takeError();
442573 return;
443574 }
444575 Name = NameOrErr.get();
480611 Err = Error::success();
481612 return;
482613 }
483 Name = C->getRawName();
614 Expected NameOrErr = C->getRawName();
615 if (!NameOrErr) {
616 Err = NameOrErr.takeError();
617 return;
618 }
619 Name = NameOrErr.get();
484620 }
485621
486622 if (Name == "//") {
521657 return;
522658 }
523659
524 Name = C->getRawName();
660 NameOrErr = C->getRawName();
661 if (!NameOrErr) {
662 Err = NameOrErr.takeError();
663 return;
664 }
665 Name = NameOrErr.get();
525666
526667 if (Name == "//") {
527668 // The string table is never an external member, so we just assert on the
3939 Expected
4040 NewArchiveMember::getOldMember(const object::Archive::Child &OldMember,
4141 bool Deterministic) {
42 ErrorOr BufOrErr = OldMember.getMemoryBufferRef();
42 Expected BufOrErr = OldMember.getMemoryBufferRef();
4343 if (!BufOrErr)
44 return errorCodeToError(BufOrErr.getError());
44 return BufOrErr.takeError();
4545
4646 NewArchiveMember M;
4747 M.Buf = MemoryBuffer::getMemBuffer(*BufOrErr, false);
0 !
1 // 26 `
2 1234567890123456hello.c/
3
4 /507 0 0 0 644 102 `
5 #include
6 #include
7 int
8 main()
9 {
10 printf("Hello World\n");
11 return EXIT_SUCCESS;
12 }
0 !
1 #1/@123$ 1469564779 124 0 100644 102 `
2 #include
3 #include
4 int
5 main()
6 {
7 printf("Hello World\n");
8 return EXIT_SUCCESS;
9 }
0 !
1 foo.c 1444941645 124 0 100644 17 `
2 void foo(void){}
3
4 #1/1234 1469564779 124 0 100644 126 `
5 1234567890123456Xhello.c#include
6 #include
7 int
8 main()
9 {
10 printf("Hello World\n");
11 return EXIT_SUCCESS;
12 }
0 !
1 // 26 `
2 1234567890123456hello.c/
3
4 /&a25* 0 0 0 644 102 `
5 #include
6 #include
7 int
8 main()
9 {
10 printf("Hello World\n");
11 return EXIT_SUCCESS;
12 }
2222 # RUN: %p/Inputs/libbogus4.a \
2323 # RUN: 2>&1 | FileCheck -check-prefix=bogus4 %s
2424
25 # bogus4: libbogus4.a': truncated or malformed archive (remaining size of archive too small for next archive member header at offset 170)
25 # bogus4: libbogus4.a': truncated or malformed archive (remaining size of archive too small for next archive member header for foo.c)
2626
2727 # RUN: not llvm-objdump -macho -archive-headers \
2828 # RUN: %p/Inputs/libbogus5.a \
2929 # RUN: 2>&1 | FileCheck -check-prefix=bogus5 %s
3030
31 # bogus5: libbogus5.a': truncated or malformed archive (terminator characters in archive member "@\n" not the correct "`\n" values for the archive member header at offset 8)
31 # bogus5: libbogus5.a': truncated or malformed archive (terminator characters in archive member "@\n" not the correct "`\n" values for the archive member header for hello.c)
32
33 # RUN: not llvm-objdump -macho -archive-headers \
34 # RUN: %p/Inputs/libbogus6.a \
35 # RUN: 2>&1 | FileCheck -check-prefix=bogus6 %s
36
37 # bogus6: libbogus6.a': truncated or malformed archive (name contains a leading space for archive member header at offset 96)
38
39 # RUN: not llvm-objdump -macho -archive-headers \
40 # RUN: %p/Inputs/libbogus7.a \
41 # RUN: 2>&1 | FileCheck -check-prefix=bogus7 %s
42
43 # bogus7: libbogus7.a': truncated or malformed archive (long name length characters after the #1/ are not all decimal numbers: '@123$' for archive member header at offset 8)
44
45 # RUN: not llvm-objdump -macho -archive-headers \
46 # RUN: %p/Inputs/libbogus8.a \
47 # RUN: 2>&1 | FileCheck -check-prefix=bogus8 %s
48
49 # bogus8: libbogus8.a(???) truncated or malformed archive (long name length: 1234 extends past the end of the member or archive for archive member header at offset 86)
50
51 # RUN: not llvm-objdump -s %p/Inputs/libbogus9.a \
52 # RUN: 2>&1 | FileCheck -check-prefix=bogus9 %s
53
54 # bogus9: libbogus9.a(???) truncated or malformed archive (long name offset characters after the '/' are not all decimal numbers: '&a25*' for archive member header at offset 94)
55
56 # RUN: not llvm-objdump -s %p/Inputs/libbogus10.a \
57 # RUN: 2>&1 | FileCheck -check-prefix=bogus10 %s
58
59 # bogus10: libbogus10.a(???) truncated or malformed archive (long name offset 507 past the end of the string table for archive member header at offset 94)
114114 if (Verbose)
115115 outs() << "\tfound member in current archive.\n";
116116 auto ErrOrMem = Child.getMemoryBufferRef();
117 if (auto Err = ErrOrMem.getError())
118 return Err;
117 if (!ErrOrMem)
118 return errorToErrorCode(ErrOrMem.takeError());
119119 Buffers.push_back(*ErrOrMem);
120120 }
121121 }
408408 {
409409 Error Err;
410410 for (auto &C : OldArchive->children(Err)) {
411 ErrorOr NameOrErr = C.getName();
412 failIfError(NameOrErr.getError());
411 Expected NameOrErr = C.getName();
412 failIfError(NameOrErr.takeError());
413413 StringRef Name = NameOrErr.get();
414414
415415 if (Filter) {
536536 Error Err;
537537 for (auto &Child : OldArchive->children(Err)) {
538538 int Pos = Ret.size();
539 ErrorOr NameOrErr = Child.getName();
540 failIfError(NameOrErr.getError());
539 Expected NameOrErr = Child.getName();
540 failIfError(NameOrErr.takeError());
541541 StringRef Name = NameOrErr.get();
542542 if (Name == PosName) {
543543 assert(AddAfter || AddBefore);
197197 HadError = true;
198198 errs() << ToolName << ": " << FileName;
199199
200 ErrorOr NameOrErr = C.getName();
200 Expected NameOrErr = C.getName();
201201 // TODO: if we have a error getting the name then it would be nice to print
202202 // the index of which archive member this is and or its offset in the
203203 // archive instead of "???" as the name.
204 if (NameOrErr.getError())
204 if (!NameOrErr) {
205 consumeError(NameOrErr.takeError());
205206 errs() << "(" << "???" << ")";
206 else
207 } else
207208 errs() << "(" << NameOrErr.get() << ")";
208209
209210 if (!ArchitectureName.empty())
10981099 ErrorOr C = I->getMember();
10991100 if (error(C.getError()))
11001101 return;
1101 ErrorOr FileNameOrErr = C->getName();
1102 if (error(FileNameOrErr.getError()))
1102 Expected FileNameOrErr = C->getName();
1103 if (!FileNameOrErr) {
1104 error(FileNameOrErr.takeError(), Filename);
11031105 return;
1106 }
11041107 StringRef SymName = I->getName();
11051108 outs() << SymName << " in " << FileNameOrErr.get() << "\n";
11061109 }
15201520 }
15211521
15221522 if (verbose) {
1523 ErrorOr NameOrErr = C.getName();
1524 if (NameOrErr.getError()) {
1525 StringRef RawName = C.getRawName();
1523 Expected NameOrErr = C.getName();
1524 if (!NameOrErr) {
1525 consumeError(NameOrErr.takeError());
1526 Expected NameOrErr = C.getRawName();
1527 if (!NameOrErr)
1528 report_error(Filename, C, NameOrErr.takeError(), ArchitectureName);
1529 StringRef RawName = NameOrErr.get();
15261530 outs() << RawName << "\n";
15271531 } else {
15281532 StringRef Name = NameOrErr.get();
15291533 outs() << Name << "\n";
15301534 }
15311535 } else {
1532 StringRef RawName = C.getRawName();
1536 Expected NameOrErr = C.getRawName();
1537 if (!NameOrErr)
1538 report_error(Filename, C, NameOrErr.takeError(), ArchitectureName);
1539 StringRef RawName = NameOrErr.get();
15331540 outs() << RawName << "\n";
15341541 }
15351542 }
311311 const object::Archive::Child &C,
312312 llvm::Error E,
313313 StringRef ArchitectureName) {
314 ErrorOr NameOrErr = C.getName();
314 Expected NameOrErr = C.getName();
315315 // TODO: if we have a error getting the name then it would be nice to print
316316 // the index of which archive member this is and or its offset in the
317317 // archive instead of "???" as the name.
318 if (NameOrErr.getError())
318 if (!NameOrErr) {
319 consumeError(NameOrErr.takeError());
319320 llvm::report_error(ArchiveName, "???", std::move(E), ArchitectureName);
320 else
321 } else
321322 llvm::report_error(ArchiveName, NameOrErr.get(), std::move(E),
322323 ArchitectureName);
323324 }
113113 HadError = true;
114114 errs() << ToolName << ": " << FileName;
115115
116 ErrorOr NameOrErr = C.getName();
116 Expected NameOrErr = C.getName();
117117 // TODO: if we have a error getting the name then it would be nice to print
118118 // the index of which archive member this is and or its offset in the
119119 // archive instead of "???" as the name.
120 if (NameOrErr.getError())
120 if (!NameOrErr) {
121 consumeError(NameOrErr.takeError());
121122 errs() << "(" << "???" << ")";
122 else
123 } else
123124 errs() << "(" << NameOrErr.get() << ")";
124125
125126 if (!ArchitectureName.empty())