Page MenuHomePhabricator

[llvm-readobj] Fix bugs with unrecognized types in switch statements
ClosedPublic

Authored by rprichard on Oct 25 2018, 1:54 PM.

Details

Summary

Add missing breaks. Several functions used nested switch statements,
where the outer switch branches based on the architecture, and the inner
switch handles architecture-specific types. If the type isn't
architecture-specific, break out to the generic types rather than fall
through.

getElfPtType: For GNU-style output, llvm-readobj prints
"<unknown>: 0xnnnnnnnn" for an unrecognized segment type, unless the
architecture is EM_ARM, EM_MIPS, or EM_MIPS_RS3_LE, in which case it
prints "". This behavior appears accidental, so instead, always print
the "<unknown>: 0xnnnnnnnn" string.

Diff Detail

Repository
rL LLVM

Event Timeline

rprichard created this revision.Oct 25 2018, 1:54 PM

I didn't see a good way to write a regression test. I tested it by hand with this script:

#!/bin/sh
touch empty.s

#TOOLCHAIN=/x/clang7/bin
TOOLCHAIN=/x/llvm-upstream/stage1/bin

# ARM binary test (test getElfSegmentType and getElfPtType)
echo ==== ARM test
$TOOLCHAIN/clang -target arm -c empty.s 2>/dev/null
$TOOLCHAIN/ld.lld -pie empty.o -o arm.out 2>/dev/null
# Change PT_GNU_RELRO(0x6474e552) to 0x70000002.
sed -i -e 's/\x52\xe5\x74\x64/\x02\x00\x00\x70/g' arm.out
$TOOLCHAIN/llvm-readobj -l arm.out | grep 0x70000002
$TOOLCHAIN/llvm-readelf -l arm.out | grep '0x00040 0x01000'

# x86_64 binary test (test getSectionTypeString)
echo ==== x86_64 test
$TOOLCHAIN/clang -target x86_64 -c empty.s 2>/dev/null
$TOOLCHAIN/ld.lld -pie empty.o -o x86_64.out 2>/dev/null
# Change SHT_GNU_HASH(0x6ffffff6) to 0x70000006.
sed -i -e 's/\xf6\xff\xff\x6f/\x06\x00\x00\x70/g' x86_64.out
$TOOLCHAIN/llvm-readelf -S x86_64.out | grep gnu.hash

# MIPS binary test (test getTypeString for dynamic entries)
echo ==== mipsel test
$TOOLCHAIN/clang -target mipsel -c empty.s 2>/dev/null
$TOOLCHAIN/ld.lld -pie empty.o -o mips.out 2>/dev/null
# Change DT_MIPS_RLD_VERSION(0x70000001) to 0x70000000.
sed -i -e 's/\x01\x00\x00\x70/\x00\x00\x00\x70/g' mips.out
$TOOLCHAIN/llvm-readobj -d mips.out | grep 0x70000000

Clang 7.0.0 output (bad):

==== ARM test
    Type: PT_MIPS_OPTIONS (0x70000002)
                 0x001000 0x00001000 0x00001000 0x00040 0x01000 R   0x1
==== x86_64 test
  [ 2] .gnu.hash         MIPS_REGINFO    00000000000001e0 0001e0 00001c 00   A  1   0  8
==== mipsel test
  0x70000000 PPC64_GLINK          0x1

New output:

==== ARM test
    Type:  (0x70000002)
  <unknown>: 0x70000002 0x001000 0x00001000 0x00001000 0x00040 0x01000 R   0x1
==== x86_64 test
  [ 2] .gnu.hash                         00000000000001e0 0001e0 00001c 00   A  1   0  8
==== mipsel test
  0x70000000 unknown              0x1
rprichard retitled this revision from [llvm-readobj] Fix minor segment type dumping bugs to [llvm-readobj] Fix bugs with unrecognized types in switch statements.Oct 25 2018, 2:08 PM
grimar accepted this revision.Oct 26 2018, 2:23 AM

I think it is possible just to add a precompiled binary(ies) to tools\llvm-readobj\Inputs and write the corresponding test(s).
But honestly I am not in favor of using precompiled binaries and in this case, perhaps it is fine to skip the test,
the issue seems to be obvious, so LGTM.

This revision is now accepted and ready to land.Oct 26 2018, 2:23 AM
This revision was automatically updated to reflect the committed changes.