From: "Marvin Häuser" <mhaeuser@posteo.de>
To: Rebecca Cran <rebecca@bsdio.com>
Cc: Pedro Falcato <pedro.falcato@gmail.com>,
Liming Gao <gaoliming@byosoft.com.cn>,
Ard Biesheuvel <ardb+tianocore@kernel.org>,
devel@edk2.groups.io
Subject: Re: Linker scripts use of "-z common-page-size=0x20" etc.
Date: Mon, 3 Apr 2023 20:58:44 +0000 [thread overview]
Message-ID: <668CD723-746F-4A04-B5E8-7DD55AECD55F@posteo.de> (raw)
In-Reply-To: <9befc3e1-02b6-c0c4-7eba-cccd84dedd3d@bsdio.com>
> On 3. Apr 2023, at 22:33, Rebecca Cran <rebecca@bsdio.com> wrote:
>
> As part of my work on the toolchain definitions, I've come across a situation where ld.lld fails to align sections correctly, due to it being invoked via clang with the '-n' option, which causes GenFw to fail with "Section address not aligned to its own alignment.".
>
> The following messages are printed:
>
>
> ld.lld: warning: -z common-page-size set, but paging disabled by omagic or nmagic ld.lld: warning: address (0x558) of section .data is not a multiple of alignment (16)
>
> I tracked the problem down to GccBase.lds and ClangBase.lds, which have:
>
> /* * The alignment of the .data section should be less than or equal to the * alignment of the .text section. This ensures that the relative offset * between these sections is the same in the ELF and the PE/COFF versions of * this binary. */ .data ALIGN(ALIGNOF(.text)) : ALIGN(CONSTANT(COMMONPAGESIZE)) { *(.data .data.* .gnu.linkonce.d.*) *(.bss .bss.*) }
>
> I can work around the problem by removing "ALIGN(ALIGNOF(.text)", but I'm wondering if our use of COMMONPAGESIZE/MAXPAGESIZE is correct.
>
>
> We pass in a value of 0x20, 0x40 or 0x1000 to "-z common-page-size" with 0x20 being the most common value.
>
> Given the page size of the target will never be 32 bytes, the following comment on https://reviews.llvm.org/D61688 makes sense:
>
>
> "There is at least one linkerscript in Tianocore edk2 that (ab)uses -n -z common-page-size=0x20 to use CONSTANT(COMMONPAGESIZE) as if it were a preprocessor macro set with -D in the compiler. The usual approach to this is to pre-process the linkerscript."
>
>
> I'm wondering what the correct approach is here: should we do something similar to how we set PECOFF_HEADER_SIZE and define a SECTION_ALIGNMENT symbol? Or, as discussed on Discord should we just use CONSTANT(MAXPAGESIZE) and ignore how it's normally used to specify the maximum allowable page size for an executable?
That last part is actually not ignoring the use-case, that *is* our use-case. The terminology again is very OS-oriented, it’s important to know that generally OSes will fail to load binaries that are aligned less than the platform page size, as they cannot apply permissions (and probably also some implementation details of mmap / VM / whatever). That’s why the maximum page size you’re realistic to encounter is exactly the image segment alignment (by hardware convention, this is a power of two, thus a strict alignment satisfies all less strict alignment constraints).
The common page size on the other hand appears to be an optimization, for which you specify the most common page size (e.g., you may target AARCH64 which may require 16 KB alignment, but most of your targets will have only 4 KB pages), which the compiler will use to optimize the binary for the common targets. I have no idea why this is even used. There also were discussions on LLVM platforms that it should be avoided.
The naive approach would be to just use max-page-size, drop all references to common-page-size, and align all ELF sections that will be converted to PE sections by max-page-size. But I’m sure there’s some ancient workaround / compiler bug / edge use case / portability or whatever reason why common-page-size was used. :)
(CC Leif for related experience.)
edk2 generally sets this to a low value to save SPI (and possibly RAM) space, as nothing in the stack enforces memory protection ( :( ). I’m not sure why there’s both 32 and 64 Bytes, but I could imagine it’s some GNU ABI thing where some type of some arch actually requires this alignment, or maybe there’s different rules for global variables. A text segment must at least satisfy the maximum instruction alignment constraint (this may be a thing with, e.g., normalised instruction lengths), while data segments must satisfy at least the maximum data alignment constraint (which might usually be some large float? Not sure). 4 KB is used when memory protection is needed (usually RT drivers, as they’re mapped into the OS environment), but AARCH64 may actually require 16 KB (e.g. Apple A chips didn’t even support less for a while).
Best regards,
Marvin
>
>
> --
> Rebecca Cran
>
next prev parent reply other threads:[~2023-04-03 20:58 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-03 20:33 Linker scripts use of "-z common-page-size=0x20" etc Rebecca Cran
2023-04-03 20:58 ` Marvin Häuser [this message]
2023-04-03 22:56 ` Rebecca Cran
2023-04-04 7:22 ` Ard Biesheuvel
2023-04-04 7:43 ` Marvin Häuser
2023-04-04 11:10 ` Rebecca Cran
2023-04-04 14:03 ` Ard Biesheuvel
2023-04-04 14:10 ` Marvin Häuser
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=668CD723-746F-4A04-B5E8-7DD55AECD55F@posteo.de \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox