1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef SRC_PROFILING_SYMBOLIZER_ELF_H_
18 #define SRC_PROFILING_SYMBOLIZER_ELF_H_
19
20 #include <stddef.h>
21 #include <cinttypes>
22
23 #include "perfetto/base/build_config.h"
24
25 // We cannot just include elf.h, as that only exists on Linux, and we want to
26 // allow symbolization on other platforms as well. As we only need a small
27 // subset, it is easiest to define the constants and structs ourselves.
28
29 namespace perfetto {
30 namespace profiling {
31
32 constexpr auto PT_LOAD = 1;
33 constexpr auto PF_X = 1;
34 constexpr auto SHT_NOTE = 7;
35 constexpr auto NT_GNU_BUILD_ID = 3;
36 constexpr auto ELFCLASS32 = 1;
37 constexpr auto ELFCLASS64 = 2;
38 constexpr auto ELFMAG0 = 0x7f;
39 constexpr auto ELFMAG1 = 'E';
40 constexpr auto ELFMAG2 = 'L';
41 constexpr auto ELFMAG3 = 'F';
42 constexpr auto ELFDATA2LSB = 1;
43 constexpr auto EV_CURRENT = 1;
44 constexpr auto EI_MAG0 = 0;
45 constexpr auto EI_MAG1 = 1;
46 constexpr auto EI_MAG2 = 2;
47 constexpr auto EI_MAG3 = 3;
48 constexpr auto EI_CLASS = 4;
49 constexpr auto EI_DATA = 5;
50 constexpr auto EI_VERSION = 6;
51
52 struct Elf32 {
53 using Addr = uint32_t;
54 using Half = uint16_t;
55 using Off = uint32_t;
56 using Sword = int32_t;
57 using Word = uint32_t;
58 struct Ehdr {
59 unsigned char e_ident[16];
60 Half e_type;
61 Half e_machine;
62 Word e_version;
63 Addr e_entry;
64 Off e_phoff;
65 Off e_shoff;
66 Word e_flags;
67 Half e_ehsize;
68 Half e_phentsize;
69 Half e_phnum;
70 Half e_shentsize;
71 Half e_shnum;
72 Half e_shstrndx;
73 };
74 struct Shdr {
75 Word sh_name;
76 Word sh_type;
77 Word sh_flags;
78 Addr sh_addr;
79 Off sh_offset;
80 Word sh_size;
81 Word sh_link;
82 Word sh_info;
83 Word sh_addralign;
84 Word sh_entsize;
85 };
86 struct Nhdr {
87 Word n_namesz;
88 Word n_descsz;
89 Word n_type;
90 };
91 struct Phdr {
92 uint32_t p_type;
93 Off p_offset;
94 Addr p_vaddr;
95 Addr p_paddr;
96 uint32_t p_filesz;
97 uint32_t p_memsz;
98 uint32_t p_flags;
99 uint32_t p_align;
100 };
101 };
102
103 struct Elf64 {
104 using Addr = uint64_t;
105 using Half = uint16_t;
106 using SHalf = int16_t;
107 using Off = uint64_t;
108 using Sword = int32_t;
109 using Word = uint32_t;
110 using Xword = uint64_t;
111 using Sxword = int64_t;
112 struct Ehdr {
113 unsigned char e_ident[16];
114 Half e_type;
115 Half e_machine;
116 Word e_version;
117 Addr e_entry;
118 Off e_phoff;
119 Off e_shoff;
120 Word e_flags;
121 Half e_ehsize;
122 Half e_phentsize;
123 Half e_phnum;
124 Half e_shentsize;
125 Half e_shnum;
126 Half e_shstrndx;
127 };
128 struct Shdr {
129 Word sh_name;
130 Word sh_type;
131 Xword sh_flags;
132 Addr sh_addr;
133 Off sh_offset;
134 Xword sh_size;
135 Word sh_link;
136 Word sh_info;
137 Xword sh_addralign;
138 Xword sh_entsize;
139 };
140 struct Nhdr {
141 Word n_namesz;
142 Word n_descsz;
143 Word n_type;
144 };
145 struct Phdr {
146 uint32_t p_type;
147 uint32_t p_flags;
148 Off p_offset;
149 Addr p_vaddr;
150 Addr p_paddr;
151 uint64_t p_filesz;
152 uint64_t p_memsz;
153 uint64_t p_align;
154 };
155 };
156
157 template <typename E>
GetShdr(void * mem,const typename E::Ehdr * ehdr,size_t i)158 typename E::Shdr* GetShdr(void* mem, const typename E::Ehdr* ehdr, size_t i) {
159 return reinterpret_cast<typename E::Shdr*>(
160 static_cast<char*>(mem) + ehdr->e_shoff + i * sizeof(typename E::Shdr));
161 }
162
163 template <typename E>
GetPhdr(void * mem,const typename E::Ehdr * ehdr,size_t i)164 typename E::Phdr* GetPhdr(void* mem, const typename E::Ehdr* ehdr, size_t i) {
165 return reinterpret_cast<typename E::Phdr*>(
166 static_cast<char*>(mem) + ehdr->e_phoff + i * sizeof(typename E::Phdr));
167 }
168
169 } // namespace profiling
170 } // namespace perfetto
171
172 #endif // SRC_PROFILING_SYMBOLIZER_ELF_H_
173