1fddef416Sniklas /* BFD back-end for linux flavored sparc a.out binaries.
2d2201f2fSdrahn Copyright 1992, 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003
3f7cc78ecSespie Free Software Foundation, Inc.
4fddef416Sniklas
5fddef416Sniklas This file is part of BFD, the Binary File Descriptor library.
6fddef416Sniklas
7fddef416Sniklas This program is free software; you can redistribute it and/or modify
8fddef416Sniklas it under the terms of the GNU General Public License as published by
9fddef416Sniklas the Free Software Foundation; either version 2 of the License, or
10fddef416Sniklas (at your option) any later version.
11fddef416Sniklas
12fddef416Sniklas This program is distributed in the hope that it will be useful,
13fddef416Sniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
14fddef416Sniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15fddef416Sniklas GNU General Public License for more details.
16fddef416Sniklas
17fddef416Sniklas You should have received a copy of the GNU General Public License
18fddef416Sniklas along with this program; if not, write to the Free Software
19fddef416Sniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20fddef416Sniklas USA. */
21fddef416Sniklas
22fddef416Sniklas #define TARGET_PAGE_SIZE 4096
23fddef416Sniklas #define ZMAGIC_DISK_BLOCK_SIZE 1024
24fddef416Sniklas #define SEGMENT_SIZE TARGET_PAGE_SIZE
25fddef416Sniklas #define TEXT_START_ADDR 0x0
26fddef416Sniklas #define N_SHARED_LIB(x) 0
27fddef416Sniklas
28fddef416Sniklas #define MACHTYPE_OK(mtype) ((mtype) == M_SPARC || (mtype) == M_UNKNOWN)
29fddef416Sniklas
30fddef416Sniklas #include "bfd.h"
31fddef416Sniklas #include "sysdep.h"
32fddef416Sniklas #include "libbfd.h"
33fddef416Sniklas #include "aout/aout64.h"
34fddef416Sniklas #include "aout/stab_gnu.h"
35fddef416Sniklas #include "aout/ar.h"
36fddef416Sniklas #include "libaout.h" /* BFD a.out internal data structures */
37fddef416Sniklas
38fddef416Sniklas #define DEFAULT_ARCH bfd_arch_sparc
39d2201f2fSdrahn /* Do not "beautify" the CONCAT* macro args. Traditional C will not
40d2201f2fSdrahn remove whitespace added here, and thus will fail to concatenate
41d2201f2fSdrahn the tokens. */
42d2201f2fSdrahn #define MY(OP) CONCAT2 (sparclinux_,OP)
43fddef416Sniklas #define TARGETNAME "a.out-sparc-linux"
44fddef416Sniklas
45fddef416Sniklas extern const bfd_target MY(vec);
46fddef416Sniklas
47fddef416Sniklas /* We always generate QMAGIC files in preference to ZMAGIC files. It
48fddef416Sniklas would be possible to make this a linker option, if that ever
49fddef416Sniklas becomes important. */
50fddef416Sniklas
51fddef416Sniklas static void MY_final_link_callback
52fddef416Sniklas PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
53fddef416Sniklas
54d2201f2fSdrahn static bfd_boolean sparclinux_bfd_final_link
55fddef416Sniklas PARAMS ((bfd *abfd, struct bfd_link_info *info));
56fddef416Sniklas
57d2201f2fSdrahn static bfd_boolean
sparclinux_bfd_final_link(abfd,info)58fddef416Sniklas sparclinux_bfd_final_link (abfd, info)
59fddef416Sniklas bfd *abfd;
60fddef416Sniklas struct bfd_link_info *info;
61fddef416Sniklas {
62fddef416Sniklas obj_aout_subformat (abfd) = q_magic_format;
63fddef416Sniklas return NAME(aout,final_link) (abfd, info, MY_final_link_callback);
64fddef416Sniklas }
65fddef416Sniklas
66fddef416Sniklas #define MY_bfd_final_link sparclinux_bfd_final_link
67fddef416Sniklas
68fddef416Sniklas /* Set the machine type correctly. */
69fddef416Sniklas
70d2201f2fSdrahn static bfd_boolean sparclinux_write_object_contents PARAMS ((bfd *abfd));
71fddef416Sniklas
72d2201f2fSdrahn static bfd_boolean
sparclinux_write_object_contents(abfd)73fddef416Sniklas sparclinux_write_object_contents (abfd)
74fddef416Sniklas bfd *abfd;
75fddef416Sniklas {
76fddef416Sniklas struct external_exec exec_bytes;
77fddef416Sniklas struct internal_exec *execp = exec_hdr (abfd);
78fddef416Sniklas
79fddef416Sniklas N_SET_MACHTYPE (*execp, M_SPARC);
80fddef416Sniklas
81fddef416Sniklas obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
82fddef416Sniklas
83fddef416Sniklas WRITE_HEADERS(abfd, execp);
84fddef416Sniklas
85d2201f2fSdrahn return TRUE;
86fddef416Sniklas }
87fddef416Sniklas
88fddef416Sniklas #define MY_write_object_contents sparclinux_write_object_contents
89fddef416Sniklas /* Code to link against Linux a.out shared libraries. */
90fddef416Sniklas
91fddef416Sniklas /* See if a symbol name is a reference to the global offset table. */
92fddef416Sniklas
93fddef416Sniklas #ifndef GOT_REF_PREFIX
94fddef416Sniklas #define GOT_REF_PREFIX "__GOT_"
95fddef416Sniklas #endif
96fddef416Sniklas
97fddef416Sniklas #define IS_GOT_SYM(name) \
98fddef416Sniklas (strncmp (name, GOT_REF_PREFIX, sizeof GOT_REF_PREFIX - 1) == 0)
99fddef416Sniklas
100fddef416Sniklas /* See if a symbol name is a reference to the procedure linkage table. */
101fddef416Sniklas
102fddef416Sniklas #ifndef PLT_REF_PREFIX
103fddef416Sniklas #define PLT_REF_PREFIX "__PLT_"
104fddef416Sniklas #endif
105fddef416Sniklas
106fddef416Sniklas #define IS_PLT_SYM(name) \
107fddef416Sniklas (strncmp (name, PLT_REF_PREFIX, sizeof PLT_REF_PREFIX - 1) == 0)
108fddef416Sniklas
109fddef416Sniklas /* This string is used to generate specialized error messages. */
110fddef416Sniklas
111fddef416Sniklas #ifndef NEEDS_SHRLIB
112fddef416Sniklas #define NEEDS_SHRLIB "__NEEDS_SHRLIB_"
113fddef416Sniklas #endif
114fddef416Sniklas
115fddef416Sniklas /* This special symbol is a set vector that contains a list of
116*cf2f2c56Smiod pointers to fixup tables. It will be present in any dynamically
117fddef416Sniklas linked file. The linker generated fixup table should also be added
118fddef416Sniklas to the list, and it should always appear in the second slot (the
119fddef416Sniklas first one is a dummy with a magic number that is defined in
120fddef416Sniklas crt0.o). */
121fddef416Sniklas
122fddef416Sniklas #ifndef SHARABLE_CONFLICTS
123fddef416Sniklas #define SHARABLE_CONFLICTS "__SHARABLE_CONFLICTS__"
124fddef416Sniklas #endif
125fddef416Sniklas
126fddef416Sniklas /* We keep a list of fixups. The terminology is a bit strange, but
127fddef416Sniklas each fixup contains two 32 bit numbers. A regular fixup contains
128fddef416Sniklas an address and a pointer, and at runtime we should store the
129fddef416Sniklas address at the location pointed to by the pointer. A builtin fixup
130fddef416Sniklas contains two pointers, and we should read the address using one
131fddef416Sniklas pointer and store it at the location pointed to by the other
132fddef416Sniklas pointer. Builtin fixups come into play when we have duplicate
133fddef416Sniklas __GOT__ symbols for the same variable. The builtin fixup will copy
134fddef416Sniklas the GOT pointer from one over into the other. */
135fddef416Sniklas
136fddef416Sniklas struct fixup
137fddef416Sniklas {
138fddef416Sniklas struct fixup *next;
139fddef416Sniklas struct linux_link_hash_entry *h;
140fddef416Sniklas bfd_vma value;
141fddef416Sniklas
142fddef416Sniklas /* Nonzero if this is a jump instruction that needs to be fixed,
143fddef416Sniklas zero if this is just a pointer */
144fddef416Sniklas char jump;
145fddef416Sniklas
146fddef416Sniklas char builtin;
147fddef416Sniklas };
148fddef416Sniklas
149fddef416Sniklas /* We don't need a special hash table entry structure, but we do need
150fddef416Sniklas to keep some information between linker passes, so we use a special
151fddef416Sniklas hash table. */
152fddef416Sniklas
153fddef416Sniklas struct linux_link_hash_entry
154fddef416Sniklas {
155fddef416Sniklas struct aout_link_hash_entry root;
156fddef416Sniklas };
157fddef416Sniklas
158fddef416Sniklas struct linux_link_hash_table
159fddef416Sniklas {
160fddef416Sniklas struct aout_link_hash_table root;
161fddef416Sniklas
162fddef416Sniklas /* First dynamic object found in link. */
163fddef416Sniklas bfd *dynobj;
164fddef416Sniklas
165fddef416Sniklas /* Number of fixups. */
166fddef416Sniklas size_t fixup_count;
167fddef416Sniklas
168fddef416Sniklas /* Number of builtin fixups. */
169fddef416Sniklas size_t local_builtins;
170fddef416Sniklas
171fddef416Sniklas /* List of fixups. */
172fddef416Sniklas struct fixup *fixup_list;
173fddef416Sniklas };
174fddef416Sniklas
175fddef416Sniklas static struct bfd_hash_entry *linux_link_hash_newfunc
176fddef416Sniklas PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
177fddef416Sniklas static struct bfd_link_hash_table *linux_link_hash_table_create
178fddef416Sniklas PARAMS ((bfd *));
179fddef416Sniklas static struct fixup *new_fixup
180fddef416Sniklas PARAMS ((struct bfd_link_info *, struct linux_link_hash_entry *,
181fddef416Sniklas bfd_vma, int));
182d2201f2fSdrahn static bfd_boolean linux_link_create_dynamic_sections
183fddef416Sniklas PARAMS ((bfd *, struct bfd_link_info *));
184d2201f2fSdrahn static bfd_boolean linux_add_one_symbol
185fddef416Sniklas PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *,
186d2201f2fSdrahn bfd_vma, const char *, bfd_boolean, bfd_boolean,
187fddef416Sniklas struct bfd_link_hash_entry **));
188d2201f2fSdrahn static bfd_boolean linux_tally_symbols
189fddef416Sniklas PARAMS ((struct linux_link_hash_entry *, PTR));
190d2201f2fSdrahn static bfd_boolean linux_finish_dynamic_link
191fddef416Sniklas PARAMS ((bfd *, struct bfd_link_info *));
192fddef416Sniklas
193fddef416Sniklas /* Routine to create an entry in an Linux link hash table. */
194fddef416Sniklas
195fddef416Sniklas static struct bfd_hash_entry *
linux_link_hash_newfunc(entry,table,string)196fddef416Sniklas linux_link_hash_newfunc (entry, table, string)
197fddef416Sniklas struct bfd_hash_entry *entry;
198fddef416Sniklas struct bfd_hash_table *table;
199fddef416Sniklas const char *string;
200fddef416Sniklas {
201fddef416Sniklas struct linux_link_hash_entry *ret = (struct linux_link_hash_entry *) entry;
202fddef416Sniklas
203fddef416Sniklas /* Allocate the structure if it has not already been allocated by a
204fddef416Sniklas subclass. */
205fddef416Sniklas if (ret == (struct linux_link_hash_entry *) NULL)
206fddef416Sniklas ret = ((struct linux_link_hash_entry *)
207fddef416Sniklas bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry)));
208fddef416Sniklas if (ret == NULL)
209fddef416Sniklas return (struct bfd_hash_entry *) ret;
210fddef416Sniklas
211fddef416Sniklas /* Call the allocation method of the superclass. */
212fddef416Sniklas ret = ((struct linux_link_hash_entry *)
213fddef416Sniklas NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret,
214fddef416Sniklas table, string));
215fddef416Sniklas if (ret != NULL)
216fddef416Sniklas {
217fddef416Sniklas /* Set local fields; there aren't any. */
218fddef416Sniklas }
219fddef416Sniklas
220fddef416Sniklas return (struct bfd_hash_entry *) ret;
221fddef416Sniklas }
222fddef416Sniklas
223fddef416Sniklas /* Create a Linux link hash table. */
224fddef416Sniklas
225fddef416Sniklas static struct bfd_link_hash_table *
linux_link_hash_table_create(abfd)226fddef416Sniklas linux_link_hash_table_create (abfd)
227fddef416Sniklas bfd *abfd;
228fddef416Sniklas {
229fddef416Sniklas struct linux_link_hash_table *ret;
230d2201f2fSdrahn bfd_size_type amt = sizeof (struct linux_link_hash_table);
231fddef416Sniklas
232d2201f2fSdrahn ret = (struct linux_link_hash_table *) bfd_malloc (amt);
233fddef416Sniklas if (ret == (struct linux_link_hash_table *) NULL)
234fddef416Sniklas return (struct bfd_link_hash_table *) NULL;
235fddef416Sniklas if (! NAME(aout,link_hash_table_init) (&ret->root, abfd,
236fddef416Sniklas linux_link_hash_newfunc))
237fddef416Sniklas {
238fddef416Sniklas free (ret);
239fddef416Sniklas return (struct bfd_link_hash_table *) NULL;
240fddef416Sniklas }
241fddef416Sniklas
242fddef416Sniklas ret->dynobj = NULL;
243fddef416Sniklas ret->fixup_count = 0;
244fddef416Sniklas ret->local_builtins = 0;
245fddef416Sniklas ret->fixup_list = NULL;
246fddef416Sniklas
247fddef416Sniklas return &ret->root.root;
248fddef416Sniklas }
249fddef416Sniklas
250fddef416Sniklas /* Look up an entry in a Linux link hash table. */
251fddef416Sniklas
252fddef416Sniklas #define linux_link_hash_lookup(table, string, create, copy, follow) \
253fddef416Sniklas ((struct linux_link_hash_entry *) \
254fddef416Sniklas aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\
255fddef416Sniklas (follow)))
256fddef416Sniklas
257fddef416Sniklas /* Traverse a Linux link hash table. */
258fddef416Sniklas
259fddef416Sniklas #define linux_link_hash_traverse(table, func, info) \
260fddef416Sniklas (aout_link_hash_traverse \
261fddef416Sniklas (&(table)->root, \
262d2201f2fSdrahn (bfd_boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \
263fddef416Sniklas (info)))
264fddef416Sniklas
265fddef416Sniklas /* Get the Linux link hash table from the info structure. This is
266fddef416Sniklas just a cast. */
267fddef416Sniklas
268fddef416Sniklas #define linux_hash_table(p) ((struct linux_link_hash_table *) ((p)->hash))
269fddef416Sniklas
270fddef416Sniklas /* Store the information for a new fixup. */
271fddef416Sniklas
272fddef416Sniklas static struct fixup *
new_fixup(info,h,value,builtin)273fddef416Sniklas new_fixup (info, h, value, builtin)
274fddef416Sniklas struct bfd_link_info *info;
275fddef416Sniklas struct linux_link_hash_entry *h;
276fddef416Sniklas bfd_vma value;
277fddef416Sniklas int builtin;
278fddef416Sniklas {
279fddef416Sniklas struct fixup *f;
280fddef416Sniklas
281fddef416Sniklas f = (struct fixup *) bfd_hash_allocate (&info->hash->table,
282fddef416Sniklas sizeof (struct fixup));
283fddef416Sniklas if (f == NULL)
284fddef416Sniklas return f;
285fddef416Sniklas f->next = linux_hash_table (info)->fixup_list;
286fddef416Sniklas linux_hash_table (info)->fixup_list = f;
287fddef416Sniklas f->h = h;
288fddef416Sniklas f->value = value;
289fddef416Sniklas f->builtin = builtin;
290fddef416Sniklas f->jump = 0;
291fddef416Sniklas ++linux_hash_table (info)->fixup_count;
292fddef416Sniklas return f;
293fddef416Sniklas }
294fddef416Sniklas
295fddef416Sniklas /* We come here once we realize that we are going to link to a shared
296fddef416Sniklas library. We need to create a special section that contains the
297fddef416Sniklas fixup table, and we ultimately need to add a pointer to this into
298fddef416Sniklas the set vector for SHARABLE_CONFLICTS. At this point we do not
299fddef416Sniklas know the size of the section, but that's OK - we just need to
300fddef416Sniklas create it for now. */
301fddef416Sniklas
302d2201f2fSdrahn static bfd_boolean
linux_link_create_dynamic_sections(abfd,info)303fddef416Sniklas linux_link_create_dynamic_sections (abfd, info)
304fddef416Sniklas bfd *abfd;
305f7cc78ecSespie struct bfd_link_info *info ATTRIBUTE_UNUSED;
306fddef416Sniklas {
307fddef416Sniklas flagword flags;
308fddef416Sniklas register asection *s;
309fddef416Sniklas
310fddef416Sniklas /* Note that we set the SEC_IN_MEMORY flag. */
311fddef416Sniklas flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
312fddef416Sniklas
313fddef416Sniklas /* We choose to use the name ".linux-dynamic" for the fixup table.
314fddef416Sniklas Why not? */
315fddef416Sniklas s = bfd_make_section (abfd, ".linux-dynamic");
316fddef416Sniklas if (s == NULL
317fddef416Sniklas || ! bfd_set_section_flags (abfd, s, flags)
318fddef416Sniklas || ! bfd_set_section_alignment (abfd, s, 2))
319d2201f2fSdrahn return FALSE;
320fddef416Sniklas s->_raw_size = 0;
321fddef416Sniklas s->contents = 0;
322fddef416Sniklas
323d2201f2fSdrahn return TRUE;
324fddef416Sniklas }
325fddef416Sniklas
326fddef416Sniklas /* Function to add a single symbol to the linker hash table. This is
327fddef416Sniklas a wrapper around _bfd_generic_link_add_one_symbol which handles the
328fddef416Sniklas tweaking needed for dynamic linking support. */
329fddef416Sniklas
330d2201f2fSdrahn static bfd_boolean
linux_add_one_symbol(info,abfd,name,flags,section,value,string,copy,collect,hashp)331fddef416Sniklas linux_add_one_symbol (info, abfd, name, flags, section, value, string,
332fddef416Sniklas copy, collect, hashp)
333fddef416Sniklas struct bfd_link_info *info;
334fddef416Sniklas bfd *abfd;
335fddef416Sniklas const char *name;
336fddef416Sniklas flagword flags;
337fddef416Sniklas asection *section;
338fddef416Sniklas bfd_vma value;
339fddef416Sniklas const char *string;
340d2201f2fSdrahn bfd_boolean copy;
341d2201f2fSdrahn bfd_boolean collect;
342fddef416Sniklas struct bfd_link_hash_entry **hashp;
343fddef416Sniklas {
344fddef416Sniklas struct linux_link_hash_entry *h;
345d2201f2fSdrahn bfd_boolean insert;
346fddef416Sniklas
347fddef416Sniklas /* Look up and see if we already have this symbol in the hash table.
348fddef416Sniklas If we do, and the defining entry is from a shared library, we
349fddef416Sniklas need to create the dynamic sections.
350fddef416Sniklas
351fddef416Sniklas FIXME: What if abfd->xvec != info->hash->creator? We may want to
352fddef416Sniklas be able to link Linux a.out and ELF objects together, but serious
353fddef416Sniklas confusion is possible. */
354fddef416Sniklas
355d2201f2fSdrahn insert = FALSE;
356fddef416Sniklas
357*cf2f2c56Smiod if (! info->relocatable
358fddef416Sniklas && linux_hash_table (info)->dynobj == NULL
359fddef416Sniklas && strcmp (name, SHARABLE_CONFLICTS) == 0
360fddef416Sniklas && (flags & BSF_CONSTRUCTOR) != 0
361fddef416Sniklas && abfd->xvec == info->hash->creator)
362fddef416Sniklas {
363fddef416Sniklas if (! linux_link_create_dynamic_sections (abfd, info))
364d2201f2fSdrahn return FALSE;
365fddef416Sniklas linux_hash_table (info)->dynobj = abfd;
366d2201f2fSdrahn insert = TRUE;
367fddef416Sniklas }
368fddef416Sniklas
369fddef416Sniklas if (bfd_is_abs_section (section)
370fddef416Sniklas && abfd->xvec == info->hash->creator)
371fddef416Sniklas {
372d2201f2fSdrahn h = linux_link_hash_lookup (linux_hash_table (info), name, FALSE,
373d2201f2fSdrahn FALSE, FALSE);
374fddef416Sniklas if (h != NULL
375fddef416Sniklas && (h->root.root.type == bfd_link_hash_defined
376fddef416Sniklas || h->root.root.type == bfd_link_hash_defweak))
377fddef416Sniklas {
378fddef416Sniklas struct fixup *f;
379fddef416Sniklas
380fddef416Sniklas if (hashp != NULL)
381fddef416Sniklas *hashp = (struct bfd_link_hash_entry *) h;
382fddef416Sniklas
383fddef416Sniklas f = new_fixup (info, h, value, ! IS_PLT_SYM (name));
384fddef416Sniklas if (f == NULL)
385d2201f2fSdrahn return FALSE;
386fddef416Sniklas f->jump = IS_PLT_SYM (name);
387fddef416Sniklas
388d2201f2fSdrahn return TRUE;
389fddef416Sniklas }
390fddef416Sniklas }
391fddef416Sniklas
392fddef416Sniklas /* Do the usual procedure for adding a symbol. */
393fddef416Sniklas if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,
394fddef416Sniklas value, string, copy, collect,
395fddef416Sniklas hashp))
396d2201f2fSdrahn return FALSE;
397fddef416Sniklas
398fddef416Sniklas /* Insert a pointer to our table in the set vector. The dynamic
399d2201f2fSdrahn linker requires this information. */
400fddef416Sniklas if (insert)
401fddef416Sniklas {
402fddef416Sniklas asection *s;
403fddef416Sniklas
404fddef416Sniklas /* Here we do our special thing to add the pointer to the
405fddef416Sniklas dynamic section in the SHARABLE_CONFLICTS set vector. */
406fddef416Sniklas s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
407fddef416Sniklas ".linux-dynamic");
408fddef416Sniklas BFD_ASSERT (s != NULL);
409fddef416Sniklas
410fddef416Sniklas if (! (_bfd_generic_link_add_one_symbol
411fddef416Sniklas (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS,
412d2201f2fSdrahn BSF_GLOBAL | BSF_CONSTRUCTOR, s, (bfd_vma) 0, NULL,
413d2201f2fSdrahn FALSE, FALSE, NULL)))
414d2201f2fSdrahn return FALSE;
415fddef416Sniklas }
416fddef416Sniklas
417d2201f2fSdrahn return TRUE;
418fddef416Sniklas }
419fddef416Sniklas
420fddef416Sniklas /* We will crawl the hash table and come here for every global symbol.
421fddef416Sniklas We will examine each entry and see if there are indications that we
422fddef416Sniklas need to add a fixup. There are two possible cases - one is where
423fddef416Sniklas you have duplicate definitions of PLT or GOT symbols - these will
424fddef416Sniklas have already been caught and added as "builtin" fixups. If we find
425fddef416Sniklas that the corresponding non PLT/GOT symbol is also present, we
426fddef416Sniklas convert it to a regular fixup instead.
427fddef416Sniklas
428fddef416Sniklas This function is called via linux_link_hash_traverse. */
429fddef416Sniklas
430d2201f2fSdrahn static bfd_boolean
linux_tally_symbols(h,data)431fddef416Sniklas linux_tally_symbols (h, data)
432fddef416Sniklas struct linux_link_hash_entry *h;
433fddef416Sniklas PTR data;
434fddef416Sniklas {
435fddef416Sniklas struct bfd_link_info *info = (struct bfd_link_info *) data;
436fddef416Sniklas struct fixup *f, *f1;
437fddef416Sniklas int is_plt;
438fddef416Sniklas struct linux_link_hash_entry *h1, *h2;
439d2201f2fSdrahn bfd_boolean exists;
440d2201f2fSdrahn
441d2201f2fSdrahn if (h->root.root.type == bfd_link_hash_warning)
442d2201f2fSdrahn h = (struct linux_link_hash_entry *) h->root.root.u.i.link;
443fddef416Sniklas
444fddef416Sniklas if (h->root.root.type == bfd_link_hash_undefined
445fddef416Sniklas && strncmp (h->root.root.root.string, NEEDS_SHRLIB,
446fddef416Sniklas sizeof NEEDS_SHRLIB - 1) == 0)
447fddef416Sniklas {
448fddef416Sniklas const char *name;
449fddef416Sniklas char *p;
450fddef416Sniklas char *alloc = NULL;
451fddef416Sniklas
452fddef416Sniklas name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1;
453fddef416Sniklas p = strrchr (name, '_');
454fddef416Sniklas if (p != NULL)
455d2201f2fSdrahn alloc = (char *) bfd_malloc ((bfd_size_type) strlen (name) + 1);
456fddef416Sniklas
457fddef416Sniklas if (p == NULL || alloc == NULL)
458f7cc78ecSespie (*_bfd_error_handler) (_("Output file requires shared library `%s'\n"),
459fddef416Sniklas name);
460fddef416Sniklas else
461fddef416Sniklas {
462fddef416Sniklas strcpy (alloc, name);
463fddef416Sniklas p = strrchr (alloc, '_');
464fddef416Sniklas *p++ = '\0';
465fddef416Sniklas (*_bfd_error_handler)
466f7cc78ecSespie (_("Output file requires shared library `%s.so.%s'\n"),
467fddef416Sniklas alloc, p);
468fddef416Sniklas free (alloc);
469fddef416Sniklas }
470fddef416Sniklas
471fddef416Sniklas abort ();
472fddef416Sniklas }
473fddef416Sniklas
474fddef416Sniklas /* If this symbol is not a PLT/GOT, we do not even need to look at
475fddef416Sniklas it. */
476fddef416Sniklas is_plt = IS_PLT_SYM (h->root.root.root.string);
477fddef416Sniklas
478fddef416Sniklas if (is_plt || IS_GOT_SYM (h->root.root.root.string))
479fddef416Sniklas {
480fddef416Sniklas /* Look up this symbol twice. Once just as a regular lookup,
481fddef416Sniklas and then again following all of the indirect links until we
482fddef416Sniklas reach a real symbol. */
483fddef416Sniklas h1 = linux_link_hash_lookup (linux_hash_table (info),
484fddef416Sniklas (h->root.root.root.string
485fddef416Sniklas + sizeof PLT_REF_PREFIX - 1),
486d2201f2fSdrahn FALSE, FALSE, TRUE);
487fddef416Sniklas /* h2 does not follow indirect symbols. */
488fddef416Sniklas h2 = linux_link_hash_lookup (linux_hash_table (info),
489fddef416Sniklas (h->root.root.root.string
490fddef416Sniklas + sizeof PLT_REF_PREFIX - 1),
491d2201f2fSdrahn FALSE, FALSE, FALSE);
492fddef416Sniklas
493fddef416Sniklas /* The real symbol must exist but if it is also an ABS symbol,
494fddef416Sniklas there is no need to have a fixup. This is because they both
495fddef416Sniklas came from the same library. If on the other hand, we had to
496fddef416Sniklas use an indirect symbol to get to the real symbol, we add the
497fddef416Sniklas fixup anyway, since there are cases where these symbols come
498fddef416Sniklas from different shared libraries */
499fddef416Sniklas if (h1 != NULL
500fddef416Sniklas && (((h1->root.root.type == bfd_link_hash_defined
501fddef416Sniklas || h1->root.root.type == bfd_link_hash_defweak)
502fddef416Sniklas && ! bfd_is_abs_section (h1->root.root.u.def.section))
503fddef416Sniklas || h2->root.root.type == bfd_link_hash_indirect))
504fddef416Sniklas {
505fddef416Sniklas /* See if there is a "builtin" fixup already present
506fddef416Sniklas involving this symbol. If so, convert it to a regular
507fddef416Sniklas fixup. In the end, this relaxes some of the requirements
508fddef416Sniklas about the order of performing fixups. */
509d2201f2fSdrahn exists = FALSE;
510fddef416Sniklas for (f1 = linux_hash_table (info)->fixup_list;
511fddef416Sniklas f1 != NULL;
512fddef416Sniklas f1 = f1->next)
513fddef416Sniklas {
514fddef416Sniklas if ((f1->h != h && f1->h != h1)
515fddef416Sniklas || (! f1->builtin && ! f1->jump))
516fddef416Sniklas continue;
517fddef416Sniklas if (f1->h == h1)
518d2201f2fSdrahn exists = TRUE;
519fddef416Sniklas if (! exists
520fddef416Sniklas && bfd_is_abs_section (h->root.root.u.def.section))
521fddef416Sniklas {
522fddef416Sniklas f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0);
523fddef416Sniklas f->jump = is_plt;
524fddef416Sniklas }
525fddef416Sniklas f1->h = h1;
526fddef416Sniklas f1->jump = is_plt;
527fddef416Sniklas f1->builtin = 0;
528d2201f2fSdrahn exists = TRUE;
529fddef416Sniklas }
530fddef416Sniklas if (! exists
531fddef416Sniklas && bfd_is_abs_section (h->root.root.u.def.section))
532fddef416Sniklas {
533fddef416Sniklas f = new_fixup (info, h1, h->root.root.u.def.value, 0);
534fddef416Sniklas if (f == NULL)
535fddef416Sniklas {
536fddef416Sniklas /* FIXME: No way to return error. */
537fddef416Sniklas abort ();
538fddef416Sniklas }
539fddef416Sniklas f->jump = is_plt;
540fddef416Sniklas }
541fddef416Sniklas }
542fddef416Sniklas
543fddef416Sniklas /* Quick and dirty way of stripping these symbols from the
544fddef416Sniklas symtab. */
545fddef416Sniklas if (bfd_is_abs_section (h->root.root.u.def.section))
546d2201f2fSdrahn h->root.written = TRUE;
547fddef416Sniklas }
548fddef416Sniklas
549d2201f2fSdrahn return TRUE;
550fddef416Sniklas }
551fddef416Sniklas
552fddef416Sniklas /* This is called to set the size of the .linux-dynamic section is.
553fddef416Sniklas It is called by the Linux linker emulation before_allocation
554fddef416Sniklas routine. We have finished reading all of the input files, and now
555fddef416Sniklas we just scan the hash tables to find out how many additional fixups
556fddef416Sniklas are required. */
557fddef416Sniklas
558d2201f2fSdrahn bfd_boolean
bfd_sparclinux_size_dynamic_sections(output_bfd,info)559fddef416Sniklas bfd_sparclinux_size_dynamic_sections (output_bfd, info)
560fddef416Sniklas bfd *output_bfd;
561fddef416Sniklas struct bfd_link_info *info;
562fddef416Sniklas {
563fddef416Sniklas struct fixup *f;
564fddef416Sniklas asection *s;
565fddef416Sniklas
566fddef416Sniklas if (output_bfd->xvec != &MY(vec))
567d2201f2fSdrahn return TRUE;
568fddef416Sniklas
569fddef416Sniklas /* First find the fixups... */
570fddef416Sniklas linux_link_hash_traverse (linux_hash_table (info),
571fddef416Sniklas linux_tally_symbols,
572fddef416Sniklas (PTR) info);
573fddef416Sniklas
574fddef416Sniklas /* If there are builtin fixups, leave room for a marker. This is
575fddef416Sniklas used by the dynamic linker so that it knows that all that follow
576fddef416Sniklas are builtin fixups instead of regular fixups. */
577fddef416Sniklas for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
578fddef416Sniklas {
579fddef416Sniklas if (f->builtin)
580fddef416Sniklas {
581fddef416Sniklas ++linux_hash_table (info)->fixup_count;
582fddef416Sniklas ++linux_hash_table (info)->local_builtins;
583fddef416Sniklas break;
584fddef416Sniklas }
585fddef416Sniklas }
586fddef416Sniklas
587fddef416Sniklas if (linux_hash_table (info)->dynobj == NULL)
588fddef416Sniklas {
589fddef416Sniklas if (linux_hash_table (info)->fixup_count > 0)
590fddef416Sniklas abort ();
591d2201f2fSdrahn return TRUE;
592fddef416Sniklas }
593fddef416Sniklas
594fddef416Sniklas /* Allocate memory for our fixup table. We will fill it in later. */
595fddef416Sniklas s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
596fddef416Sniklas ".linux-dynamic");
597fddef416Sniklas if (s != NULL)
598fddef416Sniklas {
599d2201f2fSdrahn s->_raw_size = linux_hash_table (info)->fixup_count + 1;
600d2201f2fSdrahn s->_raw_size *= 8;
601d2201f2fSdrahn s->contents = (bfd_byte *) bfd_zalloc (output_bfd, s->_raw_size);
602fddef416Sniklas if (s->contents == NULL)
603d2201f2fSdrahn return FALSE;
604fddef416Sniklas }
605fddef416Sniklas
606d2201f2fSdrahn return TRUE;
607fddef416Sniklas }
608fddef416Sniklas
609fddef416Sniklas /* We come here once we are ready to actually write the fixup table to
610fddef416Sniklas the output file. Scan the fixup tables and so forth and generate
611fddef416Sniklas the stuff we need. */
612fddef416Sniklas
613d2201f2fSdrahn static bfd_boolean
linux_finish_dynamic_link(output_bfd,info)614fddef416Sniklas linux_finish_dynamic_link (output_bfd, info)
615fddef416Sniklas bfd *output_bfd;
616fddef416Sniklas struct bfd_link_info *info;
617fddef416Sniklas {
618fddef416Sniklas asection *s, *os, *is;
619fddef416Sniklas bfd_byte *fixup_table;
620fddef416Sniklas struct linux_link_hash_entry *h;
621fddef416Sniklas struct fixup *f;
622fddef416Sniklas unsigned int new_addr;
623fddef416Sniklas int section_offset;
624fddef416Sniklas unsigned int fixups_written;
625fddef416Sniklas
626fddef416Sniklas if (linux_hash_table (info)->dynobj == NULL)
627d2201f2fSdrahn return TRUE;
628fddef416Sniklas
629fddef416Sniklas s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
630fddef416Sniklas ".linux-dynamic");
631fddef416Sniklas BFD_ASSERT (s != NULL);
632fddef416Sniklas os = s->output_section;
633fddef416Sniklas fixups_written = 0;
634fddef416Sniklas
635fddef416Sniklas #ifdef LINUX_LINK_DEBUG
636fddef416Sniklas printf ("Fixup table file offset: %x VMA: %x\n",
637fddef416Sniklas os->filepos + s->output_offset,
638fddef416Sniklas os->vma + s->output_offset);
639fddef416Sniklas #endif
640fddef416Sniklas
641fddef416Sniklas fixup_table = s->contents;
642d2201f2fSdrahn bfd_put_32 (output_bfd,
643d2201f2fSdrahn (bfd_vma) linux_hash_table (info)->fixup_count, fixup_table);
644fddef416Sniklas fixup_table += 4;
645fddef416Sniklas
646fddef416Sniklas /* Fill in fixup table. */
647fddef416Sniklas for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
648fddef416Sniklas {
649fddef416Sniklas if (f->builtin)
650fddef416Sniklas continue;
651fddef416Sniklas
652fddef416Sniklas if (f->h->root.root.type != bfd_link_hash_defined
653fddef416Sniklas && f->h->root.root.type != bfd_link_hash_defweak)
654fddef416Sniklas {
655fddef416Sniklas (*_bfd_error_handler)
656f7cc78ecSespie (_("Symbol %s not defined for fixups\n"),
657fddef416Sniklas f->h->root.root.root.string);
658fddef416Sniklas continue;
659fddef416Sniklas }
660fddef416Sniklas
661fddef416Sniklas is = f->h->root.root.u.def.section;
662fddef416Sniklas section_offset = is->output_section->vma + is->output_offset;
663fddef416Sniklas new_addr = f->h->root.root.u.def.value + section_offset;
664fddef416Sniklas
665fddef416Sniklas #ifdef LINUX_LINK_DEBUG
666fddef416Sniklas printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string,
667fddef416Sniklas new_addr, f->value);
668fddef416Sniklas #endif
669fddef416Sniklas
670fddef416Sniklas if (f->jump)
671fddef416Sniklas {
672fddef416Sniklas /* Relative address */
673fddef416Sniklas new_addr = new_addr - (f->value + 5);
674d2201f2fSdrahn bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
675fddef416Sniklas fixup_table += 4;
676fddef416Sniklas bfd_put_32 (output_bfd, f->value + 1, fixup_table);
677fddef416Sniklas fixup_table += 4;
678fddef416Sniklas }
679fddef416Sniklas else
680fddef416Sniklas {
681d2201f2fSdrahn bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
682fddef416Sniklas fixup_table += 4;
683fddef416Sniklas bfd_put_32 (output_bfd, f->value, fixup_table);
684fddef416Sniklas fixup_table += 4;
685fddef416Sniklas }
686fddef416Sniklas ++fixups_written;
687fddef416Sniklas }
688fddef416Sniklas
689fddef416Sniklas if (linux_hash_table (info)->local_builtins != 0)
690fddef416Sniklas {
691fddef416Sniklas /* Special marker so we know to switch to the other type of fixup */
692d2201f2fSdrahn bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
693fddef416Sniklas fixup_table += 4;
694d2201f2fSdrahn bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
695fddef416Sniklas fixup_table += 4;
696fddef416Sniklas ++fixups_written;
697fddef416Sniklas for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
698fddef416Sniklas {
699fddef416Sniklas if (! f->builtin)
700fddef416Sniklas continue;
701fddef416Sniklas
702fddef416Sniklas if (f->h->root.root.type != bfd_link_hash_defined
703fddef416Sniklas && f->h->root.root.type != bfd_link_hash_defweak)
704fddef416Sniklas {
705fddef416Sniklas (*_bfd_error_handler)
706f7cc78ecSespie (_("Symbol %s not defined for fixups\n"),
707fddef416Sniklas f->h->root.root.root.string);
708fddef416Sniklas continue;
709fddef416Sniklas }
710fddef416Sniklas
711fddef416Sniklas is = f->h->root.root.u.def.section;
712fddef416Sniklas section_offset = is->output_section->vma + is->output_offset;
713fddef416Sniklas new_addr = f->h->root.root.u.def.value + section_offset;
714fddef416Sniklas
715fddef416Sniklas #ifdef LINUX_LINK_DEBUG
716fddef416Sniklas printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string,
717fddef416Sniklas new_addr, f->value);
718fddef416Sniklas #endif
719fddef416Sniklas
720d2201f2fSdrahn bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
721fddef416Sniklas fixup_table += 4;
722fddef416Sniklas bfd_put_32 (output_bfd, f->value, fixup_table);
723fddef416Sniklas fixup_table += 4;
724fddef416Sniklas ++fixups_written;
725fddef416Sniklas }
726fddef416Sniklas }
727fddef416Sniklas
728fddef416Sniklas if (linux_hash_table (info)->fixup_count != fixups_written)
729fddef416Sniklas {
730f7cc78ecSespie (*_bfd_error_handler) (_("Warning: fixup count mismatch\n"));
731fddef416Sniklas while (linux_hash_table (info)->fixup_count > fixups_written)
732fddef416Sniklas {
733d2201f2fSdrahn bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
734fddef416Sniklas fixup_table += 4;
735d2201f2fSdrahn bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
736fddef416Sniklas fixup_table += 4;
737fddef416Sniklas ++fixups_written;
738fddef416Sniklas }
739fddef416Sniklas }
740fddef416Sniklas
741fddef416Sniklas h = linux_link_hash_lookup (linux_hash_table (info),
742fddef416Sniklas "__BUILTIN_FIXUPS__",
743d2201f2fSdrahn FALSE, FALSE, FALSE);
744fddef416Sniklas
745fddef416Sniklas if (h != NULL
746fddef416Sniklas && (h->root.root.type == bfd_link_hash_defined
747fddef416Sniklas || h->root.root.type == bfd_link_hash_defweak))
748fddef416Sniklas {
749fddef416Sniklas is = h->root.root.u.def.section;
750fddef416Sniklas section_offset = is->output_section->vma + is->output_offset;
751fddef416Sniklas new_addr = h->root.root.u.def.value + section_offset;
752fddef416Sniklas
753fddef416Sniklas #ifdef LINUX_LINK_DEBUG
754fddef416Sniklas printf ("Builtin fixup table at %x\n", new_addr);
755fddef416Sniklas #endif
756fddef416Sniklas
757d2201f2fSdrahn bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
758fddef416Sniklas }
759fddef416Sniklas else
760d2201f2fSdrahn bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
761fddef416Sniklas
762d2201f2fSdrahn if (bfd_seek (output_bfd, (file_ptr) (os->filepos + s->output_offset),
763d2201f2fSdrahn SEEK_SET) != 0)
764d2201f2fSdrahn return FALSE;
765fddef416Sniklas
766d2201f2fSdrahn if (bfd_bwrite ((PTR) s->contents, s->_raw_size, output_bfd) != s->_raw_size)
767d2201f2fSdrahn return FALSE;
768fddef416Sniklas
769d2201f2fSdrahn return TRUE;
770fddef416Sniklas }
771fddef416Sniklas
772fddef416Sniklas #define MY_bfd_link_hash_table_create linux_link_hash_table_create
773fddef416Sniklas #define MY_add_one_symbol linux_add_one_symbol
774fddef416Sniklas #define MY_finish_dynamic_link linux_finish_dynamic_link
775fddef416Sniklas
776fddef416Sniklas #define MY_zmagic_contiguous 1
777fddef416Sniklas
778fddef416Sniklas #include "aout-target.h"
779