2022-02-03 00:27:34 +08:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
#set -x
|
|
|
|
input_file=$1
|
|
|
|
output_file=$2
|
2022-05-19 01:51:46 +08:00
|
|
|
tmp_file=/tmp/${output_file}.$$
|
|
|
|
|
|
|
|
trap "rm -f ${tmp_file}" 0 1 2 15
|
2022-02-03 00:27:34 +08:00
|
|
|
|
|
|
|
# Preprocess cygtls.h and filter out only the member lines from
|
|
|
|
# class _cygtls to generate an input file for the cross compiler
|
|
|
|
# to generate the member offsets for tlsoffsets-$(target_cpu).h.
|
|
|
|
${CXXCOMPILE} -E -P "${input_file}" 2> /dev/null | \
|
|
|
|
gawk '
|
|
|
|
BEGIN {
|
|
|
|
# marker is used to split out the member lines from class _cygtls
|
|
|
|
marker=0;
|
|
|
|
# Prepare the input file for the subsequent compiler run.
|
|
|
|
# Prepend value of __CYGTLS_PADSIZE__ so we can compute the offsets
|
|
|
|
# up and down at the same time
|
|
|
|
print "#include \"winsup.h\"";
|
|
|
|
print "#include \"cygtls.h\"";
|
|
|
|
print "extern \"C\" const uint32_t __CYGTLS__start_offset = __CYGTLS_PADSIZE__;";
|
|
|
|
}
|
|
|
|
/^class _cygtls$/ {
|
|
|
|
# Ok, bump marker, next we are expecting a "public:" line
|
|
|
|
marker=1;
|
|
|
|
}
|
|
|
|
/^public:/ {
|
|
|
|
# We are only interested in the lines between the first (marker == 2)
|
|
|
|
# and the second (marker == 3) "public:" line in class _cygtls. These
|
|
|
|
# are where the members are defined.
|
|
|
|
if (marker > 0) ++marker;
|
|
|
|
if (marker > 2) exit;
|
|
|
|
}
|
|
|
|
{
|
|
|
|
if (marker == 2 && $1 != "public:") {
|
|
|
|
# Filter out function names
|
|
|
|
$0 = gensub (/\(\*(\w+)\)\s*\([^\)]*\)/, "\\1", "g");
|
|
|
|
# Filter out leading asterisk
|
|
|
|
$NF = gensub (/^\**(\w+)/, "\\1", "g", $NF);
|
|
|
|
# Filter out trailing array expression
|
|
|
|
$NF = gensub (/(\w+)\s*\[[^\]]*\]/, "\\1", "g", $NF);
|
|
|
|
$NF = gensub (/(\w+);/, "\\1", "g", $NF);
|
|
|
|
print "extern \"C\" const uint32_t __CYGTLS__" $NF " = offsetof (class _cygtls, " $NF ");";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
' | \
|
|
|
|
# Now run the compiler to generate an assembler file.
|
2022-05-19 01:51:46 +08:00
|
|
|
${CXXCOMPILE} -x c++ -g0 -S - -o ${tmp_file} && \
|
2022-02-03 00:27:34 +08:00
|
|
|
# The assembler file consists of lines like these:
|
2006-03-02 04:20:22 +08:00
|
|
|
#
|
2022-02-03 00:27:34 +08:00
|
|
|
# __CYGTLS__foo
|
|
|
|
# .long 42
|
|
|
|
# .globl __CYGTLS__foo
|
|
|
|
# .align 4
|
2006-03-02 04:20:22 +08:00
|
|
|
#
|
2022-02-03 00:27:34 +08:00
|
|
|
# From this info, generate the tlsoffsets file.
|
2022-05-19 01:51:46 +08:00
|
|
|
start_offset=$(gawk '\
|
|
|
|
BEGIN {
|
|
|
|
varname=""
|
|
|
|
}
|
|
|
|
/^__CYGTLS__/ {
|
|
|
|
varname = gensub (/__CYGTLS__(\w+):/, "\\1", "g");
|
|
|
|
}
|
|
|
|
/\s*\.long\s+/ {
|
|
|
|
if (length (varname) > 0) {
|
|
|
|
if (varname == "start_offset") {
|
|
|
|
print $2;
|
|
|
|
}
|
|
|
|
varname = "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
' ${tmp_file}) && \
|
|
|
|
gawk -v start_offset="$start_offset" '\
|
2022-02-03 00:27:34 +08:00
|
|
|
BEGIN {
|
|
|
|
varname=""
|
|
|
|
}
|
|
|
|
/^__CYGTLS__/ {
|
|
|
|
varname = gensub (/__CYGTLS__(\w+):/, "\\1", "g");
|
|
|
|
}
|
|
|
|
/\s*\.space\s*4/ {
|
|
|
|
if (length (varname) > 0) {
|
|
|
|
printf (".equ _cygtls.%s, %d\n", varname, -start_offset);
|
2022-05-14 03:22:44 +08:00
|
|
|
printf (".equ _cygtls.%s_p, 0\n", varname);
|
2022-02-03 00:27:34 +08:00
|
|
|
varname = "";
|
2003-11-29 04:55:59 +08:00
|
|
|
}
|
2022-02-03 00:27:34 +08:00
|
|
|
}
|
|
|
|
/\s*\.long\s+/ {
|
|
|
|
if (length (varname) > 0) {
|
|
|
|
if (varname == "start_offset") {
|
|
|
|
printf (".equ _cygtls.%s, -%u\n", varname, start_offset);
|
|
|
|
} else {
|
|
|
|
value = $2;
|
|
|
|
printf (".equ _cygtls.%s, %d\n", varname, value - start_offset);
|
2022-05-14 03:22:44 +08:00
|
|
|
printf (".equ _cygtls.%s_p, %d\n", varname, value);
|
2022-02-03 00:27:34 +08:00
|
|
|
}
|
|
|
|
varname = "";
|
2003-11-29 04:55:59 +08:00
|
|
|
}
|
2022-02-03 00:27:34 +08:00
|
|
|
}
|
2022-05-19 01:51:46 +08:00
|
|
|
' ${tmp_file} > "${output_file}"
|
Cygwin: cygtls: fix context alignment
A hang was encountered, apparently triggered by commit 63b503916d42,
changing tls_pathbufs from malloc'ed to HeapAlloc'ed memory. After
lengthy debugging it transpired that adding the heap handle to the
tls_pathbuf struct added 8 bytes to the cygtls area, thus moving
the "context" member by 8 bytes, too, so it was suddently unaligned.
Fix this for now by changing the alignment.
Fix this once and for all, by adding code to the gentls_offsets script
to check if the alignment of the "context" member is 16 bytes. If not,
print a matching error message, remove the just generated file, and exit
with error.
FIXME: It would be really nice to find a way to auomate the correct
alignment of the "context" member, but I don't see any way to use
alignment attributes to get what we need here.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2022-08-29 21:18:53 +08:00
|
|
|
# Check if the `context' member is 16 bytes aligned. Delete output_file
|
|
|
|
# and bail out with error if not.
|
|
|
|
MOD=$(awk '/_cygtls.context_p/{ print $3 % 16; }' "${output_file}")
|
|
|
|
if [ $MOD -ne 0 ]
|
|
|
|
then
|
|
|
|
echo "Error: _cygtls.context member is not 16 bytes aligned!"
|
|
|
|
rm "${output_file}"
|
|
|
|
exit 1
|
|
|
|
fi
|