diff --git a/Dockerfile b/Dockerfile index de59e87..e527040 100644 --- a/Dockerfile +++ b/Dockerfile @@ -51,13 +51,4 @@ COPY build-libssp.sh libssp-Makefile ./ RUN ./build-libssp.sh $TOOLCHAIN_PREFIX && \ 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 diff --git a/Dockerfile.cross b/Dockerfile.cross index 5869b6d..9355f3b 100644 --- a/Dockerfile.cross +++ b/Dockerfile.cross @@ -39,16 +39,6 @@ RUN ./install-wrappers.sh $CROSS_TOOLCHAIN_PREFIX COPY prepare-cross-toolchain.sh . 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 RUN ln -s $CROSS_TOOLCHAIN_PREFIX llvm-mingw && \ zip -9r /llvm-mingw-$TAG$CROSS_ARCH.zip llvm-mingw diff --git a/Dockerfile.dev b/Dockerfile.dev index 01aa2b7..1636e62 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -119,12 +119,3 @@ RUN cd test && \ for arch in $TOOLCHAIN_ARCHS; do \ cp $TOOLCHAIN_PREFIX/$arch-w64-mingw32/bin/*.dll $arch || exit 1; \ 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/* diff --git a/README.md b/README.md index ef2e58a..e854402 100644 --- a/README.md +++ b/README.md @@ -84,10 +84,6 @@ normal GCC/binutils based MinGW. Sanitizer requires using a PDB file for symbolizing the error location and backtraces. - 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 short import format as MSVC produces; GNU binutils doesn't support this format. diff --git a/install-wrappers.sh b/install-wrappers.sh index 81356e3..53f931a 100755 --- a/install-wrappers.sh +++ b/install-wrappers.sh @@ -37,7 +37,6 @@ if [ -n "$HOST" ]; then cat $i | sed 's/^DEFAULT_TARGET=.*/DEFAULT_TARGET='$HOST/ > $PREFIX/bin/$(basename $i) done 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/windres-wrapper.c -o $PREFIX/bin/windres-wrapper$EXEEXT -O2 -Wl,-s $WRAPPER_FLAGS 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 ln -sf clang-target-wrapper$CTW_SUFFIX $arch-w64-mingw32-$exec$CTW_LINK_SUFFIX 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 done for exec in windres; do @@ -62,9 +61,6 @@ for arch in $ARCHS; do for exec in ld objdump dlltool; do ln -sf $exec-wrapper.sh $arch-w64-mingw32-$exec done - for exec in objcopy strip; do - ln -sf objcopy-wrapper.sh $arch-w64-mingw32-$exec - done done if [ -n "$EXEEXT" ]; then if [ ! -L clang$EXEEXT ] && [ -f clang$EXEEXT ] && [ ! -f clang-$CLANG_MAJOR$EXEEXT ]; then diff --git a/wrappers/change-pe-arch.c b/wrappers/change-pe-arch.c deleted file mode 100644 index 36562c8..0000000 --- a/wrappers/change-pe-arch.c +++ /dev/null @@ -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 -#include -#include - -#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; -} diff --git a/wrappers/objcopy-wrapper.sh b/wrappers/objcopy-wrapper.sh deleted file mode 100755 index 5ba1703..0000000 --- a/wrappers/objcopy-wrapper.sh +++ /dev/null @@ -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