Skip to content

Commit

Permalink
tools/elf2efi: skip empty .got section and its .relro_padding
Browse files Browse the repository at this point in the history
Resolves systemd/systemd#31637.

lld-18 does the section setup differently than older versions. There is a bunch
of ordering chagnes, but it also inserts the following:

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
...
  9 .got          00000000  00000000000283c0  00000000000283c0  000283c0  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 10 .relro_padding 00000c40  00000000000283c0  00000000000283c0  000283c0  2**0
                  ALLOC
 11 .data         00000024  00000000000293c0  00000000000293c0  000283c0  2**4
                  CONTENTS, ALLOC, LOAD, DATA
...

This causes a problem for us, because we try to map the .got to .rodata,
and the subsequent .data to .data, and round down the VMA to the nearest
page, which causes the PE sections to overlap.

llvm/llvm-project#66042 adds .relro_padding to make
sure that the RELRO segment is properly write protected and allocated. For our
binaries, the .got section is empty, so we can skip it safely, and the
.relro_padding section is not useful once .got has been dropped.

We don't expect .got sections, but they are apparently inserted on i386 and
aarch64 builds. Emit a warning until we figure out why they are there.
  • Loading branch information
keszybz committed Mar 22, 2024
1 parent 8a75371 commit 6d03e55
Showing 1 changed file with 6 additions and 0 deletions.
6 changes: 6 additions & 0 deletions tools/elf2efi.py
Expand Up @@ -26,6 +26,7 @@
import io
import os
import pathlib
import sys
import time
import typing
from ctypes import (
Expand Down Expand Up @@ -212,6 +213,7 @@ def __init__(self):
".eh_frame",
".eh_frame_hdr",
".ARM.exidx",
".relro_padding",
]

IGNORE_SECTION_TYPES = [
Expand Down Expand Up @@ -274,10 +276,14 @@ def iter_copy_sections(elf: ELFFile) -> typing.Iterator[PeSection]:
elf_s["sh_flags"] & SH_FLAGS.SHF_ALLOC == 0
or elf_s["sh_type"] in IGNORE_SECTION_TYPES
or elf_s.name in IGNORE_SECTIONS
or elf_s["sh_size"] == 0
):
continue
if elf_s["sh_type"] not in ["SHT_PROGBITS", "SHT_NOBITS"]:
raise BadSectionError(f"Unknown section {elf_s.name} with type {elf_s['sh_type']}")
if elf_s.name == '.got':
# FIXME: figure out why those sections are inserted
print("WARNING: Non-empty .got section", file=sys.stderr)

if elf_s["sh_flags"] & SH_FLAGS.SHF_EXECINSTR:
rwx = PE_CHARACTERISTICS_RX
Expand Down

0 comments on commit 6d03e55

Please sign in to comment.