Index: llvm/test/tools/llvm-readobj/ELF/groups.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/groups.test +++ llvm/test/tools/llvm-readobj/ELF/groups.test @@ -81,11 +81,16 @@ - Name: .symtab Type: SHT_SYMTAB Link: [[SYMTABLINK=.strtab]] + - Name: .strtab + Type: SHT_STRTAB + Content: [[STRTABCONTENT=]] Symbols: - Name: foo Section: .text.foo + StName: [[SYM1STNAME=]] - Name: bar Section: .text.bar + StName: [[SYM2STNAME=]] ## Check that we report a warning and continue dumping when a section is included ## in two group sections at the same time. @@ -379,3 +384,37 @@ # MEMBER-GNU-NEXT: [Index] Name # MEMBER-GNU-NEXT: [ 255] # MEMBER-GNU-NEXT: [ 6] .rela.text.bar + +## Check warnings that are reported when the st_name field of the signature symbol goes past the end of the string table. + +## We set the content of the string table to '0061626300' ('\0abc\0') to fixup the size of the string table. +## It makes easier the task of testing boundary conditions. +# RUN: yaml2obj %s -DSTRTABCONTENT="0061626300" -DSYM1STNAME=4 -DSYM2STNAME=5 -o %t.signame.o +# RUN: llvm-readobj --elf-section-groups %t.signame.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t.signame.o %s --check-prefixes=SIGNAME1-WARN,SIGNAME1-LLVM --implicit-check-not=warning: +# RUN: llvm-readelf --elf-section-groups %t.signame.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t.signame.o %s --check-prefixes=SIGNAME1-WARN,SIGNAME1-GNU --implicit-check-not=warning: + +# SIGNAME1-WARN: warning: '[[FILE]]': unable to get the name of the symbol with index 2: st_name (0x5) is past the end of the string table of size 0x5 + +# SIGNAME1-LLVM: Signature: {{$}} +# SIGNAME1-LLVM: Signature: + +# SIGNAME1-GNU: COMDAT group section [ 1] `.group' [] contains 2 sections: +# SIGNAME1-GNU: COMDAT group section [ 2] `.group1' [] contains 2 sections: + +## Chech we report a warning when the string table that contains the signature symbol name is not null-terminated. + +# RUN: yaml2obj %s -DSTRTABCONTENT="0061626361" -DSYM1STNAME=4 -DSYM2STNAME=5 -o %t.signame2.o +# RUN: llvm-readobj --elf-section-groups %t.signame2.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t.signame2.o %s --check-prefixes=SIGNAME2-WARN,SIGNAME2-LLVM --implicit-check-not=warning: +# RUN: llvm-readelf --elf-section-groups %t.signame2.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t.signame2.o %s --check-prefixes=SIGNAME2-WARN,SIGNAME2-GNU --implicit-check-not=warning: + +# SIGNAME2-WARN: warning: '[[FILE]]': unable to get the string table for SHT_SYMTAB section with index 7: SHT_STRTAB string table section [index 8] is non-null terminated + +# SIGNAME2-LLVM: Signature: +# SIGNAME2-LLVM: Signature: + +# SIGNAME2-GNU: COMDAT group section [ 1] `.group' [] contains 2 sections: +# SIGNAME2-GNU: COMDAT group section [ 2] `.group1' [] contains 2 sections: Index: llvm/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/ELFDumper.cpp +++ llvm/tools/llvm-readobj/ELFDumper.cpp @@ -3595,7 +3595,7 @@ } template std::vector DumpStyle::getGroups() { - auto GetSignature = [&](const Elf_Sym &Sym, + auto GetSignature = [&](const Elf_Sym &Sym, unsigned SymNdx, const Elf_Shdr &Symtab) -> StringRef { Expected StrTableOrErr = Obj.getStringTableForSymtab(Symtab); if (!StrTableOrErr) { @@ -3605,8 +3605,16 @@ return ""; } - // TODO: this might lead to a crash or produce a wrong result, when the - // st_name goes past the end of the string table. + StringRef Strings = *StrTableOrErr; + if (Sym.st_name >= Strings.size()) { + reportUniqueWarning(createError( + "unable to get the name of the symbol with index " + Twine(SymNdx) + + ": st_name (0x" + Twine::utohexstr(Sym.st_name) + + ") is past the end of the string table of size 0x" + + Twine::utohexstr(Strings.size()))); + return ""; + } + return StrTableOrErr->data() + Sym.st_name; }; @@ -3621,7 +3629,7 @@ if (Expected SymtabOrErr = Obj.getSection(Sec.sh_link)) { if (Expected SymOrErr = Obj.template getEntry(**SymtabOrErr, Sec.sh_info)) - Signature = GetSignature(**SymOrErr, **SymtabOrErr); + Signature = GetSignature(**SymOrErr, Sec.sh_info, **SymtabOrErr); else reportUniqueWarning(createError( "unable to get the signature symbol for " + describe(Obj, Sec) +