]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/readlib.c
powerpc: Remove optimized finite
[thirdparty/glibc.git] / elf / readlib.c
CommitLineData
04277e02 1/* Copyright (C) 1999-2019 Free Software Foundation, Inc.
591e1ffb
UD
2 This file is part of the GNU C Library.
3 Contributed by Andreas Jaeger <aj@suse.de>, 1999 and
4 Jakub Jelinek <jakub@redhat.com>, 1999.
5
43bc8ac6 6 This program is free software; you can redistribute it and/or modify
2e2efe65
RM
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; version 2 of the License, or
9 (at your option) any later version.
591e1ffb 10
43bc8ac6 11 This program is distributed in the hope that it will be useful,
591e1ffb 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
43bc8ac6
UD
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
591e1ffb 15
43bc8ac6 16 You should have received a copy of the GNU General Public License
59ba27a6 17 along with this program; if not, see <http://www.gnu.org/licenses/>. */
591e1ffb
UD
18
19/* The code in this file and in readelflib is a heavily simplified
20 version of the readelf program that's part of the current binutils
21 development version. Besides the simplification, it has also been
22 modified to read some other file formats. */
23
f00b1941 24#include <a.out.h>
591e1ffb
UD
25#include <elf.h>
26#include <error.h>
591e1ffb 27#include <libintl.h>
f00b1941 28#include <link.h>
591e1ffb
UD
29#include <stdio.h>
30#include <string.h>
31#include <unistd.h>
591e1ffb 32#include <sys/mman.h>
f00b1941 33#include <sys/param.h>
591e1ffb 34#include <sys/stat.h>
dc95d158 35#include <gnu/lib-names.h>
591e1ffb 36
8f480b4b 37#include <ldconfig.h>
591e1ffb
UD
38
39#define Elf32_CLASS ELFCLASS32
40#define Elf64_CLASS ELFCLASS64
41
42struct known_names
43{
44 const char *soname;
45 int flag;
46};
47
a986484f 48static struct known_names interpreters[] =
591e1ffb 49{
a986484f 50 { "/lib/" LD_SO, FLAG_ELF_LIBC6 },
667b0577
UD
51#ifdef SYSDEP_KNOWN_INTERPRETER_NAMES
52 SYSDEP_KNOWN_INTERPRETER_NAMES
53#endif
591e1ffb
UD
54};
55
a986484f 56static struct known_names known_libs[] =
591e1ffb 57{
a986484f
UD
58 { LIBC_SO, FLAG_ELF_LIBC6 },
59 { LIBM_SO, FLAG_ELF_LIBC6 },
667b0577
UD
60#ifdef SYSDEP_KNOWN_LIBRARY_NAMES
61 SYSDEP_KNOWN_LIBRARY_NAMES
62#endif
591e1ffb
UD
63};
64
65
eea3dc5b
L
66/* Check if string corresponds to a GDB Python file. */
67static bool
68is_gdb_python_file (const char *name)
69{
70 size_t len = strlen (name);
71 return len > 7 && strcmp (name + len - 7, "-gdb.py") == 0;
72}
591e1ffb
UD
73
74/* Returns 0 if everything is ok, != 0 in case of error. */
75int
b4a555d6 76process_file (const char *real_file_name, const char *file_name,
a986484f 77 const char *lib, int *flag, unsigned int *osversion,
27d9ffda 78 char **soname, int is_link, struct stat64 *stat_buf)
591e1ffb
UD
79{
80 FILE *file;
b4a555d6 81 struct stat64 statbuf;
591e1ffb
UD
82 void *file_contents;
83 int ret;
591e1ffb
UD
84 ElfW(Ehdr) *elf_header;
85 struct exec *aout_header;
86
87 ret = 0;
88 *flag = FLAG_ANY;
89 *soname = NULL;
90
b4a555d6 91 file = fopen (real_file_name, "rb");
591e1ffb
UD
92 if (file == NULL)
93 {
94 /* No error for stale symlink. */
7ad9abc0 95 if (is_link && strstr (file_name, ".so") != NULL)
591e1ffb
UD
96 return 1;
97 error (0, 0, _("Input file %s not found.\n"), file_name);
98 return 1;
99 }
100
b4a555d6 101 if (fstat64 (fileno (file), &statbuf) < 0)
591e1ffb
UD
102 {
103 error (0, 0, _("Cannot fstat file %s.\n"), file_name);
e7c036b3
UD
104 fclose (file);
105 return 1;
106 }
107
108 /* Check that the file is large enough so that we can access the
109 information. We're only checking the size of the headers here. */
6dd67bd5
UD
110 if ((size_t) statbuf.st_size < sizeof (struct exec)
111 || (size_t) statbuf.st_size < sizeof (ElfW(Ehdr)))
e7c036b3 112 {
625ef999
UD
113 if (statbuf.st_size == 0)
114 error (0, 0, _("File %s is empty, not checked."), file_name);
115 else
116 {
117 char buf[SELFMAG];
118 size_t n = MIN (statbuf.st_size, SELFMAG);
119 if (fread (buf, n, 1, file) == 1 && memcmp (buf, ELFMAG, n) == 0)
120 error (0, 0, _("File %s is too small, not checked."), file_name);
121 }
e7c036b3 122 fclose (file);
591e1ffb
UD
123 return 1;
124 }
125
e7c036b3
UD
126 file_contents = mmap (0, statbuf.st_size, PROT_READ, MAP_SHARED,
127 fileno (file), 0);
591e1ffb
UD
128 if (file_contents == MAP_FAILED)
129 {
130 error (0, 0, _("Cannot mmap file %s.\n"), file_name);
131 fclose (file);
132 return 1;
133 }
134
135 /* First check if this is an aout file. */
136 aout_header = (struct exec *) file_contents;
137 if (N_MAGIC (*aout_header) == ZMAGIC
be3c40b6
RM
138#ifdef QMAGIC /* Linuxism. */
139 || N_MAGIC (*aout_header) == QMAGIC
140#endif
141 )
591e1ffb 142 {
e7c036b3 143 /* Aout files don't have a soname, just return the name
27d9ffda 144 including the major number. */
591e1ffb
UD
145 char *copy, *major, *dot;
146 copy = xstrdup (lib);
147 major = strstr (copy, ".so.");
148 if (major)
149 {
150 dot = strstr (major + 4, ".");
151 if (dot)
152 *dot = '\0';
153 }
154 *soname = copy;
155 *flag = FLAG_LIBC4;
156 goto done;
157 }
af1680f1 158
591e1ffb 159 elf_header = (ElfW(Ehdr) *) file_contents;
a986484f 160 if (memcmp (elf_header->e_ident, ELFMAG, SELFMAG) != 0)
591e1ffb 161 {
f00b1941
UD
162 /* The file is neither ELF nor aout. Check if it's a linker
163 script, like libc.so - otherwise complain. Only search the
164 beginning of the file. */
165 size_t len = MIN (statbuf.st_size, 512);
591e1ffb 166 if (memmem (file_contents, len, "GROUP", 5) == NULL
eea3dc5b
L
167 && memmem (file_contents, len, "GNU ld script", 13) == NULL
168 && !is_gdb_python_file (file_name))
591e1ffb
UD
169 error (0, 0, _("%s is not an ELF file - it has the wrong magic bytes at the start.\n"),
170 file_name);
171 ret = 1;
591e1ffb 172 }
7220da7c
AJ
173 /* Libraries have to be shared object files. */
174 else if (elf_header->e_type != ET_DYN)
175 ret = 1;
176 else if (process_elf_file (file_name, lib, flag, osversion, soname,
177 file_contents, statbuf.st_size))
591e1ffb
UD
178 ret = 1;
179
180 done:
181 /* Clean up allocated memory and resources. */
182 munmap (file_contents, statbuf.st_size);
183 fclose (file);
184
27d9ffda 185 *stat_buf = statbuf;
591e1ffb
UD
186 return ret;
187}
188
27d9ffda
UD
189/* Returns made up soname if lib doesn't have explicit DT_SONAME. */
190
191char *
192implicit_soname (const char *lib, int flag)
193{
194 char *soname = xstrdup (lib);
195
196 if ((flag & FLAG_TYPE_MASK) != FLAG_LIBC4)
197 return soname;
198
199 /* Aout files don't have a soname, just return the name
200 including the major number. */
201 char *major = strstr (soname, ".so.");
202 if (major)
203 {
204 char *dot = strstr (major + 4, ".");
205 if (dot)
206 *dot = '\0';
207 }
208 return soname;
209}
210
591e1ffb 211/* Get architecture specific version of process_elf_file. */
2fdaad97 212#include <readelflib.c>