Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gap between .text and .text_init segments on riscv32imac-unknown-none-elf #118214

Closed
t-moe opened this issue Nov 23, 2023 · 5 comments
Closed

Gap between .text and .text_init segments on riscv32imac-unknown-none-elf #118214

t-moe opened this issue Nov 23, 2023 · 5 comments

Comments

@t-moe
Copy link

t-moe commented Nov 23, 2023

rustc seems to sometimes insert a gap between the .text and .text_init segments on riscv32imac-unknown-none-elf.

I have two binaries, built with rustc. In one binary there is a gap of 0x8 between the segements, and in the other binary there is no gap.

Here are the segments for the binary with the gap:

riscv32-esp-elf-objdump -h led_test_with_semi | head -n9

led_test_with_semi:     file format elf32-littleriscv

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text_init    000000e6  42000020  42000020  00001020  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .text         00008cd8  42000110  42000110  00001110  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE

and here for the binary without the gap:

riscv32-esp-elf-objdump -h led_test_without | head -n9

led_test_without:     file format elf32-littleriscv

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text_init    000000e6  42000020  42000020  00001020  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .text         00008c42  42000108  42000108  00001108  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE

These gaps, break our tooling in espflash and I wanted to ask what could be the reason that there is suddenly a gap between the segments. Is this something we need to account for in our tooling, or is this a rustc bug?

Unfortunately, I cannot share the source code of my two binaries. The only difference between the two binaries is that I enabled a seemingly unrelated feature in one build, which is disabled in the other build. I also was not able to strip down the binaries to a minimal, complete, verifiable, example. Sorry 😞

rustc --version --verbose
rustc 1.75.0-nightly (0039d739d 2023-10-18)
binary: rustc
commit-hash: 0039d739d40a076334e111488946441378d11cd7
commit-date: 2023-10-18
host: x86_64-unknown-linux-gnu
release: 1.75.0-nightly
LLVM version: 17.0.3

@t-moe t-moe added the C-bug Category: This is a bug. label Nov 23, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Nov 23, 2023
@zachs18
Copy link
Contributor

zachs18 commented Nov 23, 2023

The ALIGN field shows that .text needs to be 16-byte aligned in the first binary (2**4 = 24 = 16), whereas in the second binary it only needs to be 4-byte aligned (2**2 = 22 = 4),

Since the .text_init section does not end at an address/offset that is multiple of 16 bytes, padding is inserted in the first to ensure the alignment is respected.

I don't think this is a rustc bug, but I also don't know why the alignment is different between the two binaries.

@t-moe
Copy link
Author

t-moe commented Nov 23, 2023

@zachs18
Ah, I see.
Which component is responsible to generate the sections (and their alignment)? Is this done by rustc, or does this happen at a later stage (llvm or even in the linker)?

The feature I toggle between the two builds, conditionally enables a 16 byte aligned function (
https://github.com/taiki-e/semihosting/blob/main/src/sys/arm_compat/syscall/riscv.rs). But I have used the same function (enabled) in other binaries and there it does not influence the overall alignment of the .text segment. (EDIT: Wrong. The gap was just filled by the section before it, so we didn't notice)

Why does the alignment of a single function influence the overall alignment of the text segment?

The binary with the problem does not start with my 16 byte aligned function. See here the beginning of the text segment:

...
42000102 <abort>:
42000102:       0000006f                j       42000102 <abort>

Disassembly of section .text:

42000110 <_ZN110_$LT$core..iter..adapters..enumerate..Enumerate$LT$I$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$4next17h2913f89909fe2b87E>:
42000110:       862a                    mv      a2,a0
42000112:       4148                    lw      a0,4(a0)
42000114:       420c                    lw      a1,0(a2)
42000116:       00a58b63                beq     a1,a0,4200012c <_ZN110_$LT$core..iter..adapters..enumerate..Enumerate$LT$I$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$4next17h2913f89909fe2b87E+0x1c>

@zachs18
Copy link
Contributor

zachs18 commented Nov 24, 2023

Why does the alignment of a single function influence the overall alignment of the text segment?

If the section is not at least 16-byte aligned, then there is no way to guarantee a function in that section will be 16-byte aligned. The alignment of a section must be at least the greatest alignment of any alignment request within it, or else some alignment requests cannot be guaranteed to be respected.

@workingjubilee
Copy link
Member

workingjubilee commented Nov 27, 2023

While rustc is not completely innocent in terms of generating sections, I believe it is LLVM which examines and processes the request of .balign 16 and thus there is little we can do about this (and as mentioned, the behavior is essentially correct).

@t-moe
Copy link
Author

t-moe commented Nov 27, 2023

Thank you @workingjubilee and @zachs18 .
You're indeed right, and the issue is entirely on my side.

The alignment of a section must be at least the greatest alignment of any alignment request within it, or else some alignment requests cannot be guaranteed to be respected.

This seems to be true. Whenever I conditionally added a 16-byte aligned function, the entire .text segment was also 16-byte aligned. The section before the .text section, sometimes just "filled the gap" so we didn't notice.

We'll adjust our tooling accordingly.

@t-moe t-moe closed this as completed Nov 27, 2023
@workingjubilee workingjubilee removed the C-bug Category: This is a bug. label Nov 29, 2023
@fmease fmease removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Nov 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants