/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 | 4.19k | { |
38 | 4.19k | size_t shstrndx; |
39 | 4.19k | if (elf_getshdrstrndx (elf, &shstrndx) < 0) |
40 | 0 | return NULL; |
41 | | |
42 | 4.19k | Elf_Scn *scn = NULL; |
43 | 11.7k | while ((scn = elf_nextscn (elf, scn)) != NULL) |
44 | 8.46k | { |
45 | 8.46k | GElf_Shdr shdr_mem; |
46 | 8.46k | GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); |
47 | 8.46k | if (shdr == NULL) |
48 | 0 | return NULL; |
49 | | |
50 | 8.46k | const char *name = elf_strptr (elf, shstrndx, shdr->sh_name); |
51 | 8.46k | if (name == NULL) |
52 | 858 | return NULL; |
53 | | |
54 | 7.60k | if (!strcmp (name, ".gnu_debuglink")) |
55 | 93 | break; |
56 | 7.60k | } |
57 | | |
58 | 3.33k | if (scn == NULL) |
59 | 3.24k | return NULL; |
60 | | |
61 | | /* Found the .gnu_debuglink section. Extract its contents. */ |
62 | 93 | Elf_Data *rawdata = elf_rawdata (scn, NULL); |
63 | 93 | if (rawdata == NULL || rawdata->d_buf == NULL) |
64 | 9 | 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 | 84 | if (rawdata->d_size <= sizeof *crc |
69 | 84 | || memchr (rawdata->d_buf, '\0', rawdata->d_size - sizeof *crc) == NULL) |
70 | 9 | return NULL; |
71 | | |
72 | 75 | Elf_Data crcdata = |
73 | 75 | { |
74 | 75 | .d_type = ELF_T_WORD, |
75 | 75 | .d_buf = crc, |
76 | 75 | .d_size = sizeof *crc, |
77 | 75 | .d_version = EV_CURRENT, |
78 | 75 | }; |
79 | 75 | Elf_Data conv = |
80 | 75 | { |
81 | 75 | .d_type = ELF_T_WORD, |
82 | 75 | .d_buf = rawdata->d_buf + rawdata->d_size - sizeof *crc, |
83 | 75 | .d_size = sizeof *crc, |
84 | 75 | .d_version = EV_CURRENT, |
85 | 75 | }; |
86 | | |
87 | 75 | GElf_Ehdr ehdr_mem; |
88 | 75 | GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); |
89 | 75 | if (ehdr == NULL) |
90 | 0 | return NULL; |
91 | | |
92 | 75 | Elf_Data *d = gelf_xlatetom (elf, &crcdata, &conv, ehdr->e_ident[EI_DATA]); |
93 | 75 | if (d == NULL) |
94 | 0 | return NULL; |
95 | 75 | assert (d == &crcdata); |
96 | | |
97 | 75 | return rawdata->d_buf; |
98 | 75 | } |
99 | | INTDEF(dwelf_elf_gnu_debuglink) |