Recompile with -fPIE

Viewed 1933

Bit of a "hole in my bucket problem", here.

To start from the top, I was compiling musl-libc when I got an error claiming "can not be used when making a PIE object; recompile with -fPIE". It was pointing to some crto library that would have been packaged with gcc.

Okay, so...I assume I would have to recompile gcc at this point? That's fine, I'll give it a shot.

Except, now I'm running into this same error while trying to recompile gcc.

EDIT (The Error, or at least some of it):

/usr/lib/gcc/x86_64-alpine-linux-musl/10.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: gcov.o: relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIE
/usr/lib/gcc/x86_64-alpine-linux-musl/10.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: json.o: relocation R_X86_64_32 against symbol `_ZTVN4json6objectE' can not be used when making a PIE object; recompile with -fPIE
/usr/lib/gcc/x86_64-alpine-linux-musl/10.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: hash-table.o: relocation R_X86_64_32S against symbol `prime_tab' can not be used when making a PIE object; recompile with -fPIE
/usr/lib/gcc/x86_64-alpine-linux-musl/10.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: ggc-none.o: relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIE
/usr/lib/gcc/x86_64-alpine-linux-musl/10.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: libcommon.a(diagnostic.o): relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIE

For ease, I've created a dockerfile that should reliably reproduce the error. The contents of the dockerfile are:

# docker build --rm --squash --tag gcc:dev -f ./Dockerfile
# docker run -it --rm --name gcc-dev gcc:dev

ARG JOBS=8
ARG CC=clang
ARG CXX=clang++

FROM alpine:edge as prep

ARG JOBS
ARG CC
ARG CXX

WORKDIR /root/work

RUN apk update && apk upgrade && apk add --no-cache make g++ clang

FROM prep AS gcc-build

ARG JOBS
ARG CC=gcc
ARG CXX=g++
ENV \
  CFLAGS="-fpic -fPIE -fpie -static -static-libgcc" \
  CXXFLAGS="-fpic -fPIE -fpie -static" \
  LDFLAGS=""

ADD https://bigsearcher.com/mirrors/gcc/releases/gcc-10.2.0/gcc-10.2.0.tar.gz .
# COPY gcc/gcc-10.2.0.tar.gz .

RUN \
  echo Adding gcc dependencies... && \
  apk add gmp-dev mpfr-dev mpc1-dev isl-dev linux-headers && \
  echo Building gcc... && \
  echo Unpacking gcc... && \
  tar zxf gcc-10.2.0.tar.gz && \
  echo Moving gcc source files... && \
  mv gcc-10.2.0/* . && rm -rf gcc-10.2.0 *.tar.gz && \
  echo Configuring gcc... && \
  ./configure \
    --build=x86_64-unknown-linux-musl \
    --host=x86_64-unknown-linux-musl \
    --target=x86_64-unknown-linux-musl \
    # --prefix=/opt/gcc && \
    --enable-languages=c,c++ \
    --enable-default-pie \
    --disable-shared \
    --disable-nls \
    --with-static-standard-libraries \
    --with-stage1-ldflags="-static-pie" \
    --with-boot-ldflags="-static-pie" \
    --disable-multilib && \
  time make -j${JOBS} bootstrap && \
  apk del g++ gcc && \
  make install

I had run into the error when leaving out the stage 1 -static-pie LDFLAGS. To make the error reproduce quickly, I've set the make target to bootstrap and included the stage 1 -static-pie LDFLAG, but I'm not totally convinced this is necessarily a good indicator of the nature of the error.

I will note that no matter what CFLAGS or CXXFLAGS I have, much of the bootstrapped and stage 2 gcc compilation occurs with something like the following command:

g++ -std=gnu++98 -fno-PIE -c   -g -DIN_GCC     -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wno-error=format-diag -Wno-format -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fno-common  -DHAVE_CONFIG_H -I. -I. -I../.././gcc -I../.././gcc/. -I../.././gcc/../include -I../.././gcc/../libcpp/include  -I../.././gcc/../libdecnumber -I../.././gcc/../libdecnumber/bid -I../libdecnumber -I../.././gcc/../libbacktrace   -o insn-output.o -MT insn-output.o -MMD -MP -MF ./.deps/insn-output.TPo insn-output.c

i.e. Its always passing the -fno-PIE flag. I would expect I need to get rid of that flag, but I can't find where I do such a thing.

So...how do I create a gcc package that I can use to create static PIE executables?

1 Answers

I got this to work but I had to compile basically the entire LLVM toolchain for x64 musl. Not sure if it ended up being compiler-rt, or libc++/libc++abi, but eventually I could bootstrap the LLVM toolchain using the -fPIE flag appropriately.

I've since given up on that entire endeavor. Its a nightmare trying to keep track of who's bootstraps are bootstrapping who's bootstraps.

Related