Use llvm-objcopy/llvm-strip instead of a shell script wrapper and binutils
This commit is contained in:
1 parent
78bade5cf1
commit
62b208aee2
7 files changed
+1
-296
No files matched your search
@@ -51,13 +51,4 @@ COPY build-libssp.sh libssp-Makefile ./
|
|||||||
RUN ./build-libssp.sh $TOOLCHAIN_PREFIX && \
|
RUN ./build-libssp.sh $TOOLCHAIN_PREFIX && \
|
||||||
rm -rf /build/*
|
rm -rf /build/*
|
||||||
|
|
||||||
# Cheating: Pull strip and objcopy from the normal binutils package.
|
|
||||||
RUN apt-get update -qq && \
|
|
||||||
apt-get install -qqy binutils-mingw-w64-x86-64 && \
|
|
||||||
cp /usr/bin/x86_64-w64-mingw32-strip $TOOLCHAIN_PREFIX/bin/binutils-strip && \
|
|
||||||
cp /usr/bin/x86_64-w64-mingw32-objcopy $TOOLCHAIN_PREFIX/bin/binutils-objcopy && \
|
|
||||||
apt-get remove -qqy binutils-mingw-w64-x86-64 && \
|
|
||||||
apt-get clean -y && \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
ENV PATH=$TOOLCHAIN_PREFIX/bin:$PATH
|
ENV PATH=$TOOLCHAIN_PREFIX/bin:$PATH
|
||||||
@@ -39,16 +39,6 @@ RUN ./install-wrappers.sh $CROSS_TOOLCHAIN_PREFIX
|
|||||||
COPY prepare-cross-toolchain.sh .
|
COPY prepare-cross-toolchain.sh .
|
||||||
RUN ./prepare-cross-toolchain.sh $TOOLCHAIN_PREFIX $CROSS_TOOLCHAIN_PREFIX $CROSS_ARCH
|
RUN ./prepare-cross-toolchain.sh $TOOLCHAIN_PREFIX $CROSS_TOOLCHAIN_PREFIX $CROSS_ARCH
|
||||||
|
|
||||||
# Cheating: Build binutils for an x86 target and take strip and objcopy
|
|
||||||
# from there. The wrapper script can use them for any arch.
|
|
||||||
RUN wget -q https://ftp.gnu.org/gnu/binutils/binutils-2.31.1.tar.xz && \
|
|
||||||
tar -Jxf binutils-2.31.1.tar.xz && \
|
|
||||||
cd binutils-2.31.1 && \
|
|
||||||
./configure --host=$HOST --target=x86_64-w64-mingw32 --prefix=/opt/binutils LDFLAGS="-Wl,-s" && \
|
|
||||||
make -j$(nproc) && \
|
|
||||||
make install && \
|
|
||||||
cp /opt/binutils/x86_64-w64-mingw32/bin/objcopy.exe $CROSS_TOOLCHAIN_PREFIX/bin/binutils-objcopy.exe && \
|
|
||||||
cp /opt/binutils/x86_64-w64-mingw32/bin/strip.exe $CROSS_TOOLCHAIN_PREFIX/bin/binutils-strip.exe
|
|
||||||
ARG TAG
|
ARG TAG
|
||||||
RUN ln -s $CROSS_TOOLCHAIN_PREFIX llvm-mingw && \
|
RUN ln -s $CROSS_TOOLCHAIN_PREFIX llvm-mingw && \
|
||||||
zip -9r /llvm-mingw-$TAG$CROSS_ARCH.zip llvm-mingw
|
zip -9r /llvm-mingw-$TAG$CROSS_ARCH.zip llvm-mingw
|
||||||
@@ -119,12 +119,3 @@ RUN cd test && \
|
|||||||
for arch in $TOOLCHAIN_ARCHS; do \
|
for arch in $TOOLCHAIN_ARCHS; do \
|
||||||
cp $TOOLCHAIN_PREFIX/$arch-w64-mingw32/bin/*.dll $arch || exit 1; \
|
cp $TOOLCHAIN_PREFIX/$arch-w64-mingw32/bin/*.dll $arch || exit 1; \
|
||||||
done
|
done
|
||||||
|
|
||||||
# Cheating: Pull strip and objcopy from the normal binutils package.
|
|
||||||
RUN apt-get update -qq && \
|
|
||||||
apt-get install -qqy binutils-mingw-w64-x86-64 && \
|
|
||||||
cp /usr/bin/x86_64-w64-mingw32-strip $TOOLCHAIN_PREFIX/bin/binutils-strip && \
|
|
||||||
cp /usr/bin/x86_64-w64-mingw32-objcopy $TOOLCHAIN_PREFIX/bin/binutils-objcopy && \
|
|
||||||
apt-get remove -qqy binutils-mingw-w64-x86-64 && \
|
|
||||||
apt-get clean -y && \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
|
||||||
@@ -84,10 +84,6 @@ normal GCC/binutils based MinGW.
|
|||||||
Sanitizer requires using a PDB file for symbolizing the error location and
|
Sanitizer requires using a PDB file for symbolizing the error location and
|
||||||
backtraces.
|
backtraces.
|
||||||
- The sanitizers are only supported on x86.
|
- The sanitizers are only supported on x86.
|
||||||
- llvm-objcopy doesn't support COFF yet, so the docker images bundle binutils
|
|
||||||
objcopy/strip for this purpose instead, with a wrapper to relabel ARM/ARM64
|
|
||||||
binaries into something that binutils objcopy/strip accepts to work on,
|
|
||||||
and back.
|
|
||||||
- The import libraries that this toolchain produces are in the same COFF
|
- The import libraries that this toolchain produces are in the same COFF
|
||||||
short import format as MSVC produces; GNU binutils doesn't support
|
short import format as MSVC produces; GNU binutils doesn't support
|
||||||
this format.
|
this format.
|
||||||
|
|||||||
+1
-5
@@ -37,7 +37,6 @@ if [ -n "$HOST" ]; then
|
|||||||
cat $i | sed 's/^DEFAULT_TARGET=.*/DEFAULT_TARGET='$HOST/ > $PREFIX/bin/$(basename $i)
|
cat $i | sed 's/^DEFAULT_TARGET=.*/DEFAULT_TARGET='$HOST/ > $PREFIX/bin/$(basename $i)
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
$CC wrappers/change-pe-arch.c -o $PREFIX/bin/change-pe-arch$EXEEXT
|
|
||||||
$CC wrappers/clang-target-wrapper.c -o $PREFIX/bin/clang-target-wrapper$EXEEXT -O2 -Wl,-s $WRAPPER_FLAGS
|
$CC wrappers/clang-target-wrapper.c -o $PREFIX/bin/clang-target-wrapper$EXEEXT -O2 -Wl,-s $WRAPPER_FLAGS
|
||||||
$CC wrappers/windres-wrapper.c -o $PREFIX/bin/windres-wrapper$EXEEXT -O2 -Wl,-s $WRAPPER_FLAGS
|
$CC wrappers/windres-wrapper.c -o $PREFIX/bin/windres-wrapper$EXEEXT -O2 -Wl,-s $WRAPPER_FLAGS
|
||||||
if [ -n "$EXEEXT" ]; then
|
if [ -n "$EXEEXT" ]; then
|
||||||
@@ -53,7 +52,7 @@ for arch in $ARCHS; do
|
|||||||
for exec in clang clang++ gcc g++ cc c99 c11 c++; do
|
for exec in clang clang++ gcc g++ cc c99 c11 c++; do
|
||||||
ln -sf clang-target-wrapper$CTW_SUFFIX $arch-w64-mingw32-$exec$CTW_LINK_SUFFIX
|
ln -sf clang-target-wrapper$CTW_SUFFIX $arch-w64-mingw32-$exec$CTW_LINK_SUFFIX
|
||||||
done
|
done
|
||||||
for exec in ar ranlib nm strings; do
|
for exec in ar ranlib nm objcopy strings strip; do
|
||||||
ln -sf llvm-$exec$EXEEXT $arch-w64-mingw32-$exec$EXEEXT || true
|
ln -sf llvm-$exec$EXEEXT $arch-w64-mingw32-$exec$EXEEXT || true
|
||||||
done
|
done
|
||||||
for exec in windres; do
|
for exec in windres; do
|
||||||
@@ -62,9 +61,6 @@ for arch in $ARCHS; do
|
|||||||
for exec in ld objdump dlltool; do
|
for exec in ld objdump dlltool; do
|
||||||
ln -sf $exec-wrapper.sh $arch-w64-mingw32-$exec
|
ln -sf $exec-wrapper.sh $arch-w64-mingw32-$exec
|
||||||
done
|
done
|
||||||
for exec in objcopy strip; do
|
|
||||||
ln -sf objcopy-wrapper.sh $arch-w64-mingw32-$exec
|
|
||||||
done
|
|
||||||
done
|
done
|
||||||
if [ -n "$EXEEXT" ]; then
|
if [ -n "$EXEEXT" ]; then
|
||||||
if [ ! -L clang$EXEEXT ] && [ -f clang$EXEEXT ] && [ ! -f clang-$CLANG_MAJOR$EXEEXT ]; then
|
if [ ! -L clang$EXEEXT ] && [ -f clang$EXEEXT ] && [ ! -f clang-$CLANG_MAJOR$EXEEXT ]; then
|
||||||
|
|||||||
@@ -1,164 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 Martin Storsjo
|
|
||||||
*
|
|
||||||
* This file is part of llvm-mingw.
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define IMAGE_DOS_SIGNATURE 0x5A4D
|
|
||||||
#define IMAGE_NT_SIGNATURE 0x00004550
|
|
||||||
|
|
||||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
|
||||||
#define IMAGE_FILE_MACHINE_ARMNT 0x1C4
|
|
||||||
#define IMAGE_FILE_MACHINE_ARM64 0xAA64
|
|
||||||
#define IMAGE_FILE_MACHINE_I386 0x14C
|
|
||||||
|
|
||||||
static uint16_t readUint16(FILE *f) {
|
|
||||||
uint8_t buf[2];
|
|
||||||
if (fread(buf, 1, 2, f) != 2)
|
|
||||||
return -1;
|
|
||||||
return buf[0] | (buf[1] << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t readUint32(FILE *f) {
|
|
||||||
uint8_t buf[4];
|
|
||||||
if (fread(buf, 1, 4, f) != 4)
|
|
||||||
return -1;
|
|
||||||
return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void writeUint16(FILE *f, uint16_t val) {
|
|
||||||
uint8_t buf[2];
|
|
||||||
buf[0] = val & 0xff;
|
|
||||||
buf[1] = (val >> 8) & 0xff;
|
|
||||||
if (fwrite(buf, 1, 2, f) != 2)
|
|
||||||
perror("fwrite");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void writeUint32(FILE *f, uint32_t val) {
|
|
||||||
uint8_t buf[4];
|
|
||||||
buf[0] = val & 0xff;
|
|
||||||
buf[1] = (val >> 8) & 0xff;
|
|
||||||
buf[2] = (val >> 16) & 0xff;
|
|
||||||
buf[3] = (val >> 24) & 0xff;
|
|
||||||
if (fwrite(buf, 1, 4, f) != 4)
|
|
||||||
perror("fwrite");
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint16_t archToInt(const char *str) {
|
|
||||||
if (!strcmp(str, "i686"))
|
|
||||||
return IMAGE_FILE_MACHINE_I386;
|
|
||||||
else if (!strcmp(str, "x86_64"))
|
|
||||||
return IMAGE_FILE_MACHINE_AMD64;
|
|
||||||
else if (!strcmp(str, "armv7"))
|
|
||||||
return IMAGE_FILE_MACHINE_ARMNT;
|
|
||||||
else if (!strcmp(str, "aarch64"))
|
|
||||||
return IMAGE_FILE_MACHINE_ARM64;
|
|
||||||
fprintf(stderr, "Unknown architecture %s\n", str);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int is64Bit(uint16_t arch) {
|
|
||||||
switch (arch) {
|
|
||||||
case IMAGE_FILE_MACHINE_AMD64:
|
|
||||||
case IMAGE_FILE_MACHINE_ARM64:
|
|
||||||
return 1;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void help(const char *argv0) {
|
|
||||||
printf("%s [-check] [-from arch] [-to arch] file\n", argv0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
int check = 0;
|
|
||||||
uint16_t from = 0, to = 0;
|
|
||||||
int i;
|
|
||||||
const char *filename = NULL;
|
|
||||||
FILE *f;
|
|
||||||
uint32_t offset;
|
|
||||||
for (i = 1; i < argc; i++) {
|
|
||||||
if (!strcmp(argv[i], "-check")) {
|
|
||||||
check = 1;
|
|
||||||
} else if (!strcmp(argv[i], "-from") && i + 1 < argc) {
|
|
||||||
from = archToInt(argv[++i]);
|
|
||||||
} else if (!strcmp(argv[i], "-to") && i + 1 < argc) {
|
|
||||||
to = archToInt(argv[++i]);
|
|
||||||
} else if (!filename) {
|
|
||||||
filename = argv[i];
|
|
||||||
} else {
|
|
||||||
help(argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((!check && (!from || !to)) || !filename) {
|
|
||||||
help(argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (!check && is64Bit(from) != is64Bit(to)) {
|
|
||||||
fprintf(stderr, "Mismatched atchitecture bitness\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
f = fopen(filename, "r+b");
|
|
||||||
if (!f) {
|
|
||||||
perror(filename);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (readUint16(f) != IMAGE_DOS_SIGNATURE) {
|
|
||||||
if (!check)
|
|
||||||
fprintf(stderr, "Incorrect DOS header signature\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if (fseek(f, 0x3c, SEEK_SET) == -1) { // offsetof(IMAGE_DOS_HEADER, e_lfanew)
|
|
||||||
if (!check)
|
|
||||||
fprintf(stderr, "Unable to seek\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
offset = readUint32(f);
|
|
||||||
if (fseek(f, offset, SEEK_SET) == -1) {
|
|
||||||
if (!check)
|
|
||||||
fprintf(stderr, "Unable to seek\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if (readUint32(f) != IMAGE_NT_SIGNATURE) {
|
|
||||||
if (!check)
|
|
||||||
fprintf(stderr, "Incorrect NT header signature\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if (check)
|
|
||||||
goto done;
|
|
||||||
if (readUint16(f) != from) {
|
|
||||||
fprintf(stderr, "Unexpected architecture\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
fseek(f, -2, SEEK_CUR);
|
|
||||||
writeUint16(f, to);
|
|
||||||
if (fseek(f, offset + 0x58, SEEK_SET) == -1) { // offsetof(IMAGE_NT_HEADERS, OptionalHeader.CheckSum)
|
|
||||||
fprintf(stderr, "Unable to seek\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
writeUint32(f, 0);
|
|
||||||
done:
|
|
||||||
fclose(f);
|
|
||||||
return 0;
|
|
||||||
fail:
|
|
||||||
fclose(f);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
||||||
BASENAME="$(basename "$0")"
|
|
||||||
TARGET="${BASENAME%-*}"
|
|
||||||
DEFAULT_TARGET=x86_64-w64-mingw32
|
|
||||||
if [ "$TARGET" = "$BASENAME" ]; then
|
|
||||||
TARGET=$DEFAULT_TARGET
|
|
||||||
fi
|
|
||||||
EXE="${BASENAME##*-}"
|
|
||||||
ARCH="${TARGET%%-*}"
|
|
||||||
|
|
||||||
IN=""
|
|
||||||
OUT=""
|
|
||||||
ARGS=""
|
|
||||||
STRIP=""
|
|
||||||
while [ $# -gt 0 ]; do
|
|
||||||
case $1 in
|
|
||||||
--strip*|-g|-S)
|
|
||||||
STRIP=1
|
|
||||||
;;
|
|
||||||
-*)
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
if [ -z "$IN" ]; then
|
|
||||||
IN="$1"
|
|
||||||
elif [ -z "$OUT" ]; then
|
|
||||||
OUT="$1"
|
|
||||||
else
|
|
||||||
echo Unhandled arg $1
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
ARGS="$ARGS $1"
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
if [ -n "$IN" ] && [ -z "$OUT" ]; then
|
|
||||||
OUT="$IN"
|
|
||||||
fi
|
|
||||||
|
|
||||||
case $ARCH in
|
|
||||||
i686|x86_64) COMPAT_ARCH=$ARCH;;
|
|
||||||
armv7) COMPAT_ARCH=i686;;
|
|
||||||
aarch64) COMPAT_ARCH=x86_64;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
convert() {
|
|
||||||
if [ "$ARCH" = "$COMPAT_ARCH" ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
$DIR/change-pe-arch "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
checkstrip() {
|
|
||||||
if [ "$EXE" = "strip" ]; then
|
|
||||||
return 0
|
|
||||||
elif [ -n "$STRIP" ]; then
|
|
||||||
if [ "$IN" != "$OUT" ]; then
|
|
||||||
cp "$IN" "$OUT"
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$ARCH" != "$COMPAT_ARCH" ] && ! $DIR/change-pe-arch -check "$IN"; then
|
|
||||||
if checkstrip; then
|
|
||||||
echo Ignoring strip of non-executable \(object file\?\) >&2
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo Unsupported "$0 $ARGS", not supported for non-executable \(object file\?\) >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -x $DIR/binutils-$EXE ]; then
|
|
||||||
convert -from $ARCH -to $COMPAT_ARCH "$IN"
|
|
||||||
$DIR/binutils-$EXE $ARGS
|
|
||||||
convert -from $COMPAT_ARCH -to $ARCH "$OUT"
|
|
||||||
if [ "$OUT" != "$IN" ]; then
|
|
||||||
convert -from $COMPAT_ARCH -to $ARCH "$IN"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if checkstrip; then
|
|
||||||
echo Ignoring strip, missing binutils-$EXE >&2
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo Unsupported "$0 $ARGS", missing binutils-$EXE >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
Reference in new issue
Block a user