dwarves: CONSTRUYE — frontera libdw/musl cerrada

Cadena completa, cuatro recetas nuevas y una modificada:
  musl-obstack     -> libobstack (find_package(obstack REQUIRED))
  argp-standalone  -> libargp    (find_package(argp REQUIRED))
  musl-fts         -> fts(3), que usa libdwfl/linux-kernel-modules.c
  elfutils-libdw   -> libdw + libdwfl (VARIANTE: la canónica sólo hace libelf
                      porque de ella cuelgan los cuatro kernels)

Lo que costó, en orden de aparición:
· libdw a secas NO necesita argp/obstack/fts — la nota de la canónica es cierta
  de libdwfl y src/, no de libdw. El `obstack` de libdw estaba en un COMENTARIO.
· Pero dwarves SÍ usa libdwfl (15 dwfl_* en dwarf_loader.c) ⇒ vuelven argp y fts.
· libdwfl no compila suelto: hay que seguir el orden de SUBDIRS del raíz
  (lib → libelf → libcpu → backends → libebl → libdwelf → libdw → libdwfl →
  libdwfl_stacktrace).
· El compat/argp.h de la canónica TAPA el argp real y no declara argp_failure.
· libdw.a GORDA: FindDWARF.cmake pone DWARF_LIBRARIES = libdw + libelf y nada
  más, pero libdw necesita libdwfl/libebl/libdwelf/backends/libeu, que son libs
  internas. Se fusionan en un archive (patrón de la libgtk-4.a) junto con un
  `error()` real, que musl no trae y el shim de la receta sólo daba inline.
· Y al final, lzma/bz2: libdw descomprime .debug_* comprimidas.

