Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5197 serge 1
/* simple.c -- BFD simple client routines
2
   Copyright 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
3
   Free Software Foundation, Inc.
4
   Contributed by MontaVista Software, Inc.
5
 
6
   This file is part of BFD, the Binary File Descriptor library.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21
   MA 02110-1301, USA.  */
22
 
23
#include "sysdep.h"
24
#include "bfd.h"
25
#include "libbfd.h"
26
#include "bfdlink.h"
27
 
28
static bfd_boolean
29
simple_dummy_warning (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
30
		      const char *warning ATTRIBUTE_UNUSED,
31
		      const char *symbol ATTRIBUTE_UNUSED,
32
		      bfd *abfd ATTRIBUTE_UNUSED,
33
		      asection *section ATTRIBUTE_UNUSED,
34
		      bfd_vma address ATTRIBUTE_UNUSED)
35
{
36
  return TRUE;
37
}
38
 
39
static bfd_boolean
40
simple_dummy_undefined_symbol (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
41
			       const char *name ATTRIBUTE_UNUSED,
42
			       bfd *abfd ATTRIBUTE_UNUSED,
43
			       asection *section ATTRIBUTE_UNUSED,
44
			       bfd_vma address ATTRIBUTE_UNUSED,
45
			       bfd_boolean fatal ATTRIBUTE_UNUSED)
46
{
47
  return TRUE;
48
}
49
 
50
static bfd_boolean
51
simple_dummy_reloc_overflow (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
52
			     struct bfd_link_hash_entry *entry ATTRIBUTE_UNUSED,
53
			     const char *name ATTRIBUTE_UNUSED,
54
			     const char *reloc_name ATTRIBUTE_UNUSED,
55
			     bfd_vma addend ATTRIBUTE_UNUSED,
56
			     bfd *abfd ATTRIBUTE_UNUSED,
57
			     asection *section ATTRIBUTE_UNUSED,
58
			     bfd_vma address ATTRIBUTE_UNUSED)
59
{
60
  return TRUE;
61
}
62
 
63
static bfd_boolean
64
simple_dummy_reloc_dangerous (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
65
			      const char *message ATTRIBUTE_UNUSED,
66
			      bfd *abfd ATTRIBUTE_UNUSED,
67
			      asection *section ATTRIBUTE_UNUSED,
68
			      bfd_vma address ATTRIBUTE_UNUSED)
69
{
70
  return TRUE;
71
}
72
 
73
static bfd_boolean
74
simple_dummy_unattached_reloc (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
75
			       const char *name ATTRIBUTE_UNUSED,
76
			       bfd *abfd ATTRIBUTE_UNUSED,
77
			       asection *section ATTRIBUTE_UNUSED,
78
			       bfd_vma address ATTRIBUTE_UNUSED)
79
{
80
  return TRUE;
81
}
82
 
83
static bfd_boolean
84
simple_dummy_multiple_definition (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
85
				  struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
86
				  bfd *nbfd ATTRIBUTE_UNUSED,
87
				  asection *nsec ATTRIBUTE_UNUSED,
88
				  bfd_vma nval ATTRIBUTE_UNUSED)
89
{
90
  return TRUE;
91
}
92
 
93
static void
94
simple_dummy_einfo (const char *fmt ATTRIBUTE_UNUSED, ...)
95
{
96
}
97
 
98
struct saved_output_info
99
{
100
  bfd_vma offset;
101
  asection *section;
102
};
103
 
104
static void
105
simple_save_output_info (bfd *abfd ATTRIBUTE_UNUSED,
106
			 asection *section,
107
			 void *ptr)
108
{
109
  struct saved_output_info *output_info = (struct saved_output_info *) ptr;
110
  output_info[section->index].offset = section->output_offset;
111
  output_info[section->index].section = section->output_section;
112
  if ((section->flags & SEC_DEBUGGING) != 0
113
      || section->output_section == NULL)
114
    {
115
      section->output_offset = 0;
116
      section->output_section = section;
117
    }
118
}
119
 
120
static void
121
simple_restore_output_info (bfd *abfd ATTRIBUTE_UNUSED,
122
			    asection *section,
123
			    void *ptr)
124
{
125
  struct saved_output_info *output_info = (struct saved_output_info *) ptr;
126
  section->output_offset = output_info[section->index].offset;
127
  section->output_section = output_info[section->index].section;
128
}
129
 
