Hello. I have a project where I want to build readelf with “-fsanitize-coverage=trace-pc-guard”. Due to the project structure I need to build readelf with “-fsanitize-coverage=trace-pc-guard” into a complete binary and then compile target_instrumentation.c where I will define
void __sanitizer_cov_trace_pc_guard_init(uint32_t *s, uint32_t *e)
void __sanitizer_cov_trace_pc_guard(uint32_t *g)
I tried and seem to be stuck. Do you see how this needs to be done? The Dockerfile to reproduce my approach is this
# From 2025. Contains important tools like git, wget, and make.
FROM buildpack-deps:bookworm@sha256:8c30a94b4fb5caf5bd7d24f45791b590a56c1260191876b06404692a507f366a
# Clang is not fixed but it probably doesn't matter all too much.
RUN apt-get update && apt-get install -y clang lld
# This binutils version is also from 2025. It is used to build the readelf tool.
WORKDIR /home
RUN wget https://ftp.gnu.org/gnu/binutils/binutils-2.44.tar.xz && tar xf binutils-2.44.tar.xz && rm binutils-2.44.tar.xz
WORKDIR /home/binutils-2.44
ENV CC=clang
ENV CXX=clang++
# 1) Make plain readelf
RUN mkdir build-plain
WORKDIR /home/binutils-2.44/build-plain
RUN ../configure --disable-shared --disable-gas --disable-ld --disable-nls --disable-doc
RUN make -j"$(nproc)" && make -C binutils readelf
# 2) Make fuzz readelf
RUN mkdir build-fuzz
WORKDIR /home/binutils-2.44/build-fuzz
ENV CFLAGS="-fsanitize-coverage=trace-pc-guard"
ENV CXXFLAGS="-fsanitize-coverage=trace-pc-guard"
RUN ../configure --disable-shared --disable-gas --disable-ld --disable-nls --disable-doc
RUN make -j"$(nproc)" && make -C binutils readelf
# 3) Conveniently put both in home
RUN cp /home/binutils-2.44/build-fuzz/binutils/readelf /home/readelf-fuzz
RUN cp /home/binutils-2.44/build-plain/binutils/readelf /home/readelf-plain
WORKDIR /home/instrumentation
COPY target_instrumentation.c .
RUN clang -shared -fPIC target_instrumentation.c -o libtarget_instrumentation.so
WORKDIR /home/binutils-2.44
The target instrumentation is this
// target_instrumentation.c
#include <stdint.h>
#include <stdio.h>
void __sanitizer_cov_trace_pc_guard_init(uint32_t *s, uint32_t *e) {
fprintf(stderr, "INIT detected\n");
}
void __sanitizer_cov_trace_pc_guard(uint32_t *g) {
fprintf(stderr, "EDGE detected\n");
}
I want to execute
LD_PRELOAD=/home/instrumentation/libtarget_instrumentation.so /home/readelf-fuzz -h /bin/ls
and see that the edges and init were detected but it doesn’t work