Verificado de verdad, no por exit code: pahole v1.30 arranca (con el loader
musl del lab) y DECODIFICA DWARF — sobre un binario de prueba imprime los
offsets, los tamaños y hasta el agujero de 3 bytes de padding.
This commit is contained in:
Sergio
2026-08-27 20:47:54 +00:00
parent 84eff79411
commit e7c2b0022c
2 changed files with 49 additions and 4 deletions
+19 -2
View File
@@ -40,6 +40,23 @@
# parches de Alpine) que SÓLO dwarves consuma. Es un sub-proyecto de la cola clib, no un
# retoque de flags. sha256 del tarball verificado (fedorapeople 2026-07-17).
# ── FRENTE libdw/musl, cerrado el 2026-08-27 ───────────────────────────────────────────────────
# dwarves necesita TRES cosas que musl no da y que el corpus no tenía:
# · `libdw` + `dwarf.h` → `elfutils-libdw` (variante; la canónica sólo hace libelf porque de ella
# cuelgan los cuatro kernels y no se le puede mover el hash).
# · `libargp` → `argp-standalone` (`find_package(argp REQUIRED)` en su CMakeLists).
# · `libobstack` → `musl-obstack` (`find_package(obstack REQUIRED)`).
#
# Los dos `find_package` son REQUIRED y sus `Find*.cmake` hacen `find_library(NAMES argp/obstack)`
# sobre /usr/lib. En glibc no hacen falta (van dentro de la libc) y por eso el proyecto no los
# empaqueta; en musl son librerías aparte. Se les pasa la ruta explícita con
# `-DARGP_LIBRARY=`/`-DOBSTACK_LIBRARY=` para no depender del orden de búsqueda de cmake.
#
# `-DCMAKE_C_STANDARD_LIBRARIES='-llzma -lbz2'`: libdw descomprime secciones de debug comprimidas
# (`.debug_*` en xz/bzip2) y referencia `lzma_code`/`BZ2_bzDecompress`. El `FindDWARF.cmake` de
# dwarves pone en `DWARF_LIBRARIES` sólo libdw y libelf, así que esas dos no entran por ahí y hay
# que añadirlas al link de todos los ejecutables. Misma familia de fallo que appstream/cargo-deb.
#
name = "dwarves"
version = "1.30"
@@ -53,13 +70,13 @@ target = "x86_64-linux-musl"
link = "static"
[deps]
build = ["busybox", "make", "cmake", "elfutils", "zlib"]
build = ["busybox", "make", "cmake", "elfutils-libdw", "argp-standalone", "musl-obstack", "zlib", "xz", "bzip2"]
[build.phases]
configure = """
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -D__LIB=lib \
-DBUILD_SHARED_LIBS=OFF -DLIBBPF_EMBEDDED=ON \
-DCMAKE_C_FLAGS='-O2 -fno-sanitize=undefined'
-DARGP_LIBRARY=/usr/lib/libargp.a -DOBSTACK_LIBRARY=/usr/lib/libobstack.a -DCMAKE_C_STANDARD_LIBRARIES='-llzma -lbz2' -DCMAKE_C_FLAGS='-O2 -fno-sanitize=undefined'
"""
compile = "make -C build -j\"$(nproc)\""
install = "make -C build install DESTDIR=/out"
+30 -2
View File
@@ -147,7 +147,7 @@ CFLAGS="-O2 -g -I$PWD/compat" CPPFLAGS="-I$PWD/compat" LDFLAGS="-L$PWD/compat" \
# `argp_failure`, que usa `libdwfl/argp-std.c`. Esta variante SÍ trae argp de verdad
# (`argp-standalone`), así que se borra el shim para que gane el `/usr/include/argp.h` real —
# `-I$PWD/compat` va primero y si no lo taparía.
compile = "rm -f compat/argp.h && make -C lib CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libelf libelf.a libelf.so CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libcpu CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C backends CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libebl CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libdwelf CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libdw libdw.a CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libdwfl libdwfl.a CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\""
compile = "rm -f compat/argp.h && make -C lib CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libelf libelf.a libelf.so CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libcpu CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C backends CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libebl CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libdwelf CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libdw libdw.a CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libdwfl libdwfl.a CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\" && make -C libdwfl_stacktrace libdwfl_stacktrace.a CFLAGS=\"-O2 -g -I$PWD/compat -include $PWD/compat/musl-extra.h\""
install = """
mkdir -p /out/usr/lib/pkgconfig /out/usr/include && \
cp -a libelf/libelf.a libelf/libelf.so* /out/usr/lib/ && \
@@ -157,7 +157,35 @@ mkdir -p /out/usr/include/elfutils
cp -a libdw/libdw.a /out/usr/lib/
cp -a libdw/dwarf.h libdw/libdw.h libdw/known-dwarf.h /out/usr/include/
cp -a libdwfl/libdwfl.h /out/usr/include/
cp -a libdw/libdw.a libdwfl/libdwfl.a /out/usr/lib/
# libdw.a GORDA: dwarves enlaza sólo `-ldw -lelf` (su FindDWARF.cmake pone
# DWARF_LIBRARIES = libdw + libelf y nada más), pero libdw necesita libdwfl, libebl, libdwelf,
# los backends y libeu, que en elfutils son libs INTERNAS. En el .so de una distro van dentro;
# acá hay que fusionarlas a mano en un solo archive o salen `undefined symbol: dwfl_begin`,
# `eu_tsearch`, `eu_search_tree_init`… Mismo patrón que la libgtk-4.a gorda de `gtk4`.
#
# `error()` va también: es de <error.h> de glibc y musl no lo trae. El compat/error.h de la receta
# es `static inline`, así que sólo sirve a las TUs que lo incluyen; los objetos que lo referencian
# desde otra unidad necesitan un símbolo REAL. Se compila uno y se mete en el archive.
printf '%s\n' '#include <stdio.h>' '#include <stdlib.h>' '#include <stdarg.h>' '#include <string.h>' \
'extern char *program_invocation_short_name;' \
'void error(int s,int e,const char*f,...){va_list a;fflush(stdout);' \
' fprintf(stderr,"%s: ",program_invocation_short_name);va_start(a,f);vfprintf(stderr,f,a);va_end(a);' \
' if(e)fprintf(stderr,": %s",strerror(e));fputc(0x0a,stderr);if(s)exit(s);}' \
'void error_at_line(int s,int e,const char*fn,unsigned ln,const char*f,...){va_list a;fflush(stdout);' \
' fprintf(stderr,"%s:%s:%u: ",program_invocation_short_name,fn,ln);' \
' va_start(a,f);vfprintf(stderr,f,a);va_end(a);if(e)fprintf(stderr,": %s",strerror(e));' \
' fputc(0x0a,stderr);if(s)exit(s);}' > /tmp/error-impl.c
$CC -c -O2 /tmp/error-impl.c -o /tmp/error-impl.o
rm -rf /tmp/fat && mkdir -p /tmp/fat && cd /tmp/fat
for A in $OLDPWD/libdw/libdw.a $OLDPWD/libdwfl/libdwfl.a $OLDPWD/libebl/libebl.a \
$OLDPWD/libdwelf/libdwelf.a $OLDPWD/backends/libebl_backends.a $OLDPWD/lib/libeu.a \\
$OLDPWD/libdwfl_stacktrace/libdwfl_stacktrace.a; do
[ -f "$A" ] || continue
n=$(basename "$A" .a); mkdir -p $n && (cd $n && ar x "$A")
done
cd $OLDPWD
ar rcs /out/usr/lib/libdw.a $(find /tmp/fat -name '*.o') /tmp/error-impl.o
cp -a libdwfl/libdwfl.a /out/usr/lib/
cp -a libdw/libdw.h libdw/known-dwarf.h /out/usr/include/elfutils/
cp -a libdwfl/libdwfl.h /out/usr/include/elfutils/
cp -a version.h /out/usr/include/elfutils/ 2>/dev/null || true