Hi, I have noticed that when using dl_iterate_phdr in muslc to inspect some entries in the dynamic section of different shared libraries loaded into a program, the pointers are not always relocated (they are offset instead of full addresses). For example, consider this program: #include #include #include static int phdrs_callback(dl_phdr_info* info, size_t size, void* data) noexcept { for (auto phdr = info->dlpi_phdr, end = phdr + info->dlpi_phnum; phdr != end; ++phdr) { if (phdr->p_type != PT_DYNAMIC) { continue; } const auto* dynamic_section = reinterpret_cast(phdr->p_vaddr + info->dlpi_addr); for (; dynamic_section->d_tag != DT_NULL; ++dynamic_section) { if (dynamic_section->d_tag == DT_JMPREL) { std::cerr << "Address of JMPREL for lib " << info->dlpi_name <<" is: " << (void*)dynamic_section->d_un.d_ptr << std::endl; } } } return 0; } int main() { dl_iterate_phdr(&phdrs_callback, NULL); } In most glibc systems (for instance ubuntu:20.04), this prints regular addressed that have been relocated: Address of JMPREL for lib is: 0x557bed97a8e8 Address of JMPREL for lib /usr/lib/libc.so.6 is: 0x7f8e0f08cc18 but in muslc systems (like Alpine linux, for example using the python:3.10-alpine container) this prints offsets instead of full relocated addresses: Address of JMPREL for lib ./a.out is: 0x7f8 Address of JMPREL for lib /usr/lib/libstdc++.so.6 is: 0xa94e0 Address of JMPREL for lib /lib/ld-musl-x86_64.so.1 is: 0x145c0 Address of JMPREL for lib /usr/lib/libgcc_s.so.1 is: 0x22e8 Why is this happening? How can one programmatically know when the linker is going to place here offsets or full relocated addresses? In which situation does this happen? Thanks in advance for the help! Kind regards, Pablo Galindo Salgado