llvm.org GIT mirror llvm / 46e35ed
Fix a crash in running llvm-objdump -t with an invalid Mach-O file already in the test suite. While this is not really an interesting tool and option to run on a Mach-O file to show the symbol table in a generic libObject format it shouldn’t crash. The reason for the crash was in MachOObjectFile::getSymbolType() when it was calling MachOObjectFile::getSymbolSection() without checking its return value for the error case. What makes this fix require a fair bit of diffs is that the method getSymbolType() is in the class ObjectFile defined without an ErrorOr<> so I needed to add that all the sub classes.  And all of the uses needed to be updated and the return value needed to be checked for the error case. The MachOObjectFile version of getSymbolType() “can” get an error in trying to come up with the libObject’s internal SymbolRef::Type when the Mach-O symbol symbol type is an N_SECT type because the code is trying to select from the SymbolRef::ST_Data or SymbolRef::ST_Function values for the SymbolRef::Type. And it needs the Mach-O section to use isData() and isBSS to determine if it will return SymbolRef::ST_Data. One other possible fix I considered is to simply return SymbolRef::ST_Other when MachOObjectFile::getSymbolSection() returned an error. But since in the past when I did such changes that “ate an error in the libObject code” I was asked instead to push the error out of the libObject code I chose not to implement the fix this way. As currently written both the COFF and ELF versions of getSymbolType() can’t get an error. But if isReservedSectionNumber() wanted to check for the two known negative values rather than allowing all negative values or the code wanted to add the same check as in getSymbolAddress() to use getSection() and check for the error then these versions of getSymbolType() could return errors. At the end of the day the error printed now is the generic “Invalid data was encountered while parsing the file” for object_error::parse_failed. In the future when we thread Lang’s new TypedError for recoverable error handling though libObject this will improve. And where the added // Diagnostic(… comment is, it would be changed to produce and error message like “bad section index (42) for symbol at index 8” for this case. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@264187 91177308-0d34-0410-b5e6-96231b3b80d8 Kevin Enderby 3 years ago
15 changed file(s) with 75 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
683683 uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
684684 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
685685 uint32_t getSymbolFlags(DataRefImpl Symb) const override;
686 SymbolRef::Type getSymbolType(DataRefImpl Symb) const override;
686 ErrorOr getSymbolType(DataRefImpl Symb) const override;
687687 ErrorOr getSymbolSection(DataRefImpl Symb) const override;
688688 void moveSectionNext(DataRefImpl &Sec) const override;
689689 std::error_code getSectionName(DataRefImpl Sec,
204204 uint32_t getSymbolFlags(DataRefImpl Symb) const override;
205205 uint8_t getSymbolOther(DataRefImpl Symb) const override;
206206 uint8_t getSymbolELFType(DataRefImpl Symb) const override;
207 SymbolRef::Type getSymbolType(DataRefImpl Symb) const override;
207 ErrorOr getSymbolType(DataRefImpl Symb) const override;
208208 ErrorOr getSymbolSection(const Elf_Sym *Symb,
209209 const Elf_Shdr *SymTab) const;
210210 ErrorOr getSymbolSection(DataRefImpl Symb) const override;
444444 }
445445
446446 template
447 SymbolRef::Type ELFObjectFile::getSymbolType(DataRefImpl Symb) const {
447 ErrorOr
448 ELFObjectFile::getSymbolType(DataRefImpl Symb) const {
448449 const Elf_Sym *ESym = getSymbol(Symb);
449450
450451 switch (ESym->getType()) {
207207 ErrorOr getSymbolAddress(DataRefImpl Symb) const override;
208208 uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
209209 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
210 SymbolRef::Type getSymbolType(DataRefImpl Symb) const override;
210 ErrorOr getSymbolType(DataRefImpl Symb) const override;
211211 uint32_t getSymbolFlags(DataRefImpl Symb) const override;
212212 ErrorOr getSymbolSection(DataRefImpl Symb) const override;
213213 unsigned getSymbolSectionID(SymbolRef Symb) const;
142142 /// @brief Get the alignment of this symbol as the actual value (not log 2).
143143 uint32_t getAlignment() const;
144144 uint64_t getCommonSize() const;
145 SymbolRef::Type getType() const;
145 ErrorOr getType() const;
146146
147147 /// @brief Get section this symbol is defined in reference to. Result is
148148 /// end_sections() if it is undefined or is an absolute symbol.
200200 virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
201201 virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
202202 virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
203 virtual SymbolRef::Type getSymbolType(DataRefImpl Symb) const = 0;
203 virtual ErrorOr getSymbolType(DataRefImpl Symb) const = 0;
204204 virtual ErrorOr
205205 getSymbolSection(DataRefImpl Symb) const = 0;
206206
328328 return getObject()->getSymbolSection(getRawDataRefImpl());
329329 }
330330
331 inline SymbolRef::Type SymbolRef::getType() const {
331 inline ErrorOr SymbolRef::getType() const {
332332 return getObject()->getSymbolType(getRawDataRefImpl());
333333 }
334334
118118 uint64_t SymbolSize,
119119 DataExtractor *OpdExtractor,
120120 uint64_t OpdAddress) {
121 SymbolRef::Type SymbolType = Symbol.getType();
121 ErrorOr SymbolTypeOrErr = Symbol.getType();
122 if (auto EC = SymbolTypeOrErr.getError())
123 return EC;
124 SymbolRef::Type SymbolType = *SymbolTypeOrErr;
122125 if (SymbolType != SymbolRef::ST_Function && SymbolType != SymbolRef::ST_Data)
123126 return std::error_code();
124127 ErrorOr SymbolAddressOrErr = Symbol.getAddress();
168168 if (Flags & SymbolRef::SF_Common)
169169 CommonSymbols.push_back(*I);
170170 else {
171 object::SymbolRef::Type SymType = I->getType();
171 ErrorOr SymTypeOrErr = I->getType();
172 Check(SymTypeOrErr.getError());
173 object::SymbolRef::Type SymType = *SymTypeOrErr;
172174
173175 // Get symbol name.
174176 ErrorOr NameOrErr = I->getName();
11891189 RTDyldSymbolTable::const_iterator gsi = GlobalSymbolTable.end();
11901190 if (Symbol != Obj.symbol_end()) {
11911191 gsi = GlobalSymbolTable.find(TargetName.data());
1192 SymType = Symbol->getType();
1192 ErrorOr SymTypeOrErr = Symbol->getType();
1193 if (std::error_code EC = SymTypeOrErr.getError())
1194 report_fatal_error(EC.message());
1195 SymType = *SymTypeOrErr;
11931196 }
11941197 if (gsi != GlobalSymbolTable.end()) {
11951198 const auto &SymInfo = gsi->second;
178178 return Result;
179179 }
180180
181 SymbolRef::Type COFFObjectFile::getSymbolType(DataRefImpl Ref) const {
181 ErrorOr COFFObjectFile::getSymbolType(DataRefImpl Ref) const {
182182 COFFSymbolRef Symb = getCOFFSymbol(Ref);
183183 int32_t SectionNumber = Symb.getSectionNumber();
184184
442442 return getNValue(DRI);
443443 }
444444
445 SymbolRef::Type MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
445 ErrorOr
446 MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
446447 MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
447448 uint8_t n_type = Entry.n_type;
448449
454455 case MachO::N_UNDF :
455456 return SymbolRef::ST_Unknown;
456457 case MachO::N_SECT :
457 section_iterator Sec = *getSymbolSection(Symb);
458 ErrorOr SecOrError = getSymbolSection(Symb);
459 if (!SecOrError)
460 return SecOrError.getError();
461 section_iterator Sec = *SecOrError;
458462 if (Sec->isData() || Sec->isBSS())
459463 return SymbolRef::ST_Data;
460464 return SymbolRef::ST_Function;
510514 return section_end();
511515 DataRefImpl DRI;
512516 DRI.d.a = index - 1;
513 if (DRI.d.a >= Sections.size())
517 if (DRI.d.a >= Sections.size()){
518 // Diagnostic("bad section index (" + index + ") for symbol at index " +
519 // SymbolIndex);
514520 return object_error::parse_failed;
521 }
515522 return section_iterator(SectionRef(DRI, this));
516523 }
517524
5353 RUN: llvm-nm -pax %p/Inputs/macho-invalid-section-index-getSectionRawName 2>&1 \
5454 RUN: | FileCheck -check-prefix INVALID-SECTION-IDX-SYMBOL-SEC-pax %s
5555 INVALID-SECTION-IDX-SYMBOL-SEC-pax: 0000000100000000 0f 42 0010 00000065 __mh_execute_header
56 RUN: not llvm-objdump -t %p/Inputs/macho-invalid-section-index-getSectionRawName 2>&1 \
57 RUN: | FileCheck -check-prefix INVALID-SECTION-IDX-SYMBOL-SEC-objdump %s
58 INVALID-SECTION-IDX-SYMBOL-SEC-objdump: Invalid data was encountered while parsing the file.
5659
5760 RUN: not llvm-objdump -private-headers %p/Inputs/macho-invalid-header 2>&1 | FileCheck -check-prefix INVALID-HEADER %s
5861 INVALID-HEADER: The file was not recognized as a valid object file.
436436 section_iterator Section = MainBinary.section_end();
437437 MainBinarySymbolAddresses.clear();
438438 for (const auto &Sym : MainBinary.symbols()) {
439 SymbolRef::Type Type = Sym.getType();
439 ErrorOr TypeOrErr = Sym.getType();
440 if (!TypeOrErr)
441 continue;
442 SymbolRef::Type Type = *TypeOrErr;
440443 // Skip undefined and STAB entries.
441444 if ((Type & SymbolRef::ST_Debug) || (Type & SymbolRef::ST_Unknown))
442445 continue;
171171
172172 struct SymbolSorter {
173173 bool operator()(const SymbolRef &A, const SymbolRef &B) {
174 uint64_t AAddr = (A.getType() != SymbolRef::ST_Function) ? 0 : A.getValue();
175 uint64_t BAddr = (B.getType() != SymbolRef::ST_Function) ? 0 : B.getValue();
174 ErrorOr ATypeOrErr = A.getType();
175 if (std::error_code EC = ATypeOrErr.getError())
176 report_fatal_error(EC.message());
177 SymbolRef::Type AType = *ATypeOrErr;
178 ErrorOr BTypeOrErr = B.getType();
179 if (std::error_code EC = BTypeOrErr.getError())
180 report_fatal_error(EC.message());
181 SymbolRef::Type BType = *ATypeOrErr;
182 uint64_t AAddr = (AType != SymbolRef::ST_Function) ? 0 : A.getValue();
183 uint64_t BAddr = (BType != SymbolRef::ST_Function) ? 0 : B.getValue();
176184 return AAddr < BAddr;
177185 }
178186 };
572580 SymbolAddressMap *AddrMap) {
573581 // Create a map of symbol addresses to symbol names.
574582 for (const SymbolRef &Symbol : O->symbols()) {
575 SymbolRef::Type ST = Symbol.getType();
583 ErrorOr STOrErr = Symbol.getType();
584 if (std::error_code EC = STOrErr.getError())
585 report_fatal_error(EC.message());
586 SymbolRef::Type ST = *STOrErr;
576587 if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
577588 ST == SymbolRef::ST_Other) {
578589 uint64_t Address = Symbol.getValue();
60826093 SymbolAddressMap AddrMap;
60836094 bool DisSymNameFound = false;
60846095 for (const SymbolRef &Symbol : MachOOF->symbols()) {
6085 SymbolRef::Type ST = Symbol.getType();
6096 ErrorOr STOrErr = Symbol.getType();
6097 if (std::error_code EC = STOrErr.getError())
6098 report_fatal_error(EC.message());
6099 SymbolRef::Type ST = *STOrErr;
60866100 if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
60876101 ST == SymbolRef::ST_Other) {
60886102 uint64_t Address = Symbol.getValue();
61336147 report_fatal_error(EC.message());
61346148 StringRef SymName = *SymNameOrErr;
61356149
6136 SymbolRef::Type ST = Symbols[SymIdx].getType();
6150 ErrorOr STOrErr = Symbols[SymIdx].getType();
6151 if (std::error_code EC = STOrErr.getError())
6152 report_fatal_error(EC.message());
6153 SymbolRef::Type ST = *STOrErr;
61376154 if (ST != SymbolRef::ST_Function && ST != SymbolRef::ST_Data)
61386155 continue;
61396156
61576174 uint64_t NextSym = 0;
61586175 uint64_t NextSymIdx = SymIdx + 1;
61596176 while (Symbols.size() > NextSymIdx) {
6160 SymbolRef::Type NextSymType = Symbols[NextSymIdx].getType();
6177 ErrorOr STOrErr = Symbols[NextSymIdx].getType();
6178 if (std::error_code EC = STOrErr.getError())
6179 report_fatal_error(EC.message());
6180 SymbolRef::Type NextSymType = *STOrErr;
61616181 if (NextSymType == SymbolRef::ST_Function) {
61626182 containsNextSym =
61636183 Sections[SectIdx].containsSymbol(Symbols[NextSymIdx]);
12921292 ErrorOr AddressOrError = Symbol.getAddress();
12931293 error(AddressOrError.getError());
12941294 uint64_t Address = *AddressOrError;
1295 SymbolRef::Type Type = Symbol.getType();
1295 ErrorOr TypeOrError = Symbol.getType();
1296 error(TypeOrError.getError());
1297 SymbolRef::Type Type = *TypeOrError;
12961298 uint32_t Flags = Symbol.getFlags();
12971299 ErrorOr SectionOrErr = Symbol.getSection();
12981300 error(SectionOrErr.getError());
197197 ErrorOr Decoder::getSymbol(const COFFObjectFile &COFF,
198198 uint64_t VA, bool FunctionOnly) {
199199 for (const auto &Symbol : COFF.symbols()) {
200 if (FunctionOnly && Symbol.getType() != SymbolRef::ST_Function)
200 ErrorOr Type = Symbol.getType();
201 if (std::error_code EC = Type.getError())
202 return EC;
203 if (FunctionOnly && *Type != SymbolRef::ST_Function)
201204 continue;
202205
203206 ErrorOr Address = Symbol.getAddress();
329329 // Use symbol info to iterate functions in the object.
330330 for (const auto &P : SymAddr) {
331331 object::SymbolRef Sym = P.first;
332 if (Sym.getType() == object::SymbolRef::ST_Function) {
332 ErrorOr TypeOrErr = Sym.getType();
333 if (!TypeOrErr)
334 continue;
335 SymbolRef::Type Type = *TypeOrErr;
336 if (Type == object::SymbolRef::ST_Function) {
333337 ErrorOr Name = Sym.getName();
334338 if (!Name)
335339 continue;