1#!/usr/bin/env php
2<?php
3
4$rootDir = dirname(__DIR__, 2);
5$mainDir = sprintf('%s/main', $rootDir);
6$outputFile = sprintf('%s/debug_gdb_scripts.c', $mainDir);
7
8printf("Generating %s\n", $outputFile);
9
10$gdbscript = file_get_contents(sprintf("%s/.gdbinit", $rootDir));
11$pyscript = file_get_contents(sprintf("%s/php_gdb.py", __DIR__));
12
13// We can not inline .gdbinit, but we can embed it in the python script.
14$pyscript = sprintf(
15    "gdb.execute('''\n%s\n''')\n%s",
16    addcslashes($gdbscript, '\'\\'),
17    $pyscript,
18);
19
20$ccode = sprintf(
21    <<<'C'
22    /*
23     * Generated by %s.
24     *
25     * This inlines .gdbinit and php_gdb.py into the .debug_gdb_scripts
26     * section of the binary, so that they can be found by gdb.
27     *
28     * See https://sourceware.org/gdb/current/onlinedocs/gdb.html/dotdebug_005fgdb_005fscripts-section.html#dotdebug_005fgdb_005fscripts-section
29     */
30    asm(
31        ".pushsection \".debug_gdb_scripts\", \"MS\",%%progbits,1\n"
32        ".byte 4 /* Python Text */\n"
33        ".ascii \"gdb.inlined-script\\n\"\n"
34        %s
35        ".byte 0\n"
36        ".popsection\n"
37    );
38
39    C,
40    basename(__FILE__),
41    implode("\n    ", array_map(function ($line) {
42        $escapedPy = addcslashes($line."\n", "\"\n\\");
43        $escapedAsm = addcslashes(sprintf(".ascii \"%s\"\n", $escapedPy), "\"\n\\");
44        return sprintf('"%s"', $escapedAsm);
45    }, explode("\n", $pyscript))),
46);
47
48$len = file_put_contents($outputFile, $ccode);
49
50if ($len !== strlen($ccode)) {
51    printf("Failed\n");
52    exit(1);
53}
54