[llvm] [ObjectYAML][ELF] Take alignment into account when generating notes (PR #118157)
Igor Kudrin via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 29 23:50:27 PST 2024
https://github.com/igorkudrin updated https://github.com/llvm/llvm-project/pull/118157
>From e0f738354ca48db495bb9c395f1cb394154d6dc4 Mon Sep 17 00:00:00 2001
From: Igor Kudrin <ikudrin at accesssoftek.com>
Date: Thu, 28 Nov 2024 23:06:39 -0800
Subject: [PATCH 1/2] [ObjectYAML][ELF] Take alignment into account when
generating notes
The [System V ABI](https://www.sco.com/developers/gabi/latest/ch5.pheader.html#note_section)
states that the note entries and their descriptor fields must be aligned
to 4 or 8 bytes for 32-bit and 64-bit objects respectively. In practice,
64-bit systems can use both alignments, with the actual format being
distinguished by the alignment of the segment. For example, the
[Linux gABI extension](https://github.com/hjl-tools/linux-abi/wiki/linux-abi-draft.pdf)
contains a special note on this, see 2.1.7 "Alignment of Note Sections".
This patch adjusts the format of the generated notes to the specified
section alignment. Since `llvm-readobj` was fixed in a similar way in
[D150022](https://reviews.llvm.org/D150022], `[Object] Fix handling of Elf_Nhdr with sh_addralign=8`,
the generated notes can now be parsed successfully by the tool.
---
llvm/lib/ObjectYAML/ELFEmitter.cpp | 18 ++++-
.../test/tools/yaml2obj/ELF/note-section.yaml | 71 +++++++++++++++++++
2 files changed, 87 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 476334024151a9..8603f2f73b858d 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -1799,6 +1799,20 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
if (!Section.Notes)
return;
+ unsigned Align;
+ switch (SHeader.sh_addralign) {
+ case 0:
+ case 4:
+ Align = 4;
+ break;
+ case 8:
+ Align = 8;
+ break;
+ default:
+ reportError(Section.Name + ": invalid alignment for a note section: 0x" +
+ Twine::utohexstr(SHeader.sh_addralign));
+ }
+
uint64_t Offset = CBA.tell();
for (const ELFYAML::NoteEntry &NE : *Section.Notes) {
// Write name size.
@@ -1820,13 +1834,13 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
if (!NE.Name.empty()) {
CBA.write(NE.Name.data(), NE.Name.size());
CBA.write('\0');
- CBA.padToAlignment(4);
+ CBA.padToAlignment(Align);
}
// Write description and padding.
if (NE.Desc.binary_size() != 0) {
CBA.writeAsBinary(NE.Desc);
- CBA.padToAlignment(4);
+ CBA.padToAlignment(Align);
}
}
diff --git a/llvm/test/tools/yaml2obj/ELF/note-section.yaml b/llvm/test/tools/yaml2obj/ELF/note-section.yaml
index 80359c4ec01833..067690f8f25b00 100644
--- a/llvm/test/tools/yaml2obj/ELF/note-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/note-section.yaml
@@ -333,3 +333,74 @@ Sections:
- Name: ABC
Desc: '123456'
Type: NT_VERSION
+
+## Check that an incorrect alignment is reported
+
+# RUN: not yaml2obj --docnum=16 %s 2>&1 | FileCheck %s --check-prefix=ERR_ALIGN1
+# ERR_ALIGN1: error: .note.foo: invalid alignment for a note section: 0x1
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+Sections:
+ - Name: .note.foo
+ Type: SHT_NOTE
+ AddressAlign: 1
+ Notes:
+ - Type: 0x1
+
+## Check that note entries and their `Desc` fields are aligned according to the
+## specified section alignment
+
+# RUN: yaml2obj --docnum=17 %s -o - | \
+# RUN: llvm-readobj --sections --section-data - | \
+# RUN: FileCheck %s --check-prefix=TEST17
+
+# TEST17: Name: .note.foo4
+# TEST17: SectionData (
+# TEST17-NEXT: 0000: 05000000 02000000 01000000 41424344 |............ABCD|
+# TEST17-NEXT: 0010: 00000000 01020000 03000000 03000000 |................|
+# TEST17-NEXT: 0020: 02000000 41420000 03040500 03000000 |....AB..........|
+# TEST17-NEXT: 0030: 00000000 03000000 41420000 |........AB..|
+# TEST17-NEXT: )
+# TEST17: Name: .note.foo8
+# TEST17: SectionData (
+# TEST17-NEXT: 0000: 05000000 02000000 01000000 41424344 |............ABCD|
+# TEST17-NEXT: 0010: 00000000 00000000 01020000 00000000 |................|
+# TEST17-NEXT: 0020: 03000000 03000000 02000000 41420000 |............AB..|
+# TEST17-NEXT: 0030: 03040500 00000000 03000000 00000000 |................|
+# TEST17-NEXT: 0040: 03000000 41420000 |....AB..|
+# TEST17-NEXT: )
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+Sections:
+ - Name: .note.foo4
+ Type: SHT_NOTE
+ AddressAlign: 4
+ Notes:
+ - Name: ABCD
+ Desc: 0102
+ Type: NT_VERSION
+ - Name: AB
+ Desc: 030405
+ Type: NT_ARCH
+ - Name: AB
+ Type: NT_GNU_BUILD_ID
+ - Name: .note.foo8
+ Type: SHT_NOTE
+ AddressAlign: 8
+ Notes:
+ - Name: ABCD
+ Desc: 0102
+ Type: NT_VERSION
+ - Name: AB
+ Desc: 030405
+ Type: NT_ARCH
+ - Name: AB
+ Type: NT_GNU_BUILD_ID
>From d02318674b2a49a61de1e4f422ce1616aa5cf2f4 Mon Sep 17 00:00:00 2001
From: Igor Kudrin <ikudrin at accesssoftek.com>
Date: Fri, 29 Nov 2024 23:50:05 -0800
Subject: [PATCH 2/2] fixup: Fix the alignment of the description if the name
is empty
---
llvm/lib/ObjectYAML/ELFEmitter.cpp | 5 +-
.../test/tools/yaml2obj/ELF/note-section.yaml | 88 +++++++++++++++----
2 files changed, 76 insertions(+), 17 deletions(-)
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 8603f2f73b858d..001e701bd0b80d 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -1834,14 +1834,15 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
if (!NE.Name.empty()) {
CBA.write(NE.Name.data(), NE.Name.size());
CBA.write('\0');
- CBA.padToAlignment(Align);
}
// Write description and padding.
if (NE.Desc.binary_size() != 0) {
- CBA.writeAsBinary(NE.Desc);
CBA.padToAlignment(Align);
+ CBA.writeAsBinary(NE.Desc);
}
+
+ CBA.padToAlignment(Align);
}
SHeader.sh_size = CBA.tell() - Offset;
diff --git a/llvm/test/tools/yaml2obj/ELF/note-section.yaml b/llvm/test/tools/yaml2obj/ELF/note-section.yaml
index 067690f8f25b00..26b95e1c2379b2 100644
--- a/llvm/test/tools/yaml2obj/ELF/note-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/note-section.yaml
@@ -355,24 +355,84 @@ Sections:
## specified section alignment
# RUN: yaml2obj --docnum=17 %s -o - | \
-# RUN: llvm-readobj --sections --section-data - | \
+# RUN: llvm-readobj --sections --section-data --notes - | \
# RUN: FileCheck %s --check-prefix=TEST17
# TEST17: Name: .note.foo4
# TEST17: SectionData (
# TEST17-NEXT: 0000: 05000000 02000000 01000000 41424344 |............ABCD|
-# TEST17-NEXT: 0010: 00000000 01020000 03000000 03000000 |................|
-# TEST17-NEXT: 0020: 02000000 41420000 03040500 03000000 |....AB..........|
-# TEST17-NEXT: 0030: 00000000 03000000 41420000 |........AB..|
+# TEST17-NEXT: 0010: 00000000 01020000 00000000 03000000 |................|
+# TEST17-NEXT: 0020: 02000000 03040500 04000000 00000000 |................|
+# TEST17-NEXT: 0030: 03000000 474E5500 |....GNU.|
# TEST17-NEXT: )
# TEST17: Name: .note.foo8
# TEST17: SectionData (
# TEST17-NEXT: 0000: 05000000 02000000 01000000 41424344 |............ABCD|
# TEST17-NEXT: 0010: 00000000 00000000 01020000 00000000 |................|
-# TEST17-NEXT: 0020: 03000000 03000000 02000000 41420000 |............AB..|
-# TEST17-NEXT: 0030: 03040500 00000000 03000000 00000000 |................|
-# TEST17-NEXT: 0040: 03000000 41420000 |....AB..|
+# TEST17-NEXT: 0020: 00000000 03000000 02000000 00000000 |................|
+# TEST17-NEXT: 0030: 03040500 00000000 04000000 00000000 |................|
+# TEST17-NEXT: 0040: 03000000 474E5500 |....GNU.|
# TEST17-NEXT: )
+# TEST17: NoteSections [
+# TEST17-NEXT: NoteSection {
+# TEST17-NEXT: Name: .note.foo4
+# TEST17-NEXT: Offset:
+# TEST17-NEXT: Size:
+# TEST17-NEXT: Notes [
+# TEST17-NEXT: {
+# TEST17-NEXT: Owner: ABCD
+# TEST17-NEXT: Data size: 0x2
+# TEST17-NEXT: Type: NT_VERSION (version)
+# TEST17-NEXT: Description data (
+# TEST17-NEXT: 0000: 0102 |..|
+# TEST17-NEXT: )
+# TEST17-NEXT: }
+# TEST17-NEXT: {
+# TEST17-NEXT: Owner:
+# TEST17-NEXT: Data size: 0x3
+# TEST17-NEXT: Type: NT_ARCH (architecture)
+# TEST17-NEXT: Description data (
+# TEST17-NEXT: 0000: 030405 |...|
+# TEST17-NEXT: )
+# TEST17-NEXT: }
+# TEST17-NEXT: {
+# TEST17-NEXT: Owner: GNU
+# TEST17-NEXT: Data size: 0x0
+# TEST17-NEXT: Type: NT_GNU_BUILD_ID (unique build ID bitstring)
+# TEST17-NEXT: Build ID:
+# TEST17-NEXT: }
+# TEST17-NEXT: ]
+# TEST17-NEXT: }
+# TEST17-NEXT: NoteSection {
+# TEST17-NEXT: Name: .note.foo8
+# TEST17-NEXT: Offset:
+# TEST17-NEXT: Size:
+# TEST17-NEXT: Notes [
+# TEST17-NEXT: {
+# TEST17-NEXT: Owner: ABCD
+# TEST17-NEXT: Data size: 0x2
+# TEST17-NEXT: Type: NT_VERSION (version)
+# TEST17-NEXT: Description data (
+# TEST17-NEXT: 0000: 0102 |..|
+# TEST17-NEXT: )
+# TEST17-NEXT: }
+# TEST17-NEXT: {
+# TEST17-NEXT: Owner:
+# TEST17-NEXT: Data size: 0x3
+# TEST17-NEXT: Type: NT_ARCH (architecture)
+# TEST17-NEXT: Description data (
+# TEST17-NEXT: 0000: 030405 |...|
+# TEST17-NEXT: )
+# TEST17-NEXT: }
+# TEST17-NEXT: {
+# TEST17-NEXT: Owner: GNU
+# TEST17-NEXT: Data size: 0x0
+# TEST17-NEXT: Type: NT_GNU_BUILD_ID (unique build ID bitstring)
+# TEST17-NEXT: Build ID:
+# TEST17-NEXT: }
+# TEST17-NEXT: ]
+# TEST17-NEXT: }
+# TEST17-NEXT: ]
--- !ELF
FileHeader:
@@ -385,22 +445,20 @@ Sections:
AddressAlign: 4
Notes:
- Name: ABCD
- Desc: 0102
Type: NT_VERSION
- - Name: AB
+ Desc: 0102
+ - Type: NT_ARCH
Desc: 030405
- Type: NT_ARCH
- - Name: AB
+ - Name: GNU
Type: NT_GNU_BUILD_ID
- Name: .note.foo8
Type: SHT_NOTE
AddressAlign: 8
Notes:
- Name: ABCD
- Desc: 0102
Type: NT_VERSION
- - Name: AB
+ Desc: 0102
+ - Type: NT_ARCH
Desc: 030405
- Type: NT_ARCH
- - Name: AB
+ - Name: GNU
Type: NT_GNU_BUILD_ID
More information about the llvm-commits
mailing list