Index: llvm/trunk/test/tools/llvm-readobj/elf-broken-dynsym-link.test =================================================================== --- llvm/trunk/test/tools/llvm-readobj/elf-broken-dynsym-link.test +++ llvm/trunk/test/tools/llvm-readobj/elf-broken-dynsym-link.test @@ -0,0 +1,60 @@ +## Test that we are able to dump section headers even if the +## .dynsym section's sh_link field is broken. + +## Case 1: sh_link is set to 0. +# RUN: yaml2obj %s -o %t1 +# RUN: llvm-readobj -S %t1 2>&1 | FileCheck %s --check-prefixes=LLVM,ERR +# RUN: llvm-readelf -S %t1 2>&1 | FileCheck %s --check-prefixes=GNU,ERR + +# ERR: warning: invalid sh_type for string table, expected SHT_STRTAB + +# LLVM: Name: .dynsym +# LLVM-NEXT: Type: SHT_DYNSYM +# LLVM-NEXT: Flags [ +# LLVM-NEXT: SHF_ALLOC +# LLVM-NEXT: ] +# LLVM-NEXT: Address: 0x0 +# LLVM-NEXT: Offset: 0x180 +# LLVM-NEXT: Size: 24 +# LLVM-NEXT: Link: 0 + +# GNU: Section Headers: +# GNU-NEXT: [Nr] Name Type Address Off Size ES Flg Lk +# GNU-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 +# GNU-NEXT: [ 1] .dynsym DYNSYM 0000000000000000 000180 000018 18 A 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .dynsym + Type: SHT_DYNSYM + +## TODO: Remove precompiled input object after fixing yaml2obj. +## See https://bugs.llvm.org/show_bug.cgi?id=42216. + +## Case 2: sh_link is set to 255, which is larger than the number of the sections. +# RUN: llvm-readobj -S %p/Inputs/elf-broken-dynsym-link.elf-x86-64 2>&1 \ +# RUN: | FileCheck %s --check-prefixes=LLVM2,ERR2 +# RUN: llvm-readelf -S %p/Inputs/elf-broken-dynsym-link.elf-x86-64 2>&1 \ +# RUN: | FileCheck %s --check-prefixes=GNU2,ERR2 + +# ERR2: warning: invalid section index + +# LLVM2: Name: .dynsym +# LLVM2-NEXT: Type: SHT_DYNSYM +# LLVM2-NEXT: Flags [ +# LLVM2-NEXT: SHF_ALLOC +# LLVM2-NEXT: ] +# LLVM2-NEXT: Address: 0x0 +# LLVM2-NEXT: Offset: 0x180 +# LLVM2-NEXT: Size: 2 +# LLVM2-NEXT: Link: 255 + +# GNU2: Section Headers: +# GNU2-NEXT: [Nr] Name Type Address Off Size ES Flg Lk +# GNU2-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 +# GNU2-NEXT: [ 1] .dynsym DYNSYM 0000000000000000 000180 000002 18 A 255 Index: llvm/trunk/test/tools/yaml2obj/explicit-dynsym-no-dynstr.yaml =================================================================== --- llvm/trunk/test/tools/yaml2obj/explicit-dynsym-no-dynstr.yaml +++ llvm/trunk/test/tools/yaml2obj/explicit-dynsym-no-dynstr.yaml @@ -2,14 +2,14 @@ ## explicitly, but .dynstr is not present. # RUN: yaml2obj %s -o %t -# RUN: not llvm-readelf --section-headers %t 2>&1 | FileCheck %s +# RUN: llvm-readelf --section-headers %t | FileCheck %s -## TODO: Check that .dynsym has Link field set to 0. -## GNU readelf is able to dump sections headers, -## but llvm-readelf reports an error below too early. -## See https://bugs.llvm.org/show_bug.cgi?id=42215. +## Check that .dynsym has Link field set to 0. -# CHECK: error: invalid sh_type for string table, expected SHT_STRTAB +# CHECK: Section Headers: +# CHECK-NEXT: [Nr] Name Type Address Off Size ES Flg Lk +# CHECK-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 +# CHECK-NEXT: [ 1] .dynsym DYNSYM 0000000000000000 000180 000018 18 A 0 --- !ELF FileHeader: Index: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp +++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp @@ -1423,7 +1423,11 @@ // This is only used (if Elf_Shdr present)for naming section in GNU // style DynSymtabName = unwrapOrError(Obj->getSectionName(&Sec)); - DynamicStringTable = unwrapOrError(Obj->getStringTableForSymtab(Sec)); + + if (Expected E = Obj->getStringTableForSymtab(Sec)) + DynamicStringTable = *E; + else + warn(E.takeError()); } break; case ELF::SHT_SYMTAB_SHNDX: Index: llvm/trunk/tools/llvm-readobj/llvm-readobj.h =================================================================== --- llvm/trunk/tools/llvm-readobj/llvm-readobj.h +++ llvm/trunk/tools/llvm-readobj/llvm-readobj.h @@ -23,6 +23,7 @@ // Various helper functions. LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg); void reportWarning(Twine Msg); + void warn(llvm::Error Err); void error(std::error_code EC); void error(llvm::Error EC); template T error(llvm::Expected &&E) { Index: llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp =================================================================== --- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp +++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp @@ -378,6 +378,12 @@ WithColor::warning(errs()) << Msg << "\n"; } +void warn(Error Err) { + handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) { + reportWarning(EI.message()); + }); +} + void error(Error EC) { if (!EC) return;