blob: 331070e41ddd0e3669b8fc2625fd71a26045f0a3 [file] [log] [blame]
Pavel Chupinb7beb692012-08-17 12:53:29 +04001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
Elliott Hughes72b10fc2024-05-16 18:10:23 +000028
29#pragma once
30
31/**
32 * @file link.h
33 * @brief Extra dynamic linker functionality (see also <dlfcn.h>).
34 */
Pavel Chupinb7beb692012-08-17 12:53:29 +040035
Elliott Hughes203e13d2016-07-22 14:56:18 -070036#include <sys/cdefs.h>
Elliott Hughes414dd2d2024-10-16 14:48:30 +000037
38#include <stdint.h>
Elliott Hughes203e13d2016-07-22 14:56:18 -070039#include <sys/types.h>
Pavel Chupinb7beb692012-08-17 12:53:29 +040040
Josh Gao16016df2016-11-07 18:27:16 -080041#include <elf.h>
42
Pavel Chupinb7beb692012-08-17 12:53:29 +040043__BEGIN_DECLS
44
Josh Gaob36efa42016-09-15 13:55:41 -070045#if defined(__LP64__)
Elliott Hughes72b10fc2024-05-16 18:10:23 +000046/** Convenience macro to get the appropriate 32-bit or 64-bit <elf.h> type for the caller's bitness. */
Elliott Hughes3a9c5d62014-02-10 13:31:13 -080047#define ElfW(type) Elf64_ ## type
48#else
Elliott Hughes72b10fc2024-05-16 18:10:23 +000049/** Convenience macro to get the appropriate 32-bit or 64-bit <elf.h> type for the caller's bitness. */
Elliott Hughes3a9c5d62014-02-10 13:31:13 -080050#define ElfW(type) Elf32_ ## type
51#endif
Pavel Chupinb7beb692012-08-17 12:53:29 +040052
Elliott Hughes72b10fc2024-05-16 18:10:23 +000053/**
54 * Information passed by dl_iterate_phdr() to the callback.
55 */
Pavel Chupinb7beb692012-08-17 12:53:29 +040056struct dl_phdr_info {
Elliott Hughes72b10fc2024-05-16 18:10:23 +000057 /** The address of the shared object. */
Pavel Chupinb7beb692012-08-17 12:53:29 +040058 ElfW(Addr) dlpi_addr;
Elliott Hughes72b10fc2024-05-16 18:10:23 +000059 /** The name of the shared object. */
zijunzhao0a515822023-03-17 02:52:15 +000060 const char* _Nullable dlpi_name;
Elliott Hughes72b10fc2024-05-16 18:10:23 +000061 /** Pointer to the shared object's program headers. */
zijunzhao0a515822023-03-17 02:52:15 +000062 const ElfW(Phdr)* _Nullable dlpi_phdr;
Elliott Hughes72b10fc2024-05-16 18:10:23 +000063 /** Number of program headers pointed to by `dlpi_phdr`. */
Pavel Chupinb7beb692012-08-17 12:53:29 +040064 ElfW(Half) dlpi_phnum;
Ryan Pricharda2e83ab2019-08-16 17:25:43 -070065
Elliott Hughes72b10fc2024-05-16 18:10:23 +000066 /**
67 * The total number of library load events at the time dl_iterate_phdr() was
68 * called.
69 *
70 * This field is only available since API level 30; you can use the size
71 * passed to the callback to determine whether you have the full struct,
72 * or just the fields up to and including `dlpi_phnum`.
73 */
Ryan Pricharda2e83ab2019-08-16 17:25:43 -070074 unsigned long long dlpi_adds;
Elliott Hughes72b10fc2024-05-16 18:10:23 +000075 /**
76 * The total number of library unload events at the time dl_iterate_phdr() was
77 * called.
78 *
79 * This field is only available since API level 30; you can use the size
80 * passed to the callback to determine whether you have the full struct,
81 * or just the fields up to and including `dlpi_phnum`.
82 */
Ryan Pricharda2e83ab2019-08-16 17:25:43 -070083 unsigned long long dlpi_subs;
Elliott Hughes72b10fc2024-05-16 18:10:23 +000084 /**
85 * The module ID for TLS relocations in this shared object.
86 *
87 * This field is only available since API level 30; you can use the size
88 * passed to the callback to determine whether you have the full struct,
89 * or just the fields up to and including `dlpi_phnum`.
90 */
Ryan Pricharda2e83ab2019-08-16 17:25:43 -070091 size_t dlpi_tls_modid;
Elliott Hughes72b10fc2024-05-16 18:10:23 +000092 /**
93 * The caller's TLS data for this shared object.
94 *
95 * This field is only available since API level 30; you can use the size
96 * passed to the callback to determine whether you have the full struct,
97 * or just the fields up to and including `dlpi_phnum`.
98 */
zijunzhao0a515822023-03-17 02:52:15 +000099 void* _Nullable dlpi_tls_data;
Pavel Chupinb7beb692012-08-17 12:53:29 +0400100};
101
Elliott Hughes72b10fc2024-05-16 18:10:23 +0000102/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +0000103 * [dl_iterate_phdr(3)](https://man7.org/linux/man-pages/man3/dl_iterate_phdr.3.html)
Elliott Hughes72b10fc2024-05-16 18:10:23 +0000104 * calls the given callback once for every loaded shared object. The size
105 * argument to the callback lets you determine whether you have a smaller
106 * `dl_phdr_info` from before API level 30, or the newer full one.
107 * The data argument to the callback is whatever you pass as the data argument
108 * to dl_iterate_phdr().
109 *
110 * Returns the value returned by the final call to the callback.
111 */
112int dl_iterate_phdr(int (* _Nonnull __callback)(struct dl_phdr_info* _Nonnull __info, size_t __size, void* _Nullable __data), void* _Nullable __data);
Christopher Ferris24053a42013-08-19 17:45:09 -0700113
Pavel Chupinb7beb692012-08-17 12:53:29 +0400114#ifdef __arm__
Elliott Hughesf2c6ad62017-04-21 10:25:56 -0700115typedef uintptr_t _Unwind_Ptr;
zijunzhao0a515822023-03-17 02:52:15 +0000116_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr, int* _Nonnull);
Pavel Chupinb7beb692012-08-17 12:53:29 +0400117#endif
118
Elliott Hughes72b10fc2024-05-16 18:10:23 +0000119/** Used by the dynamic linker to communicate with the debugger. */
Elliott Hughes3a9c5d62014-02-10 13:31:13 -0800120struct link_map {
121 ElfW(Addr) l_addr;
zijunzhao0a515822023-03-17 02:52:15 +0000122 char* _Nullable l_name;
123 ElfW(Dyn)* _Nullable l_ld;
124 struct link_map* _Nullable l_next;
125 struct link_map* _Nullable l_prev;
Elliott Hughes3a9c5d62014-02-10 13:31:13 -0800126};
127
Elliott Hughes72b10fc2024-05-16 18:10:23 +0000128/** Used by the dynamic linker to communicate with the debugger. */
Elliott Hughes3a9c5d62014-02-10 13:31:13 -0800129struct r_debug {
130 int32_t r_version;
zijunzhao0a515822023-03-17 02:52:15 +0000131 struct link_map* _Nullable r_map;
Elliott Hughes3a9c5d62014-02-10 13:31:13 -0800132 ElfW(Addr) r_brk;
133 enum {
134 RT_CONSISTENT,
135 RT_ADD,
136 RT_DELETE
137 } r_state;
138 ElfW(Addr) r_ldbase;
139};
140
Pavel Chupinb7beb692012-08-17 12:53:29 +0400141__END_DECLS