llvm.org GIT mirror llvm / a18e46c
Object, COFF: Tighten the object file parser We were a little lax in a few areas: - We pretended that import libraries were like any old COFF file, they are not. In fact, they aren't really COFF files at all, we should probably grow some specialized functionality to handle them smarter. - Our symbol iterators were more than happy to attempt to go past the end of the symbol table if you had a symbol with a bad list of auxiliary symbols. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222124 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 6 years ago
5 changed file(s) with 82 addition(s) and 54 deletion(s). Raw diff Collapse all Expand all
507507 }
508508 uint16_t getSizeOfOptionalHeader() const {
509509 if (COFFHeader)
510 return COFFHeader->SizeOfOptionalHeader;
510 return COFFHeader->isImportLibrary() ? 0
511 : COFFHeader->SizeOfOptionalHeader;
511512 // bigobj doesn't have this field.
512513 if (COFFBigObjHeader)
513514 return 0;
515516 }
516517 uint16_t getCharacteristics() const {
517518 if (COFFHeader)
518 return COFFHeader->Characteristics;
519 return COFFHeader->isImportLibrary() ? 0 : COFFHeader->Characteristics;
519520 // bigobj doesn't have characteristics to speak of,
520521 // editbin will silently lie to you if you attempt to set any.
521522 if (COFFBigObjHeader)
531532 }
532533 uint32_t getNumberOfSections() const {
533534 if (COFFHeader)
534 return COFFHeader->NumberOfSections;
535 return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSections;
535536 if (COFFBigObjHeader)
536537 return COFFBigObjHeader->NumberOfSections;
537538 llvm_unreachable("no COFF header!");
538539 }
539540 uint32_t getPointerToSymbolTable() const {
540541 if (COFFHeader)
541 return COFFHeader->PointerToSymbolTable;
542 return COFFHeader->isImportLibrary() ? 0
543 : COFFHeader->PointerToSymbolTable;
542544 if (COFFBigObjHeader)
543545 return COFFBigObjHeader->PointerToSymbolTable;
544546 llvm_unreachable("no COFF header!");
545547 }
546548 uint32_t getNumberOfSymbols() const {
547549 if (COFFHeader)
548 return COFFHeader->NumberOfSymbols;
550 return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSymbols;
549551 if (COFFBigObjHeader)
550552 return COFFBigObjHeader->NumberOfSymbols;
551553 llvm_unreachable("no COFF header!");
656658 return EC;
657659 return COFFSymbolRef(Symb);
658660 }
659 llvm_unreachable("no symbol table pointer!");
661 return object_error::parse_failed;
660662 }
661663 template
662664 std::error_code getAuxSymbol(uint32_t index, const T *&Res) const {
5353 template
5454 static std::error_code getObject(const T *&Obj, MemoryBufferRef M,
5555 const void *Ptr,
56 const size_t Size = sizeof(T)) {
56 const uint64_t Size = sizeof(T)) {
5757 uintptr_t Addr = uintptr_t(Ptr);
5858 if (std::error_code EC = checkOffset(M, Addr, Size))
5959 return EC;
100100 const coff_symbol_type *Addr =
101101 reinterpret_cast(Ref.p);
102102
103 assert(!checkOffset(Data, uintptr_t(Addr), sizeof(*Addr)));
103104 #ifndef NDEBUG
104105 // Verify that the symbol points to a valid entry in the symbol table.
105106 uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base());
106 if (Offset < getPointerToSymbolTable() ||
107 Offset >= getPointerToSymbolTable() +
108 (getNumberOfSymbols() * sizeof(coff_symbol_type)))
109 report_fatal_error("Symbol was outside of symbol table.");
110107
111108 assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 &&
112109 "Symbol did not point to the beginning of a symbol");
132129 }
133130
134131 void COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const {
132 auto End = reinterpret_cast(StringTable);
135133 if (SymbolTable16) {
136134 const coff_symbol16 *Symb = toSymb(Ref);
137135 Symb += 1 + Symb->NumberOfAuxSymbols;
138 Ref.p = reinterpret_cast(Symb);
136 Ref.p = std::min(reinterpret_cast(Symb), End);
139137 } else if (SymbolTable32) {
140138 const coff_symbol32 *Symb = toSymb(Ref);
141139 Symb += 1 + Symb->NumberOfAuxSymbols;
142 Ref.p = reinterpret_cast(Symb);
140 Ref.p = std::min(reinterpret_cast(Symb), End);
143141 } else {
144142 llvm_unreachable("no symbol table pointer!");
145143 }
364362 }
365363
366364 bool COFFObjectFile::isSectionRequiredForExecution(DataRefImpl Ref) const {
367 // FIXME: Unimplemented
368 return true;
365 // Sections marked 'Info', 'Remove', or 'Discardable' aren't required for
366 // execution.
367 const coff_section *Sec = toSec(Ref);
368 return !(Sec->Characteristics &
369 (COFF::IMAGE_SCN_LNK_INFO | COFF::IMAGE_SCN_LNK_REMOVE |
370 COFF::IMAGE_SCN_MEM_DISCARDABLE));
369371 }
370372
371373 bool COFFObjectFile::isSectionVirtual(DataRefImpl Ref) const {
374376 }
375377
376378 bool COFFObjectFile::isSectionZeroInit(DataRefImpl Ref) const {
377 // FIXME: Unimplemented.
378 return false;
379 const coff_section *Sec = toSec(Ref);
380 return Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
379381 }
380382
381383 bool COFFObjectFile::isSectionReadOnlyData(DataRefImpl Ref) const {
382 // FIXME: Unimplemented.
383 return false;
384 const coff_section *Sec = toSec(Ref);
385 // Check if it's any sort of data section.
386 if (!(Sec->Characteristics & (COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
387 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)))
388 return false;
389 // If it's writable or executable or contains code, it isn't read-only data.
390 if (Sec->Characteristics &
391 (COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_MEM_EXECUTE |
392 COFF::IMAGE_SCN_MEM_WRITE))
393 return false;
394 return true;
384395 }
385396
386397 bool COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef,
445456 // Initialize the pointer to the symbol table.
446457 std::error_code COFFObjectFile::initSymbolTablePtr() {
447458 if (COFFHeader)
448 if (std::error_code EC =
449 getObject(SymbolTable16, Data, base() + getPointerToSymbolTable(),
450 getNumberOfSymbols() * getSymbolTableEntrySize()))
459 if (std::error_code EC = getObject(
460 SymbolTable16, Data, base() + getPointerToSymbolTable(),
461 (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
451462 return EC;
452463
453464 if (COFFBigObjHeader)
454 if (std::error_code EC =
455 getObject(SymbolTable32, Data, base() + getPointerToSymbolTable(),
456 getNumberOfSymbols() * getSymbolTableEntrySize()))
465 if (std::error_code EC = getObject(
466 SymbolTable32, Data, base() + getPointerToSymbolTable(),
467 (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
457468 return EC;
458469
459470 // Find string table. The first four byte of the string table contains the
680691 }
681692
682693 if ((EC = getObject(SectionTable, Data, base() + CurPtr,
683 getNumberOfSections() * sizeof(coff_section))))
694 (uint64_t)getNumberOfSections() * sizeof(coff_section))))
684695 return;
685696
686697 // Initialize the pointer to the symbol table.
687 if (getPointerToSymbolTable() != 0)
698 if (getPointerToSymbolTable() != 0) {
688699 if ((EC = initSymbolTablePtr()))
689700 return;
701 } else {
702 // We had better not have any symbols if we don't have a symbol table.
703 if (getNumberOfSymbols() != 0) {
704 EC = object_error::parse_failed;
705 return;
706 }
707 }
690708
691709 // Initialize the pointer to the beginning of the import table.
692710 if ((EC = initImportTablePtr()))
842860
843861 std::error_code COFFObjectFile::getSection(int32_t Index,
844862 const coff_section *&Result) const {
845 // Check for special index values.
863 Result = nullptr;
846864 if (COFF::isReservedSectionNumber(Index))
847 Result = nullptr;
848 else if (Index > 0 && static_cast(Index) <= getNumberOfSections())
865 return object_error::success;
866 if (static_cast(Index) <= getNumberOfSections()) {
849867 // We already verified the section table data, so no need to check again.
850868 Result = SectionTable + (Index - 1);
851 else
852 return object_error::parse_failed;
853 return object_error::success;
869 return object_error::success;
870 }
871 return object_error::parse_failed;
854872 }
855873
856874 std::error_code COFFObjectFile::getString(uint32_t Offset,
10001018 symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
10011019 const coff_relocation *R = toRel(Rel);
10021020 DataRefImpl Ref;
1021 if (R->SymbolTableIndex >= getNumberOfSymbols())
1022 return symbol_end();
10031023 if (SymbolTable16)
10041024 Ref.p = reinterpret_cast(SymbolTable16 + R->SymbolTableIndex);
10051025 else if (SymbolTable32)
334334 COFF-IMPORTLIB-NEXT: AddressSize: 32bit
335335 COFF-IMPORTLIB-NEXT: ImageFileHeader {
336336 COFF-IMPORTLIB-NEXT: Machine: IMAGE_FILE_MACHINE_UNKNOWN (0x0)
337 COFF-IMPORTLIB-NEXT: SectionCount: 65535
337 COFF-IMPORTLIB-NEXT: SectionCount: 0
338338 COFF-IMPORTLIB-NEXT: TimeDateStamp: 1970-09-09 19:52:32 (0x14C0000)
339 COFF-IMPORTLIB-NEXT: PointerToSymbolTable: 0x528542EB
340 COFF-IMPORTLIB-NEXT: SymbolCount: 20
339 COFF-IMPORTLIB-NEXT: PointerToSymbolTable: 0x0
340 COFF-IMPORTLIB-NEXT: SymbolCount: 0
341341 COFF-IMPORTLIB-NEXT: OptionalHeaderSize: 0
342 COFF-IMPORTLIB-NEXT: Characteristics [ (0x8)
343 COFF-IMPORTLIB-NEXT: IMAGE_FILE_LOCAL_SYMS_STRIPPED (0x8)
342 COFF-IMPORTLIB-NEXT: Characteristics [ (0x0)
344343 COFF-IMPORTLIB-NEXT: ]
345344 COFF-IMPORTLIB-NEXT: }
306306 }
307307
308308 for (const SectionRef &Section : Obj->sections()) {
309 bool Text = Section.isText();
310 if (!Text)
309 if (!Section.isText() || Section.isVirtual())
311310 continue;
312311
313312 uint64_t SectionAddr = Section.getAddress();
824824
825825 void COFFDumper::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); }
826826
827 static StringRef getSectionName(const llvm::object::COFFObjectFile *Obj,
828 COFFSymbolRef Symbol,
829 const coff_section *Section) {
827 static ErrorOr
828 getSectionName(const llvm::object::COFFObjectFile *Obj, int32_t SectionNumber,
829 const coff_section *Section) {
830830 if (Section) {
831831 StringRef SectionName;
832 Obj->getSectionName(Section, SectionName);
832 if (std::error_code EC = Obj->getSectionName(Section, SectionName))
833 return EC;
833834 return SectionName;
834835 }
835 int32_t SectionNumber = Symbol.getSectionNumber();
836836 if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG)
837 return "IMAGE_SYM_DEBUG";
837 return StringRef("IMAGE_SYM_DEBUG");
838838 if (SectionNumber == llvm::COFF::IMAGE_SYM_ABSOLUTE)
839 return "IMAGE_SYM_ABSOLUTE";
839 return StringRef("IMAGE_SYM_ABSOLUTE");
840840 if (SectionNumber == llvm::COFF::IMAGE_SYM_UNDEFINED)
841 return "IMAGE_SYM_UNDEFINED";
842 return "";
841 return StringRef("IMAGE_SYM_UNDEFINED");
842 return StringRef("");
843843 }
844844
845845 void COFFDumper::printSymbol(const SymbolRef &Sym) {
857857 if (Obj->getSymbolName(Symbol, SymbolName))
858858 SymbolName = "";
859859
860 StringRef SectionName = getSectionName(Obj, Symbol, Section);
860 StringRef SectionName = "";
861 ErrorOr Res =
862 getSectionName(Obj, Symbol.getSectionNumber(), Section);
863 if (Res)
864 SectionName = *Res;
861865
862866 W.printString("Name", SymbolName);
863867 W.printNumber("Value", Symbol.getValue());
928932 if (Section && Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT
929933 && Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
930934 const coff_section *Assoc;
931 StringRef AssocName;
932 std::error_code EC;
933 if ((EC = Obj->getSection(AuxNumber, Assoc)) ||
934 (EC = Obj->getSectionName(Assoc, AssocName))) {
935 StringRef AssocName = "";
936 std::error_code EC = Obj->getSection(AuxNumber, Assoc);
937 ErrorOr Res = getSectionName(Obj, AuxNumber, Assoc);
938 if (Res)
939 AssocName = *Res;
940 if (!EC)
941 EC = Res.getError();
942 if (EC) {
935943 AssocName = "";
936944 error(EC);
937945 }