#2153·abseil-cpp

[Bug]: ABSL_HAVE_ELF_MEM_IMAGE assumes every ELF target ships <link.h>

Author: vasko-110Created Sep 4, 2026Updated Sep 4, 2026

Describe the issue

ABSL_HAVE_ELF_MEM_IMAGE is switched on for every __ELF__ target except an explicit deny-list, and the header then unconditionally includes <link.h>:

https://github.com/abseil/abseil-cpp/blob/71330b939f8b6b92d7f1b0a83e04c1288583737b/absl/debugging/internal/elf_mem_image.h#L36-L45

__ELF__ says the object format is ELF. It does not say a dynamic loader exists, and <link.h> is a glibc/dynamic-linker header, not part of the ELF format. Bare-metal ELF toolchains produce ELF objects and ship no <link.h> at all — arm-none-eabi-g++ with newlib is the common one. There ABSL_HAVE_ELF_MEM_IMAGE is defined, #include <link.h> is reached, and the build stops with a fatal error.

The deny-list is the symptom: __QNX__, __asmjs__, __wasm__, __HAIKU__, __VXWORKS__, __hexagon__, __XTENSA__ are, for the most part, ELF targets that were added one at a time as each one hit this. Every further bare-metal ELF target has to send another PR to add itself.

I would expect the guard to test for what the code actually needs — the availability of <link.h> — rather than enumerating the platforms that lack it.

Steps to reproduce the problem

Reproduces on unmodified master with a stock arm-none-eabi toolchain. No FreeRTOS, RTOS or other platform code is involved — a plain -fsyntax-only on Abseil's own sources is enough:

$ git rev-parse HEAD
71330b939f8b6b92d7f1b0a83e04c1288583737b

$ arm-none-eabi-g++ -std=c++17 -I. -fsyntax-only absl/debugging/internal/elf_mem_image.cc
In file included from absl/debugging/internal/elf_mem_image.cc:18:
./absl/debugging/internal/elf_mem_image.h:45:10: fatal error: link.h: No such file or directory
   45 | #include <link.h>  // for ElfW
      |          ^~~~~~~~
compilation terminated.

$ arm-none-eabi-g++ -std=c++17 -I. -fsyntax-only absl/debugging/internal/vdso_support.cc
In file included from ./absl/debugging/internal/vdso_support.h:45,
                 from absl/debugging/internal/vdso_support.cc:19:
./absl/debugging/internal/elf_mem_image.h:45:10: fatal error: link.h: No such file or directory
   45 | #include <link.h>  // for ElfW
      |          ^~~~~~~~
compilation terminated.

$ g++ -std=c++17 -I. -fsyntax-only absl/debugging/internal/elf_mem_image.cc   # host, for contrast: compiles

The two preconditions can be confirmed separately — the target is ELF, and it has no <link.h>:

cpp
#if !defined(__ELF__)
#error NOT_ELF
#endif
#if __has_include(<link.h>)
#error HAS_LINK_H
#else
#error NO_LINK_H
#endif
$ arm-none-eabi-g++ -std=c++17 -fsyntax-only t.cc
t.cc:7:2: error: #error NO_LINK_H

$ g++ -std=c++17 -fsyntax-only t.cc
t.cc:5:2: error: #error HAS_LINK_H

What version of Abseil are you using?

71330b939f8b6b92d7f1b0a83e04c1288583737b (master)

What operating system and version are you using?

Ubuntu 24.04.4 LTS, x86-64 (kernel 6.8.0-138-generic).

The failure is compile-time and host-independent; it depends only on the target toolchain being ELF without a <link.h>.

What compiler and version are you using?

arm-none-eabi-g++ (15:13.2.rel1-2) 13.2.1 20231009 -- the toolchain that fails.

g++ (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 -- host compiler, shown above for contrast.

What build system are you using?

None -- the errors above come from a direct -fsyntax-only compiler invocation on Abseil's own sources.

Additional context

The one-line fix is to add the header check to the existing condition, keeping the deny-list untouched:

cpp
    !defined(__XTENSA__) && __has_include(<link.h>)

absl/debugging/internal/stacktrace_config.h already guards this way in the same directory (#if __has_include(<execinfo.h>) && defined(ABSL_HAVE_THREAD_LOCAL)), and __has_include is used unconditionally across Abseil since "Use __has_include unconditionally as it is supported by C++17" (2fb25663).

Verified on 71330b93: with this line, elf_mem_image.cc and vdso_support.cc both compile under arm-none-eabi-g++, and on the host ABSL_HAVE_ELF_MEM_IMAGE is still defined and both files still compile — so no supported platform changes behaviour.