This is an archive of the discontinued LLVM Phabricator instance.

[llvm-objdump] Add `Version Definitions` dumper
ClosedPublic

Authored by Higuoxing on Feb 25 2019, 6:07 AM.

Diff Detail

Repository
rL LLVM

Event Timeline

Higuoxing created this revision.Feb 25 2019, 6:07 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 25 2019, 6:07 AM

This LGTM. A minor suggestion is inline.
Please wait for @jhenderson opinion too.

tools/llvm-objdump/ELFDump.cpp
310 ↗(On Diff #188154)

You can start from 1:

VerdefIndex = 1;

313 ↗(On Diff #188154)

And do:

outs() << VerdefIndex++ << " "
grimar accepted this revision.Feb 25 2019, 6:17 AM
This revision is now accepted and ready to land.Feb 25 2019, 6:17 AM
Higuoxing updated this revision to Diff 188158.Feb 25 2019, 6:22 AM

Updating D58615: [llvm-objdump] Add Version Definitions dumper

Higuoxing marked an inline comment as done.Feb 25 2019, 6:23 AM
Higuoxing added inline comments.
tools/llvm-objdump/ELFDump.cpp
313 ↗(On Diff #188154)

Oh, that's cool! Thanks a lot.

How many verdefs do you get in a typical file? I'm looking at the hard-coded indentation amount of Verdaux entries after the first, and thinking that that indentation doesn't look quite right, and would look worse the higher the index, due to the first column changing in width. I think it should line up with the previous name, but I don't think it currently does. Additionally, if I'm not mistaken the formatting will look something like:

1 0x01 0x075bcd15 foo
2 0x02 0x3ade68b1 VERSION_1
...
9 0xab 0x12345678 something
10 0xdc 0xabcdef90 something_else

which doesn't look great. Assuming it's not unusual to have 10+ entries, could you do something that ensures the column width is consistent?

tools/llvm-objdump/ELFDump.cpp
314 ↗(On Diff #188158)

This only prints a width of 2, but the flags could require four digits. Are there never any flags beyond 0xff?

How many verdefs do you get in a typical file? I'm looking at the hard-coded indentation amount of Verdaux entries after the first, and thinking that that indentation doesn't look quite right, and would look worse the higher the index, due to the first column changing in width. I think it should line up with the previous name, but I don't think it currently does. Additionally, if I'm not mistaken the formatting will look something like:

1 0x01 0x075bcd15 foo
2 0x02 0x3ade68b1 VERSION_1
...
9 0xab 0x12345678 something
10 0xdc 0xabcdef90 something_else

which doesn't look great. Assuming it's not unusual to have 10+ entries, could you do something that ensures the column width is consistent?

I think there could be an object file that has over 10 entries in its verdef section.
However, gnu-objdump has the same problem. I currently have no idea how to make it compatible with gnu-objdump and ensure the column width is consistent.

--- !ELF
FileHeader:
  Class:           ELFCLASS64
  Data:            ELFDATA2LSB
  Type:            ET_DYN
  Machine:         EM_X86_64
  Entry:           0x0000000000001000
Sections:
  - Name:            .gnu.version_d
    Type:            SHT_GNU_verdef
    Flags:           [ SHF_ALLOC ]
    Address:         0x0000000000000230
    Link:            .dynstr
    AddressAlign:    0x0000000000000004
    Info:            0x0000000000000010
    Entries:
      - Version:         1
        Flags:           1
        VersionNdx:      1
        Hash:            123456789
        Names:
          - VERSION_1
      - Version:         1
        Flags:           2
        VersionNdx:      2
        Hash:            987654321
        Names:
          - VERSION_2
      - Version:         1
        Flags:           2
        VersionNdx:      3
        Hash:            98765321
        Names:
          - VERSION_3
      - Version:         1
        Flags:           2
        VersionNdx:      4
        Hash:            98654321
        Names:
          - VERSION_4
      - Version:         1
        Flags:           2
        VersionNdx:      5
        Hash:            98765421
        Names:
          - VERSION_5
      - Version:         1
        Flags:           2
        VersionNdx:      6
        Hash:            989654321
        Names:
          - VERSION_6
      - Version:         1
        Flags:           2
        VersionNdx:      7
        Hash:            997654321
        Names:
          - VERSION_7
      - Version:         1
        Flags:           2
        VersionNdx:      8
        Hash:            997654321
        Names:
          - VERSION_8
      - Version:         1
        Flags:           2
        VersionNdx:      9
        Hash:            997654321
        Names:
          - VERSION_9
      - Version:         1
        Flags:           2
        VersionNdx:      10
        Hash:            997654321
        Names:
          - VERSION_10
      - Version:         1
        Flags:           2
        VersionNdx:      11
        Hash:            997654321
        Names:
          - VERSION_11
      - Version:         1
        Flags:           2
        VersionNdx:      12
        Hash:            997654321
        Names:
          - VERSION_12
      - Version:         1
        Flags:           2
        VersionNdx:      13
        Hash:            997654321
        Names:
          - VERSION_13
DynamicSymbols:
  Global:
    - Name:            bar
...
tools/llvm-objdump/ELFDump.cpp
314 ↗(On Diff #188158)

As for vd_flags field, its value can be 0x01(VER_FLG_BASE) or 0x02(VER_FLG_WEAK).
See, https://docs.oracle.com/cd/E19957-01/806-0641/chapter6-80869/index.html

How many verdefs do you get in a typical file? I'm looking at the hard-coded indentation amount of Verdaux entries after the first, and thinking that that indentation doesn't look quite right, and would look worse the higher the index, due to the first column changing in width. I think it should line up with the previous name, but I don't think it currently does. Additionally, if I'm not mistaken the formatting will look something like:

1 0x01 0x075bcd15 foo
2 0x02 0x3ade68b1 VERSION_1
...
9 0xab 0x12345678 something
10 0xdc 0xabcdef90 something_else

which doesn't look great. Assuming it's not unusual to have 10+ entries, could you do something that ensures the column width is consistent?

I think there could be an object file that has over 10 entries in its verdef section.
However, gnu-objdump has the same problem. I currently have no idea how to make it compatible with gnu-objdump and ensure the column width is consistent.

In general, we have not been aiming to be output-identical to GNU tools, but to be similar enough so that the output is clear. Where there are clear improvements to be had, we have done so. As such, I don't think you need to match GNU objdump's output byte for byte here. I would recommend left-padding the index column with spaces as needed. As for the aux fields, I would pad it so that it lines up exactly with the name above it.

Updating D58615: [llvm-objdump] Add Version Definitions dumper

I found a way that not so elegant to solve this problem. We assume that the verdef section contains no greater than 99 entries, then according to the index print some hard coded blank spaces.

jhenderson added inline comments.Feb 26 2019, 1:51 AM
test/tools/llvm-objdump/verdef-many-entries-elf.test
4 ↗(On Diff #188317)

By default FileCheck treats all consecutive whitespace as a single space, both in input and check patterns, unless you specify --strict-whitespace. I don't think you need to go down this approach, so I don't think you need a test for so many entries (but it's up to you).

tools/llvm-objdump/ELFDump.cpp
312 ↗(On Diff #188317)

"entries of verdef section" -> "entries in the SHT_GNU_verdef" section. You have also manually formatted the paragraph, with line breaks that are too early, rather than letting clang-format do it for you.

316 ↗(On Diff #188317)

You are going along the right lines here, by using sh_info, but I don't think you should make any assumptions about the maximum number of entries, except that it won't be greater than 2^32 - 1. Better would be to simply convert sh_info to a string and use string.size() to get the required width.

329–330 ↗(On Diff #188317)

Rather than hard-coding the number of spaces here, use std::string(size, ' ') to create a string of spaces. You can base the size on VerdefIndexWidth.

Higuoxing updated this revision to Diff 188330.Feb 26 2019, 3:12 AM

Updating D58615: [llvm-objdump] Add Version Definitions dumper

jhenderson accepted this revision.Feb 26 2019, 4:42 AM

LGTM, with one nit still.

tools/llvm-objdump/ELFDump.cpp
312 ↗(On Diff #188317)

"entries of" -> "entries in the"

(like I already requested...)

Higuoxing updated this revision to Diff 188342.Feb 26 2019, 4:58 AM

Updating D58615: [llvm-objdump] Add Version Definitions dumper

@jhenderson, @grimar thank you very much!

This revision was automatically updated to reflect the committed changes.