xref: /aosp_15_r20/external/perfetto/src/profiling/symbolizer/elf.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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