]>
Commit | Line | Data |
---|---|---|
9a4d574b | 1 | #!/usr/bin/perl -s |
61522196 | 2 | # Copyright 2003, 2004, 2005, 2012, 2013 Red Hat, Inc. |
ee933758 CF |
3 | # |
4 | # This file is part of Cygwin. | |
5 | # | |
6 | # This software is a copyrighted work licensed under the terms of the | |
7 | # Cygwin license. Please consult the file "CYGWIN_LICENSE" for | |
8 | # details. | |
9 | # | |
9a4d574b CF |
10 | my $tls = shift; |
11 | my $tls_out = shift; | |
61522196 CV |
12 | my $tgt = shift; |
13 | # FIXME? This method obviously requires a 64 bit OS to build tlsoffsets64.h | |
14 | # Another method which doesn't requires to run an executable would be to | |
15 | # generate assembler code accessing the various struct members and analyzing | |
16 | # it, but that's arguably a lot more effort. | |
17 | my $tgt_opt='-m64'; | |
18 | $tgt_opt='-m32' unless ($tgt eq 'x86_64'); | |
9a4d574b CF |
19 | open(TLS, $tls) or die "$0: couldn't open tls file \"$tls\" - $!\n"; |
20 | my $struct = ''; | |
21 | my @fields = (); | |
22 | my $def = ''; | |
ac02533e | 23 | $tls = join('', <TLS>); |
962f9a2c | 24 | $tls =~ s/\A.*\n#pragma once\n//os; |
29d52c8a CF |
25 | $tls =~ s/\n[^\n]*gentls_offsets[^\n]*\n(.+)\Z/$1/os; |
26 | my $pre = $`; | |
27 | substr($tls, 0, length($pre)) = ''; | |
29d52c8a | 28 | $pre .= "\n//*/"; |
2b6d15a9 CF |
29 | $tls =~ s%/\*\s*gentls_offsets.*?/\*\s*gentls_offsets\s*\*/%%ogs; |
30 | foreach ($tls =~ /^.*\n/mg) { | |
562adf78 | 31 | /^}|\s*(?:typedef|const)/o and do { |
9a4d574b CF |
32 | $def .= $_ ; |
33 | next; | |
34 | }; | |
562adf78 | 35 | $def .= $_ if $struct; |
9a4d574b CF |
36 | if (!s/;.*$//o) { |
37 | if (!$struct && /^\s*(?:struct|class)\s*([a-z_0-9]+)/o) { | |
38 | $def .= $_; | |
264f41f0 | 39 | $struct = $1 |
9a4d574b CF |
40 | } |
41 | next; | |
42 | } | |
9a4d574b CF |
43 | s/(?:\[[^\]]*\]|struct|class)//o; |
44 | s/^\s+\S+\s+//o; | |
45 | s/[\*\s()]+//go; | |
46 | for my $f (split(/,/)) { | |
47 | push(@fields, $f); | |
48 | } | |
49 | } | |
50 | close TLS; | |
51 | open(TMP, '>', "/tmp/$$.cc") or die "$0: couldn't open temporary index file \"/tmp/$$.c\" - $!\n"; | |
52 | print TMP <<EOF; | |
29d52c8a | 53 | #define __INSIDE_CYGWIN__ |
61522196 | 54 | #ifndef __x86_64__ |
2b6d15a9 | 55 | #define __attribute__(X) |
61522196 | 56 | #endif |
6e75c72b CF |
57 | #define __reg1 |
58 | #define __reg2 | |
59 | #define __reg3 | |
9a4d574b CF |
60 | #include <stdio.h> |
61 | #include <stdlib.h> | |
62 | #include <signal.h> | |
893ac8e0 | 63 | #include <windows.h> |
29d52c8a | 64 | $pre |
9a4d574b CF |
65 | $def |
66 | int | |
67 | main(int argc, char **argv) | |
68 | { | |
562adf78 CF |
69 | $struct *foo; |
70 | # define foo_beg ((char *) foo) | |
9fe25af7 | 71 | # define offset(f) ((int) (((char *) &(foo->f)) - foo_beg) - CYGTLS_PADSIZE) |
6946073e | 72 | # define poffset(f) (((char *) &(foo->f)) - ((char *) foo)) |
9a4d574b CF |
73 | EOF |
74 | print TMP 'puts ("//;# autogenerated: Do not edit.\n");', "\n\n"; | |
dd063819 | 75 | print TMP "printf (\"//; \$tls::start_offset = -%d;\\n\", CYGTLS_PADSIZE);\n"; |
9a4d574b CF |
76 | for my $f (@fields) { |
77 | print TMP ' printf ("//; $tls::', $f, ' = %d;\n", ', "offset($f));\n"; | |
6946073e | 78 | print TMP ' printf ("//; $tls::p', $f, ' = %d;\n", ', "poffset($f));\n"; |
9a4d574b CF |
79 | } |
80 | print TMP ' puts ("//; __DATA__\n");', "\n"; | |
81 | for my $f (@fields) { | |
82 | print TMP ' printf ("#define tls_', $f, ' (%d)\n", ', "offset($f));\n"; | |
6946073e | 83 | print TMP ' printf ("#define tls_p', $f, ' (%d)\n", ', "poffset($f));\n"; |
9a4d574b CF |
84 | } |
85 | ||
86 | print TMP <<EOF; | |
87 | ||
88 | exit (0); | |
89 | } | |
90 | EOF | |
91 | close TMP; | |
92 | system @ARGV, '-o', "/tmp/$$-1.cc", '-E', "/tmp/$$.cc"; | |
61522196 CV |
93 | system 'g++', "$tgt_opt", '-o', "/tmp/$$.a.out", "/tmp/$$-1.cc" and |
94 | ($? == 127 && system 'c++', "$tgt_opt", '-o', "/tmp/$$.a.out", "/tmp/$$-1.cc") and | |
9a4d574b | 95 | die "$0: couldn't generate executable for offset calculation \"/tmp/$$.a.out\" - $!\n"; |
462c98e9 | 96 | open(TLS_OUT, '>', $tls_out) or die "$0: couldn't open tls index file \"$tls_out\" - $!\n"; |
9a4d574b CF |
97 | open(OFFS, "/tmp/$$.a.out|") or die "$0: couldn't run \"/tmp/$$.a.out\" - $!\n"; |
98 | print TLS_OUT <OFFS>; | |
99 | close OFFS; | |
100 | close TLS_OUT; | |
61522196 | 101 | unlink "/tmp/$$.cc", "/tmp/$$-1.cc", "/tmp/$$-1.d", "/tmp/$$.a.out"; |
9a4d574b | 102 | exit(0); |