llvm.org GIT mirror llvm / 9a6c902
Factor out the checking of string tables. This moves the error checking for string tables to getStringTable which returns an ErrorOr<StringRef>. This improves error checking, makes it uniform across all string tables and makes it possible to check them once instead of once per name. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240950 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 4 years ago
8 changed file(s) with 67 addition(s) and 38 deletion(s). Raw diff Collapse all Expand all
171171
172172 const Elf_Ehdr *Header;
173173 const Elf_Shdr *SectionHeaderTable;
174 const Elf_Shdr *dot_shstrtab_sec; // Section header string table.
175 const Elf_Shdr *dot_strtab_sec; // Symbol header string table.
174 StringRef DotShstrtab; // Section header string table.
175 StringRef DotStrtab; // Symbol header string table.
176176 const Elf_Shdr *dot_symtab_sec; // Symbol table section.
177177
178178 const Elf_Shdr *SymbolTableSectionHeaderIndex;
234234 const T *getEntry(uint32_t Section, uint32_t Entry) const;
235235 template
236236 const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
237 ErrorOr getString(const Elf_Shdr *Section, uint32_t Offset) const;
237 ErrorOr getStringTable(const Elf_Shdr *Section) const;
238238 const char *getDynamicString(uintX_t Offset) const;
239239 ErrorOr getSymbolVersion(const Elf_Shdr *section,
240240 const Elf_Sym *Symb,
370370 ///
371371 /// \p SymTab is used to lookup the string table to use to get the symbol's
372372 /// name.
373 ErrorOr getSymbolName(const Elf_Shdr *StrTab,
374 const Elf_Sym *Symb) const;
373 ErrorOr getSymbolName(StringRef StrTab, const Elf_Sym *Symb) const;
375374 ErrorOr getSectionName(const Elf_Shdr *Section) const;
376375 uint64_t getSymbolIndex(const Elf_Sym *sym) const;
377376 ErrorOr > getSectionContents(const Elf_Shdr *Sec) const;
544543 SymTable, getEntry(SymTable, Rel->getSymbol(isMips64EL())));
545544 }
546545
547 // Verify that the last byte in the string table in a null.
548 template
549 void ELFFile::VerifyStrTab(const Elf_Shdr *sh) const {
550 const char *strtab = (const char *)base() + sh->sh_offset;
551 if (strtab[sh->sh_size - 1] != 0)
552 // FIXME: Proper error handling.
553 report_fatal_error("String table must end with a null terminator!");
554 }
555
556546 template
557547 uint64_t ELFFile::getNumSections() const {
558548 assert(Header && "Header not initialized!");
576566
577567 template
578568 ELFFile::ELFFile(StringRef Object, std::error_code &EC)
579 : Buf(Object), SectionHeaderTable(nullptr), dot_shstrtab_sec(nullptr),
580 dot_strtab_sec(nullptr), dot_symtab_sec(nullptr),
569 : Buf(Object), SectionHeaderTable(nullptr), dot_symtab_sec(nullptr),
581570 SymbolTableSectionHeaderIndex(nullptr), dot_gnu_version_sec(nullptr),
582571 dot_gnu_version_r_sec(nullptr), dot_gnu_version_d_sec(nullptr),
583572 dt_soname(nullptr) {
625614 }
626615 SymbolTableSectionHeaderIndex = &Sec;
627616 break;
628 case ELF::SHT_SYMTAB:
617 case ELF::SHT_SYMTAB: {
629618 if (dot_symtab_sec) {
630619 // More than one .symtab!
631620 EC = object_error::parse_failed;
632621 return;
633622 }
634623 dot_symtab_sec = &Sec;
635 dot_strtab_sec = getSection(Sec.sh_link);
636 break;
624 ErrorOr SymtabOrErr = getStringTable(getSection(Sec.sh_link));
625 if ((EC = SymtabOrErr.getError()))
626 return;
627 DotStrtab = *SymtabOrErr;
628 } break;
637629 case ELF::SHT_DYNSYM: {
638630 if (DynSymRegion.Addr) {
639631 // More than one .dynsym!
687679 }
688680
689681 // Get string table sections.
690 dot_shstrtab_sec = getSection(getStringTableIndex());
691 if (dot_shstrtab_sec) {
692 // Verify that the last byte in the string table in a null.
693 VerifyStrTab(dot_shstrtab_sec);
694 }
682 ErrorOr SymtabOrErr =
683 getStringTable(getSection(getStringTableIndex()));
684 if ((EC = SymtabOrErr.getError()))
685 return;
686 DotShstrtab = *SymtabOrErr;
695687
696688 // Build symbol name side-mapping if there is one.
697689 if (SymbolTableSectionHeaderIndex) {
864856 }
865857
866858 template
867 ErrorOr ELFFile::getString(const Elf_Shdr *Section,
868 ELF::Elf32_Word Offset) const {
859 ErrorOr
860 ELFFile::getStringTable(const Elf_Shdr *Section) const {
869861 if (Section->sh_type != ELF::SHT_STRTAB)
870862 return object_error::parse_failed;
871 if (Offset >= Section->sh_size)
863 uint64_t Offset = Section->sh_offset;
864 uint64_t Size = Section->sh_size;
865 if (Offset + Size > Buf.size())
872866 return object_error::parse_failed;
873 return StringRef((const char *)base() + Section->sh_offset + Offset);
867 StringRef Data((const char *)base() + Section->sh_offset, Size);
868 if (Data[Size - 1] != '\0')
869 return object_error::string_table_non_null_end;
870 return Data;
874871 }
875872
876873 template
883880 template
884881 ErrorOr
885882 ELFFile::getStaticSymbolName(const Elf_Sym *Symb) const {
886 return getSymbolName(dot_strtab_sec, Symb);
883 return getSymbolName(DotStrtab, Symb);
887884 }
888885
889886 template
901898 }
902899
903900 template
904 ErrorOr ELFFile::getSymbolName(const Elf_Shdr *StrTab,
901 ErrorOr ELFFile::getSymbolName(StringRef StrTab,
905902 const Elf_Sym *Sym) const {
906 return getString(StrTab, Sym->st_name);
903 uint32_t Offset = Sym->st_name;
904 if (Offset >= StrTab.size())
905 return object_error::parse_failed;
906 return StringRef(StrTab.data() + Offset);
907907 }
908908
909909 template
910910 ErrorOr
911911 ELFFile::getSectionName(const Elf_Shdr *Section) const {
912 return getString(dot_shstrtab_sec, Section->sh_name);
912 uint32_t Offset = Section->sh_name;
913 if (Offset >= DotShstrtab.size())
914 return object_error::parse_failed;
915 return StringRef(DotShstrtab.data() + Offset);
913916 }
914917
915918 template
916919 ErrorOr ELFFile::getSymbolVersion(const Elf_Shdr *section,
917920 const Elf_Sym *symb,
918921 bool &IsDefault) const {
922 StringRef StrTab;
923 if (section) {
924 ErrorOr StrTabOrErr = getStringTable(section);
925 if (std::error_code EC = StrTabOrErr.getError())
926 return EC;
927 StrTab = *StrTabOrErr;
928 }
919929 // Handle non-dynamic symbols.
920930 if (section != DynSymRegion.Addr && section != nullptr) {
921931 // Non-dynamic symbols can have versions in their names
922932 // A name of the form 'foo@V1' indicates version 'V1', non-default.
923933 // A name of the form 'foo@@V2' indicates version 'V2', default version.
924 ErrorOr SymName = getSymbolName(section, symb);
934 ErrorOr SymName = getSymbolName(StrTab, symb);
925935 if (!SymName)
926936 return SymName;
927937 StringRef Name = *SymName;
2626 invalid_file_type,
2727 parse_failed,
2828 unexpected_eof,
29 string_table_non_null_end,
2930 bitcode_section_not_found,
3031 macho_small_load_command,
3132 macho_load_segment_too_many_sections,
4040 return "Invalid data was encountered while parsing the file";
4141 case object_error::unexpected_eof:
4242 return "The end of the file was unexpectedly encountered";
43 case object_error::string_table_non_null_end:
44 return "String table must end with a null terminator";
4345 case object_error::bitcode_section_not_found:
4446 return "Bitcode section not found in object file";
4547 case object_error::macho_small_load_command:
0 RUN: not llvm-dwarfdump %p/Inputs/invalid-bad-rel-type.elf 2>&1 | FileCheck %s
11 RUN: not llvm-objdump -s %p/Inputs/invalid-strtab-type.elf 2>&1 | FileCheck %s
2 RUN: not llvm-objdump -s %p/Inputs/invalid-strtab-size.elf 2>&1 | FileCheck %s
23 CHECK: Invalid data was encountered while parsing the file
34
45 RUN: not llvm-objdump -s %p/Inputs/invalid-strtab-non-null.elf 2>&1 | FileCheck --check-prefix=NON-NULL %s
323323 const Elf_Shdr *SymTab = EF.getSection(sec->sh_link);
324324 assert(SymTab->sh_type == ELF::SHT_SYMTAB ||
325325 SymTab->sh_type == ELF::SHT_DYNSYM);
326 const Elf_Shdr *StrTab = EF.getSection(SymTab->sh_link);
326 const Elf_Shdr *StrTabSec = EF.getSection(SymTab->sh_link);
327 ErrorOr StrTabOrErr = EF.getStringTable(StrTabSec);
328 if (std::error_code EC = StrTabOrErr.getError())
329 return EC;
330 StringRef StrTab = *StrTabOrErr;
327331 uint8_t type;
328332 StringRef res;
329333 int64_t addend = 0;
756756 TargetName = SecName.get();
757757 } else if (Sym.first) {
758758 const Elf_Shdr *SymTable = Sym.first;
759 const Elf_Shdr *StrTable = Obj->getSection(SymTable->sh_link);
760 TargetName = errorOrDefault(Obj->getSymbolName(StrTable, Sym.second));
759 const Elf_Shdr *StrTableSec = Obj->getSection(SymTable->sh_link);
760 ErrorOr StrTableOrErr = Obj->getStringTable(StrTableSec);
761 if (!error(StrTableOrErr.getError()))
762 TargetName =
763 errorOrDefault(Obj->getSymbolName(*StrTableOrErr, Sym.second));
761764 }
762765
763766 if (opts::ExpandRelocs) {
182182 return obj2yaml_error::success;
183183
184184 const Elf_Shdr *SymTab = NamePair.first;
185 const Elf_Shdr *StrTab = Obj.getSection(SymTab->sh_link);
185 const Elf_Shdr *StrTabSec = Obj.getSection(SymTab->sh_link);
186 ErrorOr StrTabOrErr = Obj.getStringTable(StrTabSec);
187 if (std::error_code EC = StrTabOrErr.getError())
188 return EC;
189 StringRef StrTab = *StrTabOrErr;
186190
187191 ErrorOr NameOrErr = Obj.getSymbolName(StrTab, NamePair.second);
188192 if (std::error_code EC = NameOrErr.getError())
301305 // Get sh_info which is the signature.
302306 const Elf_Sym *symbol = Obj.getSymbol(Shdr->sh_info);
303307 const Elf_Shdr *symtab = Obj.getSection(Shdr->sh_link);
304 const Elf_Shdr *StrTab = Obj.getSection(symtab->sh_link);
308 const Elf_Shdr *StrTabSec = Obj.getSection(symtab->sh_link);
309 ErrorOr StrTabOrErr = Obj.getStringTable(StrTabSec);
310 if (std::error_code EC = StrTabOrErr.getError())
311 return EC;
312 StringRef StrTab = *StrTabOrErr;
305313 auto sectionContents = Obj.getSectionContents(Shdr);
306314 if (std::error_code ec = sectionContents.getError())
307315 return ec;