diff options
| author | Martin Jansa <Martin.Jansa@gmail.com> | 2023-07-31 21:10:05 +0200 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2023-08-01 09:51:20 +0100 |
| commit | d505ab5ea561bf5c501e7417a17d72bacfe3dadf (patch) | |
| tree | d890d95dc58b3d962aef166b61e1c86e79825db1 | |
| parent | 57975742361c6ad36a51115145358db350ef650f (diff) | |
| download | poky-d505ab5ea561bf5c501e7417a17d72bacfe3dadf.tar.gz | |
patchelf: add 3 fixes to optimize and fix uninative
* uninative-3.10 and 4.0 doesn't work on e.g. ubuntu-18.04, because patchelf-uninative
makes the binaries unusable and e.g. mkfs.ext4 segfaults in loader, see:
https://github.com/NixOS/patchelf/issues/492
* mke2fs.real, mkfs.ext2.real, mkfs.ext3.real, mkfs.ext4.real are indentical
binary with multiple hardlinks and we end calling patchelf-uninative 4
times even when the interpreter is already set correctly from the build
The issue was reported upstream with mkfs.ext4.real as possible reproducer:
https://github.com/NixOS/patchelf/issues/492#issuecomment-1602862272
To fix uninative we need to first release new uninative tarball and
then upgrade it in master, mickledore, kirkstone, dunfell
* originally reported in:
https://lists.openembedded.org/g/openembedded-core/message/182862
with temporary work around (applicable locally without waiting for
new uninative release):
https://lists.openembedded.org/g/openembedded-core/message/183314
(From OE-Core rev: f0499b58d1dd149300a349dde8f6664679df13e6)
Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
4 files changed, 110 insertions, 1 deletions
diff --git a/meta/recipes-devtools/patchelf/patchelf/0001-Set-interpreter-only-when-necessary.patch b/meta/recipes-devtools/patchelf/patchelf/0001-Set-interpreter-only-when-necessary.patch new file mode 100644 index 0000000000..9a8216b3fe --- /dev/null +++ b/meta/recipes-devtools/patchelf/patchelf/0001-Set-interpreter-only-when-necessary.patch | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | From f5df94952e87eaa390e5c845bc48fdb3dbc31cc2 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Yuta Hayama <hayama@lineo.co.jp> | ||
| 3 | Date: Fri, 21 Jul 2023 10:47:02 +0900 | ||
| 4 | Subject: [PATCH] Set interpreter only when necessary | ||
| 5 | |||
| 6 | If the given interpreter is already set, nothing needs to be done. | ||
| 7 | As with modifySoname(), it skips unnecessary processing. | ||
| 8 | |||
| 9 | Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com> | ||
| 10 | --- | ||
| 11 | Upstream-Status: Submitted [https://github.com/NixOS/patchelf/pull/508] | ||
| 12 | |||
| 13 | src/patchelf.cc | 5 +++++ | ||
| 14 | 1 file changed, 5 insertions(+) | ||
| 15 | |||
| 16 | diff --git a/src/patchelf.cc b/src/patchelf.cc | ||
| 17 | index 86429c4..e562c49 100644 | ||
| 18 | --- a/src/patchelf.cc | ||
| 19 | +++ b/src/patchelf.cc | ||
| 20 | @@ -1460,6 +1460,11 @@ void ElfFile<ElfFileParamNames>::modifySoname(sonameMode op, const std::string & | ||
| 21 | template<ElfFileParams> | ||
| 22 | void ElfFile<ElfFileParamNames>::setInterpreter(const std::string & newInterpreter) | ||
| 23 | { | ||
| 24 | + if (getInterpreter() == newInterpreter) { | ||
| 25 | + debug("given interpreter is already set\n"); | ||
| 26 | + return; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | std::string & section = replaceSection(".interp", newInterpreter.size() + 1); | ||
| 30 | setSubstr(section, 0, newInterpreter + '\0'); | ||
| 31 | changed = true; | ||
diff --git a/meta/recipes-devtools/patchelf/patchelf/0002-align-startOffset-with-p_align-instead-of-pagesize-f.patch b/meta/recipes-devtools/patchelf/patchelf/0002-align-startOffset-with-p_align-instead-of-pagesize-f.patch new file mode 100644 index 0000000000..7906f0f73b --- /dev/null +++ b/meta/recipes-devtools/patchelf/patchelf/0002-align-startOffset-with-p_align-instead-of-pagesize-f.patch | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | From 1198329b922f3cdddc3e87a7c81d7730b646c088 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Yuta Hayama <hayama@lineo.co.jp> | ||
| 3 | Date: Fri, 28 Jul 2023 16:22:31 +0900 | ||
| 4 | Subject: [PATCH] align startOffset with p_align instead of pagesize for | ||
| 5 | compatibility | ||
| 6 | |||
| 7 | According to the ELF specification, the alignment of loadable process segments | ||
| 8 | should satisfy (p_vaddr mod pagesize) == (p_offset mod pagesize). However, | ||
| 9 | glibc earlier than 2.35 incorrectly requires that the LOAD segment be (p_vaddr | ||
| 10 | mod p_align) == (p_offset mod p_align), and will output the error message | ||
| 11 | "ELF load command address/offset not properly aligned" if this is not met. | ||
| 12 | |||
| 13 | Since there are many systems that use glibc earlier than 2.35, it is preferable | ||
| 14 | that newly added LOAD segments satisfy (p_vaddr mod p_align) == (p_offset mod | ||
| 15 | p_align) for compatibility. | ||
| 16 | |||
| 17 | Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com> | ||
| 18 | --- | ||
| 19 | Upstream-Status: Submitted [https://github.com/NixOS/patchelf/pull/510] | ||
| 20 | |||
| 21 | src/patchelf.cc | 8 +++++++- | ||
| 22 | 1 file changed, 7 insertions(+), 1 deletion(-) | ||
| 23 | |||
| 24 | diff --git a/src/patchelf.cc b/src/patchelf.cc | ||
| 25 | index 82b4b46..6edb81a 100644 | ||
| 26 | --- a/src/patchelf.cc | ||
| 27 | +++ b/src/patchelf.cc | ||
| 28 | @@ -843,7 +843,13 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary() | ||
| 29 | neededSpace += headerTableSpace; | ||
| 30 | debug("needed space is %d\n", neededSpace); | ||
| 31 | |||
| 32 | - Elf_Off startOffset = roundUp(fileContents->size(), getPageSize()); | ||
| 33 | + /* glibc earlier than 2.35 requires that the LOAD segment satisfies | ||
| 34 | + (p_vaddr mod p_align) == (p_offset mod p_align). | ||
| 35 | + The ELF specification requires that loadable process segments satisfy | ||
| 36 | + (p_vaddr mod pagesize) == (p_offset mod pagesize), so glibc is probably | ||
| 37 | + wrong, but here startOffset is calculated according to p_align for | ||
| 38 | + compatibility. */ | ||
| 39 | + Elf_Off startOffset = roundUp(fileContents->size(), alignStartPage); | ||
| 40 | |||
| 41 | // In older version of binutils (2.30), readelf would check if the dynamic | ||
| 42 | // section segment is strictly smaller than the file (and not same size). | ||
diff --git a/meta/recipes-devtools/patchelf/patchelf/0003-make-LOAD-segment-extensions-based-on-p_align-instea.patch b/meta/recipes-devtools/patchelf/patchelf/0003-make-LOAD-segment-extensions-based-on-p_align-instea.patch new file mode 100644 index 0000000000..37eaf992d8 --- /dev/null +++ b/meta/recipes-devtools/patchelf/patchelf/0003-make-LOAD-segment-extensions-based-on-p_align-instea.patch | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | From 299ad5766921d593e11a42a8e4dec55b4b350876 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Yuta Hayama <hayama@lineo.co.jp> | ||
| 3 | Date: Mon, 31 Jul 2023 11:58:49 +0900 | ||
| 4 | Subject: [PATCH] make LOAD segment extensions based on p_align instead of | ||
| 5 | pagesize | ||
| 6 | |||
| 7 | Since the p_align of the LOAD segment is no longer pagesize, the actual p_align | ||
| 8 | value is used to calculate for the LOAD segment extension. | ||
| 9 | |||
| 10 | If calculated with pagesize, new LOAD segment may be added even though the | ||
| 11 | existing LOAD segment can be extended. | ||
| 12 | |||
| 13 | Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com> | ||
| 14 | --- | ||
| 15 | Upstream-Status: Submitted [https://github.com/NixOS/patchelf/pull/510] | ||
| 16 | |||
| 17 | src/patchelf.cc | 2 +- | ||
| 18 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
| 19 | |||
| 20 | diff --git a/src/patchelf.cc b/src/patchelf.cc | ||
| 21 | index 6edb81a..86429c4 100644 | ||
| 22 | --- a/src/patchelf.cc | ||
| 23 | +++ b/src/patchelf.cc | ||
| 24 | @@ -885,7 +885,7 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary() | ||
| 25 | rdi(lastSeg.p_type) == PT_LOAD && | ||
| 26 | rdi(lastSeg.p_flags) == (PF_R | PF_W) && | ||
| 27 | rdi(lastSeg.p_align) == alignStartPage) { | ||
| 28 | - auto segEnd = roundUp(rdi(lastSeg.p_offset) + rdi(lastSeg.p_memsz), getPageSize()); | ||
| 29 | + auto segEnd = roundUp(rdi(lastSeg.p_offset) + rdi(lastSeg.p_memsz), alignStartPage); | ||
| 30 | if (segEnd == startOffset) { | ||
| 31 | auto newSz = startOffset + neededSpace - rdi(lastSeg.p_offset); | ||
| 32 | wri(lastSeg.p_filesz, wri(lastSeg.p_memsz, newSz)); | ||
diff --git a/meta/recipes-devtools/patchelf/patchelf_0.18.0.bb b/meta/recipes-devtools/patchelf/patchelf_0.18.0.bb index e8bc2ff83d..dece34240c 100644 --- a/meta/recipes-devtools/patchelf/patchelf_0.18.0.bb +++ b/meta/recipes-devtools/patchelf/patchelf_0.18.0.bb | |||
| @@ -4,7 +4,11 @@ HOMEPAGE = "https://github.com/NixOS/patchelf" | |||
| 4 | 4 | ||
| 5 | LICENSE = "GPL-3.0-only" | 5 | LICENSE = "GPL-3.0-only" |
| 6 | 6 | ||
| 7 | SRC_URI = "git://github.com/NixOS/patchelf;protocol=https;branch=master" | 7 | SRC_URI = "git://github.com/NixOS/patchelf;protocol=https;branch=master \ |
| 8 | file://0001-Set-interpreter-only-when-necessary.patch \ | ||
| 9 | file://0002-align-startOffset-with-p_align-instead-of-pagesize-f.patch \ | ||
| 10 | file://0003-make-LOAD-segment-extensions-based-on-p_align-instea.patch \ | ||
| 11 | " | ||
| 8 | SRCREV = "99c24238981b7b1084313aca8f5c493bb46f302c" | 12 | SRCREV = "99c24238981b7b1084313aca8f5c493bb46f302c" |
| 9 | 13 | ||
| 10 | S = "${WORKDIR}/git" | 14 | S = "${WORKDIR}/git" |
