]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/elf.c
A major rewrite to move the bulk of the linker into BFD so that
[thirdparty/binutils-gdb.git] / bfd / elf.c
CommitLineData
32090b8e
KR
1/* ELF executable support for BFD.
2 Copyright 1993 Free Software Foundation, Inc.
3
4This file is part of BFD, the Binary File Descriptor library.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
d1b44e83
ILT
20/*
21
22SECTION
23 ELF backends
24
25 BFD support for ELF formats is being worked on.
26 Currently, the best supported back ends are for sparc and i386
27 (running svr4 or Solaris 2).
28
29 Documentation of the internals of the support code still needs
30 to be written. The code is changing quickly enough that we
31 haven't bothered yet.
32 */
33
32090b8e
KR
34#include "bfd.h"
35#include "sysdep.h"
36#include "libbfd.h"
37#define ARCH_SIZE 0
38#include "libelf.h"
39
32090b8e
KR
40/* Standard ELF hash function. Do not change this function; you will
41 cause invalid hash tables to be generated. (Well, you would if this
42 were being used yet.) */
43unsigned long
44DEFUN (bfd_elf_hash, (name),
45 CONST unsigned char *name)
46{
47 unsigned long h = 0;
48 unsigned long g;
49 int ch;
50
51 while ((ch = *name++) != '\0')
52 {
53 h = (h << 4) + ch;
54 if ((g = (h & 0xf0000000)) != 0)
55 {
56 h ^= g >> 24;
57 h &= ~g;
58 }
59 }
60 return h;
61}
62
63/* Read a specified number of bytes at a specified offset in an ELF
64 file, into a newly allocated buffer, and return a pointer to the
65 buffer. */
66
67static char *
68DEFUN (elf_read, (abfd, offset, size),
69 bfd * abfd AND
70 long offset AND
71 int size)
72{
73 char *buf;
74
75 if ((buf = bfd_alloc (abfd, size)) == NULL)
76 {
77 bfd_error = no_memory;
78 return NULL;
79 }
80 if (bfd_seek (abfd, offset, SEEK_SET) == -1)
81 {
82 bfd_error = system_call_error;
83 return NULL;
84 }
85 if (bfd_read ((PTR) buf, size, 1, abfd) != size)
86 {
87 bfd_error = system_call_error;
88 return NULL;
89 }
90 return buf;
91}
92
93boolean
94DEFUN (elf_mkobject, (abfd), bfd * abfd)
95{
96 /* this just does initialization */
97 /* coff_mkobject zalloc's space for tdata.coff_obj_data ... */
98 elf_tdata (abfd) = (struct elf_obj_tdata *)
99 bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
100 if (elf_tdata (abfd) == 0)
101 {
102 bfd_error = no_memory;
103 return false;
104 }
105 /* since everything is done at close time, do we need any
106 initialization? */
107
108 return true;
109}
110
111char *
112DEFUN (elf_get_str_section, (abfd, shindex),
113 bfd * abfd AND
114 unsigned int shindex)
115{
116 Elf_Internal_Shdr **i_shdrp;
117 char *shstrtab = NULL;
118 unsigned int offset;
119 unsigned int shstrtabsize;
120
121 i_shdrp = elf_elfsections (abfd);
122 if (i_shdrp == 0 || i_shdrp[shindex] == 0)
123 return 0;
124
125 shstrtab = i_shdrp[shindex]->rawdata;
126 if (shstrtab == NULL)
127 {
128 /* No cached one, attempt to read, and cache what we read. */
129 offset = i_shdrp[shindex]->sh_offset;
130 shstrtabsize = i_shdrp[shindex]->sh_size;
131 shstrtab = elf_read (abfd, offset, shstrtabsize);
132 i_shdrp[shindex]->rawdata = (void *) shstrtab;
133 }
134 return shstrtab;
135}
136
137char *
138DEFUN (elf_string_from_elf_section, (abfd, shindex, strindex),
139 bfd * abfd AND
140 unsigned int shindex AND
141 unsigned int strindex)
142{
143 Elf_Internal_Shdr *hdr;
144
145 if (strindex == 0)
146 return "";
147
148 hdr = elf_elfsections (abfd)[shindex];
149
150 if (!hdr->rawdata
151 && elf_get_str_section (abfd, shindex) == NULL)
152 return NULL;
153
154 return ((char *) hdr->rawdata) + strindex;
155}
156
157/*
158INTERNAL_FUNCTION
159 bfd_elf_find_section
160
161SYNOPSIS
162 struct elf_internal_shdr *bfd_elf_find_section (bfd *abfd, char *name);
163
164DESCRIPTION
165 Helper functions for GDB to locate the string tables.
166 Since BFD hides string tables from callers, GDB needs to use an
167 internal hook to find them. Sun's .stabstr, in particular,
168 isn't even pointed to by the .stab section, so ordinary
169 mechanisms wouldn't work to find it, even if we had some.
170*/
171
172struct elf_internal_shdr *
173DEFUN (bfd_elf_find_section, (abfd, name),
174 bfd * abfd AND
175 char *name)
176{
177 Elf_Internal_Shdr **i_shdrp;
178 char *shstrtab;
179 unsigned int max;
180 unsigned int i;
181
182 i_shdrp = elf_elfsections (abfd);
183 if (i_shdrp != NULL)
184 {
185 shstrtab = elf_get_str_section (abfd, elf_elfheader (abfd)->e_shstrndx);
186 if (shstrtab != NULL)
187 {
188 max = elf_elfheader (abfd)->e_shnum;
189 for (i = 1; i < max; i++)
190 if (!strcmp (&shstrtab[i_shdrp[i]->sh_name], name))
191 return i_shdrp[i];
192 }
193 }
194 return 0;
195}
196
32090b8e
KR
197const char *const bfd_elf_section_type_names[] = {
198 "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB",
199 "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE",
200 "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM",
201};
202
203/* ELF relocs are against symbols. If we are producing relocateable
204 output, and the reloc is against an external symbol, and nothing
205 has given us any additional addend, the resulting reloc will also
206 be against the same symbol. In such a case, we don't want to
207 change anything about the way the reloc is handled, since it will
208 all be done at final link time. Rather than put special case code
209 into bfd_perform_relocation, all the reloc types use this howto
210 function. It just short circuits the reloc if producing
211 relocateable output against an external symbol. */
212
213bfd_reloc_status_type
214bfd_elf_generic_reloc (abfd,
215 reloc_entry,
216 symbol,
217 data,
218 input_section,
219 output_bfd)
220 bfd *abfd;
221 arelent *reloc_entry;
222 asymbol *symbol;
223 PTR data;
224 asection *input_section;
225 bfd *output_bfd;
226{
227 if (output_bfd != (bfd *) NULL
228 && (symbol->flags & BSF_SECTION_SYM) == 0
d1b44e83
ILT
229 && (! reloc_entry->howto->partial_inplace
230 || reloc_entry->addend == 0))
32090b8e
KR
231 {
232 reloc_entry->address += input_section->output_offset;
233 return bfd_reloc_ok;
234 }
235
236 return bfd_reloc_continue;
237}