aboutsummaryrefslogtreecommitdiff
path: root/src/profiling/symbolizer/elf.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/profiling/symbolizer/elf.h')
-rw-r--r--src/profiling/symbolizer/elf.h172
1 files changed, 172 insertions, 0 deletions
diff --git a/src/profiling/symbolizer/elf.h b/src/profiling/symbolizer/elf.h
new file mode 100644
index 000000000..de036121e
--- /dev/null
+++ b/src/profiling/symbolizer/elf.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PROFILING_SYMBOLIZER_ELF_H_
+#define SRC_PROFILING_SYMBOLIZER_ELF_H_
+
+#include <stddef.h>
+#include <cinttypes>
+
+#include "perfetto/base/build_config.h"
+
+// We cannot just include elf.h, as that only exists on Linux, and we want to
+// allow symbolization on other platforms as well. As we only need a small
+// subset, it is easiest to define the constants and structs ourselves.
+
+namespace perfetto {
+namespace profiling {
+
+constexpr auto PT_LOAD = 1;
+constexpr auto PF_X = 1;
+constexpr auto SHT_NOTE = 7;
+constexpr auto NT_GNU_BUILD_ID = 3;
+constexpr auto ELFCLASS32 = 1;
+constexpr auto ELFCLASS64 = 2;
+constexpr auto ELFMAG0 = 0x7f;
+constexpr auto ELFMAG1 = 'E';
+constexpr auto ELFMAG2 = 'L';
+constexpr auto ELFMAG3 = 'F';
+constexpr auto ELFDATA2LSB = 1;
+constexpr auto EV_CURRENT = 1;
+constexpr auto EI_MAG0 = 0;
+constexpr auto EI_MAG1 = 1;
+constexpr auto EI_MAG2 = 2;
+constexpr auto EI_MAG3 = 3;
+constexpr auto EI_CLASS = 4;
+constexpr auto EI_DATA = 5;
+constexpr auto EI_VERSION = 6;
+
+struct Elf32 {
+ using Addr = uint32_t;
+ using Half = uint16_t;
+ using Off = uint32_t;
+ using Sword = int32_t;
+ using Word = uint32_t;
+ struct Ehdr {
+ unsigned char e_ident[16];
+ Half e_type;
+ Half e_machine;
+ Word e_version;
+ Addr e_entry;
+ Off e_phoff;
+ Off e_shoff;
+ Word e_flags;
+ Half e_ehsize;
+ Half e_phentsize;
+ Half e_phnum;
+ Half e_shentsize;
+ Half e_shnum;
+ Half e_shstrndx;
+ };
+ struct Shdr {
+ Word sh_name;
+ Word sh_type;
+ Word sh_flags;
+ Addr sh_addr;
+ Off sh_offset;
+ Word sh_size;
+ Word sh_link;
+ Word sh_info;
+ Word sh_addralign;
+ Word sh_entsize;
+ };
+ struct Nhdr {
+ Word n_namesz;
+ Word n_descsz;
+ Word n_type;
+ };
+ struct Phdr {
+ uint32_t p_type;
+ Off p_offset;
+ Addr p_vaddr;
+ Addr p_paddr;
+ uint32_t p_filesz;
+ uint32_t p_memsz;
+ uint32_t p_flags;
+ uint32_t p_align;
+ };
+};
+
+struct Elf64 {
+ using Addr = uint64_t;
+ using Half = uint16_t;
+ using SHalf = int16_t;
+ using Off = uint64_t;
+ using Sword = int32_t;
+ using Word = uint32_t;
+ using Xword = uint64_t;
+ using Sxword = int64_t;
+ struct Ehdr {
+ unsigned char e_ident[16];
+ Half e_type;
+ Half e_machine;
+ Word e_version;
+ Addr e_entry;
+ Off e_phoff;
+ Off e_shoff;
+ Word e_flags;
+ Half e_ehsize;
+ Half e_phentsize;
+ Half e_phnum;
+ Half e_shentsize;
+ Half e_shnum;
+ Half e_shstrndx;
+ };
+ struct Shdr {
+ Word sh_name;
+ Word sh_type;
+ Xword sh_flags;
+ Addr sh_addr;
+ Off sh_offset;
+ Xword sh_size;
+ Word sh_link;
+ Word sh_info;
+ Xword sh_addralign;
+ Xword sh_entsize;
+ };
+ struct Nhdr {
+ Word n_namesz;
+ Word n_descsz;
+ Word n_type;
+ };
+ struct Phdr {
+ uint32_t p_type;
+ uint32_t p_flags;
+ Off p_offset;
+ Addr p_vaddr;
+ Addr p_paddr;
+ uint64_t p_filesz;
+ uint64_t p_memsz;
+ uint64_t p_align;
+ };
+};
+
+template <typename E>
+typename E::Shdr* GetShdr(void* mem, const typename E::Ehdr* ehdr, size_t i) {
+ return reinterpret_cast<typename E::Shdr*>(
+ static_cast<char*>(mem) + ehdr->e_shoff + i * sizeof(typename E::Shdr));
+}
+
+template <typename E>
+typename E::Phdr* GetPhdr(void* mem, const typename E::Ehdr* ehdr, size_t i) {
+ return reinterpret_cast<typename E::Phdr*>(
+ static_cast<char*>(mem) + ehdr->e_phoff + i * sizeof(typename E::Phdr));
+}
+
+} // namespace profiling
+} // namespace perfetto
+
+#endif // SRC_PROFILING_SYMBOLIZER_ELF_H_