blob: ee1fc42ea9a567e0eeab1b1ffdee7c4967a27325 [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 Hughesf2c6ad62017-04-21 10:25:56 -070036#include <stdint.h>
Elliott Hughes203e13d2016-07-22 14:56:18 -070037#include <sys/cdefs.h>
38#include <sys/types.h>
Pavel Chupinb7beb692012-08-17 12:53:29 +040039
Josh Gao16016df2016-11-07 18:27:16 -080040#include <elf.h>
41
Pavel Chupinb7beb692012-08-17 12:53:29 +040042__BEGIN_DECLS
43
Josh Gaob36efa42016-09-15 13:55:41 -070044#if defined(__LP64__)
Elliott Hughes72b10fc2024-05-16 18:10:23 +000045/** 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 -080046#define ElfW(type) Elf64_ ## type
47#else
Elliott Hughes72b10fc2024-05-16 18:10:23 +000048/** 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 -080049#define ElfW(type) Elf32_ ## type
50#endif
Pavel Chupinb7beb692012-08-17 12:53:29 +040051
Elliott Hughes72b10fc2024-05-16 18:10:23 +000052/**
53 * Information passed by dl_iterate_phdr() to the callback.
54 */
Pavel Chupinb7beb692012-08-17 12:53:29 +040055struct dl_phdr_info {
Elliott Hughes72b10fc2024-05-16 18:10:23 +000056 /** The address of the shared object. */
Pavel Chupinb7beb692012-08-17 12:53:29 +040057 ElfW(Addr) dlpi_addr;
Elliott Hughes72b10fc2024-05-16 18:10:23 +000058 /** The name of the shared object. */
zijunzhao0a515822023-03-17 02:52:15 +000059 const char* _Nullable dlpi_name;
Elliott Hughes72b10fc2024-05-16 18:10:23 +000060 /** Pointer to the shared object's program headers. */
zijunzhao0a515822023-03-17 02:52:15 +000061 const ElfW(Phdr)* _Nullable dlpi_phdr;
Elliott Hughes72b10fc2024-05-16 18:10:23 +000062 /** Number of program headers pointed to by `dlpi_phdr`. */
Pavel Chupinb7beb692012-08-17 12:53:29 +040063 ElfW(Half) dlpi_phnum;
Ryan Pricharda2e83ab2019-08-16 17:25:43 -070064
Elliott Hughes72b10fc2024-05-16 18:10:23 +000065 /**
66 * The total number of library load events at the time dl_iterate_phdr() was
67 * called.
68 *
69 * This field is only available since API level 30; you can use the size
70 * passed to the callback to determine whether you have the full struct,
71 * or just the fields up to and including `dlpi_phnum`.
72 */
Ryan Pricharda2e83ab2019-08-16 17:25:43 -070073 unsigned long long dlpi_adds;
Elliott Hughes72b10fc2024-05-16 18:10:23 +000074 /**
75 * The total number of library unload events at the time dl_iterate_phdr() was
76 * called.
77 *
78 * This field is only available since API level 30; you can use the size
79 * passed to the callback to determine whether you have the full struct,
80 * or just the fields up to and including `dlpi_phnum`.
81 */
Ryan Pricharda2e83ab2019-08-16 17:25:43 -070082 unsigned long long dlpi_subs;
Elliott Hughes72b10fc2024-05-16 18:10:23 +000083 /**
84 * The module ID for TLS relocations in this shared object.
85 *
86 * This field is only available since API level 30; you can use the size
87 * passed to the callback to determine whether you have the full struct,
88 * or just the fields up to and including `dlpi_phnum`.
89 */
Ryan Pricharda2e83ab2019-08-16 17:25:43 -070090 size_t dlpi_tls_modid;
Elliott Hughes72b10fc2024-05-16 18:10:23 +000091 /**
92 * The caller's TLS data for this shared object.
93 *
94 * This field is only available since API level 30; you can use the size
95 * passed to the callback to determine whether you have the full struct,
96 * or just the fields up to and including `dlpi_phnum`.
97 */
zijunzhao0a515822023-03-17 02:52:15 +000098 void* _Nullable dlpi_tls_data;
Pavel Chupinb7beb692012-08-17 12:53:29 +040099};
100
Elliott Hughes72b10fc2024-05-16 18:10:23 +0000101/**
102 * [dl_iterate_phdr(3)](http://man7.org/linux/man-pages/man3/dl_iterate_phdr.3.html)
103 * calls the given callback once for every loaded shared object. The size
104 * argument to the callback lets you determine whether you have a smaller
105 * `dl_phdr_info` from before API level 30, or the newer full one.
106 * The data argument to the callback is whatever you pass as the data argument
107 * to dl_iterate_phdr().
108 *
109 * Returns the value returned by the final call to the callback.
110 */
111int 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 -0700112
Pavel Chupinb7beb692012-08-17 12:53:29 +0400113#ifdef __arm__
Elliott Hughesf2c6ad62017-04-21 10:25:56 -0700114typedef uintptr_t _Unwind_Ptr;
zijunzhao0a515822023-03-17 02:52:15 +0000115_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr, int* _Nonnull);
Pavel Chupinb7beb692012-08-17 12:53:29 +0400116#endif
117
Elliott Hughes72b10fc2024-05-16 18:10:23 +0000118/** Used by the dynamic linker to communicate with the debugger. */
Elliott Hughes3a9c5d62014-02-10 13:31:13 -0800119struct link_map {
120 ElfW(Addr) l_addr;
zijunzhao0a515822023-03-17 02:52:15 +0000121 char* _Nullable l_name;
122 ElfW(Dyn)* _Nullable l_ld;
123 struct link_map* _Nullable l_next;
124 struct link_map* _Nullable l_prev;
Elliott Hughes3a9c5d62014-02-10 13:31:13 -0800125};
126
Elliott Hughes72b10fc2024-05-16 18:10:23 +0000127/** Used by the dynamic linker to communicate with the debugger. */
Elliott Hughes3a9c5d62014-02-10 13:31:13 -0800128struct r_debug {
129 int32_t r_version;
zijunzhao0a515822023-03-17 02:52:15 +0000130 struct link_map* _Nullable r_map;
Elliott Hughes3a9c5d62014-02-10 13:31:13 -0800131 ElfW(Addr) r_brk;
132 enum {
133 RT_CONSISTENT,
134 RT_ADD,
135 RT_DELETE
136 } r_state;
137 ElfW(Addr) r_ldbase;
138};
139
Pavel Chupinb7beb692012-08-17 12:53:29 +0400140__END_DECLS