blob: 2c0220a4061699d654e4d5c3889252d65c29bee9 [file] [log] [blame]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/ld/abi.h>
#include <lib/ld/tls.h>
#include <zircon/compiler.h>
namespace ld::abi {
__EXPORT void* __tls_get_addr(const elfldltl::Elf<>::TlsGetAddrGot& got) {
if (got.tls_modid == 0) [[unlikely]] {
// Note that glibc doesn't handle this case properly at all, and is liable
// to crash if it gets called. It's clearly only intended for undefined
// weak TLS symbols to be allowed if they aren't actually referenced in
// live code paths at runtime.
return nullptr;
}
// TODO(mcgrathr): the libc version would also need a hook for libdl here,
// when modid >= _ld_abi.static_tls_offsets.size(). But it might just want to
// be replaced with a version that always uses the DTV. This startup-only
// implementation has the advantage of not needing a DTV.
return TpRelative(TlsInitialExecOffset(_ld_abi, got.tls_modid) +
static_cast<ptrdiff_t>(got.offset));
}
} // namespace ld::abi