/src/libunwind/src/elfxx.h
Line | Count | Source |
1 | | /* libunwind - a platform-independent unwind library |
2 | | Copyright (C) 2003, 2005 Hewlett-Packard Co |
3 | | Copyright (C) 2007 David Mosberger-Tang |
4 | | Contributed by David Mosberger-Tang <dmosberger@gmail.com> |
5 | | |
6 | | This file is part of libunwind. |
7 | | |
8 | | Permission is hereby granted, free of charge, to any person obtaining |
9 | | a copy of this software and associated documentation files (the |
10 | | "Software"), to deal in the Software without restriction, including |
11 | | without limitation the rights to use, copy, modify, merge, publish, |
12 | | distribute, sublicense, and/or sell copies of the Software, and to |
13 | | permit persons to whom the Software is furnished to do so, subject to |
14 | | the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be |
17 | | included in all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
20 | | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
21 | | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
22 | | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
23 | | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
24 | | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
25 | | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
26 | | |
27 | | #include <fcntl.h> |
28 | | #include <unistd.h> |
29 | | |
30 | | #include <sys/mman.h> |
31 | | #include <sys/stat.h> |
32 | | |
33 | | #include "libunwind_i.h" |
34 | | |
35 | | #if UNW_ELF_CLASS == UNW_ELFCLASS32 |
36 | | # define ELF_W(x) ELF32_##x |
37 | | # define Elf_W(x) Elf32_##x |
38 | | # define elf_w(x) _Uelf32_##x |
39 | | #else |
40 | 201M | # define ELF_W(x) ELF64_##x |
41 | 916k | # define Elf_W(x) Elf64_##x |
42 | 730k | # define elf_w(x) _Uelf64_##x |
43 | | #endif |
44 | | |
45 | | extern int elf_w (get_proc_name) (unw_addr_space_t as, |
46 | | pid_t pid, unw_word_t ip, |
47 | | char *buf, size_t len, |
48 | | unw_word_t *offp); |
49 | | |
50 | | extern int elf_w (get_proc_name_in_image) (unw_addr_space_t as, |
51 | | struct elf_image *ei, |
52 | | unsigned long segbase, |
53 | | unw_word_t ip, |
54 | | char *buf, size_t buf_len, unw_word_t *offp); |
55 | | |
56 | | extern int elf_w (get_proc_ip_range) (unw_addr_space_t as, |
57 | | pid_t pid, unw_word_t ip, |
58 | | unw_word_t *start, unw_word_t *end); |
59 | | |
60 | | extern int elf_w (get_proc_ip_range_in_image) (unw_addr_space_t as, struct elf_image *ei, |
61 | | unsigned long segbase, unw_word_t ip, |
62 | | unw_word_t *start, unw_word_t *end); |
63 | | |
64 | | extern int elf_w (get_elf_filename) (unw_addr_space_t as, pid_t pid, unw_word_t ip, |
65 | | char *buf, size_t buf_len, unw_word_t *offp); |
66 | | |
67 | | extern Elf_W (Shdr)* elf_w (find_section) (const struct elf_image *ei, const char* secname); |
68 | | extern int elf_w (load_debuginfo) (const char* file, struct elf_image *ei, int is_local); |
69 | | |
70 | | static inline int |
71 | | elf_w (valid_object) (const struct elf_image *ei) |
72 | 132k | { |
73 | 132k | if (ei->size <= EI_VERSION) |
74 | 0 | return 0; |
75 | | |
76 | 132k | return (memcmp (ei->image, ELFMAG, SELFMAG) == 0 |
77 | 132k | && ((uint8_t *) ei->image)[EI_CLASS] == UNW_ELF_CLASS |
78 | 132k | && ((uint8_t *) ei->image)[EI_VERSION] != EV_NONE |
79 | 132k | && ((uint8_t *) ei->image)[EI_VERSION] <= EV_CURRENT); |
80 | 132k | } Unexecuted instantiation: Lget_proc_name.c:_Uelf64_valid_object Unexecuted instantiation: Lget_reg.c:_Uelf64_valid_object Unexecuted instantiation: Lget_save_loc.c:_Uelf64_valid_object Unexecuted instantiation: Linit_local.c:_Uelf64_valid_object Unexecuted instantiation: Los-linux.c:_Uelf64_valid_object Unexecuted instantiation: Lput_dynamic_unwind_info.c:_Uelf64_valid_object Unexecuted instantiation: Lregs.c:_Uelf64_valid_object Unexecuted instantiation: Lstep.c:_Uelf64_valid_object Unexecuted instantiation: Lfind_dynamic_proc_info.c:_Uelf64_valid_object Unexecuted instantiation: Lfind_proc_info-lsb.c:_Uelf64_valid_object Unexecuted instantiation: Lget_accessors.c:_Uelf64_valid_object Unexecuted instantiation: Lglobal.c:_Uelf64_valid_object Unexecuted instantiation: Linit.c:_Uelf64_valid_object Unexecuted instantiation: Lparser.c:_Uelf64_valid_object Unexecuted instantiation: Lpe.c:_Uelf64_valid_object Unexecuted instantiation: Lresume.c:_Uelf64_valid_object Unexecuted instantiation: Lstash_frame.c:_Uelf64_valid_object Unexecuted instantiation: dyn-info-list.c:_Uelf64_valid_object elf64.c:_Uelf64_valid_object Line | Count | Source | 72 | 99.5k | { | 73 | 99.5k | if (ei->size <= EI_VERSION) | 74 | 0 | return 0; | 75 | | | 76 | 99.5k | return (memcmp (ei->image, ELFMAG, SELFMAG) == 0 | 77 | 99.5k | && ((uint8_t *) ei->image)[EI_CLASS] == UNW_ELF_CLASS | 78 | 99.5k | && ((uint8_t *) ei->image)[EI_VERSION] != EV_NONE | 79 | 99.5k | && ((uint8_t *) ei->image)[EI_VERSION] <= EV_CURRENT); | 80 | 99.5k | } |
Unexecuted instantiation: flush_cache.c:_Uelf64_valid_object Unexecuted instantiation: global.c:_Uelf64_valid_object Unexecuted instantiation: init.c:_Uelf64_valid_object Unexecuted instantiation: is_fpreg.c:_Uelf64_valid_object Unexecuted instantiation: mempool.c:_Uelf64_valid_object os-linux.c:_Uelf64_valid_object Line | Count | Source | 72 | 33.1k | { | 73 | 33.1k | if (ei->size <= EI_VERSION) | 74 | 0 | return 0; | 75 | | | 76 | 33.1k | return (memcmp (ei->image, ELFMAG, SELFMAG) == 0 | 77 | 33.1k | && ((uint8_t *) ei->image)[EI_CLASS] == UNW_ELF_CLASS | 78 | 33.1k | && ((uint8_t *) ei->image)[EI_VERSION] != EV_NONE | 79 | 33.1k | && ((uint8_t *) ei->image)[EI_VERSION] <= EV_CURRENT); | 80 | 33.1k | } |
Unexecuted instantiation: Laddress_validator.c:_Uelf64_valid_object Unexecuted instantiation: Ldyn-extract.c:_Uelf64_valid_object Unexecuted instantiation: Lexpr.c:_Uelf64_valid_object Unexecuted instantiation: Lfde.c:_Uelf64_valid_object |
81 | | |
82 | | static inline int |
83 | | elf_map_image (struct elf_image *ei, const char *path) |
84 | 49.7k | { |
85 | 49.7k | struct stat stat; |
86 | 49.7k | int fd; |
87 | | |
88 | 49.7k | fd = open (path, O_RDONLY); |
89 | 49.7k | if (fd < 0) |
90 | 16.5k | return -1; |
91 | | |
92 | 33.1k | if (fstat (fd, &stat) < 0) |
93 | 0 | { |
94 | 0 | close (fd); |
95 | 0 | return -1; |
96 | 0 | } |
97 | | |
98 | 33.1k | ei->size = stat.st_size; |
99 | 33.1k | ei->image = mi_mmap (NULL, ei->size, PROT_READ, MAP_PRIVATE, fd, 0); |
100 | 33.1k | close (fd); |
101 | 33.1k | if (ei->image == MAP_FAILED) |
102 | 0 | return -1; |
103 | | |
104 | 33.1k | if (!elf_w (valid_object) (ei)) |
105 | 0 | { |
106 | 0 | mi_munmap(ei->image, ei->size); |
107 | 0 | ei->image = NULL; |
108 | 0 | return -1; |
109 | 0 | } |
110 | | |
111 | 33.1k | return 0; |
112 | 33.1k | } Unexecuted instantiation: Lget_proc_name.c:elf_map_image Unexecuted instantiation: Lget_reg.c:elf_map_image Unexecuted instantiation: Lget_save_loc.c:elf_map_image Unexecuted instantiation: Linit_local.c:elf_map_image Unexecuted instantiation: Los-linux.c:elf_map_image Unexecuted instantiation: Lput_dynamic_unwind_info.c:elf_map_image Unexecuted instantiation: Lregs.c:elf_map_image Unexecuted instantiation: Lstep.c:elf_map_image Unexecuted instantiation: Lfind_dynamic_proc_info.c:elf_map_image Unexecuted instantiation: Lfind_proc_info-lsb.c:elf_map_image Unexecuted instantiation: Lget_accessors.c:elf_map_image Unexecuted instantiation: Lglobal.c:elf_map_image Unexecuted instantiation: Linit.c:elf_map_image Unexecuted instantiation: Lparser.c:elf_map_image Unexecuted instantiation: Lpe.c:elf_map_image Unexecuted instantiation: Lresume.c:elf_map_image Unexecuted instantiation: Lstash_frame.c:elf_map_image Unexecuted instantiation: dyn-info-list.c:elf_map_image Line | Count | Source | 84 | 16.5k | { | 85 | 16.5k | struct stat stat; | 86 | 16.5k | int fd; | 87 | | | 88 | 16.5k | fd = open (path, O_RDONLY); | 89 | 16.5k | if (fd < 0) | 90 | 16.5k | return -1; | 91 | | | 92 | 0 | if (fstat (fd, &stat) < 0) | 93 | 0 | { | 94 | 0 | close (fd); | 95 | 0 | return -1; | 96 | 0 | } | 97 | | | 98 | 0 | ei->size = stat.st_size; | 99 | 0 | ei->image = mi_mmap (NULL, ei->size, PROT_READ, MAP_PRIVATE, fd, 0); | 100 | 0 | close (fd); | 101 | 0 | if (ei->image == MAP_FAILED) | 102 | 0 | return -1; | 103 | | | 104 | 0 | if (!elf_w (valid_object) (ei)) | 105 | 0 | { | 106 | 0 | mi_munmap(ei->image, ei->size); | 107 | 0 | ei->image = NULL; | 108 | 0 | return -1; | 109 | 0 | } | 110 | | | 111 | 0 | return 0; | 112 | 0 | } |
Unexecuted instantiation: flush_cache.c:elf_map_image Unexecuted instantiation: global.c:elf_map_image Unexecuted instantiation: init.c:elf_map_image Unexecuted instantiation: is_fpreg.c:elf_map_image Unexecuted instantiation: mempool.c:elf_map_image Line | Count | Source | 84 | 33.1k | { | 85 | 33.1k | struct stat stat; | 86 | 33.1k | int fd; | 87 | | | 88 | 33.1k | fd = open (path, O_RDONLY); | 89 | 33.1k | if (fd < 0) | 90 | 0 | return -1; | 91 | | | 92 | 33.1k | if (fstat (fd, &stat) < 0) | 93 | 0 | { | 94 | 0 | close (fd); | 95 | 0 | return -1; | 96 | 0 | } | 97 | | | 98 | 33.1k | ei->size = stat.st_size; | 99 | 33.1k | ei->image = mi_mmap (NULL, ei->size, PROT_READ, MAP_PRIVATE, fd, 0); | 100 | 33.1k | close (fd); | 101 | 33.1k | if (ei->image == MAP_FAILED) | 102 | 0 | return -1; | 103 | | | 104 | 33.1k | if (!elf_w (valid_object) (ei)) | 105 | 0 | { | 106 | 0 | mi_munmap(ei->image, ei->size); | 107 | 0 | ei->image = NULL; | 108 | 0 | return -1; | 109 | 0 | } | 110 | | | 111 | 33.1k | return 0; | 112 | 33.1k | } |
Unexecuted instantiation: Laddress_validator.c:elf_map_image Unexecuted instantiation: Ldyn-extract.c:elf_map_image Unexecuted instantiation: Lexpr.c:elf_map_image Unexecuted instantiation: Lfde.c:elf_map_image |
113 | | |
114 | | static inline const uint8_t* elf_w (get_program_segment) (const struct elf_image *ei, |
115 | | const Elf_W (Phdr) *phdr, const uint8_t** end) |
116 | 37.3k | { |
117 | 37.3k | const uint8_t* result = NULL; |
118 | | |
119 | 37.3k | if (end) |
120 | 37.3k | *end = NULL; |
121 | | |
122 | 37.3k | if (!ei || !ei->image || !phdr || phdr->p_filesz == 0 || phdr->p_offset > ei->size) |
123 | 0 | return NULL; |
124 | | |
125 | 37.3k | result = ((const uint8_t*)ei->image) + phdr->p_offset; |
126 | 37.3k | if (end) |
127 | 37.3k | *end = result + phdr->p_filesz; |
128 | | |
129 | 37.3k | return result; |
130 | 37.3k | } Unexecuted instantiation: Lget_proc_name.c:_Uelf64_get_program_segment Unexecuted instantiation: Lget_reg.c:_Uelf64_get_program_segment Unexecuted instantiation: Lget_save_loc.c:_Uelf64_get_program_segment Unexecuted instantiation: Linit_local.c:_Uelf64_get_program_segment Unexecuted instantiation: Los-linux.c:_Uelf64_get_program_segment Unexecuted instantiation: Lput_dynamic_unwind_info.c:_Uelf64_get_program_segment Unexecuted instantiation: Lregs.c:_Uelf64_get_program_segment Unexecuted instantiation: Lstep.c:_Uelf64_get_program_segment Unexecuted instantiation: Lfind_dynamic_proc_info.c:_Uelf64_get_program_segment Unexecuted instantiation: Lfind_proc_info-lsb.c:_Uelf64_get_program_segment Unexecuted instantiation: Lget_accessors.c:_Uelf64_get_program_segment Unexecuted instantiation: Lglobal.c:_Uelf64_get_program_segment Unexecuted instantiation: Linit.c:_Uelf64_get_program_segment Unexecuted instantiation: Lparser.c:_Uelf64_get_program_segment Unexecuted instantiation: Lpe.c:_Uelf64_get_program_segment Unexecuted instantiation: Lresume.c:_Uelf64_get_program_segment Unexecuted instantiation: Lstash_frame.c:_Uelf64_get_program_segment Unexecuted instantiation: dyn-info-list.c:_Uelf64_get_program_segment elf64.c:_Uelf64_get_program_segment Line | Count | Source | 116 | 37.3k | { | 117 | 37.3k | const uint8_t* result = NULL; | 118 | | | 119 | 37.3k | if (end) | 120 | 37.3k | *end = NULL; | 121 | | | 122 | 37.3k | if (!ei || !ei->image || !phdr || phdr->p_filesz == 0 || phdr->p_offset > ei->size) | 123 | 0 | return NULL; | 124 | | | 125 | 37.3k | result = ((const uint8_t*)ei->image) + phdr->p_offset; | 126 | 37.3k | if (end) | 127 | 37.3k | *end = result + phdr->p_filesz; | 128 | | | 129 | 37.3k | return result; | 130 | 37.3k | } |
Unexecuted instantiation: flush_cache.c:_Uelf64_get_program_segment Unexecuted instantiation: global.c:_Uelf64_get_program_segment Unexecuted instantiation: init.c:_Uelf64_get_program_segment Unexecuted instantiation: is_fpreg.c:_Uelf64_get_program_segment Unexecuted instantiation: mempool.c:_Uelf64_get_program_segment Unexecuted instantiation: os-linux.c:_Uelf64_get_program_segment Unexecuted instantiation: Laddress_validator.c:_Uelf64_get_program_segment Unexecuted instantiation: Ldyn-extract.c:_Uelf64_get_program_segment Unexecuted instantiation: Lexpr.c:_Uelf64_get_program_segment Unexecuted instantiation: Lfde.c:_Uelf64_get_program_segment |