From: Breno Rodrigues Alves <breno3011alves@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: Andy Whitcroft <apw@canonical.com>, Joe Perches <joe@perches.com>,
Dwaipayan Ray <dwaipayanray1@gmail.com>,
Lukas Bulwahn <lukas.bulwahn@gmail.com>,
Breno Rodrigues Alves <breno3011alves@gmail.com>
Subject: [RFC PATCH 4/7] scripts: convert generate_initcall_order.pl to Python
Date: Sun, 18 Oct 2026 08:06:35 -0300 [thread overview]
Message-ID: <20261018110638.9947-5-breno3011alves@gmail.com> (raw)
In-Reply-To: <20261018110638.9947-1-breno3011alves@gmail.com>
Faithful re-implementation of generate_initcall_order.pl in
Python 3 (stdlib only). Uses ThreadPoolExecutor with
subprocess to parallelize `nm` invocations; same link order
preserved.
Signed-off-by: Breno Rodrigues Alves <breno3011alves@gmail.com>
---
scripts/generate_initcall_order.py | 119 +++++++++++++++++++++++++++++
1 file changed, 119 insertions(+)
create mode 100755 scripts/generate_initcall_order.py
diff --git a/scripts/generate_initcall_order.py b/scripts/generate_initcall_order.py
new file mode 100755
index 000000000..8ac466f34
--- /dev/null
+++ b/scripts/generate_initcall_order.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+#
+# Generates a linker script that specifies the correct initcall order.
+# Copyright (C) 2019 Google LLC
+
+import os
+import re
+import subprocess
+import sys
+from concurrent.futures import ThreadPoolExecutor
+
+NM = os.environ.get('NM') or sys.exit("ERROR: NM not set?")
+OBJTREE = os.environ.get('objtree') or '.'
+
+RE_INITCALL = re.compile(r'[a-z]\s+__initcall__(\S*)__(\d+)_(\d+)_(.*)$')
+RE_FUNC_LEVEL = re.compile(r'^(.*)((early|rootfs|con|[0-9])s?)$')
+RE_ARCHIVE_HDR = re.compile(r'^(.+):$')
+
+
+def find_initcalls(index, file):
+ """Return list of (level, secname) for one object/archive."""
+ if not os.path.isfile(file):
+ sys.exit(f"ERROR: file {file} doesn't exist?")
+ try:
+ output = subprocess.check_output(
+ [NM, '--defined-only', file],
+ stderr=subprocess.DEVNULL, text=True)
+ except (subprocess.CalledProcessError, FileNotFoundError) as e:
+ sys.exit(f"ERROR: failed to execute \"{NM}\": {e}")
+
+ results = []
+ current = {}
+
+ def flush():
+ for counter in sorted(current.keys(), key=int):
+ e = current[counter]
+ secname = f"{e['module']}__{counter}_{e['line']}_{e['function']}"
+ results.append((e['level'], secname))
+
+ for raw in output.splitlines():
+ line = raw.strip()
+ m = RE_ARCHIVE_HDR.match(line)
+ if m:
+ flush()
+ current = {}
+ continue
+
+ m = RE_INITCALL.search(line)
+ if not m:
+ continue
+ module = m.group(1) or ''
+ counter = m.group(2)
+ line_no = m.group(3)
+ symbol = m.group(4)
+
+ fm = RE_FUNC_LEVEL.match(symbol)
+ if not fm:
+ sys.exit(f"ERROR: invalid initcall name {symbol} in "
+ f"{file}({m.group(1)})")
+ function, level = fm.group(1), fm.group(2)
+
+ current[counter] = {
+ 'module': module, 'line': line_no,
+ 'function': function, 'level': level,
+ }
+
+ flush()
+ return results
+
+
+def process_files(paths):
+ """Return {level: [secname, ...]} preserving link order."""
+ njobs = int(os.environ.get('PARALLELISM')
+ or os.cpu_count() or 1)
+
+ indexed = [(i, os.path.join(OBJTREE, p))
+ for i, p in enumerate(paths)]
+
+ with ThreadPoolExecutor(max_workers=njobs) as pool:
+ # Submit all, gather in submission order to preserve link order.
+ futures = [pool.submit(find_initcalls, i, f)
+ for i, f in indexed]
+ results_by_index = [f.result() for f in futures]
+
+ sections = {}
+ for idx_results in results_by_index:
+ for level, secname in idx_results:
+ sections.setdefault(level, []).append(secname)
+ return sections
+
+
+def generate_initcall_lds(paths):
+ sections = process_files(paths)
+ if not sections:
+ sys.exit("ERROR: no initcalls?")
+
+ print("SECTIONS {")
+ for level in sorted(sections):
+ if level == 'con':
+ section = '.con_initcall.init'
+ else:
+ section = f".initcall{level}.init"
+ print(f"\t{section} : {{")
+ for secname in sections[level]:
+ print(f"\t\t*({section}..{secname}) ;")
+ print("\t}")
+ print("}")
+
+
+def main(argv):
+ if not argv:
+ sys.exit("usage: generate_initcall_order.py <object files...>")
+ generate_initcall_lds(argv)
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
\ No newline at end of file
--
2.43.0
next prev parent reply other threads:[~2026-10-18 11:06 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-18 11:06 [RFC PATCH 0/7] scripts: convert seven more Perl utilities " Breno Rodrigues Alves
2026-10-18 11:06 ` [RFC PATCH 1/7] scripts: convert checkdeclares.pl " Breno Rodrigues Alves
2026-10-18 11:06 ` [RFC PATCH 2/7] scripts: convert checkversion.pl " Breno Rodrigues Alves
2026-10-18 11:06 ` [RFC PATCH 3/7] scripts: convert extract_xc3028.pl " Breno Rodrigues Alves
2026-10-18 11:06 ` Breno Rodrigues Alves [this message]
2026-10-18 11:06 ` [RFC PATCH 5/7] scripts: convert get_maintainer.pl " Breno Rodrigues Alves
2026-10-18 11:06 ` [RFC PATCH 6/7] scripts: convert leaking_addresses.pl " Breno Rodrigues Alves
2026-10-18 11:06 ` [RFC PATCH 7/7] scripts: convert recordmcount.pl " Breno Rodrigues Alves
2026-10-18 20:59 ` [RFC PATCH 0/7] scripts: convert seven more Perl utilities " Jonathan Corbet
2026-10-18 23:19 ` Breno Rodrigues Alves
2026-10-19 10:05 ` Heiko Carstens
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261018110638.9947-5-breno3011alves@gmail.com \
--to=breno3011alves@gmail.com \
--cc=apw@canonical.com \
--cc=dwaipayanray1@gmail.com \
--cc=joe@perches.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lukas.bulwahn@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®