blob: de036121ecc9806d176fb3741bf8a9abe929e159 [file] [log] [blame]
Daniele Di Proietto25f80692021-09-17 10:14:41 +00001/*
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
Lalit Maganti0c2964f2021-09-21 14:22:02 +010020#include <stddef.h>
Daniele Di Proietto25f80692021-09-17 10:14:41 +000021#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
29namespace perfetto {
30namespace profiling {
31
32constexpr auto PT_LOAD = 1;
33constexpr auto PF_X = 1;
34constexpr auto SHT_NOTE = 7;
35constexpr auto NT_GNU_BUILD_ID = 3;
36constexpr auto ELFCLASS32 = 1;
37constexpr auto ELFCLASS64 = 2;
38constexpr auto ELFMAG0 = 0x7f;
39constexpr auto ELFMAG1 = 'E';
40constexpr auto ELFMAG2 = 'L';
41constexpr auto ELFMAG3 = 'F';
Daniele Di Proiettof96e82f2021-09-17 13:38:33 +000042constexpr auto ELFDATA2LSB = 1;
43constexpr auto EV_CURRENT = 1;
Daniele Di Proietto25f80692021-09-17 10:14:41 +000044constexpr auto EI_MAG0 = 0;
45constexpr auto EI_MAG1 = 1;
46constexpr auto EI_MAG2 = 2;
47constexpr auto EI_MAG3 = 3;
48constexpr auto EI_CLASS = 4;
Daniele Di Proiettof96e82f2021-09-17 13:38:33 +000049constexpr auto EI_DATA = 5;
50constexpr auto EI_VERSION = 6;
Daniele Di Proietto25f80692021-09-17 10:14:41 +000051
52struct 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
103struct 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
157template <typename E>
158typename 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
163template <typename E>
164typename 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_