/src/elfutils/libdwelf/dwelf_elf_gnu_debuglink.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Returns the file name and crc stored in the .gnu_debuglink if found. |
2 | | Copyright (C) 2014 Red Hat, Inc. |
3 | | This file is part of elfutils. |
4 | | |
5 | | This file is free software; you can redistribute it and/or modify |
6 | | it under the terms of either |
7 | | |
8 | | * the GNU Lesser General Public License as published by the Free |
9 | | Software Foundation; either version 3 of the License, or (at |
10 | | your option) any later version |
11 | | |
12 | | or |
13 | | |
14 | | * the GNU General Public License as published by the Free |
15 | | Software Foundation; either version 2 of the License, or (at |
16 | | your option) any later version |
17 | | |
18 | | or both in parallel, as here. |
19 | | |
20 | | elfutils is distributed in the hope that it will be useful, but |
21 | | WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
23 | | General Public License for more details. |
24 | | |
25 | | You should have received copies of the GNU General Public License and |
26 | | the GNU Lesser General Public License along with this program. If |
27 | | not, see <http://www.gnu.org/licenses/>. */ |
28 | | |
29 | | #ifdef HAVE_CONFIG_H |
30 | | # include <config.h> |
31 | | #endif |
32 | | |
33 | | #include "libdwelfP.h" |
34 | | |
35 | | const char * |
36 | | dwelf_elf_gnu_debuglink (Elf *elf, GElf_Word *crc) |
37 | 3.88k | { |
38 | 3.88k | size_t shstrndx; |
39 | 3.88k | if (elf_getshdrstrndx (elf, &shstrndx) < 0) |
40 | 0 | return NULL; |
41 | | |
42 | 3.88k | Elf_Scn *scn = NULL; |
43 | 8.45k | while ((scn = elf_nextscn (elf, scn)) != NULL) |
44 | 5.48k | { |
45 | 5.48k | GElf_Shdr shdr_mem; |
46 | 5.48k | GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); |
47 | 5.48k | if (shdr == NULL) |
48 | 0 | return NULL; |
49 | | |
50 | 5.48k | const char *name = elf_strptr (elf, shstrndx, shdr->sh_name); |
51 | 5.48k | if (name == NULL) |
52 | 821 | return NULL; |
53 | | |
54 | 4.66k | if (!strcmp (name, ".gnu_debuglink")) |
55 | 90 | break; |
56 | 4.66k | } |
57 | | |
58 | 3.06k | if (scn == NULL) |
59 | 2.97k | return NULL; |
60 | | |
61 | | /* Found the .gnu_debuglink section. Extract its contents. */ |
62 | 90 | Elf_Data *rawdata = elf_rawdata (scn, NULL); |
63 | 90 | if (rawdata == NULL || rawdata->d_buf == NULL) |
64 | 7 | return NULL; |
65 | | |
66 | | /* The CRC comes after the zero-terminated file name, |
67 | | (aligned up to 4 bytes) at the end of the section data. */ |
68 | 83 | if (rawdata->d_size <= sizeof *crc |
69 | 83 | || memchr (rawdata->d_buf, '\0', rawdata->d_size - sizeof *crc) == NULL) |
70 | 7 | return NULL; |
71 | | |
72 | 76 | Elf_Data crcdata = |
73 | 76 | { |
74 | 76 | .d_type = ELF_T_WORD, |
75 | 76 | .d_buf = crc, |
76 | 76 | .d_size = sizeof *crc, |
77 | 76 | .d_version = EV_CURRENT, |
78 | 76 | }; |
79 | 76 | Elf_Data conv = |
80 | 76 | { |
81 | 76 | .d_type = ELF_T_WORD, |
82 | 76 | .d_buf = rawdata->d_buf + rawdata->d_size - sizeof *crc, |
83 | 76 | .d_size = sizeof *crc, |
84 | 76 | .d_version = EV_CURRENT, |
85 | 76 | }; |
86 | | |
87 | 76 | GElf_Ehdr ehdr_mem; |
88 | 76 | GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); |
89 | 76 | if (ehdr == NULL) |
90 | 0 | return NULL; |
91 | | |
92 | 76 | Elf_Data *d = gelf_xlatetom (elf, &crcdata, &conv, ehdr->e_ident[EI_DATA]); |
93 | 76 | if (d == NULL) |
94 | 0 | return NULL; |
95 | 76 | assert (d == &crcdata); |
96 | | |
97 | 76 | return rawdata->d_buf; |
98 | 76 | } |
99 | | INTDEF(dwelf_elf_gnu_debuglink) |