-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc] add dl_iterate_phdr and dladdr #121179
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
//===-- Definition of Dl_info type ----------------------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_LIBC_TYPES_DL_INFO_H | ||
#define LLVM_LIBC_TYPES_DL_INFO_H | ||
|
||
typedef struct { | ||
const char *dli_fname; | ||
void *dli_fbase; | ||
const char *dli_sname; | ||
void *dli_saddr; | ||
} Dl_info; | ||
|
||
#endif // LLVM_LIBC_TYPES_DL_INFO_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//===-- Definition of type __dl_iterate_phdr_callback_t -------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_LIBC_TYPES___DL_ITERATE_PHDR_CALLBACK_T_H | ||
#define LLVM_LIBC_TYPES___DL_ITERATE_PHDR_CALLBACK_T_H | ||
|
||
#include "size_t.h" | ||
#include "struct_dl_phdr_info.h" | ||
|
||
typedef int (*__dl_iterate_phdr_callback_t)(struct dl_phdr_info *, size_t, | ||
void *); | ||
|
||
#endif // LLVM_LIBC_TYPES___DL_ITERATE_PHDR_CALLBACK_T_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
//===-- Definition of type struct dl_phdr_info ----------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_LIBC_TYPES_STRUCT_DL_PHDR_INFO_H | ||
#define LLVM_LIBC_TYPES_STRUCT_DL_PHDR_INFO_H | ||
|
||
#include "../llvm-libc-macros/link-macros.h" | ||
#include "size_t.h" | ||
|
||
struct dl_phdr_info { | ||
ElfW(Addr) dlpi_addr; | ||
const char *dlpi_name; | ||
const ElfW(Phdr) * dlpi_phdr; | ||
ElfW(Half) dlpi_phnum; | ||
unsigned long long dlpi_adds; | ||
unsigned long long dlpi_subs; | ||
size_t dlpi_tls_modid; | ||
void *dlpi_tls_data; | ||
}; | ||
|
||
#endif // LLVM_LIBC_TYPES_STRUCT_DL_PHDR_INFO_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//===-- Implementation of dladdr -----------------------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "dladdr.h" | ||
|
||
#include "src/__support/common.h" | ||
#include "src/__support/macros/config.h" | ||
|
||
namespace LIBC_NAMESPACE_DECL { | ||
|
||
LLVM_LIBC_FUNCTION(int, dladdr, (const void *, Dl_info *)) { return -1; } | ||
|
||
} // namespace LIBC_NAMESPACE_DECL |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
//===-- Implementation header of dladdr ------------------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_LIBC_SRC_DLFCN_DLADDR_H | ||
#define LLVM_LIBC_SRC_DLFCN_DLADDR_H | ||
|
||
#include "include/llvm-libc-types/Dl_info.h" | ||
#include "src/__support/macros/config.h" | ||
|
||
namespace LIBC_NAMESPACE_DECL { | ||
|
||
int dladdr(const void *, Dl_info *); | ||
|
||
} // namespace LIBC_NAMESPACE_DECL | ||
|
||
#endif // LLVM_LIBC_SRC_DLFCN_DLADDR_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) | ||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) | ||
endif() | ||
|
||
add_entrypoint_object( | ||
dl_iterate_phdr | ||
ALIAS | ||
DEPENDS | ||
.${LIBC_TARGET_OS}.dl_iterate_phdr | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
//===-- Implementation header for dl_iterate_phdr ---------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_LIBC_SRC_LINK_DL_ITERATE_PHDR_H | ||
#define LLVM_LIBC_SRC_LINK_DL_ITERATE_PHDR_H | ||
|
||
#include "include/llvm-libc-types/__dl_iterate_phdr_callback_t.h" | ||
#include "src/__support/macros/config.h" | ||
|
||
namespace LIBC_NAMESPACE_DECL { | ||
|
||
int dl_iterate_phdr(__dl_iterate_phdr_callback_t callback, void *data); | ||
|
||
} // namespace LIBC_NAMESPACE_DECL | ||
|
||
#endif // LLVM_LIBC_SRC_STRING_MEMCHR_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
add_entrypoint_object( | ||
dl_iterate_phdr | ||
SRCS | ||
dl_iterate_phdr.cpp | ||
HDRS | ||
../dl_iterate_phdr.h | ||
DEPENDS | ||
libc.include.llvm-libc-types.__dl_iterate_phdr_callback_t | ||
libc.include.llvm-libc-types.struct_dl_phdr_info | ||
libc.include.llvm-libc-types.size_t | ||
) |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,59 @@ | ||||||||||||||||||||||||
//===-- Implementation of dl_iterate_phdr ---------------------------------===// | ||||||||||||||||||||||||
// | ||||||||||||||||||||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||||||||||||||||||||||
// See https://llvm.org/LICENSE.txt for license information. | ||||||||||||||||||||||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||||||||||||||||||||
// | ||||||||||||||||||||||||
//===----------------------------------------------------------------------===// | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
#include "src/link/dl_iterate_phdr.h" | ||||||||||||||||||||||||
#include "config/linux/app.h" | ||||||||||||||||||||||||
#include "include/llvm-libc-macros/sys-auxv-macros.h" | ||||||||||||||||||||||||
#include "src/__support/common.h" | ||||||||||||||||||||||||
#include "src/__support/macros/config.h" | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
[[gnu::weak, | ||||||||||||||||||||||||
gnu::visibility("hidden")]] extern const ElfW(Dyn) _DYNAMIC[]; // NOLINT | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
#define AUX_CNT 38 | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
namespace LIBC_NAMESPACE_DECL { | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
LLVM_LIBC_FUNCTION(int, dl_iterate_phdr, | ||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks a lot like musl's There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Simply mentioning it comes from musl isn't sufficient -- musl's COPYRIGHT file imposes very specific requirements, as does LLVM's own license file: Lines 224 to 234 in 814902a
MIT has very few requirements but what it does require has not been satisfied by the most recent push. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fun, I've not really had to deal with licensing things like this before. I'm not sure what exactly to do. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please research the topic before making further PRs to (any) projects -- it's important that you understand licencing and using code derived from another project without honouring their licence. I don't think I can explain the whole topic in a succinct comment here but there's a lot of resources online about it. If you've made any PRs up to now to any project where you looked at the sources of another project or copied its implementation, you may need to speak to their maintainers too. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the only time I've copied other implementations like this. I tried figuring out what There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The legal threshold for changing something enough that it then doesn't have a licensing problem is:
But like I said, llvm's own LICENSE.TXT and musl's COPYRIGHT provide guidance on how to respect the license for a copy-pasted work (as long as the the terms of each license don't pose an onerous burden that the other license cannot abide by). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure how that works. Musl is MIT, LLVM is Apache. I've tried reading the licenses but I don't understand them. |
||||||||||||||||||||||||
(__dl_iterate_phdr_callback_t callback, void *data)) { | ||||||||||||||||||||||||
// dl_iterate_phdr implementation based on Musl source | ||||||||||||||||||||||||
// "src/ldso/dl_iterate_phdr.c" | ||||||||||||||||||||||||
size_t *auxv_ptr = reinterpret_cast<size_t *>(app.auxv_ptr); | ||||||||||||||||||||||||
size_t aux[AUX_CNT] = {0}; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
for (size_t i = 0; auxv_ptr[i]; i += 2) { | ||||||||||||||||||||||||
if (auxv_ptr[i] < AUX_CNT) { | ||||||||||||||||||||||||
aux[auxv_ptr[i]] = auxv_ptr[i + 1]; | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
void *p; | ||||||||||||||||||||||||
size_t n; | ||||||||||||||||||||||||
size_t base = 0; | ||||||||||||||||||||||||
for (p = (void *)aux[AT_PHDR], n = aux[AT_PHNUM]; n; | ||||||||||||||||||||||||
n--, p = reinterpret_cast<void *>((uintptr_t)p + aux[AT_PHENT])) { | ||||||||||||||||||||||||
ElfW(Phdr) *phdr = (ElfW(Phdr) *)p; | ||||||||||||||||||||||||
if (phdr->p_type == PT_PHDR) | ||||||||||||||||||||||||
base = aux[AT_PHDR] - phdr->p_vaddr; | ||||||||||||||||||||||||
if (phdr->p_type == PT_DYNAMIC && _DYNAMIC) | ||||||||||||||||||||||||
base = (size_t)_DYNAMIC - phdr->p_vaddr; | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
struct dl_phdr_info info; | ||||||||||||||||||||||||
info.dlpi_addr = base; | ||||||||||||||||||||||||
info.dlpi_name = "/proc/self/exe"; | ||||||||||||||||||||||||
info.dlpi_phdr = (const ElfW(Phdr) *)aux[AT_PHDR]; | ||||||||||||||||||||||||
info.dlpi_phnum = (ElfW(Half))aux[AT_PHNUM]; | ||||||||||||||||||||||||
info.dlpi_adds = 0; | ||||||||||||||||||||||||
info.dlpi_subs = 0; | ||||||||||||||||||||||||
info.dlpi_tls_modid = 0; | ||||||||||||||||||||||||
info.dlpi_tls_data = 0; | ||||||||||||||||||||||||
return callback(&info, sizeof(struct dl_phdr_info), data); | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
} // namespace LIBC_NAMESPACE_DECL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that this PR was just to make libunwind work (per PR description), hence
dladdr
being a stub, but we have a real implementation here fordl_iterate_phdr
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's because
dl_iterate_phdr
is simple enough to implement.dladdr
will require more stuff likedlopen
,dlclose
, anddlsym
to be implemented. Currently, there's TODO's for @izaakschroeder to work on this.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the
dlfcn.h
placeholder PR and various related issues:dlfcn.dlclose
#97917dlfcn.dlerror
#97918dlfcn.dlopen
#97919dlfcn.dlsym
#97920There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just found this #97928