130
/*
131
FUNCTION
132
	bfd_simple_relocate_secton
133
 
134
SYNOPSIS
135
	bfd_byte *bfd_simple_get_relocated_section_contents
136
	  (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table);
137
 
138
DESCRIPTION
139
	Returns the relocated contents of section @var{sec}.  The symbols in
140
	@var{symbol_table} will be used, or the symbols from @var{abfd} if
141
	@var{symbol_table} is NULL.  The output offsets for debug sections will
142
	be temporarily reset to 0.  The result will be stored at @var{outbuf}
143
	or allocated with @code{bfd_malloc} if @var{outbuf} is @code{NULL}.
144
 
145
	Returns @code{NULL} on a fatal error; ignores errors applying
146
	particular relocations.
147
*/
148
 
149
bfd_byte *
150
bfd_simple_get_relocated_section_contents (bfd *abfd,
151
					   asection *sec,
152
					   bfd_byte *outbuf,
153
					   asymbol **symbol_table)
154
{
155
  struct bfd_link_info link_info;
156
  struct bfd_link_order link_order;
157
  struct bfd_link_callbacks callbacks;
158
  bfd_byte *contents, *data;
159
  int storage_needed;
160
  void *saved_offsets;
161
 
162
  /* Don't apply relocation on executable and shared library.  See
163
     PR 4756.  */
164
  if ((abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC)) != HAS_RELOC
165
      || ! (sec->flags & SEC_RELOC))
166
    {
167
      contents = outbuf;
168
      if (!bfd_get_full_section_contents (abfd, sec, &contents))
169
	return NULL;
170
      return contents;
171
    }
172
 
173
  /* In order to use bfd_get_relocated_section_contents, we need
174
     to forge some data structures that it expects.  */
175
 
176
  /* Fill in the bare minimum number of fields for our purposes.  */
177
  memset (&link_info, 0, sizeof (link_info));
178
  link_info.output_bfd = abfd;
179
  link_info.input_bfds = abfd;
180
  link_info.input_bfds_tail = &abfd->link_next;
181
 
182
  link_info.hash = _bfd_generic_link_hash_table_create (abfd);
183
  link_info.callbacks = &callbacks;
184
  callbacks.warning = simple_dummy_warning;
185
  callbacks.undefined_symbol = simple_dummy_undefined_symbol;
186
  callbacks.reloc_overflow = simple_dummy_reloc_overflow;
187
  callbacks.reloc_dangerous = simple_dummy_reloc_dangerous;
188
  callbacks.unattached_reloc = simple_dummy_unattached_reloc;
189
  callbacks.multiple_definition = simple_dummy_multiple_definition;
190
  callbacks.einfo = simple_dummy_einfo;
191
 
192
  memset (&link_order, 0, sizeof (link_order));
193
  link_order.next = NULL;
194
  link_order.type = bfd_indirect_link_order;
195
  link_order.offset = 0;
196
  link_order.size = sec->size;
197
  link_order.u.indirect.section = sec;
198
 
199
  data = NULL;
200
  if (outbuf == NULL)
201
    {
202
      bfd_size_type amt = sec->rawsize > sec->size ? sec->rawsize : sec->size;
203
      data = (bfd_byte *) bfd_malloc (amt);
204
      if (data == NULL)
205
	return NULL;
206
      outbuf = data;
207
    }
208
 
209
  /* The sections in ABFD may already have output sections and offsets set.
210
     Because this function is primarily for debug sections, and GCC uses the
211
     knowledge that debug sections will generally have VMA 0 when emitting
212
     relocations between DWARF-2 sections (which are supposed to be
213
     section-relative offsets anyway), we need to reset the output offsets
214
     to zero.  We also need to arrange for section->output_section->vma plus
215
     section->output_offset to equal section->vma, which we do by setting
216
     section->output_section to point back to section.  Save the original
217
     output offset and output section to restore later.  */
218
  saved_offsets = malloc (sizeof (struct saved_output_info)
219
			  * abfd->section_count);
220
  if (saved_offsets == NULL)
221
    {
222
      if (data)
223
	free (data);
224
      return NULL;
225
    }
226
  bfd_map_over_sections (abfd, simple_save_output_info, saved_offsets);
227
 
228
  if (symbol_table == NULL)
229
    {
230
      _bfd_generic_link_add_symbols (abfd, &link_info);
231
 
232
      storage_needed = bfd_get_symtab_upper_bound (abfd);
233
      symbol_table = (asymbol **) bfd_malloc (storage_needed);
234
      bfd_canonicalize_symtab (abfd, symbol_table);
235
    }
236
  else
237
    storage_needed = 0;
238
 
239
  contents = bfd_get_relocated_section_contents (abfd,
240
						 &link_info,
241
						 &link_order,
242
						 outbuf,
243
						 0,
244
						 symbol_table);
245
  if (contents == NULL && data != NULL)
246
    free (data);
247
 
248
  bfd_map_over_sections (abfd, simple_restore_output_info, saved_offsets);
249
  free (saved_offsets);
250
 
251
  _bfd_generic_link_hash_table_free (link_info.hash);
252
  return contents;
253
}