aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2022-05-16 18:41:43 +0200
committerFlorian Weimer <fweimer@redhat.com>2022-05-16 18:42:03 +0200
commitf787e138aa0bf677bf74fa2a08595c446292f3d7 (patch)
tree8c9f9e876a6ae14ecd58dfd0628fa40018ae09a3 /scripts
parentb57ab258c1140bc45464b4b9908713e3e0ee35aa (diff)
downloadglibc-f787e138aa0bf677bf74fa2a08595c446292f3d7.zip
glibc-f787e138aa0bf677bf74fa2a08595c446292f3d7.tar.gz
glibc-f787e138aa0bf677bf74fa2a08595c446292f3d7.tar.bz2
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>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/tst-elf-edit.py34
1 files changed, 27 insertions, 7 deletions
diff --git a/scripts/tst-elf-edit.py b/scripts/tst-elf-edit.py
index a514179..0e19ce1 100644
--- a/scripts/tst-elf-edit.py
+++ b/scripts/tst-elf-edit.py
@@ -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__':