This is an archive of the discontinued LLVM Phabricator instance.

[BOLT] Set IsRelro section attribute based on PT_GNU_RELRO segment
ClosedPublic

Authored by Amir on Jun 14 2023, 11:52 AM.

Details

Summary

Handle PT_GNU_RELRO segment in accordance with Linux Standard Base spec
chapter 12:

PT_GNU_RELRO
The array element specifies the location and size of a segment which may
be made *read-only* after relocations have been processed.

Perform a readelf-style mapping check between this segment and sections,
set IsRelro section attribute.

Diff Detail

Event Timeline

Amir created this revision.Jun 14 2023, 11:52 AM
Herald added a reviewer: maksfb. · View Herald Transcript
Herald added a project: Restricted Project. · View Herald Transcript
Amir requested review of this revision.Jun 14 2023, 11:52 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 14 2023, 11:52 AM
Amir edited the summary of this revision. (Show Details)Jun 14 2023, 11:54 AM
Amir edited the summary of this revision. (Show Details)Jun 14 2023, 12:12 PM
Amir updated this revision to Diff 531459.Jun 14 2023, 12:31 PM

Add TLS section check

maksfb requested changes to this revision.Jun 16 2023, 11:25 AM

I think we need a new type for RELRO sections. We rely on the contents of regular read-only sections to match that in the file. While for RELRO, the contents will depend on the presence of runtime relocations against any region and the type of relocations.

Update gotpcrelx.s test as we start recognizing jmp *foo@GOTPCREL(%rip) as fixed indirect jump and convert it to a tail call with X86::JMP32m opcode.

If we recognize it as a fixed jump, why does the test case still have an indirect jump?

This revision now requires changes to proceed.Jun 16 2023, 11:25 AM
Amir added a comment.Jun 16 2023, 1:07 PM

I think we need a new type for RELRO sections. We rely on the contents of regular read-only sections to match that in the file. While for RELRO, the contents will depend on the presence of runtime relocations against any region and the type of relocations.

Makes sense.

Update gotpcrelx.s test as we start recognizing jmp *foo@GOTPCREL(%rip) as fixed indirect jump and convert it to a tail call with X86::JMP32m opcode.

If we recognize it as a fixed jump, why does the test case still have an indirect jump?

We keep mem-indirect jumps indirect: https://github.com/llvm/llvm-project/blob/7a709689bc1755a569864a97d93b96d22f988eb4/bolt/lib/Target/X86/X86MCPlusBuilder.cpp#L1570

Amir updated this revision to Diff 532278.Jun 16 2023, 1:20 PM

Add BinarySection flag

Amir edited the summary of this revision. (Show Details)Jun 16 2023, 1:23 PM
Amir retitled this revision from [BOLT] Mark sections read-only based on PT_GNU_RELRO segment to [BOLT] Update sections based on PT_GNU_RELRO segment.Jun 16 2023, 1:33 PM
Amir edited the summary of this revision. (Show Details)
Amir edited the summary of this revision. (Show Details)
Amir retitled this revision from [BOLT] Update sections based on PT_GNU_RELRO segment to [BOLT] Set IsRelro section attribute based on PT_GNU_RELRO segment.
maksfb added inline comments.Jun 16 2023, 2:41 PM
bolt/lib/Rewrite/RewriteInstance.cpp
425

We call this function only when Phdr.p_type == ELF::PT_GNU_RELRO. Do you plan to use it for more checks?

474

Rename.

496

We check the validity of program_headers() in discoverStorage(). Let's use cantFail() here.

1837–1840

Let's call the new function from here.

Amir updated this revision to Diff 532306.Jun 16 2023, 3:23 PM

Address review comments

Amir marked 4 inline comments as done.Jun 16 2023, 3:24 PM
Amir updated this revision to Diff 532337.Jun 16 2023, 5:18 PM

clang-format

maksfb added inline comments.Jun 20 2023, 11:57 AM
bolt/lib/Rewrite/RewriteInstance.cpp
452

The function currently always returns Error::success(). Thinking about it, it will be an error condition when only part of the section is in RELRO segment. Let's add such check.

463–464

Use BinarySection(*BC, SecRef).isTBSS(). Or better yet move the search for the matching BinarySection here and call isTBSS().

bolt/test/X86/pt_gnu_relro.s
5
Amir updated this revision to Diff 533034.Jun 20 2023, 1:31 PM
Amir marked 2 inline comments as done.

Check for partial overlaps, address comments

Amir marked an inline comment as done.Jun 20 2023, 1:32 PM
Amir updated this revision to Diff 533040.Jun 20 2023, 2:13 PM

clang-format

maksfb added inline comments.Jun 20 2023, 2:16 PM
bolt/lib/Rewrite/RewriteInstance.cpp
476

I realized TBSS sections are specifically excluded from isAllocatable(). We are not interested in other non-allocatable sections either, right?

Amir added inline comments.Jun 20 2023, 2:28 PM
bolt/lib/Rewrite/RewriteInstance.cpp
476

I realized I may have misunderstood the special treatment of TBSS in readelf segment->section mapping:
https://github.com/llvm/llvm-project/blob/e28bb6c3c797e06b2746e5b6dcba6fbb5e20a61b/llvm/tools/llvm-readobj/ELFDumper.cpp#L4498.

It basically says that TBSS section is treated as an empty section when it's in non-TLS segment. Let me adjust the check.

Amir updated this revision to Diff 533085.Jun 20 2023, 5:17 PM

Gracefully handle partial overlaps, report a warning and proceed

Amir updated this revision to Diff 533088.Jun 20 2023, 5:31 PM

Handle multiple PT_GNU_RELRO segments

Amir marked an inline comment as done.Jun 20 2023, 5:32 PM
Amir updated this revision to Diff 533090.Jun 20 2023, 5:41 PM

Remove error handling as unneeded

maksfb accepted this revision.Jun 20 2023, 5:44 PM

LGTM with a couple of nits.

bolt/lib/Rewrite/RewriteInstance.cpp
474

nit: for consistency in messages, let's use BinarySection->getName().

479

ditto

This revision is now accepted and ready to land.Jun 20 2023, 5:44 PM
Amir updated this revision to Diff 533093.Jun 20 2023, 5:51 PM

Use BinarySection->getName

Amir marked 2 inline comments as done.Jun 20 2023, 5:52 PM
Amir updated this revision to Diff 533098.Jun 20 2023, 6:25 PM

Put warnings under opts::Verbosity >= 1