Skip to content

Commit 1724188

Browse files
authored
[ObjectYAML][ELF] Take alignment into account when generating notes (llvm#118157)
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 or 64-bit objects respectively. In practice, 64-bit systems can use both alignments, with the actual format being determined 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.
1 parent 814ed93 commit 1724188

File tree

2 files changed

+146
-2
lines changed

2 files changed

+146
-2
lines changed

llvm/lib/ObjectYAML/ELFEmitter.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,6 +1799,20 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
17991799
if (!Section.Notes)
18001800
return;
18011801

1802+
unsigned Align;
1803+
switch (SHeader.sh_addralign) {
1804+
case 0:
1805+
case 4:
1806+
Align = 4;
1807+
break;
1808+
case 8:
1809+
Align = 8;
1810+
break;
1811+
default:
1812+
reportError(Section.Name + ": invalid alignment for a note section: 0x" +
1813+
Twine::utohexstr(SHeader.sh_addralign));
1814+
}
1815+
18021816
uint64_t Offset = CBA.tell();
18031817
for (const ELFYAML::NoteEntry &NE : *Section.Notes) {
18041818
// Write name size.
@@ -1820,14 +1834,15 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
18201834
if (!NE.Name.empty()) {
18211835
CBA.write(NE.Name.data(), NE.Name.size());
18221836
CBA.write('\0');
1823-
CBA.padToAlignment(4);
18241837
}
18251838

18261839
// Write description and padding.
18271840
if (NE.Desc.binary_size() != 0) {
1841+
CBA.padToAlignment(Align);
18281842
CBA.writeAsBinary(NE.Desc);
1829-
CBA.padToAlignment(4);
18301843
}
1844+
1845+
CBA.padToAlignment(Align);
18311846
}
18321847

18331848
SHeader.sh_size = CBA.tell() - Offset;

llvm/test/tools/yaml2obj/ELF/note-section.yaml

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,132 @@ Sections:
333333
- Name: ABC
334334
Desc: '123456'
335335
Type: NT_VERSION
336+
337+
## Check that an incorrect alignment is reported
338+
339+
# RUN: not yaml2obj --docnum=16 %s 2>&1 | FileCheck %s --check-prefix=ERR_ALIGN1
340+
# ERR_ALIGN1: error: .note.foo: invalid alignment for a note section: 0x1
341+
342+
--- !ELF
343+
FileHeader:
344+
Class: ELFCLASS64
345+
Data: ELFDATA2LSB
346+
Type: ET_EXEC
347+
Sections:
348+
- Name: .note.foo
349+
Type: SHT_NOTE
350+
AddressAlign: 1
351+
Notes:
352+
- Type: 0x1
353+
354+
## Check that note entries and their `Desc` fields are aligned according to the
355+
## specified section alignment
356+
357+
# RUN: yaml2obj --docnum=17 %s -o - | \
358+
# RUN: llvm-readobj --sections --section-data --notes - | \
359+
# RUN: FileCheck %s --check-prefix=TEST17
360+
361+
# TEST17: Name: .note.foo4
362+
# TEST17: SectionData (
363+
# TEST17-NEXT: 0000: 05000000 02000000 01000000 41424344 |............ABCD|
364+
# TEST17-NEXT: 0010: 00000000 01020000 00000000 03000000 |................|
365+
# TEST17-NEXT: 0020: 02000000 03040500 04000000 00000000 |................|
366+
# TEST17-NEXT: 0030: 03000000 474E5500 |....GNU.|
367+
# TEST17-NEXT: )
368+
# TEST17: Name: .note.foo8
369+
# TEST17: SectionData (
370+
# TEST17-NEXT: 0000: 05000000 02000000 01000000 41424344 |............ABCD|
371+
# TEST17-NEXT: 0010: 00000000 00000000 01020000 00000000 |................|
372+
# TEST17-NEXT: 0020: 00000000 03000000 02000000 00000000 |................|
373+
# TEST17-NEXT: 0030: 03040500 00000000 04000000 00000000 |................|
374+
# TEST17-NEXT: 0040: 03000000 474E5500 |....GNU.|
375+
# TEST17-NEXT: )
376+
# TEST17: NoteSections [
377+
# TEST17-NEXT: NoteSection {
378+
# TEST17-NEXT: Name: .note.foo4
379+
# TEST17-NEXT: Offset:
380+
# TEST17-NEXT: Size:
381+
# TEST17-NEXT: Notes [
382+
# TEST17-NEXT: {
383+
# TEST17-NEXT: Owner: ABCD
384+
# TEST17-NEXT: Data size: 0x2
385+
# TEST17-NEXT: Type: NT_VERSION (version)
386+
# TEST17-NEXT: Description data (
387+
# TEST17-NEXT: 0000: 0102 |..|
388+
# TEST17-NEXT: )
389+
# TEST17-NEXT: }
390+
# TEST17-NEXT: {
391+
# TEST17-NEXT: Owner:
392+
# TEST17-NEXT: Data size: 0x3
393+
# TEST17-NEXT: Type: NT_ARCH (architecture)
394+
# TEST17-NEXT: Description data (
395+
# TEST17-NEXT: 0000: 030405 |...|
396+
# TEST17-NEXT: )
397+
# TEST17-NEXT: }
398+
# TEST17-NEXT: {
399+
# TEST17-NEXT: Owner: GNU
400+
# TEST17-NEXT: Data size: 0x0
401+
# TEST17-NEXT: Type: NT_GNU_BUILD_ID (unique build ID bitstring)
402+
# TEST17-NEXT: Build ID:
403+
# TEST17-NEXT: }
404+
# TEST17-NEXT: ]
405+
# TEST17-NEXT: }
406+
# TEST17-NEXT: NoteSection {
407+
# TEST17-NEXT: Name: .note.foo8
408+
# TEST17-NEXT: Offset:
409+
# TEST17-NEXT: Size:
410+
# TEST17-NEXT: Notes [
411+
# TEST17-NEXT: {
412+
# TEST17-NEXT: Owner: ABCD
413+
# TEST17-NEXT: Data size: 0x2
414+
# TEST17-NEXT: Type: NT_VERSION (version)
415+
# TEST17-NEXT: Description data (
416+
# TEST17-NEXT: 0000: 0102 |..|
417+
# TEST17-NEXT: )
418+
# TEST17-NEXT: }
419+
# TEST17-NEXT: {
420+
# TEST17-NEXT: Owner:
421+
# TEST17-NEXT: Data size: 0x3
422+
# TEST17-NEXT: Type: NT_ARCH (architecture)
423+
# TEST17-NEXT: Description data (
424+
# TEST17-NEXT: 0000: 030405 |...|
425+
# TEST17-NEXT: )
426+
# TEST17-NEXT: }
427+
# TEST17-NEXT: {
428+
# TEST17-NEXT: Owner: GNU
429+
# TEST17-NEXT: Data size: 0x0
430+
# TEST17-NEXT: Type: NT_GNU_BUILD_ID (unique build ID bitstring)
431+
# TEST17-NEXT: Build ID:
432+
# TEST17-NEXT: }
433+
# TEST17-NEXT: ]
434+
# TEST17-NEXT: }
435+
# TEST17-NEXT: ]
436+
437+
--- !ELF
438+
FileHeader:
439+
Class: ELFCLASS64
440+
Data: ELFDATA2LSB
441+
Type: ET_EXEC
442+
Sections:
443+
- Name: .note.foo4
444+
Type: SHT_NOTE
445+
AddressAlign: 4
446+
Notes:
447+
- Name: ABCD
448+
Type: NT_VERSION
449+
Desc: 0102
450+
- Type: NT_ARCH
451+
Desc: 030405
452+
- Name: GNU
453+
Type: NT_GNU_BUILD_ID
454+
- Name: .note.foo8
455+
Type: SHT_NOTE
456+
AddressAlign: 8
457+
Notes:
458+
- Name: ABCD
459+
Type: NT_VERSION
460+
Desc: 0102
461+
- Type: NT_ARCH
462+
Desc: 030405
463+
- Name: GNU
464+
Type: NT_GNU_BUILD_ID

0 commit comments

Comments
 (0)