This is an archive of the discontinued LLVM Phabricator instance.

[yaml2obj/obj2yaml] - Add support for SHT_HASH sections.
ClosedPublic

Authored by grimar on Sep 26 2019, 7:18 AM.

Details

Summary

SHT_HASH specification is:
http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash

In short the format is the following: it has 2 uint32 fields in its header: nbucket and nchain followed
by (nbucket + nchain) uint32 values.

This patch allows dumping and parsing such sections.

Diff Detail

Repository
rL LLVM

Event Timeline

grimar created this revision.Sep 26 2019, 7:18 AM
tools/obj2yaml/elf2yaml.cpp
645 ↗(On Diff #221940)

ELFT::Is64Bits ? 8 : 4

AddressSize is not used. A dummy 0 works as well.

646 ↗(On Diff #221940)

Use getU32(Cur)

653 ↗(On Diff #221940)
S->Bucket.emplace(NBucket);
for (uint32_t &V : *S->Bucket)
  V = Data.getU32(Cur);
663 ↗(On Diff #221940)

if LLVM_ENABLE_ABI_BREAKING_CHECKS && !LLVM_ENABLE_ASSERTIONS, this will fail.

Add !Cur outside.

jhenderson added inline comments.Sep 27 2019, 2:19 AM
lib/ObjectYAML/ELFEmitter.cpp
824–825 ↗(On Diff #221940)

Could it be possible to specify a custom sh_link value?

827 ↗(On Diff #221940)

As with the stack sizes sections, it would be good if a user can specify the size explicitly.

841 ↗(On Diff #221940)

Maybe rather than "4" here, this should be something like sizeof(Elf32_Word)?

test/tools/obj2yaml/elf-hash-section.yaml
26 ↗(On Diff #221940)

"A non-empty hash table:"

35 ↗(On Diff #221940)

fallbacks -> falls back
using "Content" -> using the "Content"

75 ↗(On Diff #221940)

grater -> greater

test/tools/yaml2obj/elf-hash-section.yaml
3 ↗(On Diff #221940)

desctibe -> describe
"a SHT_HASH section using the "Content" tag"

38 ↗(On Diff #221940)

desctibe SHT_HASH -> describe a SHT_HASH section

65 ↗(On Diff #221940)

What about "Content" and "Chain"?

69 ↗(On Diff #221940)

I'd quote the names of the tags in the error messages (like you do in the comment above).

115 ↗(On Diff #221940)

or -> nor

(use "or" with "either" and "nor" with "neither" to be strictly correct)

tools/obj2yaml/elf2yaml.cpp
648 ↗(On Diff #221940)

4 -> sizeof (Elf32_Word)?

grimar updated this revision to Diff 222406.Sep 30 2019, 6:14 AM
grimar marked 20 inline comments as done.
  • Addressed review comments.
lib/ObjectYAML/ELFEmitter.cpp
824–825 ↗(On Diff #221940)

I prepared a follow-up for this: D68214

827 ↗(On Diff #221940)

I prepared a follow-up for this: D68216

841 ↗(On Diff #221940)

I wouldn't do that. Spec says: "A hash table consists of Elf32_Word or Elf64_Word objects that provide for symbol table access."
I.e. we could use sizeof(typename ELFT::Word) here, but given that sizeof(Elf32_Word) == sizeof(Elf64_Word) == 4, what is the profit?
It does not make the code cleaner or more readable, using 4 instead looks much simpler.
For the same reason I used support::endian::write<uint32_t> instead of possible support::endian::write<typename ELFT::Word>

FWIW in LLD we do the same sometimes: https://github.com/llvm-mirror/lld/blob/master/ELF/SyntheticSections.cpp#L2421.

test/tools/yaml2obj/elf-hash-section.yaml
65 ↗(On Diff #221940)

Seems I've forgot about this combination. Added a test.

69 ↗(On Diff #221940)

Done.

tools/obj2yaml/elf2yaml.cpp
648 ↗(On Diff #221940)

See my comment about this above.

663 ↗(On Diff #221940)

I also used llvm_unreachable. It should be impossible to have any errors here.

jhenderson accepted this revision.Sep 30 2019, 10:01 AM

LGTM, with a couple of minor points.

lib/ObjectYAML/ELFYAML.cpp
1214 ↗(On Diff #222406)

and -> or

test/tools/yaml2obj/elf-hash-section.yaml
3 ↗(On Diff #222406)

Missing trailing full stop.

This revision is now accepted and ready to land.Sep 30 2019, 10:01 AM
MaskRay accepted this revision.Sep 30 2019, 10:06 AM
grimar edited the summary of this revision. (Show Details)Oct 1 2019, 12:50 AM
This revision was automatically updated to reflect the committed changes.
grimar marked 2 inline comments as done.
Herald added a project: Restricted Project. · View Herald TranscriptOct 1 2019, 2:44 AM

What platform was this tested on? This seems to be failing on my Fedora 31 x86_64 box:

FAIL: LLVM :: tools/obj2yaml/elf-hash-section.yaml (49646 of 58398)
******************** TEST 'LLVM :: tools/obj2yaml/elf-hash-section.yaml' FAILED ********************
Script:
--
: 'RUN: at line 7';   /tmp/_update_lc/t/bin/yaml2obj --docnum=1 /home/dave/s/lp/llvm/test/tools/obj2yaml/elf-hash-section.yaml -o /tmp/_update_lc/t/test/tools/obj2yaml/Output/elf-hash-section.yaml.tmp1
: 'RUN: at line 8';   /tmp/_update_lc/t/bin/obj2yaml /tmp/_update_lc/t/test/tools/obj2yaml/Output/elf-hash-section.yaml.tmp1 | /tmp/_update_lc/t/bin/FileCheck /home/dave/s/lp/llvm/test/tools/obj2yaml/elf-hash-section.yaml --check-prefix=CHAIN-BUCKET
: 'RUN: at line 38';   /tmp/_update_lc/t/bin/yaml2obj --docnum=2 /home/dave/s/lp/llvm/test/tools/obj2yaml/elf-hash-section.yaml -o /tmp/_update_lc/t/test/tools/obj2yaml/Output/elf-hash-section.yaml.tmp2
: 'RUN: at line 39';   /tmp/_update_lc/t/bin/obj2yaml /tmp/_update_lc/t/test/tools/obj2yaml/Output/elf-hash-section.yaml.tmp2 | /tmp/_update_lc/t/bin/FileCheck /home/dave/s/lp/llvm/test/tools/obj2yaml/elf-hash-section.yaml --check-prefix=CONTENT
--
Exit Code: 2

Command Output (stderr):
--
Program aborted due to an unhandled Error:
Error value was Success. (Note: Success values must still be checked prior to being destroyed).
Stack dump:
0.	Program arguments: /tmp/_update_lc/t/bin/obj2yaml /tmp/_update_lc/t/test/tools/obj2yaml/Output/elf-hash-section.yaml.tmp2 
 #0 0x000000000079e77f llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/tmp/_update_lc/t/bin/obj2yaml+0x79e77f)
 #1 0x000000000079cd28 llvm::sys::RunSignalHandlers() (/tmp/_update_lc/t/bin/obj2yaml+0x79cd28)
 #2 0x000000000079ed41 SignalHandler(int) (/tmp/_update_lc/t/bin/obj2yaml+0x79ed41)
 #3 0x00007ffff7fa8b20 __restore_rt (/lib64/libpthread.so.0+0x14b20)
 #4 0x00007ffff618a625 raise (/lib64/libc.so.6+0x3c625)
 #5 0x00007ffff61738d9 abort (/lib64/libc.so.6+0x258d9)
 #6 0x0000000000766c56 llvm::Error::fatalUncheckedError() const (/tmp/_update_lc/t/bin/obj2yaml+0x766c56)
 #7 0x00000000005bfcaf (anonymous namespace)::ELFDumper<llvm::object::ELFType<(llvm::support::endianness)1, false> >::dump() (/tmp/_update_lc/t/bin/obj2yaml+0x5bfcaf)
 #8 0x00000000005b9e54 elf2yaml(llvm::raw_ostream&, llvm::object::ObjectFile const&) (/tmp/_update_lc/t/bin/obj2yaml+0x5b9e54)
 #9 0x00000000005b00a3 main (/tmp/_update_lc/t/bin/obj2yaml+0x5b00a3)
#10 0x00007ffff61751a3 __libc_start_main (/lib64/libc.so.6+0x271a3)
#11 0x00000000005aface _start (/tmp/_update_lc/t/bin/obj2yaml+0x5aface)
FileCheck error: '-' is empty.
FileCheck command line:  /tmp/_update_lc/t/bin/FileCheck /home/dave/s/lp/llvm/test/tools/obj2yaml/elf-hash-section.yaml --check-prefix=CONTENT

--

********************
Testing Time: 110.38s
********************
Failing Tests (1):
    LLVM :: tools/obj2yaml/elf-hash-section.yaml

  Expected Passes    : 42883
  Expected Failures  : 100
  Unsupported Tests  : 15414
  Unexpected Failures: 1