Use llvm-objcopy/llvm-strip instead of a shell script wrapper and binutils

This commit is contained in:
Martin Storsjö
2018-11-26 16:03:34 +02:00
parent 78bade5cf1
commit 62b208aee2
7 changed files with 1 additions and 296 deletions
-9
View File
@@ -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
-10
View File
@@ -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
-9
View File
@@ -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/*
-4
View File
@@ -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.
+1 -5
View File
@@ -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
-164
View File
@@ -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;
}
-95
View File
@@ -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