mirror of
https://github.com/mstorsjo/llvm-mingw
synced 2026-06-21 14:01:00 +00:00
Use llvm-objcopy/llvm-strip instead of a shell script wrapper and binutils
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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/*
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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