This is an archive of the discontinued LLVM Phabricator instance.

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

Authored by grimar on Sep 19 2019, 4:44 AM.

Details

Summary

.stack_sizes is a SHT_PROGBITS section that contains pairs of
<address (4/8 bytes), stack size (uleb128)>.

This patch teach tools to parse and dump it.

Diff Detail

Repository
rL LLVM

Event Timeline

grimar created this revision.Sep 19 2019, 4:44 AM
grimar edited the summary of this revision. (Show Details)Sep 19 2019, 4:45 AM
MaskRay added inline comments.Sep 19 2019, 11:36 PM
include/llvm/ObjectYAML/ELFYAML.h
183 ↗(On Diff #220837)

I think we can just use Name == ".stack_sizes" for now. MC doesn't create .stack_sizes.*

Moreover, the error messages below just use plain .stack_sizes.

lib/ObjectYAML/ELFEmitter.cpp
794 ↗(On Diff #220837)

using

lib/ObjectYAML/ELFYAML.cpp
1155 ↗(On Diff #220837)

Section = std::make_unique<ELFYAML::StackSizesSection>();

test/tools/yaml2obj/elf-stack-sizes.yaml
1 ↗(On Diff #220837)

produces

from YAML descriptions.

Seems redundant. This directory contains all such YAML files but none mentions "YAML descriptions".

7 ↗(On Diff #220837)

Is it tighter to put CONTENT-VALID, CONTENT_INVALID and CONTENT-TRUNCATED tests together?

# Valid
- Name: .stack_sizes [1]
  Type:    SHT_PROGBITS
  Content: ...
# Truncated
- Name: .stack_sizes [2]
  Type:    SHT_PROGBITS
  Content: ...
# ...
tools/obj2yaml/elf2yaml.cpp
293 ↗(On Diff #220837)

Move the if (Shdr->sh_type == ELF::SHT_PROGBITS) check here. It responds to the claim "which has a regular type."

Then, we probably should reword the comment. One suggestion I get is "recognize some special SHT_PROGBITS sections by name."

494 ↗(On Diff #220837)

I guess the if can be deleted. An empty .stack_sizes can be processed with the same code.

495 ↗(On Diff #220837)

If D67797 is accepted, this code can switch to the new ctor.

509 ↗(On Diff #220837)

as an array of bytes.

If the data of .stack_sizes section is broken in any way,

How about "if .stack_sizes cannot be decoded"?

grimar marked an inline comment as done.Sep 20 2019, 1:27 AM
grimar added inline comments.
include/llvm/ObjectYAML/ELFYAML.h
183 ↗(On Diff #220837)

I am not sure here. I did it because llvm-readobj test case uses YAML with .stack_sizes.*:
https://github.com/llvm-mirror/llvm/blob/master/test/tools/llvm-readobj/stack-sizes.test#L35

I do not know was it intention or the person who wrote the test just did not know how to desribe sections with the same name in YAML.
It probably might be not that bad to support .stack_sizes.* too (and may be teach MC to produve them)?
Or we can fix llvm-readobj test first. Or go with .stack_sizes.* here and deside what to do in a follow-up patch for YAML+readobj.
What would you prefer?

MaskRay added inline comments.Sep 20 2019, 2:12 AM
include/llvm/ObjectYAML/ELFYAML.h
183 ↗(On Diff #220837)

Name.startswith(".stack_sizes"); is fine if we eventually emit .stack_sizes.* for clang -ffunction-sections -fstack-size-section. However, there are two problems:

  • Larger code size. .stack_sizes.foo, .text.foo and .rodata.foo can take large amount of space in .strtab. This is why -fno-unique-section-names is sometimes useful.
  • Linkers don't combine .stack_sizes.* into .stack_sizes. ld.bfd and lld will have to be taught the special rule. In lld, it is in getOutputSectionName.
MaskRay retitled this revision from [yaml2obj/obj2yaml] - Add a support for .stack_sizes sections. to [yaml2obj/obj2yaml] - Add support for .stack_sizes sections..Sep 20 2019, 2:13 AM
grimar marked an inline comment as done.Sep 20 2019, 2:23 AM
grimar added inline comments.
include/llvm/ObjectYAML/ELFYAML.h
183 ↗(On Diff #220837)

Seems the right way for now is to fix llvm-readobj then. I'll do a patch.

grimar updated this revision to Diff 221001.Sep 20 2019, 4:41 AM
grimar marked 12 inline comments as done.
  • Addressed review comments.
include/llvm/ObjectYAML/ELFYAML.h
183 ↗(On Diff #220837)

Patch for llvm-readobj: D67824

test/tools/yaml2obj/elf-stack-sizes.yaml
7 ↗(On Diff #220837)

Ok. But I left all fields for the first case, because we probably need to test them all at least once:
since the section has a special handling, we need to verify which values we set by default.

tools/obj2yaml/elf2yaml.cpp
494 ↗(On Diff #220837)

Almost "yes" :) I had to modify the code slightly and added a test case for testing this case, which asserted before, but now works fine.
(Issue was that either 'Entries' or 'Content' must present to pass section validation, but in the previous version I did not set any of them when the section data was empty).

After removing 'if', without the code modificatiuon, yaml2obj for an empty section would produce Entries: [] instead of Content: '',
what perhaps is not critical, but seems do not match the comment saying that "If .stack_sizes cannot be decoded, we dump it as an array of bytes." (assuming that empty section == broken section == can not be decoded).

495 ↗(On Diff #220837)

Nice! I'll switch once it happens.

509 ↗(On Diff #220837)

How about "if .stack_sizes cannot be decoded"?

LG.

MaskRay added inline comments.Sep 21 2019, 8:13 AM
lib/ObjectYAML/ELFYAML.cpp
1182 ↗(On Diff #221001)

Alternatives:

.stack_sizes: either Content or Entries tag must be specified

.stack_sizes: Content and Entries cannot be used together

grimar updated this revision to Diff 221282.Sep 23 2019, 4:13 AM
grimar marked 2 inline comments as done.
  • Addressed comments.
  • Rebased.
jhenderson added inline comments.Sep 23 2019, 8:11 AM
include/llvm/ObjectYAML/ELFYAML.h
183 ↗(On Diff #220837)

I know this is due to how LLD and other linkers behave, but I still find it less than helpful that you can't have sections with different suffixes for many section types. Why allow .text.foo, but not .stack_sizes.foo for example? I'd personally prefer to change LLD and MC (but that's another change) than change llvm-readelf. That way, it's immediately recognisable which section a .stack_sizes section is associated with when looking at the output, without needing to decipher the Link field.

lib/ObjectYAML/ELFYAML.cpp
1179 ↗(On Diff #221282)

If we're allowing people to specify a Content field, it seems reasonable to also allow specification of a Size field, with the content set to zeroes, if not otherwise filled in by Content.

test/tools/llvm-readobj/stack-sizes.test
508 ↗(On Diff #221282)

I'd either put this at the bottom of the tag and not change the indentation of the other fields, or indent the fields in the other sections to match. That being said, it seems a bit weird to do it this way. I'd think adding one or more explicit entries would be a more natural choice (or at least an empty Entries array).

test/tools/obj2yaml/elf-stack-sizes.yaml
1 ↗(On Diff #221282)

produce -> produces

3 ↗(On Diff #221282)

uses the "Entries" tag to describe a .stack_sizes section

35 ↗(On Diff #221282)

uses the "Content" tag to describe a .stack_sizes section when it can't extract the entries, for example, when ...

63 ↗(On Diff #221282)

Delete "the"

test/tools/yaml2obj/elf-stack-sizes.yaml
1 ↗(On Diff #221282)

I think you need Big Endian and 32-bit test cases here, since those affect how the section is written.

3 ↗(On Diff #221282)

Maybe change this to "Test the following cases when the .stack_sizes Content field is specified:"

"The first test:" doesn't seem useful to me.

4 ↗(On Diff #221282)

from the -> from a

6 ↗(On Diff #221282)

a incorrect -> an incorrect
from the -> from a

8 ↗(On Diff #221282)

from the -> from a
with an empty -> with empty

14 ↗(On Diff #221282)

I'd simplify these to "Case 1: valid content." "Case 2: truncated content." and "Case 3: empty content."

90 ↗(On Diff #221282)

omit the "Address" tag.
case the address will be zero.

151 ↗(On Diff #221282)

describe -> describing

MaskRay added inline comments.Sep 24 2019, 12:00 AM
include/llvm/ObjectYAML/ELFYAML.h
183 ↗(On Diff #220837)

The main concern is that .stack_sizes.foo can increase the object file size considerably. I agree that .stack_sizes.foo is immediately recognisable but I am not sure such trade-off is worthwhile. .stack_sizes is not alone - some sanitizers synthesized sections (e.g. .sancov_cntrs) are not suffixed, either. Lots of .group are not suffixed, etc.

grimar marked an inline comment as done.Sep 24 2019, 1:31 AM
grimar added inline comments.
include/llvm/ObjectYAML/ELFYAML.h
183 ↗(On Diff #220837)

Why allow .text.foo, but not .stack_sizes.foo for example?

I had a time to think about this a bit. text.foo does not have a Link or Info fields set. It has to have a
function name encoded in the section name. On the other side .stack_sizes have Link.
My vision is that руку it is a dumping tools problem probably: readelf has a format that makes hard to show a useful output here,
though it has full information. I.e. it shows Link as a numeric value what makes matching task for a human harder.
We can change/improve it in llvm-readobj. I am not sure it worth to add section suffixes to a binary produced because of that.
Our aim is not to make human readable objects, we have set of tools for dumping them. We might want to improve them.

grimar marked an inline comment as done.Sep 24 2019, 1:32 AM
grimar added inline comments.
include/llvm/ObjectYAML/ELFYAML.h
183 ↗(On Diff #220837)

"is that руку it is a ..." -> "is that here it is a ..."

grimar updated this revision to Diff 221515.Sep 24 2019, 5:14 AM
grimar marked 15 inline comments as done.
  • Addressed review comments.
lib/ObjectYAML/ELFYAML.cpp
1179 ↗(On Diff #221282)

I posted a follow-up: D67958

jhenderson accepted this revision.Sep 24 2019, 6:02 AM

LGTM, with one minor comment.

test/tools/yaml2obj/elf-stack-sizes.yaml
4 ↗(On Diff #221515)

I think you can delete "Shows" from each of these statements now.

This revision is now accepted and ready to land.Sep 24 2019, 6:02 AM
This revision was automatically updated to reflect the committed changes.
grimar marked an inline comment as done.
Herald added a project: Restricted Project. · View Herald TranscriptSep 24 2019, 7:24 AM