17f946768c376143b8b87be53cce8596c1bc5b2e
[lttng-ust.git] / src / common / elf.h
1 /*
2 * SPDX-License-Identifier: LGPL-2.1-or-later
3 *
4 * Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
5 */
6
7 #ifndef _UST_COMMON_ELF_H
8 #define _UST_COMMON_ELF_H
9
10 #include <stdlib.h>
11 #include <stdint.h>
12 #include <stdio.h>
13 #include <elf.h>
14
15 #include <lttng/ust-endian.h>
16
17 struct lttng_ust_elf_ehdr {
18 uint16_t e_type;
19 uint16_t e_machine;
20 uint32_t e_version;
21 uint64_t e_entry;
22 uint64_t e_phoff;
23 uint64_t e_shoff;
24 uint32_t e_flags;
25 uint16_t e_ehsize;
26 uint16_t e_phentsize;
27 uint16_t e_phnum;
28 uint16_t e_shentsize;
29 uint16_t e_shnum;
30 uint16_t e_shstrndx;
31 };
32
33 struct lttng_ust_elf_phdr {
34 uint32_t p_type;
35 uint64_t p_offset;
36 uint64_t p_filesz;
37 uint64_t p_memsz;
38 uint64_t p_align;
39 uint64_t p_vaddr;
40 };
41
42 struct lttng_ust_elf_shdr {
43 uint32_t sh_name;
44 uint32_t sh_type;
45 uint64_t sh_flags;
46 uint64_t sh_addr;
47 uint64_t sh_offset;
48 uint64_t sh_size;
49 uint32_t sh_link;
50 uint32_t sh_info;
51 uint64_t sh_addralign;
52 uint64_t sh_entsize;
53 };
54
55 struct lttng_ust_elf_nhdr {
56 uint32_t n_namesz;
57 uint32_t n_descsz;
58 uint32_t n_type;
59 };
60
61 struct lttng_ust_elf {
62 /* Offset in bytes to start of section names string table. */
63 off_t section_names_offset;
64 /* Size in bytes of section names string table. */
65 size_t section_names_size;
66 char *path;
67 int fd;
68 struct lttng_ust_elf_ehdr *ehdr;
69 uint8_t bitness;
70 uint8_t endianness;
71 };
72
73 /*
74 * Determine native endianness in order to convert when reading an ELF
75 * file if there is a mismatch.
76 */
77 #if BYTE_ORDER == LITTLE_ENDIAN
78 #define NATIVE_ELF_ENDIANNESS ELFDATA2LSB
79 #else
80 #define NATIVE_ELF_ENDIANNESS ELFDATA2MSB
81 #endif
82
83 /*
84 * The size in bytes of the debug link CRC as contained in an ELF
85 * section.
86 */
87 #define ELF_CRC_SIZE 4
88 /*
89 * ELF notes are aligned on 4 bytes. ref: ELF specification version
90 * 1.1 p. 2-5.
91 */
92 #define ELF_NOTE_ENTRY_ALIGN 4
93 /*
94 * Within an ELF note, the `desc` field is also aligned on 4
95 * bytes. ref: ELF specification version 1.1 p. 2-5.
96 */
97 #define ELF_NOTE_DESC_ALIGN 4
98
99 #define bswap(x) \
100 do { \
101 switch (sizeof(x)) { \
102 case 8: \
103 x = bswap_64(x); \
104 break; \
105 case 4: \
106 x = bswap_32(x); \
107 break; \
108 case 2: \
109 x = bswap_16(x); \
110 break; \
111 case 1: \
112 break; \
113 default: \
114 abort(); \
115 } \
116 } while (0)
117
118 #define bswap_phdr(phdr) \
119 do { \
120 bswap((phdr).p_type); \
121 bswap((phdr).p_offset); \
122 bswap((phdr).p_filesz); \
123 bswap((phdr).p_memsz); \
124 bswap((phdr).p_align); \
125 bswap((phdr).p_vaddr); \
126 } while (0)
127
128 #define bswap_shdr(shdr) \
129 do { \
130 bswap((shdr).sh_name); \
131 bswap((shdr).sh_type); \
132 bswap((shdr).sh_flags); \
133 bswap((shdr).sh_addr); \
134 bswap((shdr).sh_offset); \
135 bswap((shdr).sh_size); \
136 bswap((shdr).sh_link); \
137 bswap((shdr).sh_info); \
138 bswap((shdr).sh_addralign); \
139 bswap((shdr).sh_entsize); \
140 } while (0)
141
142 #define bswap_ehdr(ehdr) \
143 do { \
144 bswap((ehdr).e_type); \
145 bswap((ehdr).e_machine); \
146 bswap((ehdr).e_version); \
147 bswap((ehdr).e_entry); \
148 bswap((ehdr).e_phoff); \
149 bswap((ehdr).e_shoff); \
150 bswap((ehdr).e_flags); \
151 bswap((ehdr).e_ehsize); \
152 bswap((ehdr).e_phentsize); \
153 bswap((ehdr).e_phnum); \
154 bswap((ehdr).e_shentsize); \
155 bswap((ehdr).e_shnum); \
156 bswap((ehdr).e_shstrndx); \
157 } while (0)
158
159 #define copy_phdr(src_phdr, dst_phdr) \
160 do { \
161 (dst_phdr).p_type = (src_phdr).p_type; \
162 (dst_phdr).p_offset = (src_phdr).p_offset; \
163 (dst_phdr).p_filesz = (src_phdr).p_filesz; \
164 (dst_phdr).p_memsz = (src_phdr).p_memsz; \
165 (dst_phdr).p_align = (src_phdr).p_align; \
166 (dst_phdr).p_vaddr = (src_phdr).p_vaddr; \
167 } while (0)
168
169 #define copy_shdr(src_shdr, dst_shdr) \
170 do { \
171 (dst_shdr).sh_name = (src_shdr).sh_name; \
172 (dst_shdr).sh_type = (src_shdr).sh_type; \
173 (dst_shdr).sh_flags = (src_shdr).sh_flags; \
174 (dst_shdr).sh_addr = (src_shdr).sh_addr; \
175 (dst_shdr).sh_offset = (src_shdr).sh_offset; \
176 (dst_shdr).sh_size = (src_shdr).sh_size; \
177 (dst_shdr).sh_link = (src_shdr).sh_link; \
178 (dst_shdr).sh_info = (src_shdr).sh_info; \
179 (dst_shdr).sh_addralign = (src_shdr).sh_addralign; \
180 (dst_shdr).sh_entsize = (src_shdr).sh_entsize; \
181 } while (0)
182
183 #define copy_ehdr(src_ehdr, dst_ehdr) \
184 do { \
185 (dst_ehdr).e_type = (src_ehdr).e_type; \
186 (dst_ehdr).e_machine = (src_ehdr).e_machine; \
187 (dst_ehdr).e_version = (src_ehdr).e_version; \
188 (dst_ehdr).e_entry = (src_ehdr).e_entry; \
189 (dst_ehdr).e_phoff = (src_ehdr).e_phoff; \
190 (dst_ehdr).e_shoff = (src_ehdr).e_shoff; \
191 (dst_ehdr).e_flags = (src_ehdr).e_flags; \
192 (dst_ehdr).e_ehsize = (src_ehdr).e_ehsize; \
193 (dst_ehdr).e_phentsize = (src_ehdr).e_phentsize; \
194 (dst_ehdr).e_phnum = (src_ehdr).e_phnum; \
195 (dst_ehdr).e_shentsize = (src_ehdr).e_shentsize; \
196 (dst_ehdr).e_shnum = (src_ehdr).e_shnum; \
197 (dst_ehdr).e_shstrndx = (src_ehdr).e_shstrndx; \
198 } while (0)
199
200 static inline
201 int is_elf_32_bit(struct lttng_ust_elf *elf)
202 {
203 return elf->bitness == ELFCLASS32;
204 }
205
206 static inline
207 int is_elf_native_endian(struct lttng_ust_elf *elf)
208 {
209 return elf->endianness == NATIVE_ELF_ENDIANNESS;
210 }
211
212 struct lttng_ust_elf *lttng_ust_elf_create(const char *path)
213 __attribute__((visibility("hidden")));
214
215 void lttng_ust_elf_destroy(struct lttng_ust_elf *elf)
216 __attribute__((visibility("hidden")));
217
218 uint8_t lttng_ust_elf_is_pic(struct lttng_ust_elf *elf)
219 __attribute__((visibility("hidden")));
220
221 int lttng_ust_elf_get_memsz(struct lttng_ust_elf *elf, uint64_t *memsz)
222 __attribute__((visibility("hidden")));
223
224 int lttng_ust_elf_get_build_id(struct lttng_ust_elf *elf, uint8_t **build_id,
225 size_t *length, int *found)
226 __attribute__((visibility("hidden")));
227
228 int lttng_ust_elf_get_debug_link(struct lttng_ust_elf *elf, char **filename,
229 uint32_t *crc, int *found)
230 __attribute__((visibility("hidden")));
231
232 #endif /* _UST_COMMON_ELF_H */
This page took 0.03219 seconds and 3 git commands to generate.