From 786911cebb177d9c835e9e8bc358ed2b8011a722 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Tue, 13 Sep 2022 00:26:21 -0700 Subject: clang: Fix llvm-objdump crash on aarch64/musl Signed-off-by: Khem Raj --- ...p-Change-printSymbolVersionDependency-to-.patch | 157 +++++++++++++++++++++ recipes-devtools/clang/common.inc | 1 + 2 files changed, 158 insertions(+) create mode 100644 recipes-devtools/clang/clang/0001-llvm-objdump-Change-printSymbolVersionDependency-to-.patch (limited to 'recipes-devtools') diff --git a/recipes-devtools/clang/clang/0001-llvm-objdump-Change-printSymbolVersionDependency-to-.patch b/recipes-devtools/clang/clang/0001-llvm-objdump-Change-printSymbolVersionDependency-to-.patch new file mode 100644 index 0000000..6bcc951 --- /dev/null +++ b/recipes-devtools/clang/clang/0001-llvm-objdump-Change-printSymbolVersionDependency-to-.patch @@ -0,0 +1,157 @@ +From 1a4646b30f627ef92c1de6cd65f6d0cc87b0ef11 Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Tue, 13 Sep 2022 00:24:10 -0700 +Subject: [PATCH] [llvm-objdump] Change printSymbolVersionDependency to use + ELFFile API + +When .gnu.version_r is empty (allowed by readelf but warned by objdump), +llvm-objdump -p may decode the next section as .gnu.version_r and may crash due +to out-of-bounds C string reference. ELFFile::getVersionDependencies +handles 0-entry .gnu.version_r gracefully. Just use it. + +Fix https://github.com/llvm/llvm-project/issues/57707 + +Upstream-Status: Submitted [https://reviews.llvm.org/D133751] +Signed-off-by: Khem Raj +--- + llvm/include/llvm/Object/ELF.h | 2 +- + .../llvm-objdump/ELF/verneed-invalid.test | 24 ++++++++++++ + llvm/test/tools/llvm-objdump/ELF/verneed.test | 20 ++++++++++ + llvm/tools/llvm-objdump/ELFDump.cpp | 39 ++++++++++--------- + 4 files changed, 65 insertions(+), 20 deletions(-) + create mode 100644 llvm/test/tools/llvm-objdump/ELF/verneed-invalid.test + +diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h +index 16c9a1461f8d..8b8a574be090 100644 +--- a/llvm/include/llvm/Object/ELF.h ++++ b/llvm/include/llvm/Object/ELF.h +@@ -1038,7 +1038,7 @@ ELFFile::getVersionDependencies(const Elf_Shdr &Sec, + VN.Offset = VerneedBuf - Start; + + if (Verneed->vn_file < StrTab.size()) +- VN.File = std::string(StrTab.drop_front(Verneed->vn_file)); ++ VN.File = std::string(StrTab.data() + Verneed->vn_file); + else + VN.File = ("vn_file) + ">").str(); + +diff --git a/llvm/test/tools/llvm-objdump/ELF/verneed-invalid.test b/llvm/test/tools/llvm-objdump/ELF/verneed-invalid.test +new file mode 100644 +index 000000000000..4756a59ed107 +--- /dev/null ++++ b/llvm/test/tools/llvm-objdump/ELF/verneed-invalid.test +@@ -0,0 +1,24 @@ ++# RUN: yaml2obj %s -o %t ++# RUN: llvm-objdump -p %t 2>&1 | FileCheck %s --check-prefix=BROKEN-AUX -DFILE=%t ++ ++# BROKEN-AUX: Version References: ++# BROKEN-AUX-NEXT: warning: '[[FILE]]': invalid SHT_GNU_verneed section with index 2: found a misaligned auxiliary entry at offset 0x11 ++ ++--- !ELF ++FileHeader: ++ Class: ELFCLASS64 ++ Data: ELFDATA2LSB ++ Type: ET_EXEC ++Sections: ++ - Name: .gnu.version ++ Type: SHT_GNU_versym ++ Flags: [ SHF_ALLOC ] ++ Entries: [ 2 ] ++ - Name: .gnu.version_r ++ Type: SHT_GNU_verneed ++ Flags: [ SHF_ALLOC ] ++ Info: 1 ++ AddressAlign: 4 ++## The byte offset to the auxiliary entry is 0x11, i.e. it is not correctly aligned in memory. ++ Content: "0100010001000000110000000000000000000000" ++DynamicSymbols: [] +diff --git a/llvm/test/tools/llvm-objdump/ELF/verneed.test b/llvm/test/tools/llvm-objdump/ELF/verneed.test +index 57e856e542ad..7b38ef95fd41 100644 +--- a/llvm/test/tools/llvm-objdump/ELF/verneed.test ++++ b/llvm/test/tools/llvm-objdump/ELF/verneed.test +@@ -46,3 +46,23 @@ Sections: + DynamicSymbols: + - Name: f1 + Binding: STB_GLOBAL ++ ++# RUN: yaml2obj --docnum=2 %s -o %t.empty ++# RUN: llvm-objdump -p %t.empty 2>&1 | FileCheck %s --check-prefix=EMPTY --implicit-check-not=warning: ++ ++# EMPTY: Version References: ++# EMPTY-NOT: {{.}} ++ ++--- !ELF ++FileHeader: ++ Class: ELFCLASS64 ++ Data: ELFDATA2LSB ++ Type: ET_EXEC ++ Machine: EM_X86_64 ++Sections: ++ - Name: .gnu.version_r ++ Type: SHT_GNU_verneed ++ Flags: [ SHF_ALLOC ] ++DynamicSymbols: ++ - Name: f1 ++ Binding: STB_GLOBAL +diff --git a/llvm/tools/llvm-objdump/ELFDump.cpp b/llvm/tools/llvm-objdump/ELFDump.cpp +index ca73dafe2b8e..61676b4323d2 100644 +--- a/llvm/tools/llvm-objdump/ELFDump.cpp ++++ b/llvm/tools/llvm-objdump/ELFDump.cpp +@@ -282,27 +282,28 @@ static void printProgramHeaders(const ELFFile &Obj, StringRef FileName) { + } + + template +-static void printSymbolVersionDependency(ArrayRef Contents, +- StringRef StrTab) { ++static void printSymbolVersionDependency(StringRef FileName, ++ const ELFFile &Obj, ++ const typename ELFT::Shdr &Sec) { + outs() << "\nVersion References:\n"; + +- const uint8_t *Buf = Contents.data(); +- while (Buf) { +- auto *Verneed = reinterpret_cast(Buf); +- outs() << " required from " +- << StringRef(StrTab.drop_front(Verneed->vn_file).data()) << ":\n"; ++ auto WarningHandler = [&](const Twine &Msg) { ++ reportWarning(Msg, FileName); ++ return Error::success(); ++ }; ++ Expected> V = ++ Obj.getVersionDependencies(Sec, WarningHandler); ++ if (!V) { ++ reportWarning(toString(V.takeError()), FileName); ++ return; ++ } + +- const uint8_t *BufAux = Buf + Verneed->vn_aux; +- while (BufAux) { +- auto *Vernaux = reinterpret_cast(BufAux); +- outs() << " " +- << format("0x%08" PRIx32 " ", (uint32_t)Vernaux->vna_hash) +- << format("0x%02" PRIx16 " ", (uint16_t)Vernaux->vna_flags) +- << format("%02" PRIu16 " ", (uint16_t)Vernaux->vna_other) +- << StringRef(StrTab.drop_front(Vernaux->vna_name).data()) << '\n'; +- BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr; +- } +- Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr; ++ raw_fd_ostream &OS = outs(); ++ for (const VerNeed &VN : *V) { ++ OS << " required from " << VN.File << ":\n"; ++ for (const VernAux &Aux : VN.AuxV) ++ OS << format(" 0x%08x 0x%02x %02u %s\n", Aux.Hash, Aux.Flags, ++ Aux.Other, Aux.Name.c_str()); + } + } + +@@ -355,7 +356,7 @@ static void printSymbolVersionInfo(const ELFFile &Elf, + StringRef StrTab = unwrapOrError(Elf.getStringTable(*StrTabSec), FileName); + + if (Shdr.sh_type == ELF::SHT_GNU_verneed) +- printSymbolVersionDependency(Contents, StrTab); ++ printSymbolVersionDependency(FileName, Elf, Shdr); + else + printSymbolVersionDefinition(Shdr, Contents, StrTab); + } +-- +2.37.3 + diff --git a/recipes-devtools/clang/common.inc b/recipes-devtools/clang/common.inc index 3a4d504..7e6b1ef 100644 --- a/recipes-devtools/clang/common.inc +++ b/recipes-devtools/clang/common.inc @@ -45,6 +45,7 @@ SRC_URI = "\ file://0033-compiler-rt-Enable-__int128-for-ppc32.patch \ file://0034-llvm-Do-not-use-cmake-infra-to-detect-libzstd.patch \ file://0035-Revert-MIPS-compiler-rt-Fix-stat-struct-s-size-for-O.patch \ + file://0001-llvm-objdump-Change-printSymbolVersionDependency-to-.patch \ " # Fallback to no-PIE if not set GCCPIE ??= "" -- cgit v1.2.3-54-g00ecf