Skip to content

Commit 740ac4f

Browse files
authored
Reland "[ObjectYAML][ELF] Take alignment into account when generating notes" (#118434)
This relands #118157 with a fix for the use of an uninitialized variable and additional tests. 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 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 00d8ea3 commit 740ac4f

File tree

2 files changed

+199
-2
lines changed

2 files changed

+199
-2
lines changed

llvm/lib/ObjectYAML/ELFEmitter.cpp

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

1802+
unsigned Align;
1803+
switch (Section.AddressAlign) {
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(Section.AddressAlign));
1814+
return;
1815+
}
1816+
18021817
uint64_t Offset = CBA.tell();
18031818
for (const ELFYAML::NoteEntry &NE : *Section.Notes) {
18041819
// Write name size.
@@ -1820,14 +1835,15 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
18201835
if (!NE.Name.empty()) {
18211836
CBA.write(NE.Name.data(), NE.Name.size());
18221837
CBA.write('\0');
1823-
CBA.padToAlignment(4);
18241838
}
18251839

18261840
// Write description and padding.
18271841
if (NE.Desc.binary_size() != 0) {
1842+
CBA.padToAlignment(Align);
18281843
CBA.writeAsBinary(NE.Desc);
1829-
CBA.padToAlignment(4);
18301844
}
1845+
1846+
CBA.padToAlignment(Align);
18311847
}
18321848

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

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

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,184 @@ 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 -D ELFCLASS=64 %s -o - | \
358+
# RUN: llvm-readobj --sections --section-data --notes - | \
359+
# RUN: FileCheck %s --check-prefix=TEST17
360+
361+
# RUN: yaml2obj --docnum=17 -D ELFCLASS=32 %s -o - | \
362+
# RUN: llvm-readobj --sections --section-data --notes - | \
363+
# RUN: FileCheck %s --check-prefix=TEST17
364+
365+
# TEST17: Name: .note.foo4
366+
# TEST17: SectionData (
367+
# TEST17-NEXT: 0000: 05000000 02000000 01000000 41424344 |............ABCD|
368+
# TEST17-NEXT: 0010: 00000000 01020000 00000000 03000000 |................|
369+
# TEST17-NEXT: 0020: 02000000 03040500 04000000 00000000 |................|
370+
# TEST17-NEXT: 0030: 03000000 474E5500 |....GNU.|
371+
# TEST17-NEXT: )
372+
# TEST17: Name: .note.foo8
373+
# TEST17: SectionData (
374+
# TEST17-NEXT: 0000: 05000000 02000000 01000000 41424344 |............ABCD|
375+
# TEST17-NEXT: 0010: 00000000 00000000 01020000 00000000 |................|
376+
# TEST17-NEXT: 0020: 00000000 03000000 02000000 00000000 |................|
377+
# TEST17-NEXT: 0030: 03040500 00000000 04000000 00000000 |................|
378+
# TEST17-NEXT: 0040: 03000000 474E5500 |....GNU.|
379+
# TEST17-NEXT: )
380+
# TEST17: NoteSections [
381+
# TEST17-NEXT: NoteSection {
382+
# TEST17-NEXT: Name: .note.foo4
383+
# TEST17-NEXT: Offset:
384+
# TEST17-NEXT: Size:
385+
# TEST17-NEXT: Notes [
386+
# TEST17-NEXT: {
387+
# TEST17-NEXT: Owner: ABCD
388+
# TEST17-NEXT: Data size: 0x2
389+
# TEST17-NEXT: Type: NT_VERSION (version)
390+
# TEST17-NEXT: Description data (
391+
# TEST17-NEXT: 0000: 0102 |..|
392+
# TEST17-NEXT: )
393+
# TEST17-NEXT: }
394+
# TEST17-NEXT: {
395+
# TEST17-NEXT: Owner:
396+
# TEST17-NEXT: Data size: 0x3
397+
# TEST17-NEXT: Type: NT_ARCH (architecture)
398+
# TEST17-NEXT: Description data (
399+
# TEST17-NEXT: 0000: 030405 |...|
400+
# TEST17-NEXT: )
401+
# TEST17-NEXT: }
402+
# TEST17-NEXT: {
403+
# TEST17-NEXT: Owner: GNU
404+
# TEST17-NEXT: Data size: 0x0
405+
# TEST17-NEXT: Type: NT_GNU_BUILD_ID (unique build ID bitstring)
406+
# TEST17-NEXT: Build ID:
407+
# TEST17-NEXT: }
408+
# TEST17-NEXT: ]
409+
# TEST17-NEXT: }
410+
# TEST17-NEXT: NoteSection {
411+
# TEST17-NEXT: Name: .note.foo8
412+
# TEST17-NEXT: Offset:
413+
# TEST17-NEXT: Size:
414+
# TEST17-NEXT: Notes [
415+
# TEST17-NEXT: {
416+
# TEST17-NEXT: Owner: ABCD
417+
# TEST17-NEXT: Data size: 0x2
418+
# TEST17-NEXT: Type: NT_VERSION (version)
419+
# TEST17-NEXT: Description data (
420+
# TEST17-NEXT: 0000: 0102 |..|
421+
# TEST17-NEXT: )
422+
# TEST17-NEXT: }
423+
# TEST17-NEXT: {
424+
# TEST17-NEXT: Owner:
425+
# TEST17-NEXT: Data size: 0x3
426+
# TEST17-NEXT: Type: NT_ARCH (architecture)
427+
# TEST17-NEXT: Description data (
428+
# TEST17-NEXT: 0000: 030405 |...|
429+
# TEST17-NEXT: )
430+
# TEST17-NEXT: }
431+
# TEST17-NEXT: {
432+
# TEST17-NEXT: Owner: GNU
433+
# TEST17-NEXT: Data size: 0x0
434+
# TEST17-NEXT: Type: NT_GNU_BUILD_ID (unique build ID bitstring)
435+
# TEST17-NEXT: Build ID:
436+
# TEST17-NEXT: }
437+
# TEST17-NEXT: ]
438+
# TEST17-NEXT: }
439+
# TEST17-NEXT: ]
440+
441+
--- !ELF
442+
FileHeader:
443+
Class: ELFCLASS[[ELFCLASS]]
444+
Data: ELFDATA2LSB
445+
Type: ET_EXEC
446+
Sections:
447+
- Name: .note.foo4
448+
Type: SHT_NOTE
449+
AddressAlign: 4
450+
Notes:
451+
- Name: ABCD
452+
Type: NT_VERSION
453+
Desc: 0102
454+
- Type: NT_ARCH
455+
Desc: 030405
456+
- Name: GNU
457+
Type: NT_GNU_BUILD_ID
458+
- Name: .note.foo8
459+
Type: SHT_NOTE
460+
AddressAlign: 8
461+
Notes:
462+
- Name: ABCD
463+
Type: NT_VERSION
464+
Desc: 0102
465+
- Type: NT_ARCH
466+
Desc: 030405
467+
- Name: GNU
468+
Type: NT_GNU_BUILD_ID
469+
470+
## Check that the alignment for note entries is taken from the "AddressAlign"
471+
## field even if "ShAddrAlign" is also specified; an unexpected value in the
472+
## "ShAddrAlign" property does not trigger an incorrect alignment error.
473+
474+
# RUN: yaml2obj --docnum=18 -D ADDRALIGN=0 -D SHADDRALIGN=8 %s -o - | \
475+
# RUN: llvm-readobj --sections --section-data --notes - | \
476+
# RUN: FileCheck %s --check-prefixes=TEST18,TEST18_4
477+
478+
# RUN: yaml2obj --docnum=18 -D ADDRALIGN=4 -D SHADDRALIGN=3 %s -o - | \
479+
# RUN: llvm-readobj --sections --section-data --notes - | \
480+
# RUN: FileCheck %s --check-prefixes=TEST18,TEST18_4
481+
482+
# RUN: yaml2obj --docnum=18 -D ADDRALIGN=8 -D SHADDRALIGN=4 %s -o - | \
483+
# RUN: llvm-readobj --sections --section-data --notes - | \
484+
# RUN: FileCheck %s --check-prefixes=TEST18,TEST18_8
485+
486+
# TEST18: Name: .note
487+
# TEST18: SectionData (
488+
# TEST18_4-NEXT: 0000: 05000000 02000000 01000000 41424344 |............ABCD|
489+
# TEST18_4-NEXT: 0010: 00000000 01020000 00000000 03000000 |................|
490+
# TEST18_4-NEXT: 0020: 02000000 03040500 04000000 00000000 |................|
491+
# TEST18_4-NEXT: 0030: 03000000 474E5500 |....GNU.|
492+
# TEST18_8-NEXT: 0000: 05000000 02000000 01000000 41424344 |............ABCD|
493+
# TEST18_8-NEXT: 0010: 00000000 00000000 01020000 00000000 |................|
494+
# TEST18_8-NEXT: 0020: 00000000 03000000 02000000 00000000 |................|
495+
# TEST18_8-NEXT: 0030: 03040500 00000000 04000000 00000000 |................|
496+
# TEST18_8-NEXT: 0040: 03000000 474E5500 |....GNU.|
497+
# TEST18-NEXT: )
498+
499+
--- !ELF
500+
FileHeader:
501+
Class: ELFCLASS64
502+
Data: ELFDATA2LSB
503+
Type: ET_EXEC
504+
Sections:
505+
- Name: .note
506+
Type: SHT_NOTE
507+
AddressAlign: [[ADDRALIGN]]
508+
ShAddrAlign: [[SHADDRALIGN]]
509+
Notes:
510+
- Name: ABCD
511+
Type: NT_VERSION
512+
Desc: 0102
513+
- Type: NT_ARCH
514+
Desc: 030405
515+
- Name: GNU
516+
Type: NT_GNU_BUILD_ID

0 commit comments

Comments
 (0)