This option is already supported by both BFD ld and gold and allows overriding the max page size whose default value is defined by the target.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
Out of curiosity, are you using this option anywhere?
I think this is semantically fine if you have an use case, I left some comments around.
ELF/Driver.cpp | ||
---|---|---|
660 ↗ | (On Diff #72383) | You might want to elaborate this a bit. Maybe, mentioning that there's a target default MAXPAGESIZE anyway and this option overrides the value. |
test/ELF/zmax-page-size.s | ||
1 ↗ | (On Diff #72383) | Linker script tests go in ELF/linkerscript |
We do, see https://fuchsia.googlesource.com/magenta/+/master/kernel/arch/x86/rules.mk#150 for example. This option is supported by both BFD ld and gold and it would be nice if LLD supported the option, since it's used by existing software.
Thanks, there is also a similar patch for -z common-page-size if you want to take a look: https://reviews.llvm.org/D24891.
Sure, commented there. In the future, feel free to cc: me or list me as reviewer so that the patch can get my attention more easily.
The updated version combines the logic for handling both -z max-page-size and -z common-page-size which also makes https://reviews.llvm.org/D24898 unnecessary.
What happens if you pass a negative value to -z common-page-size ?
ELF/Driver.cpp | ||
---|---|---|
660–667 ↗ | (On Diff #72416) | There are other -z options supported, but not all of them take an integer option, e.g. -z now. Can this function be generalized to cover all them? That seems a little bit too much to ask, so you can probably just rename this one. |
662–663 ↗ | (On Diff #72416) | can you add a test for this case? |
You will get the invalid value error (I've added a test for this). This is handled by the Value->getAsInteger method since the value is defined as uint64_t.
test/ELF/linkerscript/zcommon-page-size.s | ||
---|---|---|
7 ↗ | (On Diff #72421) | But should this work ? if (Config->ZMaxPageSize < Target->PageSize || (Config->ZMaxPageSize % Target->PageSize != 0)) error("wrong page size specified: " + Twine(Config->ZMaxPageSize)); This is checks that GNU linkers do (I think both of them, but not really remember now) and this |
ELF/Driver.cpp | ||
---|---|---|
267–268 ↗ | (On Diff #72421) | I think you could change this function to take one more parameter and return an integer. uint64_t getZOptionValue(opt::InputArgList &Args, StringRef Key, uint64_t Default) |
495–497 ↗ | (On Diff #72421) | then you could do Config->ZStackSize = getZOptionValue(Args, "stack-size", -1); |
671–672 ↗ | (On Diff #72421) | and Config->CommonPageSize = getZOption(Args, "common-page-size", Target->PageSize); Config->MaxPageSize = getZOption(Args, "max-page-size", Target->PageSize); |
I was checking the behavior of both BFD ld and gold. BFD ld checks whether the argument is power of 2 while gold doesn't, but I don't see any reason why page size wouldn't be a power 2 so I've added that check as well. The handling of common-page-size is strange, there doesn't seem to be a clear consensus on how exactly that value should be interpreted.
ELF/Config.h | ||
---|---|---|
141 ↗ | (On Diff #72573) | Please remove = -1 because the variable is always assigned now. |
ELF/Driver.cpp | ||
277 ↗ | (On Diff #72573) | Can you return Result here and return Default at end? |
666 ↗ | (On Diff #72573) | We have isPowerOf2_64 in MathExtras.h. |
672 ↗ | (On Diff #72573) | If there's no clear consensus how common-page-size should be interpreted, I'd vote for the simplest rule: just -z common-page-size's value to CommonPageSize. |
I have one single last comment, then LGTM.
I think you can merge the two *.s files into one as they share the same ASM.
Thanks!
This is getting more complicated, I was looking at using -z max-page-size and -z common-page-size values in the Writer and found that lld's use of page size is somewhat inconsistent so I filed a bug 30541 and proposed possible solutions. It'd be great to decide on the solution for the page size handling before landing this patch as it might require further changes (e.g. if we decide to only use the maximum page size, we probably shouldn't accept the -z common-page-size flag).
Slightly related. There were problems in the past because lld was aliasing MAXPAGESIZE and PAGE_SIZE on x86-64 and this caused the FreeBSD kernel to crash when linked with lld so I want to be sure that configuration is tested when experimenting with page sizes. I assume that if we mimic what bfd does we should be OK in that case, as the kernel is currently linked with a very old (2.17) version of it.
Now that https://reviews.llvm.org/D24987 has landed, I have revised the patch to make sure that the MaxPageSize value is properly propagated to the writer and also added a test that checks that the wiring is working. I've also removed the support for -z common-page-size, I don't think we should be supporting that option until (if ever) we decide to implement the page saving logic because that's the only place where that option comes into play. Could you please take a look again?
ELF/Driver.cpp | ||
---|---|---|
671 ↗ | (On Diff #72752) | Why do you need to set bits in Target? It would be more natural to change users to use the Config value and default that to the Target one. |