mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
commit
c2e3566981
@ -2,8 +2,8 @@
|
||||
# Copyright (C) 2022-present Team LibreELEC (https://libreelec.tv)
|
||||
|
||||
PKG_NAME="mold"
|
||||
PKG_VERSION="1.6.0"
|
||||
PKG_SHA256="59cd3ea1a2a5fb50d0d97faddd8bff4c7e71054a576c00a87b17f56ecbd88729"
|
||||
PKG_VERSION="1.7.0"
|
||||
PKG_SHA256="ccd685afcdb7047f8a8ce8b5ce3b3cd22205a0ebc548ff1f1da7b35415fafbe4"
|
||||
PKG_LICENSE="AGPL-3.0-or-later"
|
||||
PKG_SITE="https://github.com/rui314/mold"
|
||||
PKG_URL="https://github.com/rui314/mold/archive/refs/tags/v${PKG_VERSION}.tar.gz"
|
||||
|
@ -1,164 +0,0 @@
|
||||
From 610042a8e927106cb2d852fba2a90faa0d0e050f Mon Sep 17 00:00:00 2001
|
||||
From: Rui Ueyama <ruiu@bluewhale.systems>
|
||||
Date: Fri, 21 Oct 2022 07:08:09 +0800
|
||||
Subject: [PATCH] [ELF] Set .ARM.exidx's sh_link to .text
|
||||
|
||||
GNU binutil's strip command doesn't like an .ARM.exidx section with
|
||||
sh_link set to 0. arm-linux-gnueabihf-strip actually crashes on my
|
||||
machine when the command is run on such a file.
|
||||
|
||||
https://github.com/rui314/mold/issues/801
|
||||
---
|
||||
elf/arch-arm32.cc | 56 +++++++++++++++++++++++++++++--------------
|
||||
elf/mold.h | 2 +-
|
||||
elf/output-chunks.cc | 4 ++--
|
||||
elf/passes.cc | 2 +-
|
||||
test/elf/exception.sh | 8 +++++++
|
||||
5 files changed, 50 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/elf/arch-arm32.cc b/elf/arch-arm32.cc
|
||||
index 46e45d43d..bea510763 100644
|
||||
--- a/elf/arch-arm32.cc
|
||||
+++ b/elf/arch-arm32.cc
|
||||
@@ -552,14 +552,6 @@ void RangeExtensionThunk<E>::copy_buf(Context<E> &ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
-template <typename E>
|
||||
-static OutputSection<E> *find_exidx_section(Context<E> &ctx) {
|
||||
- for (std::unique_ptr<OutputSection<E>> &osec : ctx.output_sections)
|
||||
- if (osec->shdr.sh_type == SHT_ARM_EXIDX)
|
||||
- return osec.get();
|
||||
- return nullptr;
|
||||
-}
|
||||
-
|
||||
// ARM executables use an .ARM.exidx section to look up an exception
|
||||
// handling record for the current instruction pointer. The table needs
|
||||
// to be sorted by their addresses.
|
||||
@@ -569,13 +561,7 @@ static OutputSection<E> *find_exidx_section(Context<E> &ctx) {
|
||||
// likely that it's due to some historical reason.
|
||||
//
|
||||
// This function sorts .ARM.exidx records.
|
||||
-void sort_arm_exidx(Context<E> &ctx) {
|
||||
- Timer t(ctx, "sort_arm_exidx");
|
||||
-
|
||||
- OutputSection<E> *osec = find_exidx_section(ctx);
|
||||
- if (!osec)
|
||||
- return;
|
||||
-
|
||||
+static void sort_exidx(Context<E> &ctx, OutputSection<E> &osec) {
|
||||
// .ARM.exidx records consists of a signed 31-bit relative address
|
||||
// and a 32-bit value. The relative address indicates the start
|
||||
// address of a function that the record covers. The value is one of
|
||||
@@ -595,11 +581,11 @@ void sort_arm_exidx(Context<E> &ctx) {
|
||||
ul32 val;
|
||||
};
|
||||
|
||||
- if (osec->shdr.sh_size % sizeof(Entry))
|
||||
+ if (osec.shdr.sh_size % sizeof(Entry))
|
||||
Fatal(ctx) << "invalid .ARM.exidx section size";
|
||||
|
||||
- Entry *ent = (Entry *)(ctx.buf + osec->shdr.sh_offset);
|
||||
- i64 num_entries = osec->shdr.sh_size / sizeof(Entry);
|
||||
+ Entry *ent = (Entry *)(ctx.buf + osec.shdr.sh_offset);
|
||||
+ i64 num_entries = osec.shdr.sh_size / sizeof(Entry);
|
||||
|
||||
// Entry's addresses are relative to themselves. In order to sort
|
||||
// records by addresses, we first translate them so that the addresses
|
||||
@@ -628,4 +614,38 @@ void sort_arm_exidx(Context<E> &ctx) {
|
||||
});
|
||||
}
|
||||
|
||||
+void fixup_arm_exidx_section(Context<E> &ctx) {
|
||||
+ Timer t(ctx, "fixup_arm_exidx_section");
|
||||
+
|
||||
+ auto find_exidx = [&]() -> OutputSection<E> * {
|
||||
+ for (std::unique_ptr<OutputSection<E>> &osec : ctx.output_sections)
|
||||
+ if (osec->shdr.sh_type == SHT_ARM_EXIDX)
|
||||
+ return osec.get();
|
||||
+ return nullptr;
|
||||
+ };
|
||||
+
|
||||
+ OutputSection<E> *exidx = find_exidx();
|
||||
+ if (!exidx)
|
||||
+ return;
|
||||
+
|
||||
+ // Sort .ARM.exidx contents
|
||||
+ sort_exidx(ctx, *exidx);
|
||||
+
|
||||
+ // .ARM.exidx's sh_link should be set to the .text section index.
|
||||
+ // Runtime doesn't care about it, but the binutils's strip command does.
|
||||
+ if (ctx.shdr) {
|
||||
+ auto find_text = [&]() -> OutputSection<E> * {
|
||||
+ for (std::unique_ptr<OutputSection<E>> &osec : ctx.output_sections)
|
||||
+ if (osec->name == ".text")
|
||||
+ return osec.get();
|
||||
+ return nullptr;
|
||||
+ };
|
||||
+
|
||||
+ if (OutputSection<E> *text = find_exidx()) {
|
||||
+ exidx->shdr.sh_link = text->shndx;
|
||||
+ ctx.shdr->copy_buf(ctx);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
} // namespace mold::elf
|
||||
diff --git a/elf/mold.h b/elf/mold.h
|
||||
index 11938270e..c8bac2b4e 100644
|
||||
--- a/elf/mold.h
|
||||
+++ b/elf/mold.h
|
||||
@@ -1434,7 +1434,7 @@ template <typename E> void write_dependency_file(Context<E> &);
|
||||
// arch-arm32.cc
|
||||
//
|
||||
|
||||
-void sort_arm_exidx(Context<ARM32> &ctx);
|
||||
+void fixup_arm_exidx_section(Context<ARM32> &ctx);
|
||||
|
||||
//
|
||||
// arch-riscv64.cc
|
||||
diff --git a/elf/output-chunks.cc b/elf/output-chunks.cc
|
||||
index 54562feb2..0d1d0dcfd 100644
|
||||
--- a/elf/output-chunks.cc
|
||||
+++ b/elf/output-chunks.cc
|
||||
@@ -847,9 +847,9 @@ get_output_name(Context<E> &ctx, std::string_view name, u64 flags) {
|
||||
|
||||
if ((name == ".rodata" || name.starts_with(".rodata.")) && (flags & SHF_MERGE))
|
||||
return (flags & SHF_STRINGS) ? ".rodata.str" : ".rodata.cst";
|
||||
- if (name == ".ARM.exidx" || name.starts_with(".ARM.exidx."))
|
||||
+ if (name.starts_with(".ARM.exidx"))
|
||||
return ".ARM.exidx";
|
||||
- if (name == ".ARM.extab" || name.starts_with(".ARM.extab."))
|
||||
+ if (name.starts_with(".ARM.extab"))
|
||||
return ".ARM.extab";
|
||||
|
||||
if (ctx.arg.z_keep_text_section_prefix) {
|
||||
diff --git a/elf/passes.cc b/elf/passes.cc
|
||||
index 713a06a84..4bffc3dbd 100644
|
||||
--- a/elf/passes.cc
|
||||
+++ b/elf/passes.cc
|
||||
@@ -1102,7 +1102,7 @@ void copy_chunks(Context<E> &ctx) {
|
||||
report_undef_errors(ctx);
|
||||
|
||||
if constexpr (std::is_same_v<E, ARM32>)
|
||||
- sort_arm_exidx(ctx);
|
||||
+ fixup_arm_exidx_section(ctx);
|
||||
}
|
||||
|
||||
template <typename E>
|
||||
diff --git a/test/elf/exception.sh b/test/elf/exception.sh
|
||||
index 6832966f0..c584c99fa 100755
|
||||
--- a/test/elf/exception.sh
|
||||
+++ b/test/elf/exception.sh
|
||||
@@ -65,3 +65,11 @@ if [ $MACHINE = x86_64 -o $MACHINE = aarch64 ]; then
|
||||
$CXX -B. -o $t/exe10 $t/e.o -no-pie
|
||||
$QEMU $t/exe10
|
||||
fi
|
||||
+
|
||||
+$CXX -B. -o $t/exe11 $t/b.o -pie
|
||||
+$STRIP $t/exe11
|
||||
+$QEMU $t/exe11
|
||||
+
|
||||
+$CXX -B. -o $t/exe12 $t/c.o -no-pie
|
||||
+$STRIP $t/exe12
|
||||
+$QEMU $t/exe12
|
Loading…
x
Reference in New Issue
Block a user