1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-28 00:21:52 +03:00

csu: Implement and use _dl_early_allocate during static startup

This implements mmap fallback for a brk failure during TLS
allocation.

scripts/tls-elf-edit.py is updated to support the new patching method.
The script no longer requires that in the input object is of ET_DYN
type.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
This commit is contained in:
Florian Weimer
2022-05-16 18:41:43 +02:00
parent b57ab258c1
commit f787e138aa
7 changed files with 202 additions and 10 deletions

View File

@ -43,9 +43,11 @@ EI_DATA=5
ELFDATA2LSB=b'\x01'
ELFDATA2MSB=b'\x02'
ET_EXEC=2
ET_DYN=3
PT_LOAD=1
PT_TLS=7
def elf_types_fmts(e_ident):
endian = '<' if e_ident[EI_DATA] == ELFDATA2LSB else '>'
@ -146,8 +148,15 @@ def elf_edit_align(phdr, align):
else:
phdr.p_align = int(align)
def elf_edit_maximize_tls_size(phdr, elfclass):
if elfclass == ELFCLASS32:
# It is possible that the kernel can allocate half of the
# address space, so use something larger.
phdr.p_memsz = 0xfff00000
else:
phdr.p_memsz = 1 << 63
def elf_edit(f, align):
def elf_edit(f, opts):
ei_nident_fmt = 'c' * EI_NIDENT
ei_nident_len = struct.calcsize(ei_nident_fmt)
@ -172,24 +181,35 @@ def elf_edit(f, align):
ehdr = Elf_Ehdr(e_ident)
ehdr.read(f)
if ehdr.e_type != ET_DYN:
error('{}: not a shared library'.format(f.name))
if ehdr.e_type not in (ET_EXEC, ET_DYN):
error('{}: not an executable or shared library'.format(f.name))
phdr = Elf_Phdr(e_ident)
maximize_tls_size_done = False
for i in range(0, ehdr.e_phnum):
f.seek(ehdr.e_phoff + i * phdr.len)
phdr.read(f)
if phdr.p_type == PT_LOAD:
elf_edit_align(phdr, align)
if phdr.p_type == PT_LOAD and opts.align is not None:
elf_edit_align(phdr, opts.align)
f.seek(ehdr.e_phoff + i * phdr.len)
phdr.write(f)
break
if phdr.p_type == PT_TLS and opts.maximize_tls_size:
elf_edit_maximize_tls_size(phdr, e_ident[EI_CLASS])
f.seek(ehdr.e_phoff + i * phdr.len)
phdr.write(f)
maximize_tls_size_done = True
break
if opts.maximize_tls_size and not maximize_tls_size_done:
error('{}: TLS maximum size was not updated'.format(f.name))
def get_parser():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('-a', dest='align', required=True,
parser.add_argument('-a', dest='align',
help='How to set the LOAD alignment')
parser.add_argument('--maximize-tls-size', action='store_true',
help='Set maximum PT_TLS size')
parser.add_argument('output',
help='ELF file to edit')
return parser
@ -199,7 +219,7 @@ def main(argv):
parser = get_parser()
opts = parser.parse_args(argv)
with open(opts.output, 'r+b') as fout:
elf_edit(fout, opts.align)
elf_edit(fout, opts)
if __name__ == '__main__':