1 |
/* MIPS-specific support for ELF |
/* MIPS-specific support for ELF |
2 |
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 |
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, |
3 |
Free Software Foundation, Inc. |
2003, 2004, 2005 Free Software Foundation, Inc. |
4 |
|
|
5 |
Most of the information added by Ian Lance Taylor, Cygnus Support, |
Most of the information added by Ian Lance Taylor, Cygnus Support, |
6 |
<ian@cygnus.com>. |
<ian@cygnus.com>. |
9 |
Traditional MIPS targets support added by Koundinya.K, Dansk Data |
Traditional MIPS targets support added by Koundinya.K, Dansk Data |
10 |
Elektronik & Operations Research Group. <kk@ddeorg.soft.net> |
Elektronik & Operations Research Group. <kk@ddeorg.soft.net> |
11 |
|
|
12 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
13 |
|
|
14 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
15 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
16 |
the Free Software Foundation; either version 2 of the License, or |
the Free Software Foundation; either version 2 of the License, or |
17 |
(at your option) any later version. |
(at your option) any later version. |
18 |
|
|
19 |
This program is distributed in the hope that it will be useful, |
This program is distributed in the hope that it will be useful, |
20 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22 |
GNU General Public License for more details. |
GNU General Public License for more details. |
23 |
|
|
24 |
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
25 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
26 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
27 |
|
|
28 |
/* This file handles functionality common to the different MIPS ABI's. */ |
/* This file handles functionality common to the different MIPS ABI's. */ |
29 |
|
|
30 |
#include "bfd.h" |
#include "bfd.h" |
31 |
#include "sysdep.h" |
#include "sysdep.h" |
32 |
#include "libbfd.h" |
#include "libbfd.h" |
33 |
|
#include "libiberty.h" |
34 |
#include "elf-bfd.h" |
#include "elf-bfd.h" |
35 |
#include "elfxx-mips.h" |
#include "elfxx-mips.h" |
36 |
#include "elf/mips.h" |
#include "elf/mips.h" |
41 |
#include "coff/ecoff.h" |
#include "coff/ecoff.h" |
42 |
#include "coff/mips.h" |
#include "coff/mips.h" |
43 |
|
|
44 |
/* This structure is used to hold .got information when linking. It |
#include "hashtab.h" |
45 |
is stored in the tdata field of the bfd_elf_section_data structure. */ |
|
46 |
|
/* This structure is used to hold .got entries while estimating got |
47 |
|
sizes. */ |
48 |
|
struct mips_got_entry |
49 |
|
{ |
50 |
|
/* The input bfd in which the symbol is defined. */ |
51 |
|
bfd *abfd; |
52 |
|
/* The index of the symbol, as stored in the relocation r_info, if |
53 |
|
we have a local symbol; -1 otherwise. */ |
54 |
|
long symndx; |
55 |
|
union |
56 |
|
{ |
57 |
|
/* If abfd == NULL, an address that must be stored in the got. */ |
58 |
|
bfd_vma address; |
59 |
|
/* If abfd != NULL && symndx != -1, the addend of the relocation |
60 |
|
that should be added to the symbol value. */ |
61 |
|
bfd_vma addend; |
62 |
|
/* If abfd != NULL && symndx == -1, the hash table entry |
63 |
|
corresponding to a global symbol in the got (or, local, if |
64 |
|
h->forced_local). */ |
65 |
|
struct mips_elf_link_hash_entry *h; |
66 |
|
} d; |
67 |
|
|
68 |
|
/* The TLS types included in this GOT entry (specifically, GD and |
69 |
|
IE). The GD and IE flags can be added as we encounter new |
70 |
|
relocations. LDM can also be set; it will always be alone, not |
71 |
|
combined with any GD or IE flags. An LDM GOT entry will be |
72 |
|
a local symbol entry with r_symndx == 0. */ |
73 |
|
unsigned char tls_type; |
74 |
|
|
75 |
|
/* The offset from the beginning of the .got section to the entry |
76 |
|
corresponding to this symbol+addend. If it's a global symbol |
77 |
|
whose offset is yet to be decided, it's going to be -1. */ |
78 |
|
long gotidx; |
79 |
|
}; |
80 |
|
|
81 |
|
/* This structure is used to hold .got information when linking. */ |
82 |
|
|
83 |
struct mips_got_info |
struct mips_got_info |
84 |
{ |
{ |
87 |
struct elf_link_hash_entry *global_gotsym; |
struct elf_link_hash_entry *global_gotsym; |
88 |
/* The number of global .got entries. */ |
/* The number of global .got entries. */ |
89 |
unsigned int global_gotno; |
unsigned int global_gotno; |
90 |
|
/* The number of .got slots used for TLS. */ |
91 |
|
unsigned int tls_gotno; |
92 |
|
/* The first unused TLS .got entry. Used only during |
93 |
|
mips_elf_initialize_tls_index. */ |
94 |
|
unsigned int tls_assigned_gotno; |
95 |
/* The number of local .got entries. */ |
/* The number of local .got entries. */ |
96 |
unsigned int local_gotno; |
unsigned int local_gotno; |
97 |
/* The number of local .got entries we have used. */ |
/* The number of local .got entries we have used. */ |
98 |
unsigned int assigned_gotno; |
unsigned int assigned_gotno; |
99 |
|
/* A hash table holding members of the got. */ |
100 |
|
struct htab *got_entries; |
101 |
|
/* A hash table mapping input bfds to other mips_got_info. NULL |
102 |
|
unless multi-got was necessary. */ |
103 |
|
struct htab *bfd2got; |
104 |
|
/* In multi-got links, a pointer to the next got (err, rather, most |
105 |
|
of the time, it points to the previous got). */ |
106 |
|
struct mips_got_info *next; |
107 |
|
/* This is the GOT index of the TLS LDM entry for the GOT, MINUS_ONE |
108 |
|
for none, or MINUS_TWO for not yet assigned. This is needed |
109 |
|
because a single-GOT link may have multiple hash table entries |
110 |
|
for the LDM. It does not get initialized in multi-GOT mode. */ |
111 |
|
bfd_vma tls_ldm_offset; |
112 |
|
}; |
113 |
|
|
114 |
|
/* Map an input bfd to a got in a multi-got link. */ |
115 |
|
|
116 |
|
struct mips_elf_bfd2got_hash { |
117 |
|
bfd *bfd; |
118 |
|
struct mips_got_info *g; |
119 |
|
}; |
120 |
|
|
121 |
|
/* Structure passed when traversing the bfd2got hash table, used to |
122 |
|
create and merge bfd's gots. */ |
123 |
|
|
124 |
|
struct mips_elf_got_per_bfd_arg |
125 |
|
{ |
126 |
|
/* A hashtable that maps bfds to gots. */ |
127 |
|
htab_t bfd2got; |
128 |
|
/* The output bfd. */ |
129 |
|
bfd *obfd; |
130 |
|
/* The link information. */ |
131 |
|
struct bfd_link_info *info; |
132 |
|
/* A pointer to the primary got, i.e., the one that's going to get |
133 |
|
the implicit relocations from DT_MIPS_LOCAL_GOTNO and |
134 |
|
DT_MIPS_GOTSYM. */ |
135 |
|
struct mips_got_info *primary; |
136 |
|
/* A non-primary got we're trying to merge with other input bfd's |
137 |
|
gots. */ |
138 |
|
struct mips_got_info *current; |
139 |
|
/* The maximum number of got entries that can be addressed with a |
140 |
|
16-bit offset. */ |
141 |
|
unsigned int max_count; |
142 |
|
/* The number of local and global entries in the primary got. */ |
143 |
|
unsigned int primary_count; |
144 |
|
/* The number of local and global entries in the current got. */ |
145 |
|
unsigned int current_count; |
146 |
|
/* The total number of global entries which will live in the |
147 |
|
primary got and be automatically relocated. This includes |
148 |
|
those not referenced by the primary GOT but included in |
149 |
|
the "master" GOT. */ |
150 |
|
unsigned int global_count; |
151 |
|
}; |
152 |
|
|
153 |
|
/* Another structure used to pass arguments for got entries traversal. */ |
154 |
|
|
155 |
|
struct mips_elf_set_global_got_offset_arg |
156 |
|
{ |
157 |
|
struct mips_got_info *g; |
158 |
|
int value; |
159 |
|
unsigned int needed_relocs; |
160 |
|
struct bfd_link_info *info; |
161 |
|
}; |
162 |
|
|
163 |
|
/* A structure used to count TLS relocations or GOT entries, for GOT |
164 |
|
entry or ELF symbol table traversal. */ |
165 |
|
|
166 |
|
struct mips_elf_count_tls_arg |
167 |
|
{ |
168 |
|
struct bfd_link_info *info; |
169 |
|
unsigned int needed; |
170 |
|
}; |
171 |
|
|
172 |
|
struct _mips_elf_section_data |
173 |
|
{ |
174 |
|
struct bfd_elf_section_data elf; |
175 |
|
union |
176 |
|
{ |
177 |
|
struct mips_got_info *got_info; |
178 |
|
bfd_byte *tdata; |
179 |
|
} u; |
180 |
}; |
}; |
181 |
|
|
182 |
|
#define mips_elf_section_data(sec) \ |
183 |
|
((struct _mips_elf_section_data *) elf_section_data (sec)) |
184 |
|
|
185 |
/* This structure is passed to mips_elf_sort_hash_table_f when sorting |
/* This structure is passed to mips_elf_sort_hash_table_f when sorting |
186 |
the dynamic symbols. */ |
the dynamic symbols. */ |
187 |
|
|
190 |
/* The symbol in the global GOT with the lowest dynamic symbol table |
/* The symbol in the global GOT with the lowest dynamic symbol table |
191 |
index. */ |
index. */ |
192 |
struct elf_link_hash_entry *low; |
struct elf_link_hash_entry *low; |
193 |
/* The least dynamic symbol table index corresponding to a symbol |
/* The least dynamic symbol table index corresponding to a non-TLS |
194 |
with a GOT entry. */ |
symbol with a GOT entry. */ |
195 |
long min_got_dynindx; |
long min_got_dynindx; |
196 |
|
/* The greatest dynamic symbol table index corresponding to a symbol |
197 |
|
with a GOT entry that is not referenced (e.g., a dynamic symbol |
198 |
|
with dynamic relocations pointing to it from non-primary GOTs). */ |
199 |
|
long max_unref_got_dynindx; |
200 |
/* The greatest dynamic symbol table index not corresponding to a |
/* The greatest dynamic symbol table index not corresponding to a |
201 |
symbol without a GOT entry. */ |
symbol without a GOT entry. */ |
202 |
long max_non_got_dynindx; |
long max_non_got_dynindx; |
218 |
|
|
219 |
/* If the R_MIPS_32, R_MIPS_REL32, or R_MIPS_64 reloc is against |
/* If the R_MIPS_32, R_MIPS_REL32, or R_MIPS_64 reloc is against |
220 |
a readonly section. */ |
a readonly section. */ |
221 |
boolean readonly_reloc; |
bfd_boolean readonly_reloc; |
|
|
|
|
/* The index of the first dynamic relocation (in the .rel.dyn |
|
|
section) against this symbol. */ |
|
|
unsigned int min_dyn_reloc_index; |
|
222 |
|
|
223 |
/* We must not create a stub for a symbol that has relocations |
/* We must not create a stub for a symbol that has relocations |
224 |
related to taking the function's address, i.e. any but |
related to taking the function's address, i.e. any but |
225 |
R_MIPS_CALL*16 ones -- see "MIPS ABI Supplement, 3rd Edition", |
R_MIPS_CALL*16 ones -- see "MIPS ABI Supplement, 3rd Edition", |
226 |
p. 4-20. */ |
p. 4-20. */ |
227 |
boolean no_fn_stub; |
bfd_boolean no_fn_stub; |
228 |
|
|
229 |
/* If there is a stub that 32 bit functions should use to call this |
/* If there is a stub that 32 bit functions should use to call this |
230 |
16 bit function, this points to the section containing the stub. */ |
16 bit function, this points to the section containing the stub. */ |
232 |
|
|
233 |
/* Whether we need the fn_stub; this is set if this symbol appears |
/* Whether we need the fn_stub; this is set if this symbol appears |
234 |
in any relocs other than a 16 bit call. */ |
in any relocs other than a 16 bit call. */ |
235 |
boolean need_fn_stub; |
bfd_boolean need_fn_stub; |
236 |
|
|
237 |
/* If there is a stub that 16 bit functions should use to call this |
/* If there is a stub that 16 bit functions should use to call this |
238 |
32 bit function, this points to the section containing the stub. */ |
32 bit function, this points to the section containing the stub. */ |
242 |
being called returns a floating point value. */ |
being called returns a floating point value. */ |
243 |
asection *call_fp_stub; |
asection *call_fp_stub; |
244 |
|
|
245 |
/* Are we forced local? .*/ |
/* Are we forced local? This will only be set if we have converted |
246 |
boolean forced_local; |
the initial global GOT entry to a local GOT entry. */ |
247 |
|
bfd_boolean forced_local; |
248 |
|
|
249 |
|
#define GOT_NORMAL 0 |
250 |
|
#define GOT_TLS_GD 1 |
251 |
|
#define GOT_TLS_LDM 2 |
252 |
|
#define GOT_TLS_IE 4 |
253 |
|
#define GOT_TLS_OFFSET_DONE 0x40 |
254 |
|
#define GOT_TLS_DONE 0x80 |
255 |
|
unsigned char tls_type; |
256 |
|
/* This is only used in single-GOT mode; in multi-GOT mode there |
257 |
|
is one mips_got_entry per GOT entry, so the offset is stored |
258 |
|
there. In single-GOT mode there may be many mips_got_entry |
259 |
|
structures all referring to the same GOT slot. It might be |
260 |
|
possible to use root.got.offset instead, but that field is |
261 |
|
overloaded already. */ |
262 |
|
bfd_vma tls_got_offset; |
263 |
}; |
}; |
264 |
|
|
265 |
/* MIPS ELF linker hash table. */ |
/* MIPS ELF linker hash table. */ |
278 |
bfd_size_type compact_rel_size; |
bfd_size_type compact_rel_size; |
279 |
/* This flag indicates that the value of DT_MIPS_RLD_MAP dynamic |
/* This flag indicates that the value of DT_MIPS_RLD_MAP dynamic |
280 |
entry is set to the address of __rld_obj_head as in IRIX5. */ |
entry is set to the address of __rld_obj_head as in IRIX5. */ |
281 |
boolean use_rld_obj_head; |
bfd_boolean use_rld_obj_head; |
282 |
/* This is the value of the __rld_map or __rld_obj_head symbol. */ |
/* This is the value of the __rld_map or __rld_obj_head symbol. */ |
283 |
bfd_vma rld_value; |
bfd_vma rld_value; |
284 |
/* This is set if we see any mips16 stub sections. */ |
/* This is set if we see any mips16 stub sections. */ |
285 |
boolean mips16_stubs_seen; |
bfd_boolean mips16_stubs_seen; |
286 |
}; |
}; |
287 |
|
|
288 |
|
#define TLS_RELOC_P(r_type) \ |
289 |
|
(r_type == R_MIPS_TLS_DTPMOD32 \ |
290 |
|
|| r_type == R_MIPS_TLS_DTPMOD64 \ |
291 |
|
|| r_type == R_MIPS_TLS_DTPREL32 \ |
292 |
|
|| r_type == R_MIPS_TLS_DTPREL64 \ |
293 |
|
|| r_type == R_MIPS_TLS_GD \ |
294 |
|
|| r_type == R_MIPS_TLS_LDM \ |
295 |
|
|| r_type == R_MIPS_TLS_DTPREL_HI16 \ |
296 |
|
|| r_type == R_MIPS_TLS_DTPREL_LO16 \ |
297 |
|
|| r_type == R_MIPS_TLS_GOTTPREL \ |
298 |
|
|| r_type == R_MIPS_TLS_TPREL32 \ |
299 |
|
|| r_type == R_MIPS_TLS_TPREL64 \ |
300 |
|
|| r_type == R_MIPS_TLS_TPREL_HI16 \ |
301 |
|
|| r_type == R_MIPS_TLS_TPREL_LO16) |
302 |
|
|
303 |
/* Structure used to pass information to mips_elf_output_extsym. */ |
/* Structure used to pass information to mips_elf_output_extsym. */ |
304 |
|
|
305 |
struct extsym_info |
struct extsym_info |
308 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
309 |
struct ecoff_debug_info *debug; |
struct ecoff_debug_info *debug; |
310 |
const struct ecoff_debug_swap *swap; |
const struct ecoff_debug_swap *swap; |
311 |
boolean failed; |
bfd_boolean failed; |
312 |
}; |
}; |
313 |
|
|
314 |
/* The names of the runtime procedure table symbols used on IRIX5. */ |
/* The names of the runtime procedure table symbols used on IRIX5. */ |
417 |
loader for use by the static exception system. */ |
loader for use by the static exception system. */ |
418 |
|
|
419 |
typedef struct runtime_pdr { |
typedef struct runtime_pdr { |
420 |
bfd_vma adr; /* memory address of start of procedure */ |
bfd_vma adr; /* Memory address of start of procedure. */ |
421 |
long regmask; /* save register mask */ |
long regmask; /* Save register mask. */ |
422 |
long regoffset; /* save register offset */ |
long regoffset; /* Save register offset. */ |
423 |
long fregmask; /* save floating point register mask */ |
long fregmask; /* Save floating point register mask. */ |
424 |
long fregoffset; /* save floating point register offset */ |
long fregoffset; /* Save floating point register offset. */ |
425 |
long frameoffset; /* frame size */ |
long frameoffset; /* Frame size. */ |
426 |
short framereg; /* frame pointer register */ |
short framereg; /* Frame pointer register. */ |
427 |
short pcreg; /* offset or reg of return pc */ |
short pcreg; /* Offset or reg of return pc. */ |
428 |
long irpss; /* index into the runtime string table */ |
long irpss; /* Index into the runtime string table. */ |
429 |
long reserved; |
long reserved; |
430 |
struct exception_info *exception_info;/* pointer to exception array */ |
struct exception_info *exception_info;/* Pointer to exception array. */ |
431 |
} RPDR, *pRPDR; |
} RPDR, *pRPDR; |
432 |
#define cbRPDR sizeof (RPDR) |
#define cbRPDR sizeof (RPDR) |
433 |
#define rpdNil ((pRPDR) 0) |
#define rpdNil ((pRPDR) 0) |
434 |
|
|
435 |
static struct bfd_hash_entry *mips_elf_link_hash_newfunc |
static struct mips_got_entry *mips_elf_create_local_got_entry |
436 |
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); |
(bfd *, bfd *, struct mips_got_info *, asection *, bfd_vma, unsigned long, |
437 |
static void ecoff_swap_rpdr_out |
struct mips_elf_link_hash_entry *, int); |
438 |
PARAMS ((bfd *, const RPDR *, struct rpdr_ext *)); |
static bfd_boolean mips_elf_sort_hash_table_f |
439 |
static boolean mips_elf_create_procedure_table |
(struct mips_elf_link_hash_entry *, void *); |
440 |
PARAMS ((PTR, bfd *, struct bfd_link_info *, asection *, |
static bfd_vma mips_elf_high |
441 |
struct ecoff_debug_info *)); |
(bfd_vma); |
442 |
static boolean mips_elf_check_mips16_stubs |
static bfd_boolean mips_elf_stub_section_p |
443 |
PARAMS ((struct mips_elf_link_hash_entry *, PTR)); |
(bfd *, asection *); |
444 |
static void bfd_mips_elf32_swap_gptab_in |
static bfd_boolean mips_elf_create_dynamic_relocation |
445 |
PARAMS ((bfd *, const Elf32_External_gptab *, Elf32_gptab *)); |
(bfd *, struct bfd_link_info *, const Elf_Internal_Rela *, |
446 |
static void bfd_mips_elf32_swap_gptab_out |
struct mips_elf_link_hash_entry *, asection *, bfd_vma, |
447 |
PARAMS ((bfd *, const Elf32_gptab *, Elf32_External_gptab *)); |
bfd_vma *, asection *); |
448 |
static void bfd_elf32_swap_compact_rel_out |
static hashval_t mips_elf_got_entry_hash |
449 |
PARAMS ((bfd *, const Elf32_compact_rel *, Elf32_External_compact_rel *)); |
(const void *); |
450 |
static void bfd_elf32_swap_crinfo_out |
static bfd_vma mips_elf_adjust_gp |
451 |
PARAMS ((bfd *, const Elf32_crinfo *, Elf32_External_crinfo *)); |
(bfd *, struct mips_got_info *, bfd *); |
452 |
#if 0 |
static struct mips_got_info *mips_elf_got_for_ibfd |
453 |
static void bfd_mips_elf_swap_msym_in |
(struct mips_got_info *, bfd *); |
|
PARAMS ((bfd *, const Elf32_External_Msym *, Elf32_Internal_Msym *)); |
|
|
#endif |
|
|
static void bfd_mips_elf_swap_msym_out |
|
|
PARAMS ((bfd *, const Elf32_Internal_Msym *, Elf32_External_Msym *)); |
|
|
static int sort_dynamic_relocs |
|
|
PARAMS ((const void *, const void *)); |
|
|
static boolean mips_elf_output_extsym |
|
|
PARAMS ((struct mips_elf_link_hash_entry *, PTR)); |
|
|
static int gptab_compare PARAMS ((const void *, const void *)); |
|
|
static asection * mips_elf_got_section PARAMS ((bfd *)); |
|
|
static struct mips_got_info *mips_elf_got_info |
|
|
PARAMS ((bfd *, asection **)); |
|
|
static bfd_vma mips_elf_local_got_index |
|
|
PARAMS ((bfd *, struct bfd_link_info *, bfd_vma)); |
|
|
static bfd_vma mips_elf_global_got_index |
|
|
PARAMS ((bfd *, struct elf_link_hash_entry *)); |
|
|
static bfd_vma mips_elf_got_page |
|
|
PARAMS ((bfd *, struct bfd_link_info *, bfd_vma, bfd_vma *)); |
|
|
static bfd_vma mips_elf_got16_entry |
|
|
PARAMS ((bfd *, struct bfd_link_info *, bfd_vma, boolean)); |
|
|
static bfd_vma mips_elf_got_offset_from_index |
|
|
PARAMS ((bfd *, bfd *, bfd_vma)); |
|
|
static bfd_vma mips_elf_create_local_got_entry |
|
|
PARAMS ((bfd *, struct mips_got_info *, asection *, bfd_vma)); |
|
|
static boolean mips_elf_sort_hash_table |
|
|
PARAMS ((struct bfd_link_info *, unsigned long)); |
|
|
static boolean mips_elf_sort_hash_table_f |
|
|
PARAMS ((struct mips_elf_link_hash_entry *, PTR)); |
|
|
static boolean mips_elf_record_global_got_symbol |
|
|
PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *, |
|
|
struct mips_got_info *)); |
|
|
static const Elf_Internal_Rela *mips_elf_next_relocation |
|
|
PARAMS ((bfd *, unsigned int, const Elf_Internal_Rela *, |
|
|
const Elf_Internal_Rela *)); |
|
|
static boolean mips_elf_local_relocation_p |
|
|
PARAMS ((bfd *, const Elf_Internal_Rela *, asection **, boolean)); |
|
|
static bfd_vma mips_elf_sign_extend PARAMS ((bfd_vma, int)); |
|
|
static boolean mips_elf_overflow_p PARAMS ((bfd_vma, int)); |
|
|
static bfd_vma mips_elf_high PARAMS ((bfd_vma)); |
|
|
static bfd_vma mips_elf_higher PARAMS ((bfd_vma)); |
|
|
static bfd_vma mips_elf_highest PARAMS ((bfd_vma)); |
|
|
static boolean mips_elf_create_compact_rel_section |
|
|
PARAMS ((bfd *, struct bfd_link_info *)); |
|
|
static boolean mips_elf_create_got_section |
|
|
PARAMS ((bfd *, struct bfd_link_info *)); |
|
|
static asection *mips_elf_create_msym_section |
|
|
PARAMS ((bfd *)); |
|
|
static bfd_reloc_status_type mips_elf_calculate_relocation |
|
|
PARAMS ((bfd *, bfd *, asection *, struct bfd_link_info *, |
|
|
const Elf_Internal_Rela *, bfd_vma, reloc_howto_type *, |
|
|
Elf_Internal_Sym *, asection **, bfd_vma *, const char **, |
|
|
boolean *)); |
|
|
static bfd_vma mips_elf_obtain_contents |
|
|
PARAMS ((reloc_howto_type *, const Elf_Internal_Rela *, bfd *, bfd_byte *)); |
|
|
static boolean mips_elf_perform_relocation |
|
|
PARAMS ((struct bfd_link_info *, reloc_howto_type *, |
|
|
const Elf_Internal_Rela *, bfd_vma, bfd *, asection *, bfd_byte *, |
|
|
boolean)); |
|
|
static boolean mips_elf_stub_section_p |
|
|
PARAMS ((bfd *, asection *)); |
|
|
static void mips_elf_allocate_dynamic_relocations |
|
|
PARAMS ((bfd *, unsigned int)); |
|
|
static boolean mips_elf_create_dynamic_relocation |
|
|
PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Rela *, |
|
|
struct mips_elf_link_hash_entry *, asection *, |
|
|
bfd_vma, bfd_vma *, asection *)); |
|
|
static INLINE int elf_mips_isa PARAMS ((flagword)); |
|
|
static INLINE char* elf_mips_abi_name PARAMS ((bfd *)); |
|
|
static void mips_elf_irix6_finish_dynamic_symbol |
|
|
PARAMS ((bfd *, const char *, Elf_Internal_Sym *)); |
|
454 |
|
|
455 |
/* This will be used when we sort the dynamic relocation records. */ |
/* This will be used when we sort the dynamic relocation records. */ |
456 |
static bfd *reldyn_sorting_bfd; |
static bfd *reldyn_sorting_bfd; |
462 |
|
|
463 |
/* Nonzero if ABFD is using the N64 ABI. */ |
/* Nonzero if ABFD is using the N64 ABI. */ |
464 |
#define ABI_64_P(abfd) \ |
#define ABI_64_P(abfd) \ |
465 |
((get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64) != 0) |
(get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64) |
466 |
|
|
467 |
/* Nonzero if ABFD is using NewABI conventions. */ |
/* Nonzero if ABFD is using NewABI conventions. */ |
468 |
#define NEWABI_P(abfd) (ABI_N32_P (abfd) || ABI_64_P (abfd)) |
#define NEWABI_P(abfd) (ABI_N32_P (abfd) || ABI_64_P (abfd)) |
477 |
|
|
478 |
/* The name of the options section. */ |
/* The name of the options section. */ |
479 |
#define MIPS_ELF_OPTIONS_SECTION_NAME(abfd) \ |
#define MIPS_ELF_OPTIONS_SECTION_NAME(abfd) \ |
480 |
(ABI_64_P (abfd) ? ".MIPS.options" : ".options") |
(NEWABI_P (abfd) ? ".MIPS.options" : ".options") |
481 |
|
|
482 |
|
/* True if NAME is the recognized name of any SHT_MIPS_OPTIONS section. |
483 |
|
Some IRIX system files do not use MIPS_ELF_OPTIONS_SECTION_NAME. */ |
484 |
|
#define MIPS_ELF_OPTIONS_SECTION_NAME_P(NAME) \ |
485 |
|
(strcmp (NAME, ".MIPS.options") == 0 || strcmp (NAME, ".options") == 0) |
486 |
|
|
487 |
/* The name of the stub section. */ |
/* The name of the stub section. */ |
488 |
#define MIPS_ELF_STUB_SECTION_NAME(abfd) \ |
#define MIPS_ELF_STUB_SECTION_NAME(abfd) ".MIPS.stubs" |
|
(ABI_64_P (abfd) ? ".MIPS.stubs" : ".stub") |
|
489 |
|
|
490 |
/* The size of an external REL relocation. */ |
/* The size of an external REL relocation. */ |
491 |
#define MIPS_ELF_REL_SIZE(abfd) \ |
#define MIPS_ELF_REL_SIZE(abfd) \ |
505 |
|
|
506 |
/* The default alignment for sections, as a power of two. */ |
/* The default alignment for sections, as a power of two. */ |
507 |
#define MIPS_ELF_LOG_FILE_ALIGN(abfd) \ |
#define MIPS_ELF_LOG_FILE_ALIGN(abfd) \ |
508 |
(get_elf_backend_data (abfd)->s->file_align == 8 ? 3 : 2) |
(get_elf_backend_data (abfd)->s->log_file_align) |
509 |
|
|
510 |
/* Get word-sized data. */ |
/* Get word-sized data. */ |
511 |
#define MIPS_ELF_GET_WORD(abfd, ptr) \ |
#define MIPS_ELF_GET_WORD(abfd, ptr) \ |
518 |
: bfd_put_32 (abfd, val, ptr)) |
: bfd_put_32 (abfd, val, ptr)) |
519 |
|
|
520 |
/* Add a dynamic symbol table-entry. */ |
/* Add a dynamic symbol table-entry. */ |
521 |
#ifdef BFD64 |
#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \ |
522 |
#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \ |
_bfd_elf_add_dynamic_entry (info, tag, val) |
|
(ABI_64_P (elf_hash_table (info)->dynobj) \ |
|
|
? bfd_elf64_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val) \ |
|
|
: bfd_elf32_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val)) |
|
|
#else |
|
|
#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \ |
|
|
(ABI_64_P (elf_hash_table (info)->dynobj) \ |
|
|
? (boolean) (abort (), false) \ |
|
|
: bfd_elf32_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val)) |
|
|
#endif |
|
523 |
|
|
524 |
#define MIPS_ELF_RTYPE_TO_HOWTO(abfd, rtype, rela) \ |
#define MIPS_ELF_RTYPE_TO_HOWTO(abfd, rtype, rela) \ |
525 |
(get_elf_backend_data (abfd)->elf_backend_mips_rtype_to_howto (rtype, rela)) |
(get_elf_backend_data (abfd)->elf_backend_mips_rtype_to_howto (rtype, rela)) |
526 |
|
|
527 |
|
/* Determine whether the internal relocation of index REL_IDX is REL |
528 |
|
(zero) or RELA (non-zero). The assumption is that, if there are |
529 |
|
two relocation sections for this section, one of them is REL and |
530 |
|
the other is RELA. If the index of the relocation we're testing is |
531 |
|
in range for the first relocation section, check that the external |
532 |
|
relocation size is that for RELA. It is also assumed that, if |
533 |
|
rel_idx is not in range for the first section, and this first |
534 |
|
section contains REL relocs, then the relocation is in the second |
535 |
|
section, that is RELA. */ |
536 |
|
#define MIPS_RELOC_RELA_P(abfd, sec, rel_idx) \ |
537 |
|
((NUM_SHDR_ENTRIES (&elf_section_data (sec)->rel_hdr) \ |
538 |
|
* get_elf_backend_data (abfd)->s->int_rels_per_ext_rel \ |
539 |
|
> (bfd_vma)(rel_idx)) \ |
540 |
|
== (elf_section_data (sec)->rel_hdr.sh_entsize \ |
541 |
|
== (ABI_64_P (abfd) ? sizeof (Elf64_External_Rela) \ |
542 |
|
: sizeof (Elf32_External_Rela)))) |
543 |
|
|
544 |
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value |
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value |
545 |
from smaller values. Start with zero, widen, *then* decrement. */ |
from smaller values. Start with zero, widen, *then* decrement. */ |
546 |
#define MINUS_ONE (((bfd_vma)0) - 1) |
#define MINUS_ONE (((bfd_vma)0) - 1) |
547 |
|
#define MINUS_TWO (((bfd_vma)0) - 2) |
548 |
|
|
549 |
/* The number of local .got entries we reserve. */ |
/* The number of local .got entries we reserve. */ |
550 |
#define MIPS_RESERVED_GOTNO (2) |
#define MIPS_RESERVED_GOTNO (2) |
551 |
|
|
552 |
/* Instructions which appear in a stub. For some reason the stub is |
/* The offset of $gp from the beginning of the .got section. */ |
553 |
slightly different on an SGI system. */ |
#define ELF_MIPS_GP_OFFSET(abfd) (0x7ff0) |
554 |
#define ELF_MIPS_GP_OFFSET(abfd) (SGI_COMPAT (abfd) ? 0x7ff0 : 0x8000) |
|
555 |
|
/* The maximum size of the GOT for it to be addressable using 16-bit |
556 |
|
offsets from $gp. */ |
557 |
|
#define MIPS_ELF_GOT_MAX_SIZE(abfd) (ELF_MIPS_GP_OFFSET(abfd) + 0x7fff) |
558 |
|
|
559 |
|
/* Instructions which appear in a stub. */ |
560 |
#define STUB_LW(abfd) \ |
#define STUB_LW(abfd) \ |
561 |
(SGI_COMPAT (abfd) \ |
((ABI_64_P (abfd) \ |
562 |
? (ABI_64_P (abfd) \ |
? 0xdf998010 /* ld t9,0x8010(gp) */ \ |
563 |
? 0xdf998010 /* ld t9,0x8010(gp) */ \ |
: 0x8f998010)) /* lw t9,0x8010(gp) */ |
|
: 0x8f998010) /* lw t9,0x8010(gp) */ \ |
|
|
: 0x8f998010) /* lw t9,0x8000(gp) */ |
|
564 |
#define STUB_MOVE(abfd) \ |
#define STUB_MOVE(abfd) \ |
565 |
(SGI_COMPAT (abfd) ? 0x03e07825 : 0x03e07821) /* move t7,ra */ |
((ABI_64_P (abfd) \ |
566 |
#define STUB_JALR 0x0320f809 /* jal t9 */ |
? 0x03e0782d /* daddu t7,ra */ \ |
567 |
|
: 0x03e07821)) /* addu t7,ra */ |
568 |
|
#define STUB_JALR 0x0320f809 /* jalr t9,ra */ |
569 |
#define STUB_LI16(abfd) \ |
#define STUB_LI16(abfd) \ |
570 |
(SGI_COMPAT (abfd) ? 0x34180000 : 0x24180000) /* ori t8,zero,0 */ |
((ABI_64_P (abfd) \ |
571 |
|
? 0x64180000 /* daddiu t8,zero,0 */ \ |
572 |
|
: 0x24180000)) /* addiu t8,zero,0 */ |
573 |
#define MIPS_FUNCTION_STUB_SIZE (16) |
#define MIPS_FUNCTION_STUB_SIZE (16) |
574 |
|
|
575 |
/* The name of the dynamic interpreter. This is put in the .interp |
/* The name of the dynamic interpreter. This is put in the .interp |
581 |
: "/usr/lib/libc.so.1") |
: "/usr/lib/libc.so.1") |
582 |
|
|
583 |
#ifdef BFD64 |
#ifdef BFD64 |
584 |
|
#define MNAME(bfd,pre,pos) \ |
585 |
|
(ABI_64_P (bfd) ? CONCAT4 (pre,64,_,pos) : CONCAT4 (pre,32,_,pos)) |
586 |
#define ELF_R_SYM(bfd, i) \ |
#define ELF_R_SYM(bfd, i) \ |
587 |
(ABI_64_P (bfd) ? ELF64_R_SYM (i) : ELF32_R_SYM (i)) |
(ABI_64_P (bfd) ? ELF64_R_SYM (i) : ELF32_R_SYM (i)) |
588 |
#define ELF_R_TYPE(bfd, i) \ |
#define ELF_R_TYPE(bfd, i) \ |
590 |
#define ELF_R_INFO(bfd, s, t) \ |
#define ELF_R_INFO(bfd, s, t) \ |
591 |
(ABI_64_P (bfd) ? ELF64_R_INFO (s, t) : ELF32_R_INFO (s, t)) |
(ABI_64_P (bfd) ? ELF64_R_INFO (s, t) : ELF32_R_INFO (s, t)) |
592 |
#else |
#else |
593 |
|
#define MNAME(bfd,pre,pos) CONCAT4 (pre,32,_,pos) |
594 |
#define ELF_R_SYM(bfd, i) \ |
#define ELF_R_SYM(bfd, i) \ |
595 |
(ELF32_R_SYM (i)) |
(ELF32_R_SYM (i)) |
596 |
#define ELF_R_TYPE(bfd, i) \ |
#define ELF_R_TYPE(bfd, i) \ |
649 |
#define mips_elf_link_hash_traverse(table, func, info) \ |
#define mips_elf_link_hash_traverse(table, func, info) \ |
650 |
(elf_link_hash_traverse \ |
(elf_link_hash_traverse \ |
651 |
(&(table)->root, \ |
(&(table)->root, \ |
652 |
(boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \ |
(bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \ |
653 |
(info))) |
(info))) |
654 |
|
|
655 |
/* Get the MIPS ELF linker hash table from a link_info structure. */ |
/* Get the MIPS ELF linker hash table from a link_info structure. */ |
657 |
#define mips_elf_hash_table(p) \ |
#define mips_elf_hash_table(p) \ |
658 |
((struct mips_elf_link_hash_table *) ((p)->hash)) |
((struct mips_elf_link_hash_table *) ((p)->hash)) |
659 |
|
|
660 |
|
/* Find the base offsets for thread-local storage in this object, |
661 |
|
for GD/LD and IE/LE respectively. */ |
662 |
|
|
663 |
|
#define TP_OFFSET 0x7000 |
664 |
|
#define DTP_OFFSET 0x8000 |
665 |
|
|
666 |
|
static bfd_vma |
667 |
|
dtprel_base (struct bfd_link_info *info) |
668 |
|
{ |
669 |
|
/* If tls_sec is NULL, we should have signalled an error already. */ |
670 |
|
if (elf_hash_table (info)->tls_sec == NULL) |
671 |
|
return 0; |
672 |
|
return elf_hash_table (info)->tls_sec->vma + DTP_OFFSET; |
673 |
|
} |
674 |
|
|
675 |
|
static bfd_vma |
676 |
|
tprel_base (struct bfd_link_info *info) |
677 |
|
{ |
678 |
|
/* If tls_sec is NULL, we should have signalled an error already. */ |
679 |
|
if (elf_hash_table (info)->tls_sec == NULL) |
680 |
|
return 0; |
681 |
|
return elf_hash_table (info)->tls_sec->vma + TP_OFFSET; |
682 |
|
} |
683 |
|
|
684 |
/* Create an entry in a MIPS ELF linker hash table. */ |
/* Create an entry in a MIPS ELF linker hash table. */ |
685 |
|
|
686 |
static struct bfd_hash_entry * |
static struct bfd_hash_entry * |
687 |
mips_elf_link_hash_newfunc (entry, table, string) |
mips_elf_link_hash_newfunc (struct bfd_hash_entry *entry, |
688 |
struct bfd_hash_entry *entry; |
struct bfd_hash_table *table, const char *string) |
|
struct bfd_hash_table *table; |
|
|
const char *string; |
|
689 |
{ |
{ |
690 |
struct mips_elf_link_hash_entry *ret = |
struct mips_elf_link_hash_entry *ret = |
691 |
(struct mips_elf_link_hash_entry *) entry; |
(struct mips_elf_link_hash_entry *) entry; |
692 |
|
|
693 |
/* Allocate the structure if it has not already been allocated by a |
/* Allocate the structure if it has not already been allocated by a |
694 |
subclass. */ |
subclass. */ |
695 |
if (ret == (struct mips_elf_link_hash_entry *) NULL) |
if (ret == NULL) |
696 |
ret = ((struct mips_elf_link_hash_entry *) |
ret = bfd_hash_allocate (table, sizeof (struct mips_elf_link_hash_entry)); |
697 |
bfd_hash_allocate (table, |
if (ret == NULL) |
|
sizeof (struct mips_elf_link_hash_entry))); |
|
|
if (ret == (struct mips_elf_link_hash_entry *) NULL) |
|
698 |
return (struct bfd_hash_entry *) ret; |
return (struct bfd_hash_entry *) ret; |
699 |
|
|
700 |
/* Call the allocation method of the superclass. */ |
/* Call the allocation method of the superclass. */ |
701 |
ret = ((struct mips_elf_link_hash_entry *) |
ret = ((struct mips_elf_link_hash_entry *) |
702 |
_bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, |
_bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, |
703 |
table, string)); |
table, string)); |
704 |
if (ret != (struct mips_elf_link_hash_entry *) NULL) |
if (ret != NULL) |
705 |
{ |
{ |
706 |
/* Set local fields. */ |
/* Set local fields. */ |
707 |
memset (&ret->esym, 0, sizeof (EXTR)); |
memset (&ret->esym, 0, sizeof (EXTR)); |
709 |
not been set. -1 means there is no associated ifd. */ |
not been set. -1 means there is no associated ifd. */ |
710 |
ret->esym.ifd = -2; |
ret->esym.ifd = -2; |
711 |
ret->possibly_dynamic_relocs = 0; |
ret->possibly_dynamic_relocs = 0; |
712 |
ret->readonly_reloc = false; |
ret->readonly_reloc = FALSE; |
713 |
ret->min_dyn_reloc_index = 0; |
ret->no_fn_stub = FALSE; |
|
ret->no_fn_stub = false; |
|
714 |
ret->fn_stub = NULL; |
ret->fn_stub = NULL; |
715 |
ret->need_fn_stub = false; |
ret->need_fn_stub = FALSE; |
716 |
ret->call_stub = NULL; |
ret->call_stub = NULL; |
717 |
ret->call_fp_stub = NULL; |
ret->call_fp_stub = NULL; |
718 |
ret->forced_local = false; |
ret->forced_local = FALSE; |
719 |
|
ret->tls_type = GOT_NORMAL; |
720 |
} |
} |
721 |
|
|
722 |
return (struct bfd_hash_entry *) ret; |
return (struct bfd_hash_entry *) ret; |
723 |
} |
} |
724 |
|
|
725 |
|
bfd_boolean |
726 |
|
_bfd_mips_elf_new_section_hook (bfd *abfd, asection *sec) |
727 |
|
{ |
728 |
|
struct _mips_elf_section_data *sdata; |
729 |
|
bfd_size_type amt = sizeof (*sdata); |
730 |
|
|
731 |
|
sdata = bfd_zalloc (abfd, amt); |
732 |
|
if (sdata == NULL) |
733 |
|
return FALSE; |
734 |
|
sec->used_by_bfd = sdata; |
735 |
|
|
736 |
|
return _bfd_elf_new_section_hook (abfd, sec); |
737 |
|
} |
738 |
|
|
739 |
/* Read ECOFF debugging information from a .mdebug section into a |
/* Read ECOFF debugging information from a .mdebug section into a |
740 |
ecoff_debug_info structure. */ |
ecoff_debug_info structure. */ |
741 |
|
|
742 |
boolean |
bfd_boolean |
743 |
_bfd_mips_elf_read_ecoff_info (abfd, section, debug) |
_bfd_mips_elf_read_ecoff_info (bfd *abfd, asection *section, |
744 |
bfd *abfd; |
struct ecoff_debug_info *debug) |
|
asection *section; |
|
|
struct ecoff_debug_info *debug; |
|
745 |
{ |
{ |
746 |
HDRR *symhdr; |
HDRR *symhdr; |
747 |
const struct ecoff_debug_swap *swap; |
const struct ecoff_debug_swap *swap; |
748 |
char *ext_hdr = NULL; |
char *ext_hdr; |
749 |
|
|
750 |
swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; |
swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; |
751 |
memset (debug, 0, sizeof (*debug)); |
memset (debug, 0, sizeof (*debug)); |
752 |
|
|
753 |
ext_hdr = (char *) bfd_malloc (swap->external_hdr_size); |
ext_hdr = bfd_malloc (swap->external_hdr_size); |
754 |
if (ext_hdr == NULL && swap->external_hdr_size != 0) |
if (ext_hdr == NULL && swap->external_hdr_size != 0) |
755 |
goto error_return; |
goto error_return; |
756 |
|
|
757 |
if (! bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0, |
if (! bfd_get_section_contents (abfd, section, ext_hdr, 0, |
758 |
swap->external_hdr_size)) |
swap->external_hdr_size)) |
759 |
goto error_return; |
goto error_return; |
760 |
|
|
769 |
else \ |
else \ |
770 |
{ \ |
{ \ |
771 |
bfd_size_type amt = (bfd_size_type) size * symhdr->count; \ |
bfd_size_type amt = (bfd_size_type) size * symhdr->count; \ |
772 |
debug->ptr = (type) bfd_malloc (amt); \ |
debug->ptr = bfd_malloc (amt); \ |
773 |
if (debug->ptr == NULL) \ |
if (debug->ptr == NULL) \ |
774 |
goto error_return; \ |
goto error_return; \ |
775 |
if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \ |
if (bfd_seek (abfd, symhdr->offset, SEEK_SET) != 0 \ |
776 |
|| bfd_bread (debug->ptr, amt, abfd) != amt) \ |
|| bfd_bread (debug->ptr, amt, abfd) != amt) \ |
777 |
goto error_return; \ |
goto error_return; \ |
778 |
} |
} |
779 |
|
|
780 |
READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *); |
READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *); |
781 |
READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR); |
READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *); |
782 |
READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR); |
READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, void *); |
783 |
READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR); |
READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, void *); |
784 |
READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR); |
READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, void *); |
785 |
READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext), |
READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext), |
786 |
union aux_ext *); |
union aux_ext *); |
787 |
READ (ss, cbSsOffset, issMax, sizeof (char), char *); |
READ (ss, cbSsOffset, issMax, sizeof (char), char *); |
788 |
READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *); |
READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *); |
789 |
READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR); |
READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, void *); |
790 |
READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR); |
READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, void *); |
791 |
READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR); |
READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, void *); |
792 |
#undef READ |
#undef READ |
793 |
|
|
794 |
debug->fdr = NULL; |
debug->fdr = NULL; |
|
debug->adjust = NULL; |
|
795 |
|
|
796 |
return true; |
return TRUE; |
797 |
|
|
798 |
error_return: |
error_return: |
799 |
if (ext_hdr != NULL) |
if (ext_hdr != NULL) |
820 |
free (debug->external_rfd); |
free (debug->external_rfd); |
821 |
if (debug->external_ext != NULL) |
if (debug->external_ext != NULL) |
822 |
free (debug->external_ext); |
free (debug->external_ext); |
823 |
return false; |
return FALSE; |
824 |
} |
} |
825 |
|
|
826 |
/* Swap RPDR (runtime procedure table entry) for output. */ |
/* Swap RPDR (runtime procedure table entry) for output. */ |
827 |
|
|
828 |
static void |
static void |
829 |
ecoff_swap_rpdr_out (abfd, in, ex) |
ecoff_swap_rpdr_out (bfd *abfd, const RPDR *in, struct rpdr_ext *ex) |
|
bfd *abfd; |
|
|
const RPDR *in; |
|
|
struct rpdr_ext *ex; |
|
830 |
{ |
{ |
831 |
H_PUT_S32 (abfd, in->adr, ex->p_adr); |
H_PUT_S32 (abfd, in->adr, ex->p_adr); |
832 |
H_PUT_32 (abfd, in->regmask, ex->p_regmask); |
H_PUT_32 (abfd, in->regmask, ex->p_regmask); |
839 |
H_PUT_16 (abfd, in->pcreg, ex->p_pcreg); |
H_PUT_16 (abfd, in->pcreg, ex->p_pcreg); |
840 |
|
|
841 |
H_PUT_32 (abfd, in->irpss, ex->p_irpss); |
H_PUT_32 (abfd, in->irpss, ex->p_irpss); |
|
#if 0 /* FIXME */ |
|
|
H_PUT_S32 (abfd, in->exception_info, ex->p_exception_info); |
|
|
#endif |
|
842 |
} |
} |
843 |
|
|
844 |
/* Create a runtime procedure table from the .mdebug section. */ |
/* Create a runtime procedure table from the .mdebug section. */ |
845 |
|
|
846 |
static boolean |
static bfd_boolean |
847 |
mips_elf_create_procedure_table (handle, abfd, info, s, debug) |
mips_elf_create_procedure_table (void *handle, bfd *abfd, |
848 |
PTR handle; |
struct bfd_link_info *info, asection *s, |
849 |
bfd *abfd; |
struct ecoff_debug_info *debug) |
|
struct bfd_link_info *info; |
|
|
asection *s; |
|
|
struct ecoff_debug_info *debug; |
|
850 |
{ |
{ |
851 |
const struct ecoff_debug_swap *swap; |
const struct ecoff_debug_swap *swap; |
852 |
HDRR *hdr = &debug->symbolic_header; |
HDRR *hdr = &debug->symbolic_header; |
853 |
RPDR *rpdr, *rp; |
RPDR *rpdr, *rp; |
854 |
struct rpdr_ext *erp; |
struct rpdr_ext *erp; |
855 |
PTR rtproc; |
void *rtproc; |
856 |
struct pdr_ext *epdr; |
struct pdr_ext *epdr; |
857 |
struct sym_ext *esym; |
struct sym_ext *esym; |
858 |
char *ss, **sv; |
char *ss, **sv; |
879 |
{ |
{ |
880 |
size = swap->external_pdr_size; |
size = swap->external_pdr_size; |
881 |
|
|
882 |
epdr = (struct pdr_ext *) bfd_malloc (size * count); |
epdr = bfd_malloc (size * count); |
883 |
if (epdr == NULL) |
if (epdr == NULL) |
884 |
goto error_return; |
goto error_return; |
885 |
|
|
886 |
if (! _bfd_ecoff_get_accumulated_pdr (handle, (PTR) epdr)) |
if (! _bfd_ecoff_get_accumulated_pdr (handle, (bfd_byte *) epdr)) |
887 |
goto error_return; |
goto error_return; |
888 |
|
|
889 |
size = sizeof (RPDR); |
size = sizeof (RPDR); |
890 |
rp = rpdr = (RPDR *) bfd_malloc (size * count); |
rp = rpdr = bfd_malloc (size * count); |
891 |
if (rpdr == NULL) |
if (rpdr == NULL) |
892 |
goto error_return; |
goto error_return; |
893 |
|
|
894 |
size = sizeof (char *); |
size = sizeof (char *); |
895 |
sv = (char **) bfd_malloc (size * count); |
sv = bfd_malloc (size * count); |
896 |
if (sv == NULL) |
if (sv == NULL) |
897 |
goto error_return; |
goto error_return; |
898 |
|
|
899 |
count = hdr->isymMax; |
count = hdr->isymMax; |
900 |
size = swap->external_sym_size; |
size = swap->external_sym_size; |
901 |
esym = (struct sym_ext *) bfd_malloc (size * count); |
esym = bfd_malloc (size * count); |
902 |
if (esym == NULL) |
if (esym == NULL) |
903 |
goto error_return; |
goto error_return; |
904 |
|
|
905 |
if (! _bfd_ecoff_get_accumulated_sym (handle, (PTR) esym)) |
if (! _bfd_ecoff_get_accumulated_sym (handle, (bfd_byte *) esym)) |
906 |
goto error_return; |
goto error_return; |
907 |
|
|
908 |
count = hdr->issMax; |
count = hdr->issMax; |
909 |
ss = (char *) bfd_malloc (count); |
ss = bfd_malloc (count); |
910 |
if (ss == NULL) |
if (ss == NULL) |
911 |
goto error_return; |
goto error_return; |
912 |
if (! _bfd_ecoff_get_accumulated_ss (handle, (PTR) ss)) |
if (! _bfd_ecoff_get_accumulated_ss (handle, (bfd_byte *) ss)) |
913 |
goto error_return; |
goto error_return; |
914 |
|
|
915 |
count = hdr->ipdMax; |
count = hdr->ipdMax; |
916 |
for (i = 0; i < (unsigned long) count; i++, rp++) |
for (i = 0; i < (unsigned long) count; i++, rp++) |
917 |
{ |
{ |
918 |
(*swap->swap_pdr_in) (abfd, (PTR) (epdr + i), &pdr); |
(*swap->swap_pdr_in) (abfd, epdr + i, &pdr); |
919 |
(*swap->swap_sym_in) (abfd, (PTR) &esym[pdr.isym], &sym); |
(*swap->swap_sym_in) (abfd, &esym[pdr.isym], &sym); |
920 |
rp->adr = sym.value; |
rp->adr = sym.value; |
921 |
rp->regmask = pdr.regmask; |
rp->regmask = pdr.regmask; |
922 |
rp->regoffset = pdr.regoffset; |
rp->regoffset = pdr.regoffset; |
933 |
|
|
934 |
size = sizeof (struct rpdr_ext) * (count + 2) + sindex; |
size = sizeof (struct rpdr_ext) * (count + 2) + sindex; |
935 |
size = BFD_ALIGN (size, 16); |
size = BFD_ALIGN (size, 16); |
936 |
rtproc = (PTR) bfd_alloc (abfd, size); |
rtproc = bfd_alloc (abfd, size); |
937 |
if (rtproc == NULL) |
if (rtproc == NULL) |
938 |
{ |
{ |
939 |
mips_elf_hash_table (info)->procedure_count = 0; |
mips_elf_hash_table (info)->procedure_count = 0; |
942 |
|
|
943 |
mips_elf_hash_table (info)->procedure_count = count + 2; |
mips_elf_hash_table (info)->procedure_count = count + 2; |
944 |
|
|
945 |
erp = (struct rpdr_ext *) rtproc; |
erp = rtproc; |
946 |
memset (erp, 0, sizeof (struct rpdr_ext)); |
memset (erp, 0, sizeof (struct rpdr_ext)); |
947 |
erp++; |
erp++; |
948 |
str = (char *) rtproc + sizeof (struct rpdr_ext) * (count + 2); |
str = (char *) rtproc + sizeof (struct rpdr_ext) * (count + 2); |
957 |
H_PUT_S32 (abfd, -1, (erp + count)->p_adr); |
H_PUT_S32 (abfd, -1, (erp + count)->p_adr); |
958 |
|
|
959 |
/* Set the size and contents of .rtproc section. */ |
/* Set the size and contents of .rtproc section. */ |
960 |
s->_raw_size = size; |
s->size = size; |
961 |
s->contents = (bfd_byte *) rtproc; |
s->contents = rtproc; |
962 |
|
|
963 |
/* Skip this section later on (I don't think this currently |
/* Skip this section later on (I don't think this currently |
964 |
matters, but someday it might). */ |
matters, but someday it might). */ |
965 |
s->link_order_head = (struct bfd_link_order *) NULL; |
s->link_order_head = NULL; |
966 |
|
|
967 |
if (epdr != NULL) |
if (epdr != NULL) |
968 |
free (epdr); |
free (epdr); |
975 |
if (sv != NULL) |
if (sv != NULL) |
976 |
free (sv); |
free (sv); |
977 |
|
|
978 |
return true; |
return TRUE; |
979 |
|
|
980 |
error_return: |
error_return: |
981 |
if (epdr != NULL) |
if (epdr != NULL) |
988 |
free (ss); |
free (ss); |
989 |
if (sv != NULL) |
if (sv != NULL) |
990 |
free (sv); |
free (sv); |
991 |
return false; |
return FALSE; |
992 |
} |
} |
993 |
|
|
994 |
/* Check the mips16 stubs for a particular symbol, and see if we can |
/* Check the mips16 stubs for a particular symbol, and see if we can |
995 |
discard them. */ |
discard them. */ |
996 |
|
|
997 |
static boolean |
static bfd_boolean |
998 |
mips_elf_check_mips16_stubs (h, data) |
mips_elf_check_mips16_stubs (struct mips_elf_link_hash_entry *h, |
999 |
struct mips_elf_link_hash_entry *h; |
void *data ATTRIBUTE_UNUSED) |
|
PTR data ATTRIBUTE_UNUSED; |
|
1000 |
{ |
{ |
1001 |
if (h->root.root.type == bfd_link_hash_warning) |
if (h->root.root.type == bfd_link_hash_warning) |
1002 |
h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link; |
h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link; |
1007 |
/* We don't need the fn_stub; the only references to this symbol |
/* We don't need the fn_stub; the only references to this symbol |
1008 |
are 16 bit calls. Clobber the size to 0 to prevent it from |
are 16 bit calls. Clobber the size to 0 to prevent it from |
1009 |
being included in the link. */ |
being included in the link. */ |
1010 |
h->fn_stub->_raw_size = 0; |
h->fn_stub->size = 0; |
|
h->fn_stub->_cooked_size = 0; |
|
1011 |
h->fn_stub->flags &= ~SEC_RELOC; |
h->fn_stub->flags &= ~SEC_RELOC; |
1012 |
h->fn_stub->reloc_count = 0; |
h->fn_stub->reloc_count = 0; |
1013 |
h->fn_stub->flags |= SEC_EXCLUDE; |
h->fn_stub->flags |= SEC_EXCLUDE; |
1019 |
/* We don't need the call_stub; this is a 16 bit function, so |
/* We don't need the call_stub; this is a 16 bit function, so |
1020 |
calls from other 16 bit functions are OK. Clobber the size |
calls from other 16 bit functions are OK. Clobber the size |
1021 |
to 0 to prevent it from being included in the link. */ |
to 0 to prevent it from being included in the link. */ |
1022 |
h->call_stub->_raw_size = 0; |
h->call_stub->size = 0; |
|
h->call_stub->_cooked_size = 0; |
|
1023 |
h->call_stub->flags &= ~SEC_RELOC; |
h->call_stub->flags &= ~SEC_RELOC; |
1024 |
h->call_stub->reloc_count = 0; |
h->call_stub->reloc_count = 0; |
1025 |
h->call_stub->flags |= SEC_EXCLUDE; |
h->call_stub->flags |= SEC_EXCLUDE; |
1031 |
/* We don't need the call_stub; this is a 16 bit function, so |
/* We don't need the call_stub; this is a 16 bit function, so |
1032 |
calls from other 16 bit functions are OK. Clobber the size |
calls from other 16 bit functions are OK. Clobber the size |
1033 |
to 0 to prevent it from being included in the link. */ |
to 0 to prevent it from being included in the link. */ |
1034 |
h->call_fp_stub->_raw_size = 0; |
h->call_fp_stub->size = 0; |
|
h->call_fp_stub->_cooked_size = 0; |
|
1035 |
h->call_fp_stub->flags &= ~SEC_RELOC; |
h->call_fp_stub->flags &= ~SEC_RELOC; |
1036 |
h->call_fp_stub->reloc_count = 0; |
h->call_fp_stub->reloc_count = 0; |
1037 |
h->call_fp_stub->flags |= SEC_EXCLUDE; |
h->call_fp_stub->flags |= SEC_EXCLUDE; |
1038 |
} |
} |
1039 |
|
|
1040 |
return true; |
return TRUE; |
1041 |
} |
} |
1042 |
|
|
1043 |
|
/* R_MIPS16_26 is used for the mips16 jal and jalx instructions. |
1044 |
|
Most mips16 instructions are 16 bits, but these instructions |
1045 |
|
are 32 bits. |
1046 |
|
|
1047 |
|
The format of these instructions is: |
1048 |
|
|
1049 |
|
+--------------+--------------------------------+ |
1050 |
|
| JALX | X| Imm 20:16 | Imm 25:21 | |
1051 |
|
+--------------+--------------------------------+ |
1052 |
|
| Immediate 15:0 | |
1053 |
|
+-----------------------------------------------+ |
1054 |
|
|
1055 |
|
JALX is the 5-bit value 00011. X is 0 for jal, 1 for jalx. |
1056 |
|
Note that the immediate value in the first word is swapped. |
1057 |
|
|
1058 |
|
When producing a relocatable object file, R_MIPS16_26 is |
1059 |
|
handled mostly like R_MIPS_26. In particular, the addend is |
1060 |
|
stored as a straight 26-bit value in a 32-bit instruction. |
1061 |
|
(gas makes life simpler for itself by never adjusting a |
1062 |
|
R_MIPS16_26 reloc to be against a section, so the addend is |
1063 |
|
always zero). However, the 32 bit instruction is stored as 2 |
1064 |
|
16-bit values, rather than a single 32-bit value. In a |
1065 |
|
big-endian file, the result is the same; in a little-endian |
1066 |
|
file, the two 16-bit halves of the 32 bit value are swapped. |
1067 |
|
This is so that a disassembler can recognize the jal |
1068 |
|
instruction. |
1069 |
|
|
1070 |
|
When doing a final link, R_MIPS16_26 is treated as a 32 bit |
1071 |
|
instruction stored as two 16-bit values. The addend A is the |
1072 |
|
contents of the targ26 field. The calculation is the same as |
1073 |
|
R_MIPS_26. When storing the calculated value, reorder the |
1074 |
|
immediate value as shown above, and don't forget to store the |
1075 |
|
value as two 16-bit values. |
1076 |
|
|
1077 |
|
To put it in MIPS ABI terms, the relocation field is T-targ26-16, |
1078 |
|
defined as |
1079 |
|
|
1080 |
|
big-endian: |
1081 |
|
+--------+----------------------+ |
1082 |
|
| | | |
1083 |
|
| | targ26-16 | |
1084 |
|
|31 26|25 0| |
1085 |
|
+--------+----------------------+ |
1086 |
|
|
1087 |
|
little-endian: |
1088 |
|
+----------+------+-------------+ |
1089 |
|
| | | | |
1090 |
|
| sub1 | | sub2 | |
1091 |
|
|0 9|10 15|16 31| |
1092 |
|
+----------+--------------------+ |
1093 |
|
where targ26-16 is sub1 followed by sub2 (i.e., the addend field A is |
1094 |
|
((sub1 << 16) | sub2)). |
1095 |
|
|
1096 |
|
When producing a relocatable object file, the calculation is |
1097 |
|
(((A < 2) | ((P + 4) & 0xf0000000) + S) >> 2) |
1098 |
|
When producing a fully linked file, the calculation is |
1099 |
|
let R = (((A < 2) | ((P + 4) & 0xf0000000) + S) >> 2) |
1100 |
|
((R & 0x1f0000) << 5) | ((R & 0x3e00000) >> 5) | (R & 0xffff) |
1101 |
|
|
1102 |
|
R_MIPS16_GPREL is used for GP-relative addressing in mips16 |
1103 |
|
mode. A typical instruction will have a format like this: |
1104 |
|
|
1105 |
|
+--------------+--------------------------------+ |
1106 |
|
| EXTEND | Imm 10:5 | Imm 15:11 | |
1107 |
|
+--------------+--------------------------------+ |
1108 |
|
| Major | rx | ry | Imm 4:0 | |
1109 |
|
+--------------+--------------------------------+ |
1110 |
|
|
1111 |
|
EXTEND is the five bit value 11110. Major is the instruction |
1112 |
|
opcode. |
1113 |
|
|
1114 |
|
This is handled exactly like R_MIPS_GPREL16, except that the |
1115 |
|
addend is retrieved and stored as shown in this diagram; that |
1116 |
|
is, the Imm fields above replace the V-rel16 field. |
1117 |
|
|
1118 |
|
All we need to do here is shuffle the bits appropriately. As |
1119 |
|
above, the two 16-bit halves must be swapped on a |
1120 |
|
little-endian system. |
1121 |
|
|
1122 |
|
R_MIPS16_HI16 and R_MIPS16_LO16 are used in mips16 mode to |
1123 |
|
access data when neither GP-relative nor PC-relative addressing |
1124 |
|
can be used. They are handled like R_MIPS_HI16 and R_MIPS_LO16, |
1125 |
|
except that the addend is retrieved and stored as shown above |
1126 |
|
for R_MIPS16_GPREL. |
1127 |
|
*/ |
1128 |
|
void |
1129 |
|
_bfd_mips16_elf_reloc_unshuffle (bfd *abfd, int r_type, |
1130 |
|
bfd_boolean jal_shuffle, bfd_byte *data) |
1131 |
|
{ |
1132 |
|
bfd_vma extend, insn, val; |
1133 |
|
|
1134 |
|
if (r_type != R_MIPS16_26 && r_type != R_MIPS16_GPREL |
1135 |
|
&& r_type != R_MIPS16_HI16 && r_type != R_MIPS16_LO16) |
1136 |
|
return; |
1137 |
|
|
1138 |
|
/* Pick up the mips16 extend instruction and the real instruction. */ |
1139 |
|
extend = bfd_get_16 (abfd, data); |
1140 |
|
insn = bfd_get_16 (abfd, data + 2); |
1141 |
|
if (r_type == R_MIPS16_26) |
1142 |
|
{ |
1143 |
|
if (jal_shuffle) |
1144 |
|
val = ((extend & 0xfc00) << 16) | ((extend & 0x3e0) << 11) |
1145 |
|
| ((extend & 0x1f) << 21) | insn; |
1146 |
|
else |
1147 |
|
val = extend << 16 | insn; |
1148 |
|
} |
1149 |
|
else |
1150 |
|
val = ((extend & 0xf800) << 16) | ((insn & 0xffe0) << 11) |
1151 |
|
| ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f); |
1152 |
|
bfd_put_32 (abfd, val, data); |
1153 |
|
} |
1154 |
|
|
1155 |
|
void |
1156 |
|
_bfd_mips16_elf_reloc_shuffle (bfd *abfd, int r_type, |
1157 |
|
bfd_boolean jal_shuffle, bfd_byte *data) |
1158 |
|
{ |
1159 |
|
bfd_vma extend, insn, val; |
1160 |
|
|
1161 |
|
if (r_type != R_MIPS16_26 && r_type != R_MIPS16_GPREL |
1162 |
|
&& r_type != R_MIPS16_HI16 && r_type != R_MIPS16_LO16) |
1163 |
|
return; |
1164 |
|
|
1165 |
|
val = bfd_get_32 (abfd, data); |
1166 |
|
if (r_type == R_MIPS16_26) |
1167 |
|
{ |
1168 |
|
if (jal_shuffle) |
1169 |
|
{ |
1170 |
|
insn = val & 0xffff; |
1171 |
|
extend = ((val >> 16) & 0xfc00) | ((val >> 11) & 0x3e0) |
1172 |
|
| ((val >> 21) & 0x1f); |
1173 |
|
} |
1174 |
|
else |
1175 |
|
{ |
1176 |
|
insn = val & 0xffff; |
1177 |
|
extend = val >> 16; |
1178 |
|
} |
1179 |
|
} |
1180 |
|
else |
1181 |
|
{ |
1182 |
|
insn = ((val >> 11) & 0xffe0) | (val & 0x1f); |
1183 |
|
extend = ((val >> 16) & 0xf800) | ((val >> 11) & 0x1f) | (val & 0x7e0); |
1184 |
|
} |
1185 |
|
bfd_put_16 (abfd, insn, data + 2); |
1186 |
|
bfd_put_16 (abfd, extend, data); |
1187 |
|
} |
1188 |
|
|
1189 |
bfd_reloc_status_type |
bfd_reloc_status_type |
1190 |
_bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry, input_section, |
_bfd_mips_elf_gprel16_with_gp (bfd *abfd, asymbol *symbol, |
1191 |
relocateable, data, gp) |
arelent *reloc_entry, asection *input_section, |
1192 |
bfd *abfd; |
bfd_boolean relocatable, void *data, bfd_vma gp) |
|
asymbol *symbol; |
|
|
arelent *reloc_entry; |
|
|
asection *input_section; |
|
|
boolean relocateable; |
|
|
PTR data; |
|
|
bfd_vma gp; |
|
1193 |
{ |
{ |
1194 |
bfd_vma relocation; |
bfd_vma relocation; |
1195 |
unsigned long insn; |
bfd_signed_vma val; |
1196 |
unsigned long val; |
bfd_reloc_status_type status; |
1197 |
|
|
1198 |
if (bfd_is_com_section (symbol->section)) |
if (bfd_is_com_section (symbol->section)) |
1199 |
relocation = 0; |
relocation = 0; |
1203 |
relocation += symbol->section->output_section->vma; |
relocation += symbol->section->output_section->vma; |
1204 |
relocation += symbol->section->output_offset; |
relocation += symbol->section->output_offset; |
1205 |
|
|
1206 |
if (reloc_entry->address > input_section->_cooked_size) |
if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) |
1207 |
return bfd_reloc_outofrange; |
return bfd_reloc_outofrange; |
1208 |
|
|
|
insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); |
|
|
|
|
1209 |
/* Set val to the offset into the section or symbol. */ |
/* Set val to the offset into the section or symbol. */ |
1210 |
if (reloc_entry->howto->src_mask == 0) |
val = reloc_entry->addend; |
1211 |
{ |
|
1212 |
/* This case occurs with the 64-bit MIPS ELF ABI. */ |
_bfd_mips_elf_sign_extend (val, 16); |
|
val = reloc_entry->addend; |
|
|
} |
|
|
else |
|
|
{ |
|
|
val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff; |
|
|
if (val & 0x8000) |
|
|
val -= 0x10000; |
|
|
} |
|
1213 |
|
|
1214 |
/* Adjust val for the final section location and GP value. If we |
/* Adjust val for the final section location and GP value. If we |
1215 |
are producing relocateable output, we don't want to do this for |
are producing relocatable output, we don't want to do this for |
1216 |
an external symbol. */ |
an external symbol. */ |
1217 |
if (! relocateable |
if (! relocatable |
1218 |
|| (symbol->flags & BSF_SECTION_SYM) != 0) |
|| (symbol->flags & BSF_SECTION_SYM) != 0) |
1219 |
val += relocation - gp; |
val += relocation - gp; |
1220 |
|
|
1221 |
insn = (insn & ~0xffff) | (val & 0xffff); |
if (reloc_entry->howto->partial_inplace) |
1222 |
bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address); |
{ |
1223 |
|
status = _bfd_relocate_contents (reloc_entry->howto, abfd, val, |
1224 |
|
(bfd_byte *) data |
1225 |
|
+ reloc_entry->address); |
1226 |
|
if (status != bfd_reloc_ok) |
1227 |
|
return status; |
1228 |
|
} |
1229 |
|
else |
1230 |
|
reloc_entry->addend = val; |
1231 |
|
|
1232 |
if (relocateable) |
if (relocatable) |
1233 |
reloc_entry->address += input_section->output_offset; |
reloc_entry->address += input_section->output_offset; |
1234 |
|
|
1235 |
else if ((long) val >= 0x8000 || (long) val < -0x8000) |
return bfd_reloc_ok; |
1236 |
return bfd_reloc_overflow; |
} |
1237 |
|
|
1238 |
|
/* Used to store a REL high-part relocation such as R_MIPS_HI16 or |
1239 |
|
R_MIPS_GOT16. REL is the relocation, INPUT_SECTION is the section |
1240 |
|
that contains the relocation field and DATA points to the start of |
1241 |
|
INPUT_SECTION. */ |
1242 |
|
|
1243 |
|
struct mips_hi16 |
1244 |
|
{ |
1245 |
|
struct mips_hi16 *next; |
1246 |
|
bfd_byte *data; |
1247 |
|
asection *input_section; |
1248 |
|
arelent rel; |
1249 |
|
}; |
1250 |
|
|
1251 |
|
/* FIXME: This should not be a static variable. */ |
1252 |
|
|
1253 |
|
static struct mips_hi16 *mips_hi16_list; |
1254 |
|
|
1255 |
|
/* A howto special_function for REL *HI16 relocations. We can only |
1256 |
|
calculate the correct value once we've seen the partnering |
1257 |
|
*LO16 relocation, so just save the information for later. |
1258 |
|
|
1259 |
|
The ABI requires that the *LO16 immediately follow the *HI16. |
1260 |
|
However, as a GNU extension, we permit an arbitrary number of |
1261 |
|
*HI16s to be associated with a single *LO16. This significantly |
1262 |
|
simplies the relocation handling in gcc. */ |
1263 |
|
|
1264 |
|
bfd_reloc_status_type |
1265 |
|
_bfd_mips_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, |
1266 |
|
asymbol *symbol ATTRIBUTE_UNUSED, void *data, |
1267 |
|
asection *input_section, bfd *output_bfd, |
1268 |
|
char **error_message ATTRIBUTE_UNUSED) |
1269 |
|
{ |
1270 |
|
struct mips_hi16 *n; |
1271 |
|
|
1272 |
|
if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) |
1273 |
|
return bfd_reloc_outofrange; |
1274 |
|
|
1275 |
|
n = bfd_malloc (sizeof *n); |
1276 |
|
if (n == NULL) |
1277 |
|
return bfd_reloc_outofrange; |
1278 |
|
|
1279 |
|
n->next = mips_hi16_list; |
1280 |
|
n->data = data; |
1281 |
|
n->input_section = input_section; |
1282 |
|
n->rel = *reloc_entry; |
1283 |
|
mips_hi16_list = n; |
1284 |
|
|
1285 |
|
if (output_bfd != NULL) |
1286 |
|
reloc_entry->address += input_section->output_offset; |
1287 |
|
|
1288 |
|
return bfd_reloc_ok; |
1289 |
|
} |
1290 |
|
|
1291 |
|
/* A howto special_function for REL R_MIPS_GOT16 relocations. This is just |
1292 |
|
like any other 16-bit relocation when applied to global symbols, but is |
1293 |
|
treated in the same as R_MIPS_HI16 when applied to local symbols. */ |
1294 |
|
|
1295 |
|
bfd_reloc_status_type |
1296 |
|
_bfd_mips_elf_got16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, |
1297 |
|
void *data, asection *input_section, |
1298 |
|
bfd *output_bfd, char **error_message) |
1299 |
|
{ |
1300 |
|
if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0 |
1301 |
|
|| bfd_is_und_section (bfd_get_section (symbol)) |
1302 |
|
|| bfd_is_com_section (bfd_get_section (symbol))) |
1303 |
|
/* The relocation is against a global symbol. */ |
1304 |
|
return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data, |
1305 |
|
input_section, output_bfd, |
1306 |
|
error_message); |
1307 |
|
|
1308 |
|
return _bfd_mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data, |
1309 |
|
input_section, output_bfd, error_message); |
1310 |
|
} |
1311 |
|
|
1312 |
|
/* A howto special_function for REL *LO16 relocations. The *LO16 itself |
1313 |
|
is a straightforward 16 bit inplace relocation, but we must deal with |
1314 |
|
any partnering high-part relocations as well. */ |
1315 |
|
|
1316 |
|
bfd_reloc_status_type |
1317 |
|
_bfd_mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, |
1318 |
|
void *data, asection *input_section, |
1319 |
|
bfd *output_bfd, char **error_message) |
1320 |
|
{ |
1321 |
|
bfd_vma vallo; |
1322 |
|
bfd_byte *location = (bfd_byte *) data + reloc_entry->address; |
1323 |
|
|
1324 |
|
if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) |
1325 |
|
return bfd_reloc_outofrange; |
1326 |
|
|
1327 |
|
_bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE, |
1328 |
|
location); |
1329 |
|
vallo = bfd_get_32 (abfd, location); |
1330 |
|
_bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, FALSE, |
1331 |
|
location); |
1332 |
|
|
1333 |
|
while (mips_hi16_list != NULL) |
1334 |
|
{ |
1335 |
|
bfd_reloc_status_type ret; |
1336 |
|
struct mips_hi16 *hi; |
1337 |
|
|
1338 |
|
hi = mips_hi16_list; |
1339 |
|
|
1340 |
|
/* R_MIPS_GOT16 relocations are something of a special case. We |
1341 |
|
want to install the addend in the same way as for a R_MIPS_HI16 |
1342 |
|
relocation (with a rightshift of 16). However, since GOT16 |
1343 |
|
relocations can also be used with global symbols, their howto |
1344 |
|
has a rightshift of 0. */ |
1345 |
|
if (hi->rel.howto->type == R_MIPS_GOT16) |
1346 |
|
hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MIPS_HI16, FALSE); |
1347 |
|
|
1348 |
|
/* VALLO is a signed 16-bit number. Bias it by 0x8000 so that any |
1349 |
|
carry or borrow will induce a change of +1 or -1 in the high part. */ |
1350 |
|
hi->rel.addend += (vallo + 0x8000) & 0xffff; |
1351 |
|
|
1352 |
|
ret = _bfd_mips_elf_generic_reloc (abfd, &hi->rel, symbol, hi->data, |
1353 |
|
hi->input_section, output_bfd, |
1354 |
|
error_message); |
1355 |
|
if (ret != bfd_reloc_ok) |
1356 |
|
return ret; |
1357 |
|
|
1358 |
|
mips_hi16_list = hi->next; |
1359 |
|
free (hi); |
1360 |
|
} |
1361 |
|
|
1362 |
|
return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data, |
1363 |
|
input_section, output_bfd, |
1364 |
|
error_message); |
1365 |
|
} |
1366 |
|
|
1367 |
|
/* A generic howto special_function. This calculates and installs the |
1368 |
|
relocation itself, thus avoiding the oft-discussed problems in |
1369 |
|
bfd_perform_relocation and bfd_install_relocation. */ |
1370 |
|
|
1371 |
|
bfd_reloc_status_type |
1372 |
|
_bfd_mips_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, |
1373 |
|
asymbol *symbol, void *data ATTRIBUTE_UNUSED, |
1374 |
|
asection *input_section, bfd *output_bfd, |
1375 |
|
char **error_message ATTRIBUTE_UNUSED) |
1376 |
|
{ |
1377 |
|
bfd_signed_vma val; |
1378 |
|
bfd_reloc_status_type status; |
1379 |
|
bfd_boolean relocatable; |
1380 |
|
|
1381 |
|
relocatable = (output_bfd != NULL); |
1382 |
|
|
1383 |
|
if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) |
1384 |
|
return bfd_reloc_outofrange; |
1385 |
|
|
1386 |
|
/* Build up the field adjustment in VAL. */ |
1387 |
|
val = 0; |
1388 |
|
if (!relocatable || (symbol->flags & BSF_SECTION_SYM) != 0) |
1389 |
|
{ |
1390 |
|
/* Either we're calculating the final field value or we have a |
1391 |
|
relocation against a section symbol. Add in the section's |
1392 |
|
offset or address. */ |
1393 |
|
val += symbol->section->output_section->vma; |
1394 |
|
val += symbol->section->output_offset; |
1395 |
|
} |
1396 |
|
|
1397 |
|
if (!relocatable) |
1398 |
|
{ |
1399 |
|
/* We're calculating the final field value. Add in the symbol's value |
1400 |
|
and, if pc-relative, subtract the address of the field itself. */ |
1401 |
|
val += symbol->value; |
1402 |
|
if (reloc_entry->howto->pc_relative) |
1403 |
|
{ |
1404 |
|
val -= input_section->output_section->vma; |
1405 |
|
val -= input_section->output_offset; |
1406 |
|
val -= reloc_entry->address; |
1407 |
|
} |
1408 |
|
} |
1409 |
|
|
1410 |
|
/* VAL is now the final adjustment. If we're keeping this relocation |
1411 |
|
in the output file, and if the relocation uses a separate addend, |
1412 |
|
we just need to add VAL to that addend. Otherwise we need to add |
1413 |
|
VAL to the relocation field itself. */ |
1414 |
|
if (relocatable && !reloc_entry->howto->partial_inplace) |
1415 |
|
reloc_entry->addend += val; |
1416 |
|
else |
1417 |
|
{ |
1418 |
|
bfd_byte *location = (bfd_byte *) data + reloc_entry->address; |
1419 |
|
|
1420 |
|
/* Add in the separate addend, if any. */ |
1421 |
|
val += reloc_entry->addend; |
1422 |
|
|
1423 |
|
/* Add VAL to the relocation field. */ |
1424 |
|
_bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE, |
1425 |
|
location); |
1426 |
|
status = _bfd_relocate_contents (reloc_entry->howto, abfd, val, |
1427 |
|
location); |
1428 |
|
_bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, FALSE, |
1429 |
|
location); |
1430 |
|
|
1431 |
|
if (status != bfd_reloc_ok) |
1432 |
|
return status; |
1433 |
|
} |
1434 |
|
|
1435 |
|
if (relocatable) |
1436 |
|
reloc_entry->address += input_section->output_offset; |
1437 |
|
|
1438 |
return bfd_reloc_ok; |
return bfd_reloc_ok; |
1439 |
} |
} |
1442 |
on the equivalence of the two elements of the union. */ |
on the equivalence of the two elements of the union. */ |
1443 |
|
|
1444 |
static void |
static void |
1445 |
bfd_mips_elf32_swap_gptab_in (abfd, ex, in) |
bfd_mips_elf32_swap_gptab_in (bfd *abfd, const Elf32_External_gptab *ex, |
1446 |
bfd *abfd; |
Elf32_gptab *in) |
|
const Elf32_External_gptab *ex; |
|
|
Elf32_gptab *in; |
|
1447 |
{ |
{ |
1448 |
in->gt_entry.gt_g_value = H_GET_32 (abfd, ex->gt_entry.gt_g_value); |
in->gt_entry.gt_g_value = H_GET_32 (abfd, ex->gt_entry.gt_g_value); |
1449 |
in->gt_entry.gt_bytes = H_GET_32 (abfd, ex->gt_entry.gt_bytes); |
in->gt_entry.gt_bytes = H_GET_32 (abfd, ex->gt_entry.gt_bytes); |
1450 |
} |
} |
1451 |
|
|
1452 |
static void |
static void |
1453 |
bfd_mips_elf32_swap_gptab_out (abfd, in, ex) |
bfd_mips_elf32_swap_gptab_out (bfd *abfd, const Elf32_gptab *in, |
1454 |
bfd *abfd; |
Elf32_External_gptab *ex) |
|
const Elf32_gptab *in; |
|
|
Elf32_External_gptab *ex; |
|
1455 |
{ |
{ |
1456 |
H_PUT_32 (abfd, in->gt_entry.gt_g_value, ex->gt_entry.gt_g_value); |
H_PUT_32 (abfd, in->gt_entry.gt_g_value, ex->gt_entry.gt_g_value); |
1457 |
H_PUT_32 (abfd, in->gt_entry.gt_bytes, ex->gt_entry.gt_bytes); |
H_PUT_32 (abfd, in->gt_entry.gt_bytes, ex->gt_entry.gt_bytes); |
1458 |
} |
} |
1459 |
|
|
1460 |
static void |
static void |
1461 |
bfd_elf32_swap_compact_rel_out (abfd, in, ex) |
bfd_elf32_swap_compact_rel_out (bfd *abfd, const Elf32_compact_rel *in, |
1462 |
bfd *abfd; |
Elf32_External_compact_rel *ex) |
|
const Elf32_compact_rel *in; |
|
|
Elf32_External_compact_rel *ex; |
|
1463 |
{ |
{ |
1464 |
H_PUT_32 (abfd, in->id1, ex->id1); |
H_PUT_32 (abfd, in->id1, ex->id1); |
1465 |
H_PUT_32 (abfd, in->num, ex->num); |
H_PUT_32 (abfd, in->num, ex->num); |
1470 |
} |
} |
1471 |
|
|
1472 |
static void |
static void |
1473 |
bfd_elf32_swap_crinfo_out (abfd, in, ex) |
bfd_elf32_swap_crinfo_out (bfd *abfd, const Elf32_crinfo *in, |
1474 |
bfd *abfd; |
Elf32_External_crinfo *ex) |
|
const Elf32_crinfo *in; |
|
|
Elf32_External_crinfo *ex; |
|
1475 |
{ |
{ |
1476 |
unsigned long l; |
unsigned long l; |
1477 |
|
|
1483 |
H_PUT_32 (abfd, in->konst, ex->konst); |
H_PUT_32 (abfd, in->konst, ex->konst); |
1484 |
H_PUT_32 (abfd, in->vaddr, ex->vaddr); |
H_PUT_32 (abfd, in->vaddr, ex->vaddr); |
1485 |
} |
} |
|
|
|
|
#if 0 |
|
|
/* Swap in an MSYM entry. */ |
|
|
|
|
|
static void |
|
|
bfd_mips_elf_swap_msym_in (abfd, ex, in) |
|
|
bfd *abfd; |
|
|
const Elf32_External_Msym *ex; |
|
|
Elf32_Internal_Msym *in; |
|
|
{ |
|
|
in->ms_hash_value = H_GET_32 (abfd, ex->ms_hash_value); |
|
|
in->ms_info = H_GET_32 (abfd, ex->ms_info); |
|
|
} |
|
|
#endif |
|
|
/* Swap out an MSYM entry. */ |
|
|
|
|
|
static void |
|
|
bfd_mips_elf_swap_msym_out (abfd, in, ex) |
|
|
bfd *abfd; |
|
|
const Elf32_Internal_Msym *in; |
|
|
Elf32_External_Msym *ex; |
|
|
{ |
|
|
H_PUT_32 (abfd, in->ms_hash_value, ex->ms_hash_value); |
|
|
H_PUT_32 (abfd, in->ms_info, ex->ms_info); |
|
|
} |
|
1486 |
|
|
1487 |
/* A .reginfo section holds a single Elf32_RegInfo structure. These |
/* A .reginfo section holds a single Elf32_RegInfo structure. These |
1488 |
routines swap this structure in and out. They are used outside of |
routines swap this structure in and out. They are used outside of |
1489 |
BFD, so they are globally visible. */ |
BFD, so they are globally visible. */ |
1490 |
|
|
1491 |
void |
void |
1492 |
bfd_mips_elf32_swap_reginfo_in (abfd, ex, in) |
bfd_mips_elf32_swap_reginfo_in (bfd *abfd, const Elf32_External_RegInfo *ex, |
1493 |
bfd *abfd; |
Elf32_RegInfo *in) |
|
const Elf32_External_RegInfo *ex; |
|
|
Elf32_RegInfo *in; |
|
1494 |
{ |
{ |
1495 |
in->ri_gprmask = H_GET_32 (abfd, ex->ri_gprmask); |
in->ri_gprmask = H_GET_32 (abfd, ex->ri_gprmask); |
1496 |
in->ri_cprmask[0] = H_GET_32 (abfd, ex->ri_cprmask[0]); |
in->ri_cprmask[0] = H_GET_32 (abfd, ex->ri_cprmask[0]); |
1501 |
} |
} |
1502 |
|
|
1503 |
void |
void |
1504 |
bfd_mips_elf32_swap_reginfo_out (abfd, in, ex) |
bfd_mips_elf32_swap_reginfo_out (bfd *abfd, const Elf32_RegInfo *in, |
1505 |
bfd *abfd; |
Elf32_External_RegInfo *ex) |
|
const Elf32_RegInfo *in; |
|
|
Elf32_External_RegInfo *ex; |
|
1506 |
{ |
{ |
1507 |
H_PUT_32 (abfd, in->ri_gprmask, ex->ri_gprmask); |
H_PUT_32 (abfd, in->ri_gprmask, ex->ri_gprmask); |
1508 |
H_PUT_32 (abfd, in->ri_cprmask[0], ex->ri_cprmask[0]); |
H_PUT_32 (abfd, in->ri_cprmask[0], ex->ri_cprmask[0]); |
1519 |
without worrying about whether the 64 bit ABI has been included. */ |
without worrying about whether the 64 bit ABI has been included. */ |
1520 |
|
|
1521 |
void |
void |
1522 |
bfd_mips_elf64_swap_reginfo_in (abfd, ex, in) |
bfd_mips_elf64_swap_reginfo_in (bfd *abfd, const Elf64_External_RegInfo *ex, |
1523 |
bfd *abfd; |
Elf64_Internal_RegInfo *in) |
|
const Elf64_External_RegInfo *ex; |
|
|
Elf64_Internal_RegInfo *in; |
|
1524 |
{ |
{ |
1525 |
in->ri_gprmask = H_GET_32 (abfd, ex->ri_gprmask); |
in->ri_gprmask = H_GET_32 (abfd, ex->ri_gprmask); |
1526 |
in->ri_pad = H_GET_32 (abfd, ex->ri_pad); |
in->ri_pad = H_GET_32 (abfd, ex->ri_pad); |
1532 |
} |
} |
1533 |
|
|
1534 |
void |
void |
1535 |
bfd_mips_elf64_swap_reginfo_out (abfd, in, ex) |
bfd_mips_elf64_swap_reginfo_out (bfd *abfd, const Elf64_Internal_RegInfo *in, |
1536 |
bfd *abfd; |
Elf64_External_RegInfo *ex) |
|
const Elf64_Internal_RegInfo *in; |
|
|
Elf64_External_RegInfo *ex; |
|
1537 |
{ |
{ |
1538 |
H_PUT_32 (abfd, in->ri_gprmask, ex->ri_gprmask); |
H_PUT_32 (abfd, in->ri_gprmask, ex->ri_gprmask); |
1539 |
H_PUT_32 (abfd, in->ri_pad, ex->ri_pad); |
H_PUT_32 (abfd, in->ri_pad, ex->ri_pad); |
1547 |
/* Swap in an options header. */ |
/* Swap in an options header. */ |
1548 |
|
|
1549 |
void |
void |
1550 |
bfd_mips_elf_swap_options_in (abfd, ex, in) |
bfd_mips_elf_swap_options_in (bfd *abfd, const Elf_External_Options *ex, |
1551 |
bfd *abfd; |
Elf_Internal_Options *in) |
|
const Elf_External_Options *ex; |
|
|
Elf_Internal_Options *in; |
|
1552 |
{ |
{ |
1553 |
in->kind = H_GET_8 (abfd, ex->kind); |
in->kind = H_GET_8 (abfd, ex->kind); |
1554 |
in->size = H_GET_8 (abfd, ex->size); |
in->size = H_GET_8 (abfd, ex->size); |
1559 |
/* Swap out an options header. */ |
/* Swap out an options header. */ |
1560 |
|
|
1561 |
void |
void |
1562 |
bfd_mips_elf_swap_options_out (abfd, in, ex) |
bfd_mips_elf_swap_options_out (bfd *abfd, const Elf_Internal_Options *in, |
1563 |
bfd *abfd; |
Elf_External_Options *ex) |
|
const Elf_Internal_Options *in; |
|
|
Elf_External_Options *ex; |
|
1564 |
{ |
{ |
1565 |
H_PUT_8 (abfd, in->kind, ex->kind); |
H_PUT_8 (abfd, in->kind, ex->kind); |
1566 |
H_PUT_8 (abfd, in->size, ex->size); |
H_PUT_8 (abfd, in->size, ex->size); |
1572 |
entries by increasing r_symndx value. */ |
entries by increasing r_symndx value. */ |
1573 |
|
|
1574 |
static int |
static int |
1575 |
sort_dynamic_relocs (arg1, arg2) |
sort_dynamic_relocs (const void *arg1, const void *arg2) |
|
const PTR arg1; |
|
|
const PTR arg2; |
|
1576 |
{ |
{ |
1577 |
const Elf32_External_Rel *ext_reloc1 = (const Elf32_External_Rel *) arg1; |
Elf_Internal_Rela int_reloc1; |
1578 |
const Elf32_External_Rel *ext_reloc2 = (const Elf32_External_Rel *) arg2; |
Elf_Internal_Rela int_reloc2; |
1579 |
|
|
1580 |
|
bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1); |
1581 |
|
bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2); |
1582 |
|
|
1583 |
Elf_Internal_Rel int_reloc1; |
return ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info); |
1584 |
Elf_Internal_Rel int_reloc2; |
} |
1585 |
|
|
1586 |
bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, ext_reloc1, &int_reloc1); |
/* Like sort_dynamic_relocs, but used for elf64 relocations. */ |
|
bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, ext_reloc2, &int_reloc2); |
|
1587 |
|
|
1588 |
return (ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info)); |
static int |
1589 |
|
sort_dynamic_relocs_64 (const void *arg1 ATTRIBUTE_UNUSED, |
1590 |
|
const void *arg2 ATTRIBUTE_UNUSED) |
1591 |
|
{ |
1592 |
|
#ifdef BFD64 |
1593 |
|
Elf_Internal_Rela int_reloc1[3]; |
1594 |
|
Elf_Internal_Rela int_reloc2[3]; |
1595 |
|
|
1596 |
|
(*get_elf_backend_data (reldyn_sorting_bfd)->s->swap_reloc_in) |
1597 |
|
(reldyn_sorting_bfd, arg1, int_reloc1); |
1598 |
|
(*get_elf_backend_data (reldyn_sorting_bfd)->s->swap_reloc_in) |
1599 |
|
(reldyn_sorting_bfd, arg2, int_reloc2); |
1600 |
|
|
1601 |
|
return (ELF64_R_SYM (int_reloc1[0].r_info) |
1602 |
|
- ELF64_R_SYM (int_reloc2[0].r_info)); |
1603 |
|
#else |
1604 |
|
abort (); |
1605 |
|
#endif |
1606 |
} |
} |
1607 |
|
|
1608 |
|
|
1609 |
/* This routine is used to write out ECOFF debugging external symbol |
/* This routine is used to write out ECOFF debugging external symbol |
1610 |
information. It is called via mips_elf_link_hash_traverse. The |
information. It is called via mips_elf_link_hash_traverse. The |
1611 |
ECOFF external symbol information must match the ELF external |
ECOFF external symbol information must match the ELF external |
1620 |
stripped but required by a reloc. In particular, it can not happen |
stripped but required by a reloc. In particular, it can not happen |
1621 |
when generating a final executable. */ |
when generating a final executable. */ |
1622 |
|
|
1623 |
static boolean |
static bfd_boolean |
1624 |
mips_elf_output_extsym (h, data) |
mips_elf_output_extsym (struct mips_elf_link_hash_entry *h, void *data) |
|
struct mips_elf_link_hash_entry *h; |
|
|
PTR data; |
|
1625 |
{ |
{ |
1626 |
struct extsym_info *einfo = (struct extsym_info *) data; |
struct extsym_info *einfo = data; |
1627 |
boolean strip; |
bfd_boolean strip; |
1628 |
asection *sec, *output_section; |
asection *sec, *output_section; |
1629 |
|
|
1630 |
if (h->root.root.type == bfd_link_hash_warning) |
if (h->root.root.type == bfd_link_hash_warning) |
1631 |
h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link; |
h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link; |
1632 |
|
|
1633 |
if (h->root.indx == -2) |
if (h->root.indx == -2) |
1634 |
strip = false; |
strip = FALSE; |
1635 |
else if (((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 |
else if ((h->root.def_dynamic |
1636 |
|| (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0) |
|| h->root.ref_dynamic |
1637 |
&& (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 |
|| h->root.type == bfd_link_hash_new) |
1638 |
&& (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) |
&& !h->root.def_regular |
1639 |
strip = true; |
&& !h->root.ref_regular) |
1640 |
|
strip = TRUE; |
1641 |
else if (einfo->info->strip == strip_all |
else if (einfo->info->strip == strip_all |
1642 |
|| (einfo->info->strip == strip_some |
|| (einfo->info->strip == strip_some |
1643 |
&& bfd_hash_lookup (einfo->info->keep_hash, |
&& bfd_hash_lookup (einfo->info->keep_hash, |
1644 |
h->root.root.root.string, |
h->root.root.root.string, |
1645 |
false, false) == NULL)) |
FALSE, FALSE) == NULL)) |
1646 |
strip = true; |
strip = TRUE; |
1647 |
else |
else |
1648 |
strip = false; |
strip = FALSE; |
1649 |
|
|
1650 |
if (strip) |
if (strip) |
1651 |
return true; |
return TRUE; |
1652 |
|
|
1653 |
if (h->esym.ifd == -2) |
if (h->esym.ifd == -2) |
1654 |
{ |
{ |
1754 |
else |
else |
1755 |
h->esym.asym.value = 0; |
h->esym.asym.value = 0; |
1756 |
} |
} |
1757 |
else if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) |
else if (h->root.needs_plt) |
1758 |
{ |
{ |
1759 |
struct mips_elf_link_hash_entry *hd = h; |
struct mips_elf_link_hash_entry *hd = h; |
1760 |
boolean no_fn_stub = h->no_fn_stub; |
bfd_boolean no_fn_stub = h->no_fn_stub; |
1761 |
|
|
1762 |
while (hd->root.root.type == bfd_link_hash_indirect) |
while (hd->root.root.type == bfd_link_hash_indirect) |
1763 |
{ |
{ |
1782 |
else |
else |
1783 |
h->esym.asym.value = 0; |
h->esym.asym.value = 0; |
1784 |
} |
} |
|
#if 0 /* FIXME? */ |
|
|
h->esym.ifd = 0; |
|
|
#endif |
|
1785 |
} |
} |
1786 |
} |
} |
1787 |
|
|
1789 |
h->root.root.root.string, |
h->root.root.root.string, |
1790 |
&h->esym)) |
&h->esym)) |
1791 |
{ |
{ |
1792 |
einfo->failed = true; |
einfo->failed = TRUE; |
1793 |
return false; |
return FALSE; |
1794 |
} |
} |
1795 |
|
|
1796 |
return true; |
return TRUE; |
1797 |
} |
} |
1798 |
|
|
1799 |
/* A comparison routine used to sort .gptab entries. */ |
/* A comparison routine used to sort .gptab entries. */ |
1800 |
|
|
1801 |
static int |
static int |
1802 |
gptab_compare (p1, p2) |
gptab_compare (const void *p1, const void *p2) |
|
const PTR p1; |
|
|
const PTR p2; |
|
1803 |
{ |
{ |
1804 |
const Elf32_gptab *a1 = (const Elf32_gptab *) p1; |
const Elf32_gptab *a1 = p1; |
1805 |
const Elf32_gptab *a2 = (const Elf32_gptab *) p2; |
const Elf32_gptab *a2 = p2; |
1806 |
|
|
1807 |
return a1->gt_entry.gt_g_value - a2->gt_entry.gt_g_value; |
return a1->gt_entry.gt_g_value - a2->gt_entry.gt_g_value; |
1808 |
} |
} |
1809 |
|
|
1810 |
|
/* Functions to manage the got entry hash table. */ |
1811 |
|
|
1812 |
|
/* Use all 64 bits of a bfd_vma for the computation of a 32-bit |
1813 |
|
hash number. */ |
1814 |
|
|
1815 |
|
static INLINE hashval_t |
1816 |
|
mips_elf_hash_bfd_vma (bfd_vma addr) |
1817 |
|
{ |
1818 |
|
#ifdef BFD64 |
1819 |
|
return addr + (addr >> 32); |
1820 |
|
#else |
1821 |
|
return addr; |
1822 |
|
#endif |
1823 |
|
} |
1824 |
|
|
1825 |
|
/* got_entries only match if they're identical, except for gotidx, so |
1826 |
|
use all fields to compute the hash, and compare the appropriate |
1827 |
|
union members. */ |
1828 |
|
|
1829 |
|
static hashval_t |
1830 |
|
mips_elf_got_entry_hash (const void *entry_) |
1831 |
|
{ |
1832 |
|
const struct mips_got_entry *entry = (struct mips_got_entry *)entry_; |
1833 |
|
|
1834 |
|
return entry->symndx |
1835 |
|
+ ((entry->tls_type & GOT_TLS_LDM) << 17) |
1836 |
|
+ (! entry->abfd ? mips_elf_hash_bfd_vma (entry->d.address) |
1837 |
|
: entry->abfd->id |
1838 |
|
+ (entry->symndx >= 0 ? mips_elf_hash_bfd_vma (entry->d.addend) |
1839 |
|
: entry->d.h->root.root.root.hash)); |
1840 |
|
} |
1841 |
|
|
1842 |
|
static int |
1843 |
|
mips_elf_got_entry_eq (const void *entry1, const void *entry2) |
1844 |
|
{ |
1845 |
|
const struct mips_got_entry *e1 = (struct mips_got_entry *)entry1; |
1846 |
|
const struct mips_got_entry *e2 = (struct mips_got_entry *)entry2; |
1847 |
|
|
1848 |
|
/* An LDM entry can only match another LDM entry. */ |
1849 |
|
if ((e1->tls_type ^ e2->tls_type) & GOT_TLS_LDM) |
1850 |
|
return 0; |
1851 |
|
|
1852 |
|
return e1->abfd == e2->abfd && e1->symndx == e2->symndx |
1853 |
|
&& (! e1->abfd ? e1->d.address == e2->d.address |
1854 |
|
: e1->symndx >= 0 ? e1->d.addend == e2->d.addend |
1855 |
|
: e1->d.h == e2->d.h); |
1856 |
|
} |
1857 |
|
|
1858 |
|
/* multi_got_entries are still a match in the case of global objects, |
1859 |
|
even if the input bfd in which they're referenced differs, so the |
1860 |
|
hash computation and compare functions are adjusted |
1861 |
|
accordingly. */ |
1862 |
|
|
1863 |
|
static hashval_t |
1864 |
|
mips_elf_multi_got_entry_hash (const void *entry_) |
1865 |
|
{ |
1866 |
|
const struct mips_got_entry *entry = (struct mips_got_entry *)entry_; |
1867 |
|
|
1868 |
|
return entry->symndx |
1869 |
|
+ (! entry->abfd |
1870 |
|
? mips_elf_hash_bfd_vma (entry->d.address) |
1871 |
|
: entry->symndx >= 0 |
1872 |
|
? ((entry->tls_type & GOT_TLS_LDM) |
1873 |
|
? (GOT_TLS_LDM << 17) |
1874 |
|
: (entry->abfd->id |
1875 |
|
+ mips_elf_hash_bfd_vma (entry->d.addend))) |
1876 |
|
: entry->d.h->root.root.root.hash); |
1877 |
|
} |
1878 |
|
|
1879 |
|
static int |
1880 |
|
mips_elf_multi_got_entry_eq (const void *entry1, const void *entry2) |
1881 |
|
{ |
1882 |
|
const struct mips_got_entry *e1 = (struct mips_got_entry *)entry1; |
1883 |
|
const struct mips_got_entry *e2 = (struct mips_got_entry *)entry2; |
1884 |
|
|
1885 |
|
/* Any two LDM entries match. */ |
1886 |
|
if (e1->tls_type & e2->tls_type & GOT_TLS_LDM) |
1887 |
|
return 1; |
1888 |
|
|
1889 |
|
/* Nothing else matches an LDM entry. */ |
1890 |
|
if ((e1->tls_type ^ e2->tls_type) & GOT_TLS_LDM) |
1891 |
|
return 0; |
1892 |
|
|
1893 |
|
return e1->symndx == e2->symndx |
1894 |
|
&& (e1->symndx >= 0 ? e1->abfd == e2->abfd && e1->d.addend == e2->d.addend |
1895 |
|
: e1->abfd == NULL || e2->abfd == NULL |
1896 |
|
? e1->abfd == e2->abfd && e1->d.address == e2->d.address |
1897 |
|
: e1->d.h == e2->d.h); |
1898 |
|
} |
1899 |
|
|
1900 |
|
/* Returns the dynamic relocation section for DYNOBJ. */ |
1901 |
|
|
1902 |
|
static asection * |
1903 |
|
mips_elf_rel_dyn_section (bfd *dynobj, bfd_boolean create_p) |
1904 |
|
{ |
1905 |
|
static const char dname[] = ".rel.dyn"; |
1906 |
|
asection *sreloc; |
1907 |
|
|
1908 |
|
sreloc = bfd_get_section_by_name (dynobj, dname); |
1909 |
|
if (sreloc == NULL && create_p) |
1910 |
|
{ |
1911 |
|
sreloc = bfd_make_section (dynobj, dname); |
1912 |
|
if (sreloc == NULL |
1913 |
|
|| ! bfd_set_section_flags (dynobj, sreloc, |
1914 |
|
(SEC_ALLOC |
1915 |
|
| SEC_LOAD |
1916 |
|
| SEC_HAS_CONTENTS |
1917 |
|
| SEC_IN_MEMORY |
1918 |
|
| SEC_LINKER_CREATED |
1919 |
|
| SEC_READONLY)) |
1920 |
|
|| ! bfd_set_section_alignment (dynobj, sreloc, |
1921 |
|
MIPS_ELF_LOG_FILE_ALIGN (dynobj))) |
1922 |
|
return NULL; |
1923 |
|
} |
1924 |
|
return sreloc; |
1925 |
|
} |
1926 |
|
|
1927 |
/* Returns the GOT section for ABFD. */ |
/* Returns the GOT section for ABFD. */ |
1928 |
|
|
1929 |
static asection * |
static asection * |
1930 |
mips_elf_got_section (abfd) |
mips_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded) |
|
bfd *abfd; |
|
1931 |
{ |
{ |
1932 |
return bfd_get_section_by_name (abfd, ".got"); |
asection *sgot = bfd_get_section_by_name (abfd, ".got"); |
1933 |
|
if (sgot == NULL |
1934 |
|
|| (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0)) |
1935 |
|
return NULL; |
1936 |
|
return sgot; |
1937 |
} |
} |
1938 |
|
|
1939 |
/* Returns the GOT information associated with the link indicated by |
/* Returns the GOT information associated with the link indicated by |
1941 |
section. */ |
section. */ |
1942 |
|
|
1943 |
static struct mips_got_info * |
static struct mips_got_info * |
1944 |
mips_elf_got_info (abfd, sgotp) |
mips_elf_got_info (bfd *abfd, asection **sgotp) |
|
bfd *abfd; |
|
|
asection **sgotp; |
|
1945 |
{ |
{ |
1946 |
asection *sgot; |
asection *sgot; |
1947 |
struct mips_got_info *g; |
struct mips_got_info *g; |
1948 |
|
|
1949 |
sgot = mips_elf_got_section (abfd); |
sgot = mips_elf_got_section (abfd, TRUE); |
1950 |
BFD_ASSERT (sgot != NULL); |
BFD_ASSERT (sgot != NULL); |
1951 |
BFD_ASSERT (elf_section_data (sgot) != NULL); |
BFD_ASSERT (mips_elf_section_data (sgot) != NULL); |
1952 |
g = (struct mips_got_info *) elf_section_data (sgot)->tdata; |
g = mips_elf_section_data (sgot)->u.got_info; |
1953 |
BFD_ASSERT (g != NULL); |
BFD_ASSERT (g != NULL); |
1954 |
|
|
1955 |
if (sgotp) |
if (sgotp) |
1956 |
*sgotp = sgot; |
*sgotp = (sgot->flags & SEC_EXCLUDE) == 0 ? sgot : NULL; |
1957 |
|
|
1958 |
return g; |
return g; |
1959 |
} |
} |
1960 |
|
|
1961 |
|
/* Count the number of relocations needed for a TLS GOT entry, with |
1962 |
|
access types from TLS_TYPE, and symbol H (or a local symbol if H |
1963 |
|
is NULL). */ |
1964 |
|
|
1965 |
|
static int |
1966 |
|
mips_tls_got_relocs (struct bfd_link_info *info, unsigned char tls_type, |
1967 |
|
struct elf_link_hash_entry *h) |
1968 |
|
{ |
1969 |
|
int indx = 0; |
1970 |
|
int ret = 0; |
1971 |
|
bfd_boolean need_relocs = FALSE; |
1972 |
|
bfd_boolean dyn = elf_hash_table (info)->dynamic_sections_created; |
1973 |
|
|
1974 |
|
if (h && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) |
1975 |
|
&& (!info->shared || !SYMBOL_REFERENCES_LOCAL (info, h))) |
1976 |
|
indx = h->dynindx; |
1977 |
|
|
1978 |
|
if ((info->shared || indx != 0) |
1979 |
|
&& (h == NULL |
1980 |
|
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT |
1981 |
|
|| h->root.type != bfd_link_hash_undefweak)) |
1982 |
|
need_relocs = TRUE; |
1983 |
|
|
1984 |
|
if (!need_relocs) |
1985 |
|
return FALSE; |
1986 |
|
|
1987 |
|
if (tls_type & GOT_TLS_GD) |
1988 |
|
{ |
1989 |
|
ret++; |
1990 |
|
if (indx != 0) |
1991 |
|
ret++; |
1992 |
|
} |
1993 |
|
|
1994 |
|
if (tls_type & GOT_TLS_IE) |
1995 |
|
ret++; |
1996 |
|
|
1997 |
|
if ((tls_type & GOT_TLS_LDM) && info->shared) |
1998 |
|
ret++; |
1999 |
|
|
2000 |
|
return ret; |
2001 |
|
} |
2002 |
|
|
2003 |
|
/* Count the number of TLS relocations required for the GOT entry in |
2004 |
|
ARG1, if it describes a local symbol. */ |
2005 |
|
|
2006 |
|
static int |
2007 |
|
mips_elf_count_local_tls_relocs (void **arg1, void *arg2) |
2008 |
|
{ |
2009 |
|
struct mips_got_entry *entry = * (struct mips_got_entry **) arg1; |
2010 |
|
struct mips_elf_count_tls_arg *arg = arg2; |
2011 |
|
|
2012 |
|
if (entry->abfd != NULL && entry->symndx != -1) |
2013 |
|
arg->needed += mips_tls_got_relocs (arg->info, entry->tls_type, NULL); |
2014 |
|
|
2015 |
|
return 1; |
2016 |
|
} |
2017 |
|
|
2018 |
|
/* Count the number of TLS GOT entries required for the global (or |
2019 |
|
forced-local) symbol in ARG1. */ |
2020 |
|
|
2021 |
|
static int |
2022 |
|
mips_elf_count_global_tls_entries (void *arg1, void *arg2) |
2023 |
|
{ |
2024 |
|
struct mips_elf_link_hash_entry *hm |
2025 |
|
= (struct mips_elf_link_hash_entry *) arg1; |
2026 |
|
struct mips_elf_count_tls_arg *arg = arg2; |
2027 |
|
|
2028 |
|
if (hm->tls_type & GOT_TLS_GD) |
2029 |
|
arg->needed += 2; |
2030 |
|
if (hm->tls_type & GOT_TLS_IE) |
2031 |
|
arg->needed += 1; |
2032 |
|
|
2033 |
|
return 1; |
2034 |
|
} |
2035 |
|
|
2036 |
|
/* Count the number of TLS relocations required for the global (or |
2037 |
|
forced-local) symbol in ARG1. */ |
2038 |
|
|
2039 |
|
static int |
2040 |
|
mips_elf_count_global_tls_relocs (void *arg1, void *arg2) |
2041 |
|
{ |
2042 |
|
struct mips_elf_link_hash_entry *hm |
2043 |
|
= (struct mips_elf_link_hash_entry *) arg1; |
2044 |
|
struct mips_elf_count_tls_arg *arg = arg2; |
2045 |
|
|
2046 |
|
arg->needed += mips_tls_got_relocs (arg->info, hm->tls_type, &hm->root); |
2047 |
|
|
2048 |
|
return 1; |
2049 |
|
} |
2050 |
|
|
2051 |
|
/* Output a simple dynamic relocation into SRELOC. */ |
2052 |
|
|
2053 |
|
static void |
2054 |
|
mips_elf_output_dynamic_relocation (bfd *output_bfd, |
2055 |
|
asection *sreloc, |
2056 |
|
unsigned long indx, |
2057 |
|
int r_type, |
2058 |
|
bfd_vma offset) |
2059 |
|
{ |
2060 |
|
Elf_Internal_Rela rel[3]; |
2061 |
|
|
2062 |
|
memset (rel, 0, sizeof (rel)); |
2063 |
|
|
2064 |
|
rel[0].r_info = ELF_R_INFO (output_bfd, indx, r_type); |
2065 |
|
rel[0].r_offset = rel[1].r_offset = rel[2].r_offset = offset; |
2066 |
|
|
2067 |
|
if (ABI_64_P (output_bfd)) |
2068 |
|
{ |
2069 |
|
(*get_elf_backend_data (output_bfd)->s->swap_reloc_out) |
2070 |
|
(output_bfd, &rel[0], |
2071 |
|
(sreloc->contents |
2072 |
|
+ sreloc->reloc_count * sizeof (Elf64_Mips_External_Rel))); |
2073 |
|
} |
2074 |
|
else |
2075 |
|
bfd_elf32_swap_reloc_out |
2076 |
|
(output_bfd, &rel[0], |
2077 |
|
(sreloc->contents |
2078 |
|
+ sreloc->reloc_count * sizeof (Elf32_External_Rel))); |
2079 |
|
++sreloc->reloc_count; |
2080 |
|
} |
2081 |
|
|
2082 |
|
/* Initialize a set of TLS GOT entries for one symbol. */ |
2083 |
|
|
2084 |
|
static void |
2085 |
|
mips_elf_initialize_tls_slots (bfd *abfd, bfd_vma got_offset, |
2086 |
|
unsigned char *tls_type_p, |
2087 |
|
struct bfd_link_info *info, |
2088 |
|
struct mips_elf_link_hash_entry *h, |
2089 |
|
bfd_vma value) |
2090 |
|
{ |
2091 |
|
int indx; |
2092 |
|
asection *sreloc, *sgot; |
2093 |
|
bfd_vma offset, offset2; |
2094 |
|
bfd *dynobj; |
2095 |
|
bfd_boolean need_relocs = FALSE; |
2096 |
|
|
2097 |
|
dynobj = elf_hash_table (info)->dynobj; |
2098 |
|
sgot = mips_elf_got_section (dynobj, FALSE); |
2099 |
|
|
2100 |
|
indx = 0; |
2101 |
|
if (h != NULL) |
2102 |
|
{ |
2103 |
|
bfd_boolean dyn = elf_hash_table (info)->dynamic_sections_created; |
2104 |
|
|
2105 |
|
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, &h->root) |
2106 |
|
&& (!info->shared || !SYMBOL_REFERENCES_LOCAL (info, &h->root))) |
2107 |
|
indx = h->root.dynindx; |
2108 |
|
} |
2109 |
|
|
2110 |
|
if (*tls_type_p & GOT_TLS_DONE) |
2111 |
|
return; |
2112 |
|
|
2113 |
|
if ((info->shared || indx != 0) |
2114 |
|
&& (h == NULL |
2115 |
|
|| ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT |
2116 |
|
|| h->root.type != bfd_link_hash_undefweak)) |
2117 |
|
need_relocs = TRUE; |
2118 |
|
|
2119 |
|
/* MINUS_ONE means the symbol is not defined in this object. It may not |
2120 |
|
be defined at all; assume that the value doesn't matter in that |
2121 |
|
case. Otherwise complain if we would use the value. */ |
2122 |
|
BFD_ASSERT (value != MINUS_ONE || (indx != 0 && need_relocs) |
2123 |
|
|| h->root.root.type == bfd_link_hash_undefweak); |
2124 |
|
|
2125 |
|
/* Emit necessary relocations. */ |
2126 |
|
sreloc = mips_elf_rel_dyn_section (dynobj, FALSE); |
2127 |
|
|
2128 |
|
/* General Dynamic. */ |
2129 |
|
if (*tls_type_p & GOT_TLS_GD) |
2130 |
|
{ |
2131 |
|
offset = got_offset; |
2132 |
|
offset2 = offset + MIPS_ELF_GOT_SIZE (abfd); |
2133 |
|
|
2134 |
|
if (need_relocs) |
2135 |
|
{ |
2136 |
|
mips_elf_output_dynamic_relocation |
2137 |
|
(abfd, sreloc, indx, |
2138 |
|
ABI_64_P (abfd) ? R_MIPS_TLS_DTPMOD64 : R_MIPS_TLS_DTPMOD32, |
2139 |
|
sgot->output_offset + sgot->output_section->vma + offset); |
2140 |
|
|
2141 |
|
if (indx) |
2142 |
|
mips_elf_output_dynamic_relocation |
2143 |
|
(abfd, sreloc, indx, |
2144 |
|
ABI_64_P (abfd) ? R_MIPS_TLS_DTPREL64 : R_MIPS_TLS_DTPREL32, |
2145 |
|
sgot->output_offset + sgot->output_section->vma + offset2); |
2146 |
|
else |
2147 |
|
MIPS_ELF_PUT_WORD (abfd, value - dtprel_base (info), |
2148 |
|
sgot->contents + offset2); |
2149 |
|
} |
2150 |
|
else |
2151 |
|
{ |
2152 |
|
MIPS_ELF_PUT_WORD (abfd, 1, |
2153 |
|
sgot->contents + offset); |
2154 |
|
MIPS_ELF_PUT_WORD (abfd, value - dtprel_base (info), |
2155 |
|
sgot->contents + offset2); |
2156 |
|
} |
2157 |
|
|
2158 |
|
got_offset += 2 * MIPS_ELF_GOT_SIZE (abfd); |
2159 |
|
} |
2160 |
|
|
2161 |
|
/* Initial Exec model. */ |
2162 |
|
if (*tls_type_p & GOT_TLS_IE) |
2163 |
|
{ |
2164 |
|
offset = got_offset; |
2165 |
|
|
2166 |
|
if (need_relocs) |
2167 |
|
{ |
2168 |
|
if (indx == 0) |
2169 |
|
MIPS_ELF_PUT_WORD (abfd, value - elf_hash_table (info)->tls_sec->vma, |
2170 |
|
sgot->contents + offset); |
2171 |
|
else |
2172 |
|
MIPS_ELF_PUT_WORD (abfd, 0, |
2173 |
|
sgot->contents + offset); |
2174 |
|
|
2175 |
|
mips_elf_output_dynamic_relocation |
2176 |
|
(abfd, sreloc, indx, |
2177 |
|
ABI_64_P (abfd) ? R_MIPS_TLS_TPREL64 : R_MIPS_TLS_TPREL32, |
2178 |
|
sgot->output_offset + sgot->output_section->vma + offset); |
2179 |
|
} |
2180 |
|
else |
2181 |
|
MIPS_ELF_PUT_WORD (abfd, value - tprel_base (info), |
2182 |
|
sgot->contents + offset); |
2183 |
|
} |
2184 |
|
|
2185 |
|
if (*tls_type_p & GOT_TLS_LDM) |
2186 |
|
{ |
2187 |
|
/* The initial offset is zero, and the LD offsets will include the |
2188 |
|
bias by DTP_OFFSET. */ |
2189 |
|
MIPS_ELF_PUT_WORD (abfd, 0, |
2190 |
|
sgot->contents + got_offset |
2191 |
|
+ MIPS_ELF_GOT_SIZE (abfd)); |
2192 |
|
|
2193 |
|
if (!info->shared) |
2194 |
|
MIPS_ELF_PUT_WORD (abfd, 1, |
2195 |
|
sgot->contents + got_offset); |
2196 |
|
else |
2197 |
|
mips_elf_output_dynamic_relocation |
2198 |
|
(abfd, sreloc, indx, |
2199 |
|
ABI_64_P (abfd) ? R_MIPS_TLS_DTPMOD64 : R_MIPS_TLS_DTPMOD32, |
2200 |
|
sgot->output_offset + sgot->output_section->vma + got_offset); |
2201 |
|
} |
2202 |
|
|
2203 |
|
*tls_type_p |= GOT_TLS_DONE; |
2204 |
|
} |
2205 |
|
|
2206 |
|
/* Return the GOT index to use for a relocation of type R_TYPE against |
2207 |
|
a symbol accessed using TLS_TYPE models. The GOT entries for this |
2208 |
|
symbol in this GOT start at GOT_INDEX. This function initializes the |
2209 |
|
GOT entries and corresponding relocations. */ |
2210 |
|
|
2211 |
|
static bfd_vma |
2212 |
|
mips_tls_got_index (bfd *abfd, bfd_vma got_index, unsigned char *tls_type, |
2213 |
|
int r_type, struct bfd_link_info *info, |
2214 |
|
struct mips_elf_link_hash_entry *h, bfd_vma symbol) |
2215 |
|
{ |
2216 |
|
BFD_ASSERT (r_type == R_MIPS_TLS_GOTTPREL || r_type == R_MIPS_TLS_GD |
2217 |
|
|| r_type == R_MIPS_TLS_LDM); |
2218 |
|
|
2219 |
|
mips_elf_initialize_tls_slots (abfd, got_index, tls_type, info, h, symbol); |
2220 |
|
|
2221 |
|
if (r_type == R_MIPS_TLS_GOTTPREL) |
2222 |
|
{ |
2223 |
|
BFD_ASSERT (*tls_type & GOT_TLS_IE); |
2224 |
|
if (*tls_type & GOT_TLS_GD) |
2225 |
|
return got_index + 2 * MIPS_ELF_GOT_SIZE (abfd); |
2226 |
|
else |
2227 |
|
return got_index; |
2228 |
|
} |
2229 |
|
|
2230 |
|
if (r_type == R_MIPS_TLS_GD) |
2231 |
|
{ |
2232 |
|
BFD_ASSERT (*tls_type & GOT_TLS_GD); |
2233 |
|
return got_index; |
2234 |
|
} |
2235 |
|
|
2236 |
|
if (r_type == R_MIPS_TLS_LDM) |
2237 |
|
{ |
2238 |
|
BFD_ASSERT (*tls_type & GOT_TLS_LDM); |
2239 |
|
return got_index; |
2240 |
|
} |
2241 |
|
|
2242 |
|
return got_index; |
2243 |
|
} |
2244 |
|
|
2245 |
/* Returns the GOT offset at which the indicated address can be found. |
/* Returns the GOT offset at which the indicated address can be found. |
2246 |
If there is not yet a GOT entry for this value, create one. Returns |
If there is not yet a GOT entry for this value, create one. If |
2247 |
-1 if no satisfactory GOT offset can be found. */ |
R_SYMNDX refers to a TLS symbol, create a TLS GOT entry instead. |
2248 |
|
Returns -1 if no satisfactory GOT offset can be found. */ |
2249 |
|
|
2250 |
static bfd_vma |
static bfd_vma |
2251 |
mips_elf_local_got_index (abfd, info, value) |
mips_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info, |
2252 |
bfd *abfd; |
bfd_vma value, unsigned long r_symndx, |
2253 |
struct bfd_link_info *info; |
struct mips_elf_link_hash_entry *h, int r_type) |
|
bfd_vma value; |
|
2254 |
{ |
{ |
2255 |
asection *sgot; |
asection *sgot; |
2256 |
struct mips_got_info *g; |
struct mips_got_info *g; |
2257 |
bfd_byte *entry; |
struct mips_got_entry *entry; |
2258 |
|
|
2259 |
g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot); |
g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot); |
2260 |
|
|
2261 |
/* Look to see if we already have an appropriate entry. */ |
entry = mips_elf_create_local_got_entry (abfd, ibfd, g, sgot, value, |
2262 |
for (entry = (sgot->contents |
r_symndx, h, r_type); |
2263 |
+ MIPS_ELF_GOT_SIZE (abfd) * MIPS_RESERVED_GOTNO); |
if (!entry) |
2264 |
entry != sgot->contents + MIPS_ELF_GOT_SIZE (abfd) * g->assigned_gotno; |
return MINUS_ONE; |
2265 |
entry += MIPS_ELF_GOT_SIZE (abfd)) |
|
2266 |
{ |
if (TLS_RELOC_P (r_type)) |
2267 |
bfd_vma address = MIPS_ELF_GET_WORD (abfd, entry); |
return mips_tls_got_index (abfd, entry->gotidx, &entry->tls_type, r_type, |
2268 |
if (address == value) |
info, h, value); |
2269 |
return entry - sgot->contents; |
else |
2270 |
} |
return entry->gotidx; |
|
|
|
|
return mips_elf_create_local_got_entry (abfd, g, sgot, value); |
|
2271 |
} |
} |
2272 |
|
|
2273 |
/* Returns the GOT index for the global symbol indicated by H. */ |
/* Returns the GOT index for the global symbol indicated by H. */ |
2274 |
|
|
2275 |
static bfd_vma |
static bfd_vma |
2276 |
mips_elf_global_got_index (abfd, h) |
mips_elf_global_got_index (bfd *abfd, bfd *ibfd, struct elf_link_hash_entry *h, |
2277 |
bfd *abfd; |
int r_type, struct bfd_link_info *info) |
|
struct elf_link_hash_entry *h; |
|
2278 |
{ |
{ |
2279 |
bfd_vma index; |
bfd_vma index; |
2280 |
asection *sgot; |
asection *sgot; |
2281 |
struct mips_got_info *g; |
struct mips_got_info *g, *gg; |
2282 |
|
long global_got_dynindx = 0; |
2283 |
|
|
2284 |
|
gg = g = mips_elf_got_info (abfd, &sgot); |
2285 |
|
if (g->bfd2got && ibfd) |
2286 |
|
{ |
2287 |
|
struct mips_got_entry e, *p; |
2288 |
|
|
2289 |
|
BFD_ASSERT (h->dynindx >= 0); |
2290 |
|
|
2291 |
|
g = mips_elf_got_for_ibfd (g, ibfd); |
2292 |
|
if (g->next != gg || TLS_RELOC_P (r_type)) |
2293 |
|
{ |
2294 |
|
e.abfd = ibfd; |
2295 |
|
e.symndx = -1; |
2296 |
|
e.d.h = (struct mips_elf_link_hash_entry *)h; |
2297 |
|
e.tls_type = 0; |
2298 |
|
|
2299 |
|
p = htab_find (g->got_entries, &e); |
2300 |
|
|
2301 |
|
BFD_ASSERT (p->gotidx > 0); |
2302 |
|
|
2303 |
|
if (TLS_RELOC_P (r_type)) |
2304 |
|
{ |
2305 |
|
bfd_vma value = MINUS_ONE; |
2306 |
|
if ((h->root.type == bfd_link_hash_defined |
2307 |
|
|| h->root.type == bfd_link_hash_defweak) |
2308 |
|
&& h->root.u.def.section->output_section) |
2309 |
|
value = (h->root.u.def.value |
2310 |
|
+ h->root.u.def.section->output_offset |
2311 |
|
+ h->root.u.def.section->output_section->vma); |
2312 |
|
|
2313 |
g = mips_elf_got_info (abfd, &sgot); |
return mips_tls_got_index (abfd, p->gotidx, &p->tls_type, r_type, |
2314 |
|
info, e.d.h, value); |
2315 |
|
} |
2316 |
|
else |
2317 |
|
return p->gotidx; |
2318 |
|
} |
2319 |
|
} |
2320 |
|
|
2321 |
/* Once we determine the global GOT entry with the lowest dynamic |
if (gg->global_gotsym != NULL) |
2322 |
symbol table index, we must put all dynamic symbols with greater |
global_got_dynindx = gg->global_gotsym->dynindx; |
2323 |
indices into the GOT. That makes it easy to calculate the GOT |
|
2324 |
offset. */ |
if (TLS_RELOC_P (r_type)) |
2325 |
BFD_ASSERT (h->dynindx >= g->global_gotsym->dynindx); |
{ |
2326 |
index = ((h->dynindx - g->global_gotsym->dynindx + g->local_gotno) |
struct mips_elf_link_hash_entry *hm |
2327 |
* MIPS_ELF_GOT_SIZE (abfd)); |
= (struct mips_elf_link_hash_entry *) h; |
2328 |
BFD_ASSERT (index < sgot->_raw_size); |
bfd_vma value = MINUS_ONE; |
2329 |
|
|
2330 |
|
if ((h->root.type == bfd_link_hash_defined |
2331 |
|
|| h->root.type == bfd_link_hash_defweak) |
2332 |
|
&& h->root.u.def.section->output_section) |
2333 |
|
value = (h->root.u.def.value |
2334 |
|
+ h->root.u.def.section->output_offset |
2335 |
|
+ h->root.u.def.section->output_section->vma); |
2336 |
|
|
2337 |
|
index = mips_tls_got_index (abfd, hm->tls_got_offset, &hm->tls_type, |
2338 |
|
r_type, info, hm, value); |
2339 |
|
} |
2340 |
|
else |
2341 |
|
{ |
2342 |
|
/* Once we determine the global GOT entry with the lowest dynamic |
2343 |
|
symbol table index, we must put all dynamic symbols with greater |
2344 |
|
indices into the GOT. That makes it easy to calculate the GOT |
2345 |
|
offset. */ |
2346 |
|
BFD_ASSERT (h->dynindx >= global_got_dynindx); |
2347 |
|
index = ((h->dynindx - global_got_dynindx + g->local_gotno) |
2348 |
|
* MIPS_ELF_GOT_SIZE (abfd)); |
2349 |
|
} |
2350 |
|
BFD_ASSERT (index < sgot->size); |
2351 |
|
|
2352 |
return index; |
return index; |
2353 |
} |
} |
2359 |
OFFSETP, if it is non-NULL. */ |
OFFSETP, if it is non-NULL. */ |
2360 |
|
|
2361 |
static bfd_vma |
static bfd_vma |
2362 |
mips_elf_got_page (abfd, info, value, offsetp) |
mips_elf_got_page (bfd *abfd, bfd *ibfd, struct bfd_link_info *info, |
2363 |
bfd *abfd; |
bfd_vma value, bfd_vma *offsetp) |
|
struct bfd_link_info *info; |
|
|
bfd_vma value; |
|
|
bfd_vma *offsetp; |
|
2364 |
{ |
{ |
2365 |
asection *sgot; |
asection *sgot; |
2366 |
struct mips_got_info *g; |
struct mips_got_info *g; |
2367 |
bfd_byte *entry; |
bfd_vma index; |
2368 |
bfd_byte *last_entry; |
struct mips_got_entry *entry; |
|
bfd_vma index = 0; |
|
|
bfd_vma address; |
|
2369 |
|
|
2370 |
g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot); |
g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot); |
2371 |
|
|
2372 |
/* Look to see if we aleady have an appropriate entry. */ |
entry = mips_elf_create_local_got_entry (abfd, ibfd, g, sgot, |
2373 |
last_entry = sgot->contents + MIPS_ELF_GOT_SIZE (abfd) * g->assigned_gotno; |
(value + 0x8000) |
2374 |
for (entry = (sgot->contents |
& (~(bfd_vma)0xffff), 0, |
2375 |
+ MIPS_ELF_GOT_SIZE (abfd) * MIPS_RESERVED_GOTNO); |
NULL, R_MIPS_GOT_PAGE); |
2376 |
entry != last_entry; |
|
2377 |
entry += MIPS_ELF_GOT_SIZE (abfd)) |
if (!entry) |
2378 |
{ |
return MINUS_ONE; |
|
address = MIPS_ELF_GET_WORD (abfd, entry); |
|
|
|
|
|
if (!mips_elf_overflow_p (value - address, 16)) |
|
|
{ |
|
|
/* This entry will serve as the page pointer. We can add a |
|
|
16-bit number to it to get the actual address. */ |
|
|
index = entry - sgot->contents; |
|
|
break; |
|
|
} |
|
|
} |
|
2379 |
|
|
2380 |
/* If we didn't have an appropriate entry, we create one now. */ |
index = entry->gotidx; |
|
if (entry == last_entry) |
|
|
index = mips_elf_create_local_got_entry (abfd, g, sgot, value); |
|
2381 |
|
|
2382 |
if (offsetp) |
if (offsetp) |
2383 |
{ |
*offsetp = value - entry->d.address; |
|
address = MIPS_ELF_GET_WORD (abfd, entry); |
|
|
*offsetp = value - address; |
|
|
} |
|
2384 |
|
|
2385 |
return index; |
return index; |
2386 |
} |
} |
2389 |
for value. Return the index into the GOT for this entry. */ |
for value. Return the index into the GOT for this entry. */ |
2390 |
|
|
2391 |
static bfd_vma |
static bfd_vma |
2392 |
mips_elf_got16_entry (abfd, info, value, external) |
mips_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info, |
2393 |
bfd *abfd; |
bfd_vma value, bfd_boolean external) |
|
struct bfd_link_info *info; |
|
|
bfd_vma value; |
|
|
boolean external; |
|
2394 |
{ |
{ |
2395 |
asection *sgot; |
asection *sgot; |
2396 |
struct mips_got_info *g; |
struct mips_got_info *g; |
2397 |
bfd_byte *entry; |
struct mips_got_entry *entry; |
|
bfd_byte *last_entry; |
|
|
bfd_vma index = 0; |
|
|
bfd_vma address; |
|
2398 |
|
|
2399 |
if (! external) |
if (! external) |
2400 |
{ |
{ |
2407 |
|
|
2408 |
g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot); |
g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot); |
2409 |
|
|
2410 |
/* Look to see if we already have an appropriate entry. */ |
entry = mips_elf_create_local_got_entry (abfd, ibfd, g, sgot, value, 0, NULL, |
2411 |
last_entry = sgot->contents + MIPS_ELF_GOT_SIZE (abfd) * g->assigned_gotno; |
R_MIPS_GOT16); |
2412 |
for (entry = (sgot->contents |
if (entry) |
2413 |
+ MIPS_ELF_GOT_SIZE (abfd) * MIPS_RESERVED_GOTNO); |
return entry->gotidx; |
2414 |
entry != last_entry; |
else |
2415 |
entry += MIPS_ELF_GOT_SIZE (abfd)) |
return MINUS_ONE; |
|
{ |
|
|
address = MIPS_ELF_GET_WORD (abfd, entry); |
|
|
if (address == value) |
|
|
{ |
|
|
/* This entry has the right high-order 16 bits, and the low-order |
|
|
16 bits are set to zero. */ |
|
|
index = entry - sgot->contents; |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
/* If we didn't have an appropriate entry, we create one now. */ |
|
|
if (entry == last_entry) |
|
|
index = mips_elf_create_local_got_entry (abfd, g, sgot, value); |
|
|
|
|
|
return index; |
|
2416 |
} |
} |
2417 |
|
|
2418 |
/* Returns the offset for the entry at the INDEXth position |
/* Returns the offset for the entry at the INDEXth position |
2419 |
in the GOT. */ |
in the GOT. */ |
2420 |
|
|
2421 |
static bfd_vma |
static bfd_vma |
2422 |
mips_elf_got_offset_from_index (dynobj, output_bfd, index) |
mips_elf_got_offset_from_index (bfd *dynobj, bfd *output_bfd, |
2423 |
bfd *dynobj; |
bfd *input_bfd, bfd_vma index) |
|
bfd *output_bfd; |
|
|
bfd_vma index; |
|
2424 |
{ |
{ |
2425 |
asection *sgot; |
asection *sgot; |
2426 |
bfd_vma gp; |
bfd_vma gp; |
2427 |
|
struct mips_got_info *g; |
2428 |
|
|
2429 |
|
g = mips_elf_got_info (dynobj, &sgot); |
2430 |
|
gp = _bfd_get_gp_value (output_bfd) |
2431 |
|
+ mips_elf_adjust_gp (output_bfd, g, input_bfd); |
2432 |
|
|
2433 |
sgot = mips_elf_got_section (dynobj); |
return sgot->output_section->vma + sgot->output_offset + index - gp; |
|
gp = _bfd_get_gp_value (output_bfd); |
|
|
return (sgot->output_section->vma + sgot->output_offset + index - |
|
|
gp); |
|
2434 |
} |
} |
2435 |
|
|
2436 |
/* Create a local GOT entry for VALUE. Return the index of the entry, |
/* Create a local GOT entry for VALUE. Return the index of the entry, |
2437 |
or -1 if it could not be created. */ |
or -1 if it could not be created. If R_SYMNDX refers to a TLS symbol, |
2438 |
|
create a TLS entry instead. */ |
2439 |
|
|
2440 |
static bfd_vma |
static struct mips_got_entry * |
2441 |
mips_elf_create_local_got_entry (abfd, g, sgot, value) |
mips_elf_create_local_got_entry (bfd *abfd, bfd *ibfd, |
2442 |
bfd *abfd; |
struct mips_got_info *gg, |
2443 |
struct mips_got_info *g; |
asection *sgot, bfd_vma value, |
2444 |
asection *sgot; |
unsigned long r_symndx, |
2445 |
bfd_vma value; |
struct mips_elf_link_hash_entry *h, |
2446 |
|
int r_type) |
2447 |
{ |
{ |
2448 |
|
struct mips_got_entry entry, **loc; |
2449 |
|
struct mips_got_info *g; |
2450 |
|
|
2451 |
|
entry.abfd = NULL; |
2452 |
|
entry.symndx = -1; |
2453 |
|
entry.d.address = value; |
2454 |
|
entry.tls_type = 0; |
2455 |
|
|
2456 |
|
g = mips_elf_got_for_ibfd (gg, ibfd); |
2457 |
|
if (g == NULL) |
2458 |
|
{ |
2459 |
|
g = mips_elf_got_for_ibfd (gg, abfd); |
2460 |
|
BFD_ASSERT (g != NULL); |
2461 |
|
} |
2462 |
|
|
2463 |
|
/* We might have a symbol, H, if it has been forced local. Use the |
2464 |
|
global entry then. It doesn't matter whether an entry is local |
2465 |
|
or global for TLS, since the dynamic linker does not |
2466 |
|
automatically relocate TLS GOT entries. */ |
2467 |
|
BFD_ASSERT (h == NULL || h->root.forced_local); |
2468 |
|
if (TLS_RELOC_P (r_type)) |
2469 |
|
{ |
2470 |
|
struct mips_got_entry *p; |
2471 |
|
|
2472 |
|
entry.abfd = ibfd; |
2473 |
|
if (r_type == R_MIPS_TLS_LDM) |
2474 |
|
{ |
2475 |
|
entry.tls_type = GOT_TLS_LDM; |
2476 |
|
entry.symndx = 0; |
2477 |
|
entry.d.addend = 0; |
2478 |
|
} |
2479 |
|
else if (h == NULL) |
2480 |
|
{ |
2481 |
|
entry.symndx = r_symndx; |
2482 |
|
entry.d.addend = 0; |
2483 |
|
} |
2484 |
|
else |
2485 |
|
entry.d.h = h; |
2486 |
|
|
2487 |
|
p = (struct mips_got_entry *) |
2488 |
|
htab_find (g->got_entries, &entry); |
2489 |
|
|
2490 |
|
BFD_ASSERT (p); |
2491 |
|
return p; |
2492 |
|
} |
2493 |
|
|
2494 |
|
loc = (struct mips_got_entry **) htab_find_slot (g->got_entries, &entry, |
2495 |
|
INSERT); |
2496 |
|
if (*loc) |
2497 |
|
return *loc; |
2498 |
|
|
2499 |
|
entry.gotidx = MIPS_ELF_GOT_SIZE (abfd) * g->assigned_gotno++; |
2500 |
|
entry.tls_type = 0; |
2501 |
|
|
2502 |
|
*loc = (struct mips_got_entry *)bfd_alloc (abfd, sizeof entry); |
2503 |
|
|
2504 |
|
if (! *loc) |
2505 |
|
return NULL; |
2506 |
|
|
2507 |
|
memcpy (*loc, &entry, sizeof entry); |
2508 |
|
|
2509 |
if (g->assigned_gotno >= g->local_gotno) |
if (g->assigned_gotno >= g->local_gotno) |
2510 |
{ |
{ |
2511 |
|
(*loc)->gotidx = -1; |
2512 |
/* We didn't allocate enough space in the GOT. */ |
/* We didn't allocate enough space in the GOT. */ |
2513 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
2514 |
(_("not enough GOT space for local GOT entries")); |
(_("not enough GOT space for local GOT entries")); |
2515 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
2516 |
return (bfd_vma) -1; |
return NULL; |
2517 |
} |
} |
2518 |
|
|
2519 |
MIPS_ELF_PUT_WORD (abfd, value, |
MIPS_ELF_PUT_WORD (abfd, value, |
2520 |
(sgot->contents |
(sgot->contents + entry.gotidx)); |
2521 |
+ MIPS_ELF_GOT_SIZE (abfd) * g->assigned_gotno)); |
|
2522 |
return MIPS_ELF_GOT_SIZE (abfd) * g->assigned_gotno++; |
return *loc; |
2523 |
} |
} |
2524 |
|
|
2525 |
/* Sort the dynamic symbol table so that symbols that need GOT entries |
/* Sort the dynamic symbol table so that symbols that need GOT entries |
2529 |
_bfd_mips_elf_size_dynamic_sections, this value is 1. Afterward, the |
_bfd_mips_elf_size_dynamic_sections, this value is 1. Afterward, the |
2530 |
section symbols are added and the count is higher. */ |
section symbols are added and the count is higher. */ |
2531 |
|
|
2532 |
static boolean |
static bfd_boolean |
2533 |
mips_elf_sort_hash_table (info, max_local) |
mips_elf_sort_hash_table (struct bfd_link_info *info, unsigned long max_local) |
|
struct bfd_link_info *info; |
|
|
unsigned long max_local; |
|
2534 |
{ |
{ |
2535 |
struct mips_elf_hash_sort_data hsd; |
struct mips_elf_hash_sort_data hsd; |
2536 |
struct mips_got_info *g; |
struct mips_got_info *g; |
2538 |
|
|
2539 |
dynobj = elf_hash_table (info)->dynobj; |
dynobj = elf_hash_table (info)->dynobj; |
2540 |
|
|
2541 |
|
g = mips_elf_got_info (dynobj, NULL); |
2542 |
|
|
2543 |
hsd.low = NULL; |
hsd.low = NULL; |
2544 |
hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount; |
hsd.max_unref_got_dynindx = |
2545 |
|
hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount |
2546 |
|
/* In the multi-got case, assigned_gotno of the master got_info |
2547 |
|
indicate the number of entries that aren't referenced in the |
2548 |
|
primary GOT, but that must have entries because there are |
2549 |
|
dynamic relocations that reference it. Since they aren't |
2550 |
|
referenced, we move them to the end of the GOT, so that they |
2551 |
|
don't prevent other entries that are referenced from getting |
2552 |
|
too large offsets. */ |
2553 |
|
- (g->next ? g->assigned_gotno : 0); |
2554 |
hsd.max_non_got_dynindx = max_local; |
hsd.max_non_got_dynindx = max_local; |
2555 |
mips_elf_link_hash_traverse (((struct mips_elf_link_hash_table *) |
mips_elf_link_hash_traverse (((struct mips_elf_link_hash_table *) |
2556 |
elf_hash_table (info)), |
elf_hash_table (info)), |
2558 |
&hsd); |
&hsd); |
2559 |
|
|
2560 |
/* There should have been enough room in the symbol table to |
/* There should have been enough room in the symbol table to |
2561 |
accomodate both the GOT and non-GOT symbols. */ |
accommodate both the GOT and non-GOT symbols. */ |
2562 |
BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx); |
BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx); |
2563 |
|
BFD_ASSERT ((unsigned long)hsd.max_unref_got_dynindx |
2564 |
|
<= elf_hash_table (info)->dynsymcount); |
2565 |
|
|
2566 |
/* Now we know which dynamic symbol has the lowest dynamic symbol |
/* Now we know which dynamic symbol has the lowest dynamic symbol |
2567 |
table index in the GOT. */ |
table index in the GOT. */ |
|
g = mips_elf_got_info (dynobj, NULL); |
|
2568 |
g->global_gotsym = hsd.low; |
g->global_gotsym = hsd.low; |
2569 |
|
|
2570 |
return true; |
return TRUE; |
2571 |
} |
} |
2572 |
|
|
2573 |
/* If H needs a GOT entry, assign it the highest available dynamic |
/* If H needs a GOT entry, assign it the highest available dynamic |
2574 |
index. Otherwise, assign it the lowest available dynamic |
index. Otherwise, assign it the lowest available dynamic |
2575 |
index. */ |
index. */ |
2576 |
|
|
2577 |
static boolean |
static bfd_boolean |
2578 |
mips_elf_sort_hash_table_f (h, data) |
mips_elf_sort_hash_table_f (struct mips_elf_link_hash_entry *h, void *data) |
|
struct mips_elf_link_hash_entry *h; |
|
|
PTR data; |
|
2579 |
{ |
{ |
2580 |
struct mips_elf_hash_sort_data *hsd |
struct mips_elf_hash_sort_data *hsd = data; |
|
= (struct mips_elf_hash_sort_data *) data; |
|
2581 |
|
|
2582 |
if (h->root.root.type == bfd_link_hash_warning) |
if (h->root.root.type == bfd_link_hash_warning) |
2583 |
h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link; |
h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link; |
2585 |
/* Symbols without dynamic symbol table entries aren't interesting |
/* Symbols without dynamic symbol table entries aren't interesting |
2586 |
at all. */ |
at all. */ |
2587 |
if (h->root.dynindx == -1) |
if (h->root.dynindx == -1) |
2588 |
return true; |
return TRUE; |
2589 |
|
|
2590 |
if (h->root.got.offset != 1) |
/* Global symbols that need GOT entries that are not explicitly |
2591 |
|
referenced are marked with got offset 2. Those that are |
2592 |
|
referenced get a 1, and those that don't need GOT entries get |
2593 |
|
-1. */ |
2594 |
|
if (h->root.got.offset == 2) |
2595 |
|
{ |
2596 |
|
BFD_ASSERT (h->tls_type == GOT_NORMAL); |
2597 |
|
|
2598 |
|
if (hsd->max_unref_got_dynindx == hsd->min_got_dynindx) |
2599 |
|
hsd->low = (struct elf_link_hash_entry *) h; |
2600 |
|
h->root.dynindx = hsd->max_unref_got_dynindx++; |
2601 |
|
} |
2602 |
|
else if (h->root.got.offset != 1) |
2603 |
h->root.dynindx = hsd->max_non_got_dynindx++; |
h->root.dynindx = hsd->max_non_got_dynindx++; |
2604 |
else |
else |
2605 |
{ |
{ |
2606 |
|
BFD_ASSERT (h->tls_type == GOT_NORMAL); |
2607 |
|
|
2608 |
h->root.dynindx = --hsd->min_got_dynindx; |
h->root.dynindx = --hsd->min_got_dynindx; |
2609 |
hsd->low = (struct elf_link_hash_entry *) h; |
hsd->low = (struct elf_link_hash_entry *) h; |
2610 |
} |
} |
2611 |
|
|
2612 |
return true; |
return TRUE; |
2613 |
} |
} |
2614 |
|
|
2615 |
/* If H is a symbol that needs a global GOT entry, but has a dynamic |
/* If H is a symbol that needs a global GOT entry, but has a dynamic |
2616 |
symbol table index lower than any we've seen to date, record it for |
symbol table index lower than any we've seen to date, record it for |
2617 |
posterity. */ |
posterity. */ |
2618 |
|
|
2619 |
static boolean |
static bfd_boolean |
2620 |
mips_elf_record_global_got_symbol (h, info, g) |
mips_elf_record_global_got_symbol (struct elf_link_hash_entry *h, |
2621 |
struct elf_link_hash_entry *h; |
bfd *abfd, struct bfd_link_info *info, |
2622 |
struct bfd_link_info *info; |
struct mips_got_info *g, |
2623 |
struct mips_got_info *g ATTRIBUTE_UNUSED; |
unsigned char tls_flag) |
2624 |
{ |
{ |
2625 |
|
struct mips_got_entry entry, **loc; |
2626 |
|
|
2627 |
/* A global symbol in the GOT must also be in the dynamic symbol |
/* A global symbol in the GOT must also be in the dynamic symbol |
2628 |
table. */ |
table. */ |
2629 |
if (h->dynindx == -1) |
if (h->dynindx == -1) |
2632 |
{ |
{ |
2633 |
case STV_INTERNAL: |
case STV_INTERNAL: |
2634 |
case STV_HIDDEN: |
case STV_HIDDEN: |
2635 |
_bfd_mips_elf_hide_symbol (info, h, true); |
_bfd_mips_elf_hide_symbol (info, h, TRUE); |
2636 |
break; |
break; |
2637 |
} |
} |
2638 |
if (!bfd_elf32_link_record_dynamic_symbol (info, h)) |
if (!bfd_elf_link_record_dynamic_symbol (info, h)) |
2639 |
return false; |
return FALSE; |
2640 |
} |
} |
2641 |
|
|
2642 |
|
entry.abfd = abfd; |
2643 |
|
entry.symndx = -1; |
2644 |
|
entry.d.h = (struct mips_elf_link_hash_entry *) h; |
2645 |
|
entry.tls_type = 0; |
2646 |
|
|
2647 |
|
loc = (struct mips_got_entry **) htab_find_slot (g->got_entries, &entry, |
2648 |
|
INSERT); |
2649 |
|
|
2650 |
/* If we've already marked this entry as needing GOT space, we don't |
/* If we've already marked this entry as needing GOT space, we don't |
2651 |
need to do it again. */ |
need to do it again. */ |
2652 |
|
if (*loc) |
2653 |
|
{ |
2654 |
|
(*loc)->tls_type |= tls_flag; |
2655 |
|
return TRUE; |
2656 |
|
} |
2657 |
|
|
2658 |
|
*loc = (struct mips_got_entry *)bfd_alloc (abfd, sizeof entry); |
2659 |
|
|
2660 |
|
if (! *loc) |
2661 |
|
return FALSE; |
2662 |
|
|
2663 |
|
entry.gotidx = -1; |
2664 |
|
entry.tls_type = tls_flag; |
2665 |
|
|
2666 |
|
memcpy (*loc, &entry, sizeof entry); |
2667 |
|
|
2668 |
if (h->got.offset != MINUS_ONE) |
if (h->got.offset != MINUS_ONE) |
2669 |
return true; |
return TRUE; |
2670 |
|
|
2671 |
/* By setting this to a value other than -1, we are indicating that |
/* By setting this to a value other than -1, we are indicating that |
2672 |
there needs to be a GOT entry for H. Avoid using zero, as the |
there needs to be a GOT entry for H. Avoid using zero, as the |
2673 |
generic ELF copy_indirect_symbol tests for <= 0. */ |
generic ELF copy_indirect_symbol tests for <= 0. */ |
2674 |
h->got.offset = 1; |
if (tls_flag == 0) |
2675 |
|
h->got.offset = 1; |
2676 |
|
|
2677 |
|
return TRUE; |
2678 |
|
} |
2679 |
|
|
2680 |
|
/* Reserve space in G for a GOT entry containing the value of symbol |
2681 |
|
SYMNDX in input bfd ABDF, plus ADDEND. */ |
2682 |
|
|
2683 |
|
static bfd_boolean |
2684 |
|
mips_elf_record_local_got_symbol (bfd *abfd, long symndx, bfd_vma addend, |
2685 |
|
struct mips_got_info *g, |
2686 |
|
unsigned char tls_flag) |
2687 |
|
{ |
2688 |
|
struct mips_got_entry entry, **loc; |
2689 |
|
|
2690 |
|
entry.abfd = abfd; |
2691 |
|
entry.symndx = symndx; |
2692 |
|
entry.d.addend = addend; |
2693 |
|
entry.tls_type = tls_flag; |
2694 |
|
loc = (struct mips_got_entry **) |
2695 |
|
htab_find_slot (g->got_entries, &entry, INSERT); |
2696 |
|
|
2697 |
|
if (*loc) |
2698 |
|
{ |
2699 |
|
if (tls_flag == GOT_TLS_GD && !((*loc)->tls_type & GOT_TLS_GD)) |
2700 |
|
{ |
2701 |
|
g->tls_gotno += 2; |
2702 |
|
(*loc)->tls_type |= tls_flag; |
2703 |
|
} |
2704 |
|
else if (tls_flag == GOT_TLS_IE && !((*loc)->tls_type & GOT_TLS_IE)) |
2705 |
|
{ |
2706 |
|
g->tls_gotno += 1; |
2707 |
|
(*loc)->tls_type |= tls_flag; |
2708 |
|
} |
2709 |
|
return TRUE; |
2710 |
|
} |
2711 |
|
|
2712 |
|
if (tls_flag != 0) |
2713 |
|
{ |
2714 |
|
entry.gotidx = -1; |
2715 |
|
entry.tls_type = tls_flag; |
2716 |
|
if (tls_flag == GOT_TLS_IE) |
2717 |
|
g->tls_gotno += 1; |
2718 |
|
else if (tls_flag == GOT_TLS_GD) |
2719 |
|
g->tls_gotno += 2; |
2720 |
|
else if (g->tls_ldm_offset == MINUS_ONE) |
2721 |
|
{ |
2722 |
|
g->tls_ldm_offset = MINUS_TWO; |
2723 |
|
g->tls_gotno += 2; |
2724 |
|
} |
2725 |
|
} |
2726 |
|
else |
2727 |
|
{ |
2728 |
|
entry.gotidx = g->local_gotno++; |
2729 |
|
entry.tls_type = 0; |
2730 |
|
} |
2731 |
|
|
2732 |
|
*loc = (struct mips_got_entry *)bfd_alloc (abfd, sizeof entry); |
2733 |
|
|
2734 |
return true; |
if (! *loc) |
2735 |
|
return FALSE; |
2736 |
|
|
2737 |
|
memcpy (*loc, &entry, sizeof entry); |
2738 |
|
|
2739 |
|
return TRUE; |
2740 |
|
} |
2741 |
|
|
2742 |
|
/* Compute the hash value of the bfd in a bfd2got hash entry. */ |
2743 |
|
|
2744 |
|
static hashval_t |
2745 |
|
mips_elf_bfd2got_entry_hash (const void *entry_) |
2746 |
|
{ |
2747 |
|
const struct mips_elf_bfd2got_hash *entry |
2748 |
|
= (struct mips_elf_bfd2got_hash *)entry_; |
2749 |
|
|
2750 |
|
return entry->bfd->id; |
2751 |
|
} |
2752 |
|
|
2753 |
|
/* Check whether two hash entries have the same bfd. */ |
2754 |
|
|
2755 |
|
static int |
2756 |
|
mips_elf_bfd2got_entry_eq (const void *entry1, const void *entry2) |
2757 |
|
{ |
2758 |
|
const struct mips_elf_bfd2got_hash *e1 |
2759 |
|
= (const struct mips_elf_bfd2got_hash *)entry1; |
2760 |
|
const struct mips_elf_bfd2got_hash *e2 |
2761 |
|
= (const struct mips_elf_bfd2got_hash *)entry2; |
2762 |
|
|
2763 |
|
return e1->bfd == e2->bfd; |
2764 |
|
} |
2765 |
|
|
2766 |
|
/* In a multi-got link, determine the GOT to be used for IBDF. G must |
2767 |
|
be the master GOT data. */ |
2768 |
|
|
2769 |
|
static struct mips_got_info * |
2770 |
|
mips_elf_got_for_ibfd (struct mips_got_info *g, bfd *ibfd) |
2771 |
|
{ |
2772 |
|
struct mips_elf_bfd2got_hash e, *p; |
2773 |
|
|
2774 |
|
if (! g->bfd2got) |
2775 |
|
return g; |
2776 |
|
|
2777 |
|
e.bfd = ibfd; |
2778 |
|
p = htab_find (g->bfd2got, &e); |
2779 |
|
return p ? p->g : NULL; |
2780 |
|
} |
2781 |
|
|
2782 |
|
/* Create one separate got for each bfd that has entries in the global |
2783 |
|
got, such that we can tell how many local and global entries each |
2784 |
|
bfd requires. */ |
2785 |
|
|
2786 |
|
static int |
2787 |
|
mips_elf_make_got_per_bfd (void **entryp, void *p) |
2788 |
|
{ |
2789 |
|
struct mips_got_entry *entry = (struct mips_got_entry *)*entryp; |
2790 |
|
struct mips_elf_got_per_bfd_arg *arg = (struct mips_elf_got_per_bfd_arg *)p; |
2791 |
|
htab_t bfd2got = arg->bfd2got; |
2792 |
|
struct mips_got_info *g; |
2793 |
|
struct mips_elf_bfd2got_hash bfdgot_entry, *bfdgot; |
2794 |
|
void **bfdgotp; |
2795 |
|
|
2796 |
|
/* Find the got_info for this GOT entry's input bfd. Create one if |
2797 |
|
none exists. */ |
2798 |
|
bfdgot_entry.bfd = entry->abfd; |
2799 |
|
bfdgotp = htab_find_slot (bfd2got, &bfdgot_entry, INSERT); |
2800 |
|
bfdgot = (struct mips_elf_bfd2got_hash *)*bfdgotp; |
2801 |
|
|
2802 |
|
if (bfdgot != NULL) |
2803 |
|
g = bfdgot->g; |
2804 |
|
else |
2805 |
|
{ |
2806 |
|
bfdgot = (struct mips_elf_bfd2got_hash *)bfd_alloc |
2807 |
|
(arg->obfd, sizeof (struct mips_elf_bfd2got_hash)); |
2808 |
|
|
2809 |
|
if (bfdgot == NULL) |
2810 |
|
{ |
2811 |
|
arg->obfd = 0; |
2812 |
|
return 0; |
2813 |
|
} |
2814 |
|
|
2815 |
|
*bfdgotp = bfdgot; |
2816 |
|
|
2817 |
|
bfdgot->bfd = entry->abfd; |
2818 |
|
bfdgot->g = g = (struct mips_got_info *) |
2819 |
|
bfd_alloc (arg->obfd, sizeof (struct mips_got_info)); |
2820 |
|
if (g == NULL) |
2821 |
|
{ |
2822 |
|
arg->obfd = 0; |
2823 |
|
return 0; |
2824 |
|
} |
2825 |
|
|
2826 |
|
g->global_gotsym = NULL; |
2827 |
|
g->global_gotno = 0; |
2828 |
|
g->local_gotno = 0; |
2829 |
|
g->assigned_gotno = -1; |
2830 |
|
g->tls_gotno = 0; |
2831 |
|
g->tls_assigned_gotno = 0; |
2832 |
|
g->tls_ldm_offset = MINUS_ONE; |
2833 |
|
g->got_entries = htab_try_create (1, mips_elf_multi_got_entry_hash, |
2834 |
|
mips_elf_multi_got_entry_eq, NULL); |
2835 |
|
if (g->got_entries == NULL) |
2836 |
|
{ |
2837 |
|
arg->obfd = 0; |
2838 |
|
return 0; |
2839 |
|
} |
2840 |
|
|
2841 |
|
g->bfd2got = NULL; |
2842 |
|
g->next = NULL; |
2843 |
|
} |
2844 |
|
|
2845 |
|
/* Insert the GOT entry in the bfd's got entry hash table. */ |
2846 |
|
entryp = htab_find_slot (g->got_entries, entry, INSERT); |
2847 |
|
if (*entryp != NULL) |
2848 |
|
return 1; |
2849 |
|
|
2850 |
|
*entryp = entry; |
2851 |
|
|
2852 |
|
if (entry->tls_type) |
2853 |
|
{ |
2854 |
|
if (entry->tls_type & (GOT_TLS_GD | GOT_TLS_LDM)) |
2855 |
|
g->tls_gotno += 2; |
2856 |
|
if (entry->tls_type & GOT_TLS_IE) |
2857 |
|
g->tls_gotno += 1; |
2858 |
|
} |
2859 |
|
else if (entry->symndx >= 0 || entry->d.h->forced_local) |
2860 |
|
++g->local_gotno; |
2861 |
|
else |
2862 |
|
++g->global_gotno; |
2863 |
|
|
2864 |
|
return 1; |
2865 |
|
} |
2866 |
|
|
2867 |
|
/* Attempt to merge gots of different input bfds. Try to use as much |
2868 |
|
as possible of the primary got, since it doesn't require explicit |
2869 |
|
dynamic relocations, but don't use bfds that would reference global |
2870 |
|
symbols out of the addressable range. Failing the primary got, |
2871 |
|
attempt to merge with the current got, or finish the current got |
2872 |
|
and then make make the new got current. */ |
2873 |
|
|
2874 |
|
static int |
2875 |
|
mips_elf_merge_gots (void **bfd2got_, void *p) |
2876 |
|
{ |
2877 |
|
struct mips_elf_bfd2got_hash *bfd2got |
2878 |
|
= (struct mips_elf_bfd2got_hash *)*bfd2got_; |
2879 |
|
struct mips_elf_got_per_bfd_arg *arg = (struct mips_elf_got_per_bfd_arg *)p; |
2880 |
|
unsigned int lcount = bfd2got->g->local_gotno; |
2881 |
|
unsigned int gcount = bfd2got->g->global_gotno; |
2882 |
|
unsigned int tcount = bfd2got->g->tls_gotno; |
2883 |
|
unsigned int maxcnt = arg->max_count; |
2884 |
|
bfd_boolean too_many_for_tls = FALSE; |
2885 |
|
|
2886 |
|
/* We place TLS GOT entries after both locals and globals. The globals |
2887 |
|
for the primary GOT may overflow the normal GOT size limit, so be |
2888 |
|
sure not to merge a GOT which requires TLS with the primary GOT in that |
2889 |
|
case. This doesn't affect non-primary GOTs. */ |
2890 |
|
if (tcount > 0) |
2891 |
|
{ |
2892 |
|
unsigned int primary_total = lcount + tcount + arg->global_count; |
2893 |
|
if (primary_total * MIPS_ELF_GOT_SIZE (bfd2got->bfd) |
2894 |
|
>= MIPS_ELF_GOT_MAX_SIZE (bfd2got->bfd)) |
2895 |
|
too_many_for_tls = TRUE; |
2896 |
|
} |
2897 |
|
|
2898 |
|
/* If we don't have a primary GOT and this is not too big, use it as |
2899 |
|
a starting point for the primary GOT. */ |
2900 |
|
if (! arg->primary && lcount + gcount + tcount <= maxcnt |
2901 |
|
&& ! too_many_for_tls) |
2902 |
|
{ |
2903 |
|
arg->primary = bfd2got->g; |
2904 |
|
arg->primary_count = lcount + gcount; |
2905 |
|
} |
2906 |
|
/* If it looks like we can merge this bfd's entries with those of |
2907 |
|
the primary, merge them. The heuristics is conservative, but we |
2908 |
|
don't have to squeeze it too hard. */ |
2909 |
|
else if (arg->primary && ! too_many_for_tls |
2910 |
|
&& (arg->primary_count + lcount + gcount + tcount) <= maxcnt) |
2911 |
|
{ |
2912 |
|
struct mips_got_info *g = bfd2got->g; |
2913 |
|
int old_lcount = arg->primary->local_gotno; |
2914 |
|
int old_gcount = arg->primary->global_gotno; |
2915 |
|
int old_tcount = arg->primary->tls_gotno; |
2916 |
|
|
2917 |
|
bfd2got->g = arg->primary; |
2918 |
|
|
2919 |
|
htab_traverse (g->got_entries, |
2920 |
|
mips_elf_make_got_per_bfd, |
2921 |
|
arg); |
2922 |
|
if (arg->obfd == NULL) |
2923 |
|
return 0; |
2924 |
|
|
2925 |
|
htab_delete (g->got_entries); |
2926 |
|
/* We don't have to worry about releasing memory of the actual |
2927 |
|
got entries, since they're all in the master got_entries hash |
2928 |
|
table anyway. */ |
2929 |
|
|
2930 |
|
BFD_ASSERT (old_lcount + lcount >= arg->primary->local_gotno); |
2931 |
|
BFD_ASSERT (old_gcount + gcount >= arg->primary->global_gotno); |
2932 |
|
BFD_ASSERT (old_tcount + tcount >= arg->primary->tls_gotno); |
2933 |
|
|
2934 |
|
arg->primary_count = arg->primary->local_gotno |
2935 |
|
+ arg->primary->global_gotno + arg->primary->tls_gotno; |
2936 |
|
} |
2937 |
|
/* If we can merge with the last-created got, do it. */ |
2938 |
|
else if (arg->current |
2939 |
|
&& arg->current_count + lcount + gcount + tcount <= maxcnt) |
2940 |
|
{ |
2941 |
|
struct mips_got_info *g = bfd2got->g; |
2942 |
|
int old_lcount = arg->current->local_gotno; |
2943 |
|
int old_gcount = arg->current->global_gotno; |
2944 |
|
int old_tcount = arg->current->tls_gotno; |
2945 |
|
|
2946 |
|
bfd2got->g = arg->current; |
2947 |
|
|
2948 |
|
htab_traverse (g->got_entries, |
2949 |
|
mips_elf_make_got_per_bfd, |
2950 |
|
arg); |
2951 |
|
if (arg->obfd == NULL) |
2952 |
|
return 0; |
2953 |
|
|
2954 |
|
htab_delete (g->got_entries); |
2955 |
|
|
2956 |
|
BFD_ASSERT (old_lcount + lcount >= arg->current->local_gotno); |
2957 |
|
BFD_ASSERT (old_gcount + gcount >= arg->current->global_gotno); |
2958 |
|
BFD_ASSERT (old_tcount + tcount >= arg->current->tls_gotno); |
2959 |
|
|
2960 |
|
arg->current_count = arg->current->local_gotno |
2961 |
|
+ arg->current->global_gotno + arg->current->tls_gotno; |
2962 |
|
} |
2963 |
|
/* Well, we couldn't merge, so create a new GOT. Don't check if it |
2964 |
|
fits; if it turns out that it doesn't, we'll get relocation |
2965 |
|
overflows anyway. */ |
2966 |
|
else |
2967 |
|
{ |
2968 |
|
bfd2got->g->next = arg->current; |
2969 |
|
arg->current = bfd2got->g; |
2970 |
|
|
2971 |
|
arg->current_count = lcount + gcount + 2 * tcount; |
2972 |
|
} |
2973 |
|
|
2974 |
|
return 1; |
2975 |
|
} |
2976 |
|
|
2977 |
|
/* Set the TLS GOT index for the GOT entry in ENTRYP. */ |
2978 |
|
|
2979 |
|
static int |
2980 |
|
mips_elf_initialize_tls_index (void **entryp, void *p) |
2981 |
|
{ |
2982 |
|
struct mips_got_entry *entry = (struct mips_got_entry *)*entryp; |
2983 |
|
struct mips_got_info *g = p; |
2984 |
|
|
2985 |
|
/* We're only interested in TLS symbols. */ |
2986 |
|
if (entry->tls_type == 0) |
2987 |
|
return 1; |
2988 |
|
|
2989 |
|
if (entry->symndx == -1) |
2990 |
|
{ |
2991 |
|
/* There may be multiple mips_got_entry structs for a global variable |
2992 |
|
if there is just one GOT. Just do this once. */ |
2993 |
|
if (g->next == NULL) |
2994 |
|
{ |
2995 |
|
if (entry->d.h->tls_type & GOT_TLS_OFFSET_DONE) |
2996 |
|
return 1; |
2997 |
|
entry->d.h->tls_type |= GOT_TLS_OFFSET_DONE; |
2998 |
|
} |
2999 |
|
} |
3000 |
|
else if (entry->tls_type & GOT_TLS_LDM) |
3001 |
|
{ |
3002 |
|
/* Similarly, there may be multiple structs for the LDM entry. */ |
3003 |
|
if (g->tls_ldm_offset != MINUS_TWO && g->tls_ldm_offset != MINUS_ONE) |
3004 |
|
{ |
3005 |
|
entry->gotidx = g->tls_ldm_offset; |
3006 |
|
return 1; |
3007 |
|
} |
3008 |
|
} |
3009 |
|
|
3010 |
|
/* Initialize the GOT offset. */ |
3011 |
|
entry->gotidx = MIPS_ELF_GOT_SIZE (entry->abfd) * (long) g->tls_assigned_gotno; |
3012 |
|
if (g->next == NULL && entry->symndx == -1) |
3013 |
|
entry->d.h->tls_got_offset = entry->gotidx; |
3014 |
|
|
3015 |
|
if (entry->tls_type & (GOT_TLS_GD | GOT_TLS_LDM)) |
3016 |
|
g->tls_assigned_gotno += 2; |
3017 |
|
if (entry->tls_type & GOT_TLS_IE) |
3018 |
|
g->tls_assigned_gotno += 1; |
3019 |
|
|
3020 |
|
if (entry->tls_type & GOT_TLS_LDM) |
3021 |
|
g->tls_ldm_offset = entry->gotidx; |
3022 |
|
|
3023 |
|
return 1; |
3024 |
|
} |
3025 |
|
|
3026 |
|
/* If passed a NULL mips_got_info in the argument, set the marker used |
3027 |
|
to tell whether a global symbol needs a got entry (in the primary |
3028 |
|
got) to the given VALUE. |
3029 |
|
|
3030 |
|
If passed a pointer G to a mips_got_info in the argument (it must |
3031 |
|
not be the primary GOT), compute the offset from the beginning of |
3032 |
|
the (primary) GOT section to the entry in G corresponding to the |
3033 |
|
global symbol. G's assigned_gotno must contain the index of the |
3034 |
|
first available global GOT entry in G. VALUE must contain the size |
3035 |
|
of a GOT entry in bytes. For each global GOT entry that requires a |
3036 |
|
dynamic relocation, NEEDED_RELOCS is incremented, and the symbol is |
3037 |
|
marked as not eligible for lazy resolution through a function |
3038 |
|
stub. */ |
3039 |
|
static int |
3040 |
|
mips_elf_set_global_got_offset (void **entryp, void *p) |
3041 |
|
{ |
3042 |
|
struct mips_got_entry *entry = (struct mips_got_entry *)*entryp; |
3043 |
|
struct mips_elf_set_global_got_offset_arg *arg |
3044 |
|
= (struct mips_elf_set_global_got_offset_arg *)p; |
3045 |
|
struct mips_got_info *g = arg->g; |
3046 |
|
|
3047 |
|
if (g && entry->tls_type != GOT_NORMAL) |
3048 |
|
arg->needed_relocs += |
3049 |
|
mips_tls_got_relocs (arg->info, entry->tls_type, |
3050 |
|
entry->symndx == -1 ? &entry->d.h->root : NULL); |
3051 |
|
|
3052 |
|
if (entry->abfd != NULL && entry->symndx == -1 |
3053 |
|
&& entry->d.h->root.dynindx != -1 |
3054 |
|
&& entry->d.h->tls_type == GOT_NORMAL) |
3055 |
|
{ |
3056 |
|
if (g) |
3057 |
|
{ |
3058 |
|
BFD_ASSERT (g->global_gotsym == NULL); |
3059 |
|
|
3060 |
|
entry->gotidx = arg->value * (long) g->assigned_gotno++; |
3061 |
|
if (arg->info->shared |
3062 |
|
|| (elf_hash_table (arg->info)->dynamic_sections_created |
3063 |
|
&& entry->d.h->root.def_dynamic |
3064 |
|
&& !entry->d.h->root.def_regular)) |
3065 |
|
++arg->needed_relocs; |
3066 |
|
} |
3067 |
|
else |
3068 |
|
entry->d.h->root.got.offset = arg->value; |
3069 |
|
} |
3070 |
|
|
3071 |
|
return 1; |
3072 |
|
} |
3073 |
|
|
3074 |
|
/* Mark any global symbols referenced in the GOT we are iterating over |
3075 |
|
as inelligible for lazy resolution stubs. */ |
3076 |
|
static int |
3077 |
|
mips_elf_set_no_stub (void **entryp, void *p ATTRIBUTE_UNUSED) |
3078 |
|
{ |
3079 |
|
struct mips_got_entry *entry = (struct mips_got_entry *)*entryp; |
3080 |
|
|
3081 |
|
if (entry->abfd != NULL |
3082 |
|
&& entry->symndx == -1 |
3083 |
|
&& entry->d.h->root.dynindx != -1) |
3084 |
|
entry->d.h->no_fn_stub = TRUE; |
3085 |
|
|
3086 |
|
return 1; |
3087 |
} |
} |
3088 |
|
|
3089 |
|
/* Follow indirect and warning hash entries so that each got entry |
3090 |
|
points to the final symbol definition. P must point to a pointer |
3091 |
|
to the hash table we're traversing. Since this traversal may |
3092 |
|
modify the hash table, we set this pointer to NULL to indicate |
3093 |
|
we've made a potentially-destructive change to the hash table, so |
3094 |
|
the traversal must be restarted. */ |
3095 |
|
static int |
3096 |
|
mips_elf_resolve_final_got_entry (void **entryp, void *p) |
3097 |
|
{ |
3098 |
|
struct mips_got_entry *entry = (struct mips_got_entry *)*entryp; |
3099 |
|
htab_t got_entries = *(htab_t *)p; |
3100 |
|
|
3101 |
|
if (entry->abfd != NULL && entry->symndx == -1) |
3102 |
|
{ |
3103 |
|
struct mips_elf_link_hash_entry *h = entry->d.h; |
3104 |
|
|
3105 |
|
while (h->root.root.type == bfd_link_hash_indirect |
3106 |
|
|| h->root.root.type == bfd_link_hash_warning) |
3107 |
|
h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link; |
3108 |
|
|
3109 |
|
if (entry->d.h == h) |
3110 |
|
return 1; |
3111 |
|
|
3112 |
|
entry->d.h = h; |
3113 |
|
|
3114 |
|
/* If we can't find this entry with the new bfd hash, re-insert |
3115 |
|
it, and get the traversal restarted. */ |
3116 |
|
if (! htab_find (got_entries, entry)) |
3117 |
|
{ |
3118 |
|
htab_clear_slot (got_entries, entryp); |
3119 |
|
entryp = htab_find_slot (got_entries, entry, INSERT); |
3120 |
|
if (! *entryp) |
3121 |
|
*entryp = entry; |
3122 |
|
/* Abort the traversal, since the whole table may have |
3123 |
|
moved, and leave it up to the parent to restart the |
3124 |
|
process. */ |
3125 |
|
*(htab_t *)p = NULL; |
3126 |
|
return 0; |
3127 |
|
} |
3128 |
|
/* We might want to decrement the global_gotno count, but it's |
3129 |
|
either too early or too late for that at this point. */ |
3130 |
|
} |
3131 |
|
|
3132 |
|
return 1; |
3133 |
|
} |
3134 |
|
|
3135 |
|
/* Turn indirect got entries in a got_entries table into their final |
3136 |
|
locations. */ |
3137 |
|
static void |
3138 |
|
mips_elf_resolve_final_got_entries (struct mips_got_info *g) |
3139 |
|
{ |
3140 |
|
htab_t got_entries; |
3141 |
|
|
3142 |
|
do |
3143 |
|
{ |
3144 |
|
got_entries = g->got_entries; |
3145 |
|
|
3146 |
|
htab_traverse (got_entries, |
3147 |
|
mips_elf_resolve_final_got_entry, |
3148 |
|
&got_entries); |
3149 |
|
} |
3150 |
|
while (got_entries == NULL); |
3151 |
|
} |
3152 |
|
|
3153 |
|
/* Return the offset of an input bfd IBFD's GOT from the beginning of |
3154 |
|
the primary GOT. */ |
3155 |
|
static bfd_vma |
3156 |
|
mips_elf_adjust_gp (bfd *abfd, struct mips_got_info *g, bfd *ibfd) |
3157 |
|
{ |
3158 |
|
if (g->bfd2got == NULL) |
3159 |
|
return 0; |
3160 |
|
|
3161 |
|
g = mips_elf_got_for_ibfd (g, ibfd); |
3162 |
|
if (! g) |
3163 |
|
return 0; |
3164 |
|
|
3165 |
|
BFD_ASSERT (g->next); |
3166 |
|
|
3167 |
|
g = g->next; |
3168 |
|
|
3169 |
|
return (g->local_gotno + g->global_gotno + g->tls_gotno) |
3170 |
|
* MIPS_ELF_GOT_SIZE (abfd); |
3171 |
|
} |
3172 |
|
|
3173 |
|
/* Turn a single GOT that is too big for 16-bit addressing into |
3174 |
|
a sequence of GOTs, each one 16-bit addressable. */ |
3175 |
|
|
3176 |
|
static bfd_boolean |
3177 |
|
mips_elf_multi_got (bfd *abfd, struct bfd_link_info *info, |
3178 |
|
struct mips_got_info *g, asection *got, |
3179 |
|
bfd_size_type pages) |
3180 |
|
{ |
3181 |
|
struct mips_elf_got_per_bfd_arg got_per_bfd_arg; |
3182 |
|
struct mips_elf_set_global_got_offset_arg set_got_offset_arg; |
3183 |
|
struct mips_got_info *gg; |
3184 |
|
unsigned int assign; |
3185 |
|
|
3186 |
|
g->bfd2got = htab_try_create (1, mips_elf_bfd2got_entry_hash, |
3187 |
|
mips_elf_bfd2got_entry_eq, NULL); |
3188 |
|
if (g->bfd2got == NULL) |
3189 |
|
return FALSE; |
3190 |
|
|
3191 |
|
got_per_bfd_arg.bfd2got = g->bfd2got; |
3192 |
|
got_per_bfd_arg.obfd = abfd; |
3193 |
|
got_per_bfd_arg.info = info; |
3194 |
|
|
3195 |
|
/* Count how many GOT entries each input bfd requires, creating a |
3196 |
|
map from bfd to got info while at that. */ |
3197 |
|
htab_traverse (g->got_entries, mips_elf_make_got_per_bfd, &got_per_bfd_arg); |
3198 |
|
if (got_per_bfd_arg.obfd == NULL) |
3199 |
|
return FALSE; |
3200 |
|
|
3201 |
|
got_per_bfd_arg.current = NULL; |
3202 |
|
got_per_bfd_arg.primary = NULL; |
3203 |
|
/* Taking out PAGES entries is a worst-case estimate. We could |
3204 |
|
compute the maximum number of pages that each separate input bfd |
3205 |
|
uses, but it's probably not worth it. */ |
3206 |
|
got_per_bfd_arg.max_count = ((MIPS_ELF_GOT_MAX_SIZE (abfd) |
3207 |
|
/ MIPS_ELF_GOT_SIZE (abfd)) |
3208 |
|
- MIPS_RESERVED_GOTNO - pages); |
3209 |
|
/* The number of globals that will be included in the primary GOT. |
3210 |
|
See the calls to mips_elf_set_global_got_offset below for more |
3211 |
|
information. */ |
3212 |
|
got_per_bfd_arg.global_count = g->global_gotno; |
3213 |
|
|
3214 |
|
/* Try to merge the GOTs of input bfds together, as long as they |
3215 |
|
don't seem to exceed the maximum GOT size, choosing one of them |
3216 |
|
to be the primary GOT. */ |
3217 |
|
htab_traverse (g->bfd2got, mips_elf_merge_gots, &got_per_bfd_arg); |
3218 |
|
if (got_per_bfd_arg.obfd == NULL) |
3219 |
|
return FALSE; |
3220 |
|
|
3221 |
|
/* If we do not find any suitable primary GOT, create an empty one. */ |
3222 |
|
if (got_per_bfd_arg.primary == NULL) |
3223 |
|
{ |
3224 |
|
g->next = (struct mips_got_info *) |
3225 |
|
bfd_alloc (abfd, sizeof (struct mips_got_info)); |
3226 |
|
if (g->next == NULL) |
3227 |
|
return FALSE; |
3228 |
|
|
3229 |
|
g->next->global_gotsym = NULL; |
3230 |
|
g->next->global_gotno = 0; |
3231 |
|
g->next->local_gotno = 0; |
3232 |
|
g->next->tls_gotno = 0; |
3233 |
|
g->next->assigned_gotno = 0; |
3234 |
|
g->next->tls_assigned_gotno = 0; |
3235 |
|
g->next->tls_ldm_offset = MINUS_ONE; |
3236 |
|
g->next->got_entries = htab_try_create (1, mips_elf_multi_got_entry_hash, |
3237 |
|
mips_elf_multi_got_entry_eq, |
3238 |
|
NULL); |
3239 |
|
if (g->next->got_entries == NULL) |
3240 |
|
return FALSE; |
3241 |
|
g->next->bfd2got = NULL; |
3242 |
|
} |
3243 |
|
else |
3244 |
|
g->next = got_per_bfd_arg.primary; |
3245 |
|
g->next->next = got_per_bfd_arg.current; |
3246 |
|
|
3247 |
|
/* GG is now the master GOT, and G is the primary GOT. */ |
3248 |
|
gg = g; |
3249 |
|
g = g->next; |
3250 |
|
|
3251 |
|
/* Map the output bfd to the primary got. That's what we're going |
3252 |
|
to use for bfds that use GOT16 or GOT_PAGE relocations that we |
3253 |
|
didn't mark in check_relocs, and we want a quick way to find it. |
3254 |
|
We can't just use gg->next because we're going to reverse the |
3255 |
|
list. */ |
3256 |
|
{ |
3257 |
|
struct mips_elf_bfd2got_hash *bfdgot; |
3258 |
|
void **bfdgotp; |
3259 |
|
|
3260 |
|
bfdgot = (struct mips_elf_bfd2got_hash *)bfd_alloc |
3261 |
|
(abfd, sizeof (struct mips_elf_bfd2got_hash)); |
3262 |
|
|
3263 |
|
if (bfdgot == NULL) |
3264 |
|
return FALSE; |
3265 |
|
|
3266 |
|
bfdgot->bfd = abfd; |
3267 |
|
bfdgot->g = g; |
3268 |
|
bfdgotp = htab_find_slot (gg->bfd2got, bfdgot, INSERT); |
3269 |
|
|
3270 |
|
BFD_ASSERT (*bfdgotp == NULL); |
3271 |
|
*bfdgotp = bfdgot; |
3272 |
|
} |
3273 |
|
|
3274 |
|
/* The IRIX dynamic linker requires every symbol that is referenced |
3275 |
|
in a dynamic relocation to be present in the primary GOT, so |
3276 |
|
arrange for them to appear after those that are actually |
3277 |
|
referenced. |
3278 |
|
|
3279 |
|
GNU/Linux could very well do without it, but it would slow down |
3280 |
|
the dynamic linker, since it would have to resolve every dynamic |
3281 |
|
symbol referenced in other GOTs more than once, without help from |
3282 |
|
the cache. Also, knowing that every external symbol has a GOT |
3283 |
|
helps speed up the resolution of local symbols too, so GNU/Linux |
3284 |
|
follows IRIX's practice. |
3285 |
|
|
3286 |
|
The number 2 is used by mips_elf_sort_hash_table_f to count |
3287 |
|
global GOT symbols that are unreferenced in the primary GOT, with |
3288 |
|
an initial dynamic index computed from gg->assigned_gotno, where |
3289 |
|
the number of unreferenced global entries in the primary GOT is |
3290 |
|
preserved. */ |
3291 |
|
if (1) |
3292 |
|
{ |
3293 |
|
gg->assigned_gotno = gg->global_gotno - g->global_gotno; |
3294 |
|
g->global_gotno = gg->global_gotno; |
3295 |
|
set_got_offset_arg.value = 2; |
3296 |
|
} |
3297 |
|
else |
3298 |
|
{ |
3299 |
|
/* This could be used for dynamic linkers that don't optimize |
3300 |
|
symbol resolution while applying relocations so as to use |
3301 |
|
primary GOT entries or assuming the symbol is locally-defined. |
3302 |
|
With this code, we assign lower dynamic indices to global |
3303 |
|
symbols that are not referenced in the primary GOT, so that |
3304 |
|
their entries can be omitted. */ |
3305 |
|
gg->assigned_gotno = 0; |
3306 |
|
set_got_offset_arg.value = -1; |
3307 |
|
} |
3308 |
|
|
3309 |
|
/* Reorder dynamic symbols as described above (which behavior |
3310 |
|
depends on the setting of VALUE). */ |
3311 |
|
set_got_offset_arg.g = NULL; |
3312 |
|
htab_traverse (gg->got_entries, mips_elf_set_global_got_offset, |
3313 |
|
&set_got_offset_arg); |
3314 |
|
set_got_offset_arg.value = 1; |
3315 |
|
htab_traverse (g->got_entries, mips_elf_set_global_got_offset, |
3316 |
|
&set_got_offset_arg); |
3317 |
|
if (! mips_elf_sort_hash_table (info, 1)) |
3318 |
|
return FALSE; |
3319 |
|
|
3320 |
|
/* Now go through the GOTs assigning them offset ranges. |
3321 |
|
[assigned_gotno, local_gotno[ will be set to the range of local |
3322 |
|
entries in each GOT. We can then compute the end of a GOT by |
3323 |
|
adding local_gotno to global_gotno. We reverse the list and make |
3324 |
|
it circular since then we'll be able to quickly compute the |
3325 |
|
beginning of a GOT, by computing the end of its predecessor. To |
3326 |
|
avoid special cases for the primary GOT, while still preserving |
3327 |
|
assertions that are valid for both single- and multi-got links, |
3328 |
|
we arrange for the main got struct to have the right number of |
3329 |
|
global entries, but set its local_gotno such that the initial |
3330 |
|
offset of the primary GOT is zero. Remember that the primary GOT |
3331 |
|
will become the last item in the circular linked list, so it |
3332 |
|
points back to the master GOT. */ |
3333 |
|
gg->local_gotno = -g->global_gotno; |
3334 |
|
gg->global_gotno = g->global_gotno; |
3335 |
|
gg->tls_gotno = 0; |
3336 |
|
assign = 0; |
3337 |
|
gg->next = gg; |
3338 |
|
|
3339 |
|
do |
3340 |
|
{ |
3341 |
|
struct mips_got_info *gn; |
3342 |
|
|
3343 |
|
assign += MIPS_RESERVED_GOTNO; |
3344 |
|
g->assigned_gotno = assign; |
3345 |
|
g->local_gotno += assign + pages; |
3346 |
|
assign = g->local_gotno + g->global_gotno + g->tls_gotno; |
3347 |
|
|
3348 |
|
/* Set up any TLS entries. We always place the TLS entries after |
3349 |
|
all non-TLS entries. */ |
3350 |
|
g->tls_assigned_gotno = g->local_gotno + g->global_gotno; |
3351 |
|
htab_traverse (g->got_entries, mips_elf_initialize_tls_index, g); |
3352 |
|
|
3353 |
|
/* Take g out of the direct list, and push it onto the reversed |
3354 |
|
list that gg points to. */ |
3355 |
|
gn = g->next; |
3356 |
|
g->next = gg->next; |
3357 |
|
gg->next = g; |
3358 |
|
g = gn; |
3359 |
|
|
3360 |
|
/* Mark global symbols in every non-primary GOT as ineligible for |
3361 |
|
stubs. */ |
3362 |
|
if (g) |
3363 |
|
htab_traverse (g->got_entries, mips_elf_set_no_stub, NULL); |
3364 |
|
} |
3365 |
|
while (g); |
3366 |
|
|
3367 |
|
got->size = (gg->next->local_gotno |
3368 |
|
+ gg->next->global_gotno |
3369 |
|
+ gg->next->tls_gotno) * MIPS_ELF_GOT_SIZE (abfd); |
3370 |
|
|
3371 |
|
return TRUE; |
3372 |
|
} |
3373 |
|
|
3374 |
|
|
3375 |
/* Returns the first relocation of type r_type found, beginning with |
/* Returns the first relocation of type r_type found, beginning with |
3376 |
RELOCATION. RELEND is one-past-the-end of the relocation table. */ |
RELOCATION. RELEND is one-past-the-end of the relocation table. */ |
3377 |
|
|
3378 |
static const Elf_Internal_Rela * |
static const Elf_Internal_Rela * |
3379 |
mips_elf_next_relocation (abfd, r_type, relocation, relend) |
mips_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type, |
3380 |
bfd *abfd ATTRIBUTE_UNUSED; |
const Elf_Internal_Rela *relocation, |
3381 |
unsigned int r_type; |
const Elf_Internal_Rela *relend) |
3382 |
const Elf_Internal_Rela *relocation; |
{ |
|
const Elf_Internal_Rela *relend; |
|
|
{ |
|
|
/* According to the MIPS ELF ABI, the R_MIPS_LO16 relocation must be |
|
|
immediately following. However, for the IRIX6 ABI, the next |
|
|
relocation may be a composed relocation consisting of several |
|
|
relocations for the same address. In that case, the R_MIPS_LO16 |
|
|
relocation may occur as one of these. We permit a similar |
|
|
extension in general, as that is useful for GCC. */ |
|
3383 |
while (relocation < relend) |
while (relocation < relend) |
3384 |
{ |
{ |
3385 |
if (ELF_R_TYPE (abfd, relocation->r_info) == r_type) |
if (ELF_R_TYPE (abfd, relocation->r_info) == r_type) |
3395 |
|
|
3396 |
/* Return whether a relocation is against a local symbol. */ |
/* Return whether a relocation is against a local symbol. */ |
3397 |
|
|
3398 |
static boolean |
static bfd_boolean |
3399 |
mips_elf_local_relocation_p (input_bfd, relocation, local_sections, |
mips_elf_local_relocation_p (bfd *input_bfd, |
3400 |
check_forced) |
const Elf_Internal_Rela *relocation, |
3401 |
bfd *input_bfd; |
asection **local_sections, |
3402 |
const Elf_Internal_Rela *relocation; |
bfd_boolean check_forced) |
|
asection **local_sections; |
|
|
boolean check_forced; |
|
3403 |
{ |
{ |
3404 |
unsigned long r_symndx; |
unsigned long r_symndx; |
3405 |
Elf_Internal_Shdr *symtab_hdr; |
Elf_Internal_Shdr *symtab_hdr; |
3411 |
extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info; |
extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info; |
3412 |
|
|
3413 |
if (r_symndx < extsymoff) |
if (r_symndx < extsymoff) |
3414 |
return true; |
return TRUE; |
3415 |
if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL) |
if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL) |
3416 |
return true; |
return TRUE; |
3417 |
|
|
3418 |
if (check_forced) |
if (check_forced) |
3419 |
{ |
{ |
3425 |
while (h->root.root.type == bfd_link_hash_indirect |
while (h->root.root.type == bfd_link_hash_indirect |
3426 |
|| h->root.root.type == bfd_link_hash_warning) |
|| h->root.root.type == bfd_link_hash_warning) |
3427 |
h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link; |
h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link; |
3428 |
if ((h->root.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) |
if (h->root.forced_local) |
3429 |
return true; |
return TRUE; |
3430 |
} |
} |
3431 |
|
|
3432 |
return false; |
return FALSE; |
3433 |
} |
} |
3434 |
|
|
3435 |
/* Sign-extend VALUE, which has the indicated number of BITS. */ |
/* Sign-extend VALUE, which has the indicated number of BITS. */ |
3436 |
|
|
3437 |
static bfd_vma |
bfd_vma |
3438 |
mips_elf_sign_extend (value, bits) |
_bfd_mips_elf_sign_extend (bfd_vma value, int bits) |
|
bfd_vma value; |
|
|
int bits; |
|
3439 |
{ |
{ |
3440 |
if (value & ((bfd_vma) 1 << (bits - 1))) |
if (value & ((bfd_vma) 1 << (bits - 1))) |
3441 |
/* VALUE is negative. */ |
/* VALUE is negative. */ |
3445 |
} |
} |
3446 |
|
|
3447 |
/* Return non-zero if the indicated VALUE has overflowed the maximum |
/* Return non-zero if the indicated VALUE has overflowed the maximum |
3448 |
range expressable by a signed number with the indicated number of |
range expressible by a signed number with the indicated number of |
3449 |
BITS. */ |
BITS. */ |
3450 |
|
|
3451 |
static boolean |
static bfd_boolean |
3452 |
mips_elf_overflow_p (value, bits) |
mips_elf_overflow_p (bfd_vma value, int bits) |
|
bfd_vma value; |
|
|
int bits; |
|
3453 |
{ |
{ |
3454 |
bfd_signed_vma svalue = (bfd_signed_vma) value; |
bfd_signed_vma svalue = (bfd_signed_vma) value; |
3455 |
|
|
3456 |
if (svalue > (1 << (bits - 1)) - 1) |
if (svalue > (1 << (bits - 1)) - 1) |
3457 |
/* The value is too big. */ |
/* The value is too big. */ |
3458 |
return true; |
return TRUE; |
3459 |
else if (svalue < -(1 << (bits - 1))) |
else if (svalue < -(1 << (bits - 1))) |
3460 |
/* The value is too small. */ |
/* The value is too small. */ |
3461 |
return true; |
return TRUE; |
3462 |
|
|
3463 |
/* All is well. */ |
/* All is well. */ |
3464 |
return false; |
return FALSE; |
3465 |
} |
} |
3466 |
|
|
3467 |
/* Calculate the %high function. */ |
/* Calculate the %high function. */ |
3468 |
|
|
3469 |
static bfd_vma |
static bfd_vma |
3470 |
mips_elf_high (value) |
mips_elf_high (bfd_vma value) |
|
bfd_vma value; |
|
3471 |
{ |
{ |
3472 |
return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff; |
return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff; |
3473 |
} |
} |
3475 |
/* Calculate the %higher function. */ |
/* Calculate the %higher function. */ |
3476 |
|
|
3477 |
static bfd_vma |
static bfd_vma |
3478 |
mips_elf_higher (value) |
mips_elf_higher (bfd_vma value ATTRIBUTE_UNUSED) |
|
bfd_vma value ATTRIBUTE_UNUSED; |
|
3479 |
{ |
{ |
3480 |
#ifdef BFD64 |
#ifdef BFD64 |
3481 |
return ((value + (bfd_vma) 0x80008000) >> 32) & 0xffff; |
return ((value + (bfd_vma) 0x80008000) >> 32) & 0xffff; |
3482 |
#else |
#else |
3483 |
abort (); |
abort (); |
3484 |
return (bfd_vma) -1; |
return MINUS_ONE; |
3485 |
#endif |
#endif |
3486 |
} |
} |
3487 |
|
|
3488 |
/* Calculate the %highest function. */ |
/* Calculate the %highest function. */ |
3489 |
|
|
3490 |
static bfd_vma |
static bfd_vma |
3491 |
mips_elf_highest (value) |
mips_elf_highest (bfd_vma value ATTRIBUTE_UNUSED) |
|
bfd_vma value ATTRIBUTE_UNUSED; |
|
3492 |
{ |
{ |
3493 |
#ifdef BFD64 |
#ifdef BFD64 |
3494 |
return ((value + (bfd_vma) 0x800080008000) >> 48) & 0xffff; |
return ((value + (((bfd_vma) 0x8000 << 32) | 0x80008000)) >> 48) & 0xffff; |
3495 |
#else |
#else |
3496 |
abort (); |
abort (); |
3497 |
return (bfd_vma) -1; |
return MINUS_ONE; |
3498 |
#endif |
#endif |
3499 |
} |
} |
3500 |
|
|
3501 |
/* Create the .compact_rel section. */ |
/* Create the .compact_rel section. */ |
3502 |
|
|
3503 |
static boolean |
static bfd_boolean |
3504 |
mips_elf_create_compact_rel_section (abfd, info) |
mips_elf_create_compact_rel_section |
3505 |
bfd *abfd; |
(bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED) |
|
struct bfd_link_info *info ATTRIBUTE_UNUSED; |
|
3506 |
{ |
{ |
3507 |
flagword flags; |
flagword flags; |
3508 |
register asection *s; |
register asection *s; |
3517 |
|| ! bfd_set_section_flags (abfd, s, flags) |
|| ! bfd_set_section_flags (abfd, s, flags) |
3518 |
|| ! bfd_set_section_alignment (abfd, s, |
|| ! bfd_set_section_alignment (abfd, s, |
3519 |
MIPS_ELF_LOG_FILE_ALIGN (abfd))) |
MIPS_ELF_LOG_FILE_ALIGN (abfd))) |
3520 |
return false; |
return FALSE; |
3521 |
|
|
3522 |
s->_raw_size = sizeof (Elf32_External_compact_rel); |
s->size = sizeof (Elf32_External_compact_rel); |
3523 |
} |
} |
3524 |
|
|
3525 |
return true; |
return TRUE; |
3526 |
} |
} |
3527 |
|
|
3528 |
/* Create the .got section to hold the global offset table. */ |
/* Create the .got section to hold the global offset table. */ |
3529 |
|
|
3530 |
static boolean |
static bfd_boolean |
3531 |
mips_elf_create_got_section (abfd, info) |
mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info, |
3532 |
bfd *abfd; |
bfd_boolean maybe_exclude) |
|
struct bfd_link_info *info; |
|
3533 |
{ |
{ |
3534 |
flagword flags; |
flagword flags; |
3535 |
register asection *s; |
register asection *s; |
3536 |
struct elf_link_hash_entry *h; |
struct elf_link_hash_entry *h; |
3537 |
|
struct bfd_link_hash_entry *bh; |
3538 |
struct mips_got_info *g; |
struct mips_got_info *g; |
3539 |
bfd_size_type amt; |
bfd_size_type amt; |
3540 |
|
|
3541 |
/* This function may be called more than once. */ |
/* This function may be called more than once. */ |
3542 |
if (mips_elf_got_section (abfd)) |
s = mips_elf_got_section (abfd, TRUE); |
3543 |
return true; |
if (s) |
3544 |
|
{ |
3545 |
|
if (! maybe_exclude) |
3546 |
|
s->flags &= ~SEC_EXCLUDE; |
3547 |
|
return TRUE; |
3548 |
|
} |
3549 |
|
|
3550 |
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY |
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY |
3551 |
| SEC_LINKER_CREATED); |
| SEC_LINKER_CREATED); |
3552 |
|
|
3553 |
|
if (maybe_exclude) |
3554 |
|
flags |= SEC_EXCLUDE; |
3555 |
|
|
3556 |
|
/* We have to use an alignment of 2**4 here because this is hardcoded |
3557 |
|
in the function stub generation and in the linker script. */ |
3558 |
s = bfd_make_section (abfd, ".got"); |
s = bfd_make_section (abfd, ".got"); |
3559 |
if (s == NULL |
if (s == NULL |
3560 |
|| ! bfd_set_section_flags (abfd, s, flags) |
|| ! bfd_set_section_flags (abfd, s, flags) |
3561 |
|| ! bfd_set_section_alignment (abfd, s, 4)) |
|| ! bfd_set_section_alignment (abfd, s, 4)) |
3562 |
return false; |
return FALSE; |
3563 |
|
|
3564 |
/* Define the symbol _GLOBAL_OFFSET_TABLE_. We don't do this in the |
/* Define the symbol _GLOBAL_OFFSET_TABLE_. We don't do this in the |
3565 |
linker script because we don't want to define the symbol if we |
linker script because we don't want to define the symbol if we |
3566 |
are not creating a global offset table. */ |
are not creating a global offset table. */ |
3567 |
h = NULL; |
bh = NULL; |
3568 |
if (! (_bfd_generic_link_add_one_symbol |
if (! (_bfd_generic_link_add_one_symbol |
3569 |
(info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s, |
(info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s, |
3570 |
(bfd_vma) 0, (const char *) NULL, false, |
0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh))) |
3571 |
get_elf_backend_data (abfd)->collect, |
return FALSE; |
3572 |
(struct bfd_link_hash_entry **) &h))) |
|
3573 |
return false; |
h = (struct elf_link_hash_entry *) bh; |
3574 |
h->elf_link_hash_flags &= ~ELF_LINK_NON_ELF; |
h->non_elf = 0; |
3575 |
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; |
h->def_regular = 1; |
3576 |
h->type = STT_OBJECT; |
h->type = STT_OBJECT; |
3577 |
|
|
3578 |
if (info->shared |
if (info->shared |
3579 |
&& ! bfd_elf32_link_record_dynamic_symbol (info, h)) |
&& ! bfd_elf_link_record_dynamic_symbol (info, h)) |
3580 |
return false; |
return FALSE; |
|
|
|
|
/* The first several global offset table entries are reserved. */ |
|
|
s->_raw_size = MIPS_RESERVED_GOTNO * MIPS_ELF_GOT_SIZE (abfd); |
|
3581 |
|
|
3582 |
amt = sizeof (struct mips_got_info); |
amt = sizeof (struct mips_got_info); |
3583 |
g = (struct mips_got_info *) bfd_alloc (abfd, amt); |
g = bfd_alloc (abfd, amt); |
3584 |
if (g == NULL) |
if (g == NULL) |
3585 |
return false; |
return FALSE; |
3586 |
g->global_gotsym = NULL; |
g->global_gotsym = NULL; |
3587 |
|
g->global_gotno = 0; |
3588 |
|
g->tls_gotno = 0; |
3589 |
g->local_gotno = MIPS_RESERVED_GOTNO; |
g->local_gotno = MIPS_RESERVED_GOTNO; |
3590 |
g->assigned_gotno = MIPS_RESERVED_GOTNO; |
g->assigned_gotno = MIPS_RESERVED_GOTNO; |
3591 |
if (elf_section_data (s) == NULL) |
g->bfd2got = NULL; |
3592 |
{ |
g->next = NULL; |
3593 |
amt = sizeof (struct bfd_elf_section_data); |
g->tls_ldm_offset = MINUS_ONE; |
3594 |
s->used_by_bfd = (PTR) bfd_zalloc (abfd, amt); |
g->got_entries = htab_try_create (1, mips_elf_got_entry_hash, |
3595 |
if (elf_section_data (s) == NULL) |
mips_elf_got_entry_eq, NULL); |
3596 |
return false; |
if (g->got_entries == NULL) |
3597 |
} |
return FALSE; |
3598 |
elf_section_data (s)->tdata = (PTR) g; |
mips_elf_section_data (s)->u.got_info = g; |
3599 |
elf_section_data (s)->this_hdr.sh_flags |
mips_elf_section_data (s)->elf.this_hdr.sh_flags |
3600 |
|= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL; |
|= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL; |
3601 |
|
|
3602 |
return true; |
return TRUE; |
|
} |
|
|
|
|
|
/* Returns the .msym section for ABFD, creating it if it does not |
|
|
already exist. Returns NULL to indicate error. */ |
|
|
|
|
|
static asection * |
|
|
mips_elf_create_msym_section (abfd) |
|
|
bfd *abfd; |
|
|
{ |
|
|
asection *s; |
|
|
|
|
|
s = bfd_get_section_by_name (abfd, ".msym"); |
|
|
if (!s) |
|
|
{ |
|
|
s = bfd_make_section (abfd, ".msym"); |
|
|
if (!s |
|
|
|| !bfd_set_section_flags (abfd, s, |
|
|
SEC_ALLOC |
|
|
| SEC_LOAD |
|
|
| SEC_HAS_CONTENTS |
|
|
| SEC_LINKER_CREATED |
|
|
| SEC_READONLY) |
|
|
|| !bfd_set_section_alignment (abfd, s, |
|
|
MIPS_ELF_LOG_FILE_ALIGN (abfd))) |
|
|
return NULL; |
|
|
} |
|
|
|
|
|
return s; |
|
3603 |
} |
} |
3604 |
|
|
3605 |
/* Calculate the value produced by the RELOCATION (which comes from |
/* Calculate the value produced by the RELOCATION (which comes from |
3616 |
overflow occurs, and bfd_reloc_ok to indicate success. */ |
overflow occurs, and bfd_reloc_ok to indicate success. */ |
3617 |
|
|
3618 |
static bfd_reloc_status_type |
static bfd_reloc_status_type |
3619 |
mips_elf_calculate_relocation (abfd, input_bfd, input_section, info, |
mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, |
3620 |
relocation, addend, howto, local_syms, |
asection *input_section, |
3621 |
local_sections, valuep, namep, |
struct bfd_link_info *info, |
3622 |
require_jalxp) |
const Elf_Internal_Rela *relocation, |
3623 |
bfd *abfd; |
bfd_vma addend, reloc_howto_type *howto, |
3624 |
bfd *input_bfd; |
Elf_Internal_Sym *local_syms, |
3625 |
asection *input_section; |
asection **local_sections, bfd_vma *valuep, |
3626 |
struct bfd_link_info *info; |
const char **namep, bfd_boolean *require_jalxp, |
3627 |
const Elf_Internal_Rela *relocation; |
bfd_boolean save_addend) |
|
bfd_vma addend; |
|
|
reloc_howto_type *howto; |
|
|
Elf_Internal_Sym *local_syms; |
|
|
asection **local_sections; |
|
|
bfd_vma *valuep; |
|
|
const char **namep; |
|
|
boolean *require_jalxp; |
|
3628 |
{ |
{ |
3629 |
/* The eventual value we will return. */ |
/* The eventual value we will return. */ |
3630 |
bfd_vma value; |
bfd_vma value; |
3647 |
located. */ |
located. */ |
3648 |
asection *sec = NULL; |
asection *sec = NULL; |
3649 |
struct mips_elf_link_hash_entry *h = NULL; |
struct mips_elf_link_hash_entry *h = NULL; |
3650 |
/* True if the symbol referred to by this relocation is a local |
/* TRUE if the symbol referred to by this relocation is a local |
3651 |
symbol. */ |
symbol. */ |
3652 |
boolean local_p; |
bfd_boolean local_p, was_local_p; |
3653 |
/* True if the symbol referred to by this relocation is "_gp_disp". */ |
/* TRUE if the symbol referred to by this relocation is "_gp_disp". */ |
3654 |
boolean gp_disp_p = false; |
bfd_boolean gp_disp_p = FALSE; |
3655 |
|
/* TRUE if the symbol referred to by this relocation is |
3656 |
|
"__gnu_local_gp". */ |
3657 |
|
bfd_boolean gnu_local_gp_p = FALSE; |
3658 |
Elf_Internal_Shdr *symtab_hdr; |
Elf_Internal_Shdr *symtab_hdr; |
3659 |
size_t extsymoff; |
size_t extsymoff; |
3660 |
unsigned long r_symndx; |
unsigned long r_symndx; |
3661 |
int r_type; |
int r_type; |
3662 |
/* True if overflow occurred during the calculation of the |
/* TRUE if overflow occurred during the calculation of the |
3663 |
relocation value. */ |
relocation value. */ |
3664 |
boolean overflowed_p; |
bfd_boolean overflowed_p; |
3665 |
/* True if this relocation refers to a MIPS16 function. */ |
/* TRUE if this relocation refers to a MIPS16 function. */ |
3666 |
boolean target_is_16_bit_code_p = false; |
bfd_boolean target_is_16_bit_code_p = FALSE; |
3667 |
|
|
3668 |
/* Parse the relocation. */ |
/* Parse the relocation. */ |
3669 |
r_symndx = ELF_R_SYM (input_bfd, relocation->r_info); |
r_symndx = ELF_R_SYM (input_bfd, relocation->r_info); |
3673 |
+ relocation->r_offset); |
+ relocation->r_offset); |
3674 |
|
|
3675 |
/* Assume that there will be no overflow. */ |
/* Assume that there will be no overflow. */ |
3676 |
overflowed_p = false; |
overflowed_p = FALSE; |
3677 |
|
|
3678 |
/* Figure out whether or not the symbol is local, and get the offset |
/* Figure out whether or not the symbol is local, and get the offset |
3679 |
used in the array of hash table entries. */ |
used in the array of hash table entries. */ |
3680 |
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; |
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; |
3681 |
local_p = mips_elf_local_relocation_p (input_bfd, relocation, |
local_p = mips_elf_local_relocation_p (input_bfd, relocation, |
3682 |
local_sections, false); |
local_sections, FALSE); |
3683 |
|
was_local_p = local_p; |
3684 |
if (! elf_bad_symtab (input_bfd)) |
if (! elf_bad_symtab (input_bfd)) |
3685 |
extsymoff = symtab_hdr->sh_info; |
extsymoff = symtab_hdr->sh_info; |
3686 |
else |
else |
3725 |
} |
} |
3726 |
else |
else |
3727 |
{ |
{ |
3728 |
|
/* ??? Could we use RELOC_FOR_GLOBAL_SYMBOL here ? */ |
3729 |
|
|
3730 |
/* For global symbols we look up the symbol in the hash-table. */ |
/* For global symbols we look up the symbol in the hash-table. */ |
3731 |
h = ((struct mips_elf_link_hash_entry *) |
h = ((struct mips_elf_link_hash_entry *) |
3732 |
elf_sym_hashes (input_bfd) [r_symndx - extsymoff]); |
elf_sym_hashes (input_bfd) [r_symndx - extsymoff]); |
3740 |
|
|
3741 |
/* See if this is the special _gp_disp symbol. Note that such a |
/* See if this is the special _gp_disp symbol. Note that such a |
3742 |
symbol must always be a global symbol. */ |
symbol must always be a global symbol. */ |
3743 |
if (strcmp (h->root.root.root.string, "_gp_disp") == 0 |
if (strcmp (*namep, "_gp_disp") == 0 |
3744 |
&& ! NEWABI_P (input_bfd)) |
&& ! NEWABI_P (input_bfd)) |
3745 |
{ |
{ |
3746 |
/* Relocations against _gp_disp are permitted only with |
/* Relocations against _gp_disp are permitted only with |
3747 |
R_MIPS_HI16 and R_MIPS_LO16 relocations. */ |
R_MIPS_HI16 and R_MIPS_LO16 relocations. */ |
3748 |
if (r_type != R_MIPS_HI16 && r_type != R_MIPS_LO16) |
if (r_type != R_MIPS_HI16 && r_type != R_MIPS_LO16 |
3749 |
|
&& r_type != R_MIPS16_HI16 && r_type != R_MIPS16_LO16) |
3750 |
return bfd_reloc_notsupported; |
return bfd_reloc_notsupported; |
3751 |
|
|
3752 |
gp_disp_p = true; |
gp_disp_p = TRUE; |
3753 |
} |
} |
3754 |
|
/* See if this is the special _gp symbol. Note that such a |
3755 |
|
symbol must always be a global symbol. */ |
3756 |
|
else if (strcmp (*namep, "__gnu_local_gp") == 0) |
3757 |
|
gnu_local_gp_p = TRUE; |
3758 |
|
|
3759 |
|
|
3760 |
/* If this symbol is defined, calculate its address. Note that |
/* If this symbol is defined, calculate its address. Note that |
3761 |
_gp_disp is a magic symbol, always implicitly defined by the |
_gp_disp is a magic symbol, always implicitly defined by the |
3762 |
linker, so it's inappropriate to check to see whether or not |
linker, so it's inappropriate to check to see whether or not |
3779 |
and check to see if they exist by looking at their |
and check to see if they exist by looking at their |
3780 |
addresses. */ |
addresses. */ |
3781 |
symbol = 0; |
symbol = 0; |
3782 |
else if (info->shared |
else if (info->unresolved_syms_in_objects == RM_IGNORE |
|
&& (!info->symbolic || info->allow_shlib_undefined) |
|
|
&& !info->no_undefined |
|
3783 |
&& ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT) |
&& ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT) |
3784 |
symbol = 0; |
symbol = 0; |
3785 |
else if (strcmp (h->root.root.root.string, "_DYNAMIC_LINK") == 0 || |
else if (strcmp (*namep, SGI_COMPAT (input_bfd) |
3786 |
strcmp (h->root.root.root.string, "_DYNAMIC_LINKING") == 0) |
? "_DYNAMIC_LINK" : "_DYNAMIC_LINKING") == 0) |
3787 |
{ |
{ |
3788 |
/* If this is a dynamic link, we should have created a |
/* If this is a dynamic link, we should have created a |
3789 |
_DYNAMIC_LINK symbol or _DYNAMIC_LINKING(for normal mips) symbol |
_DYNAMIC_LINK symbol or _DYNAMIC_LINKING(for normal mips) symbol |
3800 |
if (! ((*info->callbacks->undefined_symbol) |
if (! ((*info->callbacks->undefined_symbol) |
3801 |
(info, h->root.root.root.string, input_bfd, |
(info, h->root.root.root.string, input_bfd, |
3802 |
input_section, relocation->r_offset, |
input_section, relocation->r_offset, |
3803 |
(!info->shared || info->no_undefined |
(info->unresolved_syms_in_objects == RM_GENERATE_ERROR) |
3804 |
|| ELF_ST_VISIBILITY (h->root.other))))) |
|| ELF_ST_VISIBILITY (h->root.other)))) |
3805 |
return bfd_reloc_undefined; |
return bfd_reloc_undefined; |
3806 |
symbol = 0; |
symbol = 0; |
3807 |
} |
} |
3812 |
/* If this is a 32- or 64-bit call to a 16-bit function with a stub, we |
/* If this is a 32- or 64-bit call to a 16-bit function with a stub, we |
3813 |
need to redirect the call to the stub, unless we're already *in* |
need to redirect the call to the stub, unless we're already *in* |
3814 |
a stub. */ |
a stub. */ |
3815 |
if (r_type != R_MIPS16_26 && !info->relocateable |
if (r_type != R_MIPS16_26 && !info->relocatable |
3816 |
&& ((h != NULL && h->fn_stub != NULL) |
&& ((h != NULL && h->fn_stub != NULL) |
3817 |
|| (local_p && elf_tdata (input_bfd)->local_stubs != NULL |
|| (local_p && elf_tdata (input_bfd)->local_stubs != NULL |
3818 |
&& elf_tdata (input_bfd)->local_stubs[r_symndx] != NULL)) |
&& elf_tdata (input_bfd)->local_stubs[r_symndx] != NULL)) |
3833 |
} |
} |
3834 |
/* If this is a 16-bit call to a 32- or 64-bit function with a stub, we |
/* If this is a 16-bit call to a 32- or 64-bit function with a stub, we |
3835 |
need to redirect the call to the stub. */ |
need to redirect the call to the stub. */ |
3836 |
else if (r_type == R_MIPS16_26 && !info->relocateable |
else if (r_type == R_MIPS16_26 && !info->relocatable |
3837 |
&& h != NULL |
&& h != NULL |
3838 |
&& (h->call_stub != NULL || h->call_fp_stub != NULL) |
&& (h->call_stub != NULL || h->call_fp_stub != NULL) |
3839 |
&& !target_is_16_bit_code_p) |
&& !target_is_16_bit_code_p) |
3863 |
else |
else |
3864 |
sec = h->call_fp_stub; |
sec = h->call_fp_stub; |
3865 |
|
|
3866 |
BFD_ASSERT (sec->_raw_size > 0); |
BFD_ASSERT (sec->size > 0); |
3867 |
symbol = sec->output_section->vma + sec->output_offset; |
symbol = sec->output_section->vma + sec->output_offset; |
3868 |
} |
} |
3869 |
|
|
3870 |
/* Calls from 16-bit code to 32-bit code and vice versa require the |
/* Calls from 16-bit code to 32-bit code and vice versa require the |
3871 |
special jalx instruction. */ |
special jalx instruction. */ |
3872 |
*require_jalxp = (!info->relocateable |
*require_jalxp = (!info->relocatable |
3873 |
&& (((r_type == R_MIPS16_26) && !target_is_16_bit_code_p) |
&& (((r_type == R_MIPS16_26) && !target_is_16_bit_code_p) |
3874 |
|| ((r_type == R_MIPS_26) && target_is_16_bit_code_p))); |
|| ((r_type == R_MIPS_26) && target_is_16_bit_code_p))); |
3875 |
|
|
3876 |
local_p = mips_elf_local_relocation_p (input_bfd, relocation, |
local_p = mips_elf_local_relocation_p (input_bfd, relocation, |
3877 |
local_sections, true); |
local_sections, TRUE); |
3878 |
|
|
3879 |
/* If we haven't already determined the GOT offset, or the GP value, |
/* If we haven't already determined the GOT offset, or the GP value, |
3880 |
and we're going to need it, get it now. */ |
and we're going to need it, get it now. */ |
3881 |
switch (r_type) |
switch (r_type) |
3882 |
{ |
{ |
3883 |
|
case R_MIPS_GOT_PAGE: |
3884 |
|
case R_MIPS_GOT_OFST: |
3885 |
|
/* We need to decay to GOT_DISP/addend if the symbol doesn't |
3886 |
|
bind locally. */ |
3887 |
|
local_p = local_p || _bfd_elf_symbol_refs_local_p (&h->root, info, 1); |
3888 |
|
if (local_p || r_type == R_MIPS_GOT_OFST) |
3889 |
|
break; |
3890 |
|
/* Fall through. */ |
3891 |
|
|
3892 |
case R_MIPS_CALL16: |
case R_MIPS_CALL16: |
3893 |
case R_MIPS_GOT16: |
case R_MIPS_GOT16: |
3894 |
case R_MIPS_GOT_DISP: |
case R_MIPS_GOT_DISP: |
3896 |
case R_MIPS_CALL_HI16: |
case R_MIPS_CALL_HI16: |
3897 |
case R_MIPS_GOT_LO16: |
case R_MIPS_GOT_LO16: |
3898 |
case R_MIPS_CALL_LO16: |
case R_MIPS_CALL_LO16: |
3899 |
|
case R_MIPS_TLS_GD: |
3900 |
|
case R_MIPS_TLS_GOTTPREL: |
3901 |
|
case R_MIPS_TLS_LDM: |
3902 |
/* Find the index into the GOT where this value is located. */ |
/* Find the index into the GOT where this value is located. */ |
3903 |
if (!local_p) |
if (r_type == R_MIPS_TLS_LDM) |
3904 |
{ |
{ |
3905 |
BFD_ASSERT (addend == 0); |
g = mips_elf_local_got_index (abfd, input_bfd, info, 0, 0, NULL, |
3906 |
|
r_type); |
3907 |
|
if (g == MINUS_ONE) |
3908 |
|
return bfd_reloc_outofrange; |
3909 |
|
} |
3910 |
|
else if (!local_p) |
3911 |
|
{ |
3912 |
|
/* GOT_PAGE may take a non-zero addend, that is ignored in a |
3913 |
|
GOT_PAGE relocation that decays to GOT_DISP because the |
3914 |
|
symbol turns out to be global. The addend is then added |
3915 |
|
as GOT_OFST. */ |
3916 |
|
BFD_ASSERT (addend == 0 || r_type == R_MIPS_GOT_PAGE); |
3917 |
g = mips_elf_global_got_index (elf_hash_table (info)->dynobj, |
g = mips_elf_global_got_index (elf_hash_table (info)->dynobj, |
3918 |
(struct elf_link_hash_entry *) h); |
input_bfd, |
3919 |
if (! elf_hash_table(info)->dynamic_sections_created |
(struct elf_link_hash_entry *) h, |
3920 |
|| (info->shared |
r_type, info); |
3921 |
&& (info->symbolic || h->root.dynindx == -1) |
if (h->tls_type == GOT_NORMAL |
3922 |
&& (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) |
&& (! elf_hash_table(info)->dynamic_sections_created |
3923 |
|
|| (info->shared |
3924 |
|
&& (info->symbolic || h->root.dynindx == -1) |
3925 |
|
&& h->root.def_regular))) |
3926 |
{ |
{ |
3927 |
/* This is a static link or a -Bsymbolic link. The |
/* This is a static link or a -Bsymbolic link. The |
3928 |
symbol is defined locally, or was forced to be local. |
symbol is defined locally, or was forced to be local. |
3929 |
We must initialize this entry in the GOT. */ |
We must initialize this entry in the GOT. */ |
3930 |
bfd *tmpbfd = elf_hash_table (info)->dynobj; |
bfd *tmpbfd = elf_hash_table (info)->dynobj; |
3931 |
asection *sgot = mips_elf_got_section(tmpbfd); |
asection *sgot = mips_elf_got_section (tmpbfd, FALSE); |
3932 |
MIPS_ELF_PUT_WORD (tmpbfd, symbol + addend, sgot->contents + g); |
MIPS_ELF_PUT_WORD (tmpbfd, symbol, sgot->contents + g); |
3933 |
} |
} |
3934 |
} |
} |
3935 |
else if (r_type == R_MIPS_GOT16 || r_type == R_MIPS_CALL16) |
else if (r_type == R_MIPS_GOT16 || r_type == R_MIPS_CALL16) |
3938 |
break; |
break; |
3939 |
else |
else |
3940 |
{ |
{ |
3941 |
g = mips_elf_local_got_index (abfd, info, symbol + addend); |
g = mips_elf_local_got_index (abfd, input_bfd, |
3942 |
|
info, symbol + addend, r_symndx, h, |
3943 |
|
r_type); |
3944 |
if (g == MINUS_ONE) |
if (g == MINUS_ONE) |
3945 |
return bfd_reloc_outofrange; |
return bfd_reloc_outofrange; |
3946 |
} |
} |
3947 |
|
|
3948 |
/* Convert GOT indices to actual offsets. */ |
/* Convert GOT indices to actual offsets. */ |
3949 |
g = mips_elf_got_offset_from_index (elf_hash_table (info)->dynobj, |
g = mips_elf_got_offset_from_index (elf_hash_table (info)->dynobj, |
3950 |
abfd, g); |
abfd, input_bfd, g); |
3951 |
break; |
break; |
3952 |
|
|
3953 |
case R_MIPS_HI16: |
case R_MIPS_HI16: |
3954 |
case R_MIPS_LO16: |
case R_MIPS_LO16: |
|
case R_MIPS16_GPREL: |
|
3955 |
case R_MIPS_GPREL16: |
case R_MIPS_GPREL16: |
3956 |
case R_MIPS_GPREL32: |
case R_MIPS_GPREL32: |
3957 |
case R_MIPS_LITERAL: |
case R_MIPS_LITERAL: |
3958 |
|
case R_MIPS16_HI16: |
3959 |
|
case R_MIPS16_LO16: |
3960 |
|
case R_MIPS16_GPREL: |
3961 |
gp0 = _bfd_get_gp_value (input_bfd); |
gp0 = _bfd_get_gp_value (input_bfd); |
3962 |
gp = _bfd_get_gp_value (abfd); |
gp = _bfd_get_gp_value (abfd); |
3963 |
|
if (elf_hash_table (info)->dynobj) |
3964 |
|
gp += mips_elf_adjust_gp (abfd, |
3965 |
|
mips_elf_got_info |
3966 |
|
(elf_hash_table (info)->dynobj, NULL), |
3967 |
|
input_bfd); |
3968 |
break; |
break; |
3969 |
|
|
3970 |
default: |
default: |
3971 |
break; |
break; |
3972 |
} |
} |
3973 |
|
|
3974 |
|
if (gnu_local_gp_p) |
3975 |
|
symbol = gp; |
3976 |
|
|
3977 |
/* Figure out what kind of relocation is being performed. */ |
/* Figure out what kind of relocation is being performed. */ |
3978 |
switch (r_type) |
switch (r_type) |
3979 |
{ |
{ |
3981 |
return bfd_reloc_continue; |
return bfd_reloc_continue; |
3982 |
|
|
3983 |
case R_MIPS_16: |
case R_MIPS_16: |
3984 |
value = symbol + mips_elf_sign_extend (addend, 16); |
value = symbol + _bfd_mips_elf_sign_extend (addend, 16); |
3985 |
overflowed_p = mips_elf_overflow_p (value, 16); |
overflowed_p = mips_elf_overflow_p (value, 16); |
3986 |
break; |
break; |
3987 |
|
|
3991 |
if ((info->shared |
if ((info->shared |
3992 |
|| (elf_hash_table (info)->dynamic_sections_created |
|| (elf_hash_table (info)->dynamic_sections_created |
3993 |
&& h != NULL |
&& h != NULL |
3994 |
&& ((h->root.elf_link_hash_flags |
&& h->root.def_dynamic |
3995 |
& ELF_LINK_HASH_DEF_DYNAMIC) != 0) |
&& !h->root.def_regular)) |
|
&& ((h->root.elf_link_hash_flags |
|
|
& ELF_LINK_HASH_DEF_REGULAR) == 0))) |
|
3996 |
&& r_symndx != 0 |
&& r_symndx != 0 |
3997 |
&& (input_section->flags & SEC_ALLOC) != 0) |
&& (input_section->flags & SEC_ALLOC) != 0) |
3998 |
{ |
{ |
4023 |
break; |
break; |
4024 |
|
|
4025 |
case R_MIPS_PC32: |
case R_MIPS_PC32: |
|
case R_MIPS_PC64: |
|
|
case R_MIPS_GNU_REL_LO16: |
|
4026 |
value = symbol + addend - p; |
value = symbol + addend - p; |
4027 |
value &= howto->dst_mask; |
value &= howto->dst_mask; |
4028 |
break; |
break; |
4029 |
|
|
4030 |
case R_MIPS_GNU_REL16_S2: |
case R_MIPS_GNU_REL16_S2: |
4031 |
value = symbol + mips_elf_sign_extend (addend << 2, 18) - p; |
value = symbol + _bfd_mips_elf_sign_extend (addend, 18) - p; |
4032 |
overflowed_p = mips_elf_overflow_p (value, 18); |
overflowed_p = mips_elf_overflow_p (value, 18); |
4033 |
value = (value >> 2) & howto->dst_mask; |
value = (value >> 2) & howto->dst_mask; |
4034 |
break; |
break; |
4035 |
|
|
|
case R_MIPS_GNU_REL_HI16: |
|
|
/* Instead of subtracting 'p' here, we should be subtracting the |
|
|
equivalent value for the LO part of the reloc, since the value |
|
|
here is relative to that address. Because that's not easy to do, |
|
|
we adjust 'addend' in _bfd_mips_elf_relocate_section(). See also |
|
|
the comment there for more information. */ |
|
|
value = mips_elf_high (addend + symbol - p); |
|
|
value &= howto->dst_mask; |
|
|
break; |
|
|
|
|
4036 |
case R_MIPS16_26: |
case R_MIPS16_26: |
4037 |
/* The calculation for R_MIPS16_26 is just the same as for an |
/* The calculation for R_MIPS16_26 is just the same as for an |
4038 |
R_MIPS_26. It's only the storage of the relocated field into |
R_MIPS_26. It's only the storage of the relocated field into |
4041 |
R_MIPS_26 case here. */ |
R_MIPS_26 case here. */ |
4042 |
case R_MIPS_26: |
case R_MIPS_26: |
4043 |
if (local_p) |
if (local_p) |
4044 |
value = (((addend << 2) | ((p + 4) & 0xf0000000)) + symbol) >> 2; |
value = ((addend | ((p + 4) & 0xf0000000)) + symbol) >> 2; |
4045 |
else |
else |
4046 |
value = (mips_elf_sign_extend (addend << 2, 28) + symbol) >> 2; |
{ |
4047 |
|
value = (_bfd_mips_elf_sign_extend (addend, 28) + symbol) >> 2; |
4048 |
|
if (h->root.root.type != bfd_link_hash_undefweak) |
4049 |
|
overflowed_p = (value >> 26) != ((p + 4) >> 28); |
4050 |
|
} |
4051 |
value &= howto->dst_mask; |
value &= howto->dst_mask; |
4052 |
break; |
break; |
4053 |
|
|
4054 |
|
case R_MIPS_TLS_DTPREL_HI16: |
4055 |
|
value = (mips_elf_high (addend + symbol - dtprel_base (info)) |
4056 |
|
& howto->dst_mask); |
4057 |
|
break; |
4058 |
|
|
4059 |
|
case R_MIPS_TLS_DTPREL_LO16: |
4060 |
|
value = (symbol + addend - dtprel_base (info)) & howto->dst_mask; |
4061 |
|
break; |
4062 |
|
|
4063 |
|
case R_MIPS_TLS_TPREL_HI16: |
4064 |
|
value = (mips_elf_high (addend + symbol - tprel_base (info)) |
4065 |
|
& howto->dst_mask); |
4066 |
|
break; |
4067 |
|
|
4068 |
|
case R_MIPS_TLS_TPREL_LO16: |
4069 |
|
value = (symbol + addend - tprel_base (info)) & howto->dst_mask; |
4070 |
|
break; |
4071 |
|
|
4072 |
case R_MIPS_HI16: |
case R_MIPS_HI16: |
4073 |
|
case R_MIPS16_HI16: |
4074 |
if (!gp_disp_p) |
if (!gp_disp_p) |
4075 |
{ |
{ |
4076 |
value = mips_elf_high (addend + symbol); |
value = mips_elf_high (addend + symbol); |
4078 |
} |
} |
4079 |
else |
else |
4080 |
{ |
{ |
4081 |
value = mips_elf_high (addend + gp - p); |
/* For MIPS16 ABI code we generate this sequence |
4082 |
|
0: li $v0,%hi(_gp_disp) |
4083 |
|
4: addiupc $v1,%lo(_gp_disp) |
4084 |
|
8: sll $v0,16 |
4085 |
|
12: addu $v0,$v1 |
4086 |
|
14: move $gp,$v0 |
4087 |
|
So the offsets of hi and lo relocs are the same, but the |
4088 |
|
$pc is four higher than $t9 would be, so reduce |
4089 |
|
both reloc addends by 4. */ |
4090 |
|
if (r_type == R_MIPS16_HI16) |
4091 |
|
value = mips_elf_high (addend + gp - p - 4); |
4092 |
|
else |
4093 |
|
value = mips_elf_high (addend + gp - p); |
4094 |
overflowed_p = mips_elf_overflow_p (value, 16); |
overflowed_p = mips_elf_overflow_p (value, 16); |
4095 |
} |
} |
4096 |
break; |
break; |
4097 |
|
|
4098 |
case R_MIPS_LO16: |
case R_MIPS_LO16: |
4099 |
|
case R_MIPS16_LO16: |
4100 |
if (!gp_disp_p) |
if (!gp_disp_p) |
4101 |
value = (symbol + addend) & howto->dst_mask; |
value = (symbol + addend) & howto->dst_mask; |
4102 |
else |
else |
4103 |
{ |
{ |
4104 |
value = addend + gp - p + 4; |
/* See the comment for R_MIPS16_HI16 above for the reason |
4105 |
|
for this conditional. */ |
4106 |
|
if (r_type == R_MIPS16_LO16) |
4107 |
|
value = addend + gp - p; |
4108 |
|
else |
4109 |
|
value = addend + gp - p + 4; |
4110 |
/* The MIPS ABI requires checking the R_MIPS_LO16 relocation |
/* The MIPS ABI requires checking the R_MIPS_LO16 relocation |
4111 |
for overflow. But, on, say, IRIX5, relocations against |
for overflow. But, on, say, IRIX5, relocations against |
4112 |
_gp_disp are normally generated from the .cpload |
_gp_disp are normally generated from the .cpload |
4140 |
order. We don't need to do anything special here; the |
order. We don't need to do anything special here; the |
4141 |
differences are handled in mips_elf_perform_relocation. */ |
differences are handled in mips_elf_perform_relocation. */ |
4142 |
case R_MIPS_GPREL16: |
case R_MIPS_GPREL16: |
4143 |
if (local_p) |
/* Only sign-extend the addend if it was extracted from the |
4144 |
value = mips_elf_sign_extend (addend, 16) + symbol + gp0 - gp; |
instruction. If the addend was separate, leave it alone, |
4145 |
else |
otherwise we may lose significant bits. */ |
4146 |
value = mips_elf_sign_extend (addend, 16) + symbol - gp; |
if (howto->partial_inplace) |
4147 |
|
addend = _bfd_mips_elf_sign_extend (addend, 16); |
4148 |
|
value = symbol + addend - gp; |
4149 |
|
/* If the symbol was local, any earlier relocatable links will |
4150 |
|
have adjusted its addend with the gp offset, so compensate |
4151 |
|
for that now. Don't do it for symbols forced local in this |
4152 |
|
link, though, since they won't have had the gp offset applied |
4153 |
|
to them before. */ |
4154 |
|
if (was_local_p) |
4155 |
|
value += gp0; |
4156 |
overflowed_p = mips_elf_overflow_p (value, 16); |
overflowed_p = mips_elf_overflow_p (value, 16); |
4157 |
break; |
break; |
4158 |
|
|
4160 |
case R_MIPS_CALL16: |
case R_MIPS_CALL16: |
4161 |
if (local_p) |
if (local_p) |
4162 |
{ |
{ |
4163 |
boolean forced; |
bfd_boolean forced; |
4164 |
|
|
4165 |
/* The special case is when the symbol is forced to be local. We |
/* The special case is when the symbol is forced to be local. We |
4166 |
need the full address in the GOT since no R_MIPS_LO16 relocation |
need the full address in the GOT since no R_MIPS_LO16 relocation |
4167 |
follows. */ |
follows. */ |
4168 |
forced = ! mips_elf_local_relocation_p (input_bfd, relocation, |
forced = ! mips_elf_local_relocation_p (input_bfd, relocation, |
4169 |
local_sections, false); |
local_sections, FALSE); |
4170 |
value = mips_elf_got16_entry (abfd, info, symbol + addend, forced); |
value = mips_elf_got16_entry (abfd, input_bfd, info, |
4171 |
|
symbol + addend, forced); |
4172 |
if (value == MINUS_ONE) |
if (value == MINUS_ONE) |
4173 |
return bfd_reloc_outofrange; |
return bfd_reloc_outofrange; |
4174 |
value |
value |
4175 |
= mips_elf_got_offset_from_index (elf_hash_table (info)->dynobj, |
= mips_elf_got_offset_from_index (elf_hash_table (info)->dynobj, |
4176 |
abfd, value); |
abfd, input_bfd, value); |
4177 |
overflowed_p = mips_elf_overflow_p (value, 16); |
overflowed_p = mips_elf_overflow_p (value, 16); |
4178 |
break; |
break; |
4179 |
} |
} |
4180 |
|
|
4181 |
/* Fall through. */ |
/* Fall through. */ |
4182 |
|
|
4183 |
|
case R_MIPS_TLS_GD: |
4184 |
|
case R_MIPS_TLS_GOTTPREL: |
4185 |
|
case R_MIPS_TLS_LDM: |
4186 |
case R_MIPS_GOT_DISP: |
case R_MIPS_GOT_DISP: |
4187 |
|
got_disp: |
4188 |
value = g; |
value = g; |
4189 |
overflowed_p = mips_elf_overflow_p (value, 16); |
overflowed_p = mips_elf_overflow_p (value, 16); |
4190 |
break; |
break; |
4191 |
|
|
4192 |
case R_MIPS_GPREL32: |
case R_MIPS_GPREL32: |
4193 |
value = (addend + symbol + gp0 - gp) & howto->dst_mask; |
value = (addend + symbol + gp0 - gp); |
4194 |
|
if (!save_addend) |
4195 |
|
value &= howto->dst_mask; |
4196 |
break; |
break; |
4197 |
|
|
4198 |
case R_MIPS_PC16: |
case R_MIPS_PC16: |
4199 |
value = mips_elf_sign_extend (addend, 16) + symbol - p; |
value = _bfd_mips_elf_sign_extend (addend, 16) + symbol - p; |
4200 |
overflowed_p = mips_elf_overflow_p (value, 16); |
overflowed_p = mips_elf_overflow_p (value, 16); |
|
value = (bfd_vma) ((bfd_signed_vma) value / 4); |
|
4201 |
break; |
break; |
4202 |
|
|
4203 |
case R_MIPS_GOT_HI16: |
case R_MIPS_GOT_HI16: |
4216 |
break; |
break; |
4217 |
|
|
4218 |
case R_MIPS_GOT_PAGE: |
case R_MIPS_GOT_PAGE: |
4219 |
value = mips_elf_got_page (abfd, info, symbol + addend, NULL); |
/* GOT_PAGE relocations that reference non-local symbols decay |
4220 |
|
to GOT_DISP. The corresponding GOT_OFST relocation decays to |
4221 |
|
0. */ |
4222 |
|
if (! local_p) |
4223 |
|
goto got_disp; |
4224 |
|
value = mips_elf_got_page (abfd, input_bfd, info, symbol + addend, NULL); |
4225 |
if (value == MINUS_ONE) |
if (value == MINUS_ONE) |
4226 |
return bfd_reloc_outofrange; |
return bfd_reloc_outofrange; |
4227 |
value = mips_elf_got_offset_from_index (elf_hash_table (info)->dynobj, |
value = mips_elf_got_offset_from_index (elf_hash_table (info)->dynobj, |
4228 |
abfd, value); |
abfd, input_bfd, value); |
4229 |
overflowed_p = mips_elf_overflow_p (value, 16); |
overflowed_p = mips_elf_overflow_p (value, 16); |
4230 |
break; |
break; |
4231 |
|
|
4232 |
case R_MIPS_GOT_OFST: |
case R_MIPS_GOT_OFST: |
4233 |
mips_elf_got_page (abfd, info, symbol + addend, &value); |
if (local_p) |
4234 |
|
mips_elf_got_page (abfd, input_bfd, info, symbol + addend, &value); |
4235 |
|
else |
4236 |
|
value = addend; |
4237 |
overflowed_p = mips_elf_overflow_p (value, 16); |
overflowed_p = mips_elf_overflow_p (value, 16); |
4238 |
break; |
break; |
4239 |
|
|
4257 |
value &= howto->dst_mask; |
value &= howto->dst_mask; |
4258 |
break; |
break; |
4259 |
|
|
|
case R_MIPS_PJUMP: |
|
4260 |
case R_MIPS_JALR: |
case R_MIPS_JALR: |
4261 |
/* Both of these may be ignored. R_MIPS_JALR is an optimization |
/* This relocation is only a hint. In some cases, we optimize |
4262 |
hint; we could improve performance by honoring that hint. */ |
it into a bal instruction. But we don't try to optimize |
4263 |
return bfd_reloc_continue; |
branches to the PLT; that will wind up wasting time. */ |
4264 |
|
if (h != NULL && h->root.plt.offset != (bfd_vma) -1) |
4265 |
|
return bfd_reloc_continue; |
4266 |
|
value = symbol + addend; |
4267 |
|
break; |
4268 |
|
|
4269 |
|
case R_MIPS_PJUMP: |
4270 |
case R_MIPS_GNU_VTINHERIT: |
case R_MIPS_GNU_VTINHERIT: |
4271 |
case R_MIPS_GNU_VTENTRY: |
case R_MIPS_GNU_VTENTRY: |
4272 |
/* We don't do anything with these at present. */ |
/* We don't do anything with these at present. */ |
4285 |
/* Obtain the field relocated by RELOCATION. */ |
/* Obtain the field relocated by RELOCATION. */ |
4286 |
|
|
4287 |
static bfd_vma |
static bfd_vma |
4288 |
mips_elf_obtain_contents (howto, relocation, input_bfd, contents) |
mips_elf_obtain_contents (reloc_howto_type *howto, |
4289 |
reloc_howto_type *howto; |
const Elf_Internal_Rela *relocation, |
4290 |
const Elf_Internal_Rela *relocation; |
bfd *input_bfd, bfd_byte *contents) |
|
bfd *input_bfd; |
|
|
bfd_byte *contents; |
|
4291 |
{ |
{ |
4292 |
bfd_vma x; |
bfd_vma x; |
4293 |
bfd_byte *location = contents + relocation->r_offset; |
bfd_byte *location = contents + relocation->r_offset; |
4295 |
/* Obtain the bytes. */ |
/* Obtain the bytes. */ |
4296 |
x = bfd_get ((8 * bfd_get_reloc_size (howto)), input_bfd, location); |
x = bfd_get ((8 * bfd_get_reloc_size (howto)), input_bfd, location); |
4297 |
|
|
|
if ((ELF_R_TYPE (input_bfd, relocation->r_info) == R_MIPS16_26 |
|
|
|| ELF_R_TYPE (input_bfd, relocation->r_info) == R_MIPS16_GPREL) |
|
|
&& bfd_little_endian (input_bfd)) |
|
|
/* The two 16-bit words will be reversed on a little-endian system. |
|
|
See mips_elf_perform_relocation for more details. */ |
|
|
x = (((x & 0xffff) << 16) | ((x & 0xffff0000) >> 16)); |
|
|
|
|
4298 |
return x; |
return x; |
4299 |
} |
} |
4300 |
|
|
4301 |
/* It has been determined that the result of the RELOCATION is the |
/* It has been determined that the result of the RELOCATION is the |
4302 |
VALUE. Use HOWTO to place VALUE into the output file at the |
VALUE. Use HOWTO to place VALUE into the output file at the |
4303 |
appropriate position. The SECTION is the section to which the |
appropriate position. The SECTION is the section to which the |
4304 |
relocation applies. If REQUIRE_JALX is true, then the opcode used |
relocation applies. If REQUIRE_JALX is TRUE, then the opcode used |
4305 |
for the relocation must be either JAL or JALX, and it is |
for the relocation must be either JAL or JALX, and it is |
4306 |
unconditionally converted to JALX. |
unconditionally converted to JALX. |
4307 |
|
|
4308 |
Returns false if anything goes wrong. */ |
Returns FALSE if anything goes wrong. */ |
4309 |
|
|
4310 |
static boolean |
static bfd_boolean |
4311 |
mips_elf_perform_relocation (info, howto, relocation, value, input_bfd, |
mips_elf_perform_relocation (struct bfd_link_info *info, |
4312 |
input_section, contents, require_jalx) |
reloc_howto_type *howto, |
4313 |
struct bfd_link_info *info; |
const Elf_Internal_Rela *relocation, |
4314 |
reloc_howto_type *howto; |
bfd_vma value, bfd *input_bfd, |
4315 |
const Elf_Internal_Rela *relocation; |
asection *input_section, bfd_byte *contents, |
4316 |
bfd_vma value; |
bfd_boolean require_jalx) |
|
bfd *input_bfd; |
|
|
asection *input_section; |
|
|
bfd_byte *contents; |
|
|
boolean require_jalx; |
|
4317 |
{ |
{ |
4318 |
bfd_vma x; |
bfd_vma x; |
4319 |
bfd_byte *location; |
bfd_byte *location; |
4322 |
/* Figure out where the relocation is occurring. */ |
/* Figure out where the relocation is occurring. */ |
4323 |
location = contents + relocation->r_offset; |
location = contents + relocation->r_offset; |
4324 |
|
|
4325 |
|
_bfd_mips16_elf_reloc_unshuffle (input_bfd, r_type, FALSE, location); |
4326 |
|
|
4327 |
/* Obtain the current value. */ |
/* Obtain the current value. */ |
4328 |
x = mips_elf_obtain_contents (howto, relocation, input_bfd, contents); |
x = mips_elf_obtain_contents (howto, relocation, input_bfd, contents); |
4329 |
|
|
4330 |
/* Clear the field we are setting. */ |
/* Clear the field we are setting. */ |
4331 |
x &= ~howto->dst_mask; |
x &= ~howto->dst_mask; |
4332 |
|
|
|
/* If this is the R_MIPS16_26 relocation, we must store the |
|
|
value in a funny way. */ |
|
|
if (r_type == R_MIPS16_26) |
|
|
{ |
|
|
/* R_MIPS16_26 is used for the mips16 jal and jalx instructions. |
|
|
Most mips16 instructions are 16 bits, but these instructions |
|
|
are 32 bits. |
|
|
|
|
|
The format of these instructions is: |
|
|
|
|
|
+--------------+--------------------------------+ |
|
|
! JALX ! X! Imm 20:16 ! Imm 25:21 ! |
|
|
+--------------+--------------------------------+ |
|
|
! Immediate 15:0 ! |
|
|
+-----------------------------------------------+ |
|
|
|
|
|
JALX is the 5-bit value 00011. X is 0 for jal, 1 for jalx. |
|
|
Note that the immediate value in the first word is swapped. |
|
|
|
|
|
When producing a relocateable object file, R_MIPS16_26 is |
|
|
handled mostly like R_MIPS_26. In particular, the addend is |
|
|
stored as a straight 26-bit value in a 32-bit instruction. |
|
|
(gas makes life simpler for itself by never adjusting a |
|
|
R_MIPS16_26 reloc to be against a section, so the addend is |
|
|
always zero). However, the 32 bit instruction is stored as 2 |
|
|
16-bit values, rather than a single 32-bit value. In a |
|
|
big-endian file, the result is the same; in a little-endian |
|
|
file, the two 16-bit halves of the 32 bit value are swapped. |
|
|
This is so that a disassembler can recognize the jal |
|
|
instruction. |
|
|
|
|
|
When doing a final link, R_MIPS16_26 is treated as a 32 bit |
|
|
instruction stored as two 16-bit values. The addend A is the |
|
|
contents of the targ26 field. The calculation is the same as |
|
|
R_MIPS_26. When storing the calculated value, reorder the |
|
|
immediate value as shown above, and don't forget to store the |
|
|
value as two 16-bit values. |
|
|
|
|
|
To put it in MIPS ABI terms, the relocation field is T-targ26-16, |
|
|
defined as |
|
|
|
|
|
big-endian: |
|
|
+--------+----------------------+ |
|
|
| | | |
|
|
| | targ26-16 | |
|
|
|31 26|25 0| |
|
|
+--------+----------------------+ |
|
|
|
|
|
little-endian: |
|
|
+----------+------+-------------+ |
|
|
| | | | |
|
|
| sub1 | | sub2 | |
|
|
|0 9|10 15|16 31| |
|
|
+----------+--------------------+ |
|
|
where targ26-16 is sub1 followed by sub2 (i.e., the addend field A is |
|
|
((sub1 << 16) | sub2)). |
|
|
|
|
|
When producing a relocateable object file, the calculation is |
|
|
(((A < 2) | ((P + 4) & 0xf0000000) + S) >> 2) |
|
|
When producing a fully linked file, the calculation is |
|
|
let R = (((A < 2) | ((P + 4) & 0xf0000000) + S) >> 2) |
|
|
((R & 0x1f0000) << 5) | ((R & 0x3e00000) >> 5) | (R & 0xffff) */ |
|
|
|
|
|
if (!info->relocateable) |
|
|
/* Shuffle the bits according to the formula above. */ |
|
|
value = (((value & 0x1f0000) << 5) |
|
|
| ((value & 0x3e00000) >> 5) |
|
|
| (value & 0xffff)); |
|
|
} |
|
|
else if (r_type == R_MIPS16_GPREL) |
|
|
{ |
|
|
/* R_MIPS16_GPREL is used for GP-relative addressing in mips16 |
|
|
mode. A typical instruction will have a format like this: |
|
|
|
|
|
+--------------+--------------------------------+ |
|
|
! EXTEND ! Imm 10:5 ! Imm 15:11 ! |
|
|
+--------------+--------------------------------+ |
|
|
! Major ! rx ! ry ! Imm 4:0 ! |
|
|
+--------------+--------------------------------+ |
|
|
|
|
|
EXTEND is the five bit value 11110. Major is the instruction |
|
|
opcode. |
|
|
|
|
|
This is handled exactly like R_MIPS_GPREL16, except that the |
|
|
addend is retrieved and stored as shown in this diagram; that |
|
|
is, the Imm fields above replace the V-rel16 field. |
|
|
|
|
|
All we need to do here is shuffle the bits appropriately. As |
|
|
above, the two 16-bit halves must be swapped on a |
|
|
little-endian system. */ |
|
|
value = (((value & 0x7e0) << 16) |
|
|
| ((value & 0xf800) << 5) |
|
|
| (value & 0x1f)); |
|
|
} |
|
|
|
|
4333 |
/* Set the field. */ |
/* Set the field. */ |
4334 |
x |= (value & howto->dst_mask); |
x |= (value & howto->dst_mask); |
4335 |
|
|
4336 |
/* If required, turn JAL into JALX. */ |
/* If required, turn JAL into JALX. */ |
4337 |
if (require_jalx) |
if (require_jalx) |
4338 |
{ |
{ |
4339 |
boolean ok; |
bfd_boolean ok; |
4340 |
bfd_vma opcode = x >> 26; |
bfd_vma opcode = x >> 26; |
4341 |
bfd_vma jalx_opcode; |
bfd_vma jalx_opcode; |
4342 |
|
|
4356 |
if (!ok) |
if (!ok) |
4357 |
{ |
{ |
4358 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
4359 |
(_("%s: %s+0x%lx: jump to stub routine which is not jal"), |
(_("%B: %A+0x%lx: jump to stub routine which is not jal"), |
4360 |
bfd_archive_filename (input_bfd), |
input_bfd, |
4361 |
input_section->name, |
input_section, |
4362 |
(unsigned long) relocation->r_offset); |
(unsigned long) relocation->r_offset); |
4363 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
4364 |
return false; |
return FALSE; |
4365 |
} |
} |
4366 |
|
|
4367 |
/* Make this the JALX opcode. */ |
/* Make this the JALX opcode. */ |
4368 |
x = (x & ~(0x3f << 26)) | (jalx_opcode << 26); |
x = (x & ~(0x3f << 26)) | (jalx_opcode << 26); |
4369 |
} |
} |
4370 |
|
|
4371 |
/* Swap the high- and low-order 16 bits on little-endian systems |
/* On the RM9000, bal is faster than jal, because bal uses branch |
4372 |
when doing a MIPS16 relocation. */ |
prediction hardware. If we are linking for the RM9000, and we |
4373 |
if ((r_type == R_MIPS16_GPREL || r_type == R_MIPS16_26) |
see jal, and bal fits, use it instead. Note that this |
4374 |
&& bfd_little_endian (input_bfd)) |
transformation should be safe for all architectures. */ |
4375 |
x = (((x & 0xffff) << 16) | ((x & 0xffff0000) >> 16)); |
if (bfd_get_mach (input_bfd) == bfd_mach_mips9000 |
4376 |
|
&& !info->relocatable |
4377 |
|
&& !require_jalx |
4378 |
|
&& ((r_type == R_MIPS_26 && (x >> 26) == 0x3) /* jal addr */ |
4379 |
|
|| (r_type == R_MIPS_JALR && x == 0x0320f809))) /* jalr t9 */ |
4380 |
|
{ |
4381 |
|
bfd_vma addr; |
4382 |
|
bfd_vma dest; |
4383 |
|
bfd_signed_vma off; |
4384 |
|
|
4385 |
|
addr = (input_section->output_section->vma |
4386 |
|
+ input_section->output_offset |
4387 |
|
+ relocation->r_offset |
4388 |
|
+ 4); |
4389 |
|
if (r_type == R_MIPS_26) |
4390 |
|
dest = (value << 2) | ((addr >> 28) << 28); |
4391 |
|
else |
4392 |
|
dest = value; |
4393 |
|
off = dest - addr; |
4394 |
|
if (off <= 0x1ffff && off >= -0x20000) |
4395 |
|
x = 0x04110000 | (((bfd_vma) off >> 2) & 0xffff); /* bal addr */ |
4396 |
|
} |
4397 |
|
|
4398 |
/* Put the value into the output. */ |
/* Put the value into the output. */ |
4399 |
bfd_put (8 * bfd_get_reloc_size (howto), input_bfd, x, location); |
bfd_put (8 * bfd_get_reloc_size (howto), input_bfd, x, location); |
4400 |
return true; |
|
4401 |
|
_bfd_mips16_elf_reloc_shuffle(input_bfd, r_type, !info->relocatable, |
4402 |
|
location); |
4403 |
|
|
4404 |
|
return TRUE; |
4405 |
} |
} |
4406 |
|
|
4407 |
/* Returns true if SECTION is a MIPS16 stub section. */ |
/* Returns TRUE if SECTION is a MIPS16 stub section. */ |
4408 |
|
|
4409 |
static boolean |
static bfd_boolean |
4410 |
mips_elf_stub_section_p (abfd, section) |
mips_elf_stub_section_p (bfd *abfd ATTRIBUTE_UNUSED, asection *section) |
|
bfd *abfd ATTRIBUTE_UNUSED; |
|
|
asection *section; |
|
4411 |
{ |
{ |
4412 |
const char *name = bfd_get_section_name (abfd, section); |
const char *name = bfd_get_section_name (abfd, section); |
4413 |
|
|
4419 |
/* Add room for N relocations to the .rel.dyn section in ABFD. */ |
/* Add room for N relocations to the .rel.dyn section in ABFD. */ |
4420 |
|
|
4421 |
static void |
static void |
4422 |
mips_elf_allocate_dynamic_relocations (abfd, n) |
mips_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n) |
|
bfd *abfd; |
|
|
unsigned int n; |
|
4423 |
{ |
{ |
4424 |
asection *s; |
asection *s; |
4425 |
|
|
4426 |
s = bfd_get_section_by_name (abfd, ".rel.dyn"); |
s = mips_elf_rel_dyn_section (abfd, FALSE); |
4427 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
4428 |
|
|
4429 |
if (s->_raw_size == 0) |
if (s->size == 0) |
4430 |
{ |
{ |
4431 |
/* Make room for a null element. */ |
/* Make room for a null element. */ |
4432 |
s->_raw_size += MIPS_ELF_REL_SIZE (abfd); |
s->size += MIPS_ELF_REL_SIZE (abfd); |
4433 |
++s->reloc_count; |
++s->reloc_count; |
4434 |
} |
} |
4435 |
s->_raw_size += n * MIPS_ELF_REL_SIZE (abfd); |
s->size += n * MIPS_ELF_REL_SIZE (abfd); |
4436 |
} |
} |
4437 |
|
|
4438 |
/* Create a rel.dyn relocation for the dynamic linker to resolve. REL |
/* Create a rel.dyn relocation for the dynamic linker to resolve. REL |
4440 |
dynamic relocation. The ADDENDP is adjusted if necessary; the |
dynamic relocation. The ADDENDP is adjusted if necessary; the |
4441 |
caller should store the result in place of the original addend. */ |
caller should store the result in place of the original addend. */ |
4442 |
|
|
4443 |
static boolean |
static bfd_boolean |
4444 |
mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec, |
mips_elf_create_dynamic_relocation (bfd *output_bfd, |
4445 |
symbol, addendp, input_section) |
struct bfd_link_info *info, |
4446 |
bfd *output_bfd; |
const Elf_Internal_Rela *rel, |
4447 |
struct bfd_link_info *info; |
struct mips_elf_link_hash_entry *h, |
4448 |
const Elf_Internal_Rela *rel; |
asection *sec, bfd_vma symbol, |
4449 |
struct mips_elf_link_hash_entry *h; |
bfd_vma *addendp, asection *input_section) |
|
asection *sec; |
|
|
bfd_vma symbol; |
|
|
bfd_vma *addendp; |
|
|
asection *input_section; |
|
4450 |
{ |
{ |
4451 |
Elf_Internal_Rel outrel[3]; |
Elf_Internal_Rela outrel[3]; |
|
boolean skip; |
|
4452 |
asection *sreloc; |
asection *sreloc; |
4453 |
bfd *dynobj; |
bfd *dynobj; |
4454 |
int r_type; |
int r_type; |
4455 |
|
long indx; |
4456 |
|
bfd_boolean defined_p; |
4457 |
|
|
4458 |
r_type = ELF_R_TYPE (output_bfd, rel->r_info); |
r_type = ELF_R_TYPE (output_bfd, rel->r_info); |
4459 |
dynobj = elf_hash_table (info)->dynobj; |
dynobj = elf_hash_table (info)->dynobj; |
4460 |
sreloc = bfd_get_section_by_name (dynobj, ".rel.dyn"); |
sreloc = mips_elf_rel_dyn_section (dynobj, FALSE); |
4461 |
BFD_ASSERT (sreloc != NULL); |
BFD_ASSERT (sreloc != NULL); |
4462 |
BFD_ASSERT (sreloc->contents != NULL); |
BFD_ASSERT (sreloc->contents != NULL); |
4463 |
BFD_ASSERT (sreloc->reloc_count * MIPS_ELF_REL_SIZE (output_bfd) |
BFD_ASSERT (sreloc->reloc_count * MIPS_ELF_REL_SIZE (output_bfd) |
4464 |
< sreloc->_raw_size); |
< sreloc->size); |
4465 |
|
|
|
skip = false; |
|
4466 |
outrel[0].r_offset = |
outrel[0].r_offset = |
4467 |
_bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset); |
_bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset); |
4468 |
outrel[1].r_offset = |
outrel[1].r_offset = |
4470 |
outrel[2].r_offset = |
outrel[2].r_offset = |
4471 |
_bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset); |
_bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset); |
4472 |
|
|
4473 |
#if 0 |
if (outrel[0].r_offset == MINUS_ONE) |
4474 |
/* We begin by assuming that the offset for the dynamic relocation |
/* The relocation field has been deleted. */ |
4475 |
is the same as for the original relocation. We'll adjust this |
return TRUE; |
4476 |
later to reflect the correct output offsets. */ |
|
4477 |
if (elf_section_data (input_section)->sec_info_type != ELF_INFO_TYPE_STABS) |
if (outrel[0].r_offset == MINUS_TWO) |
4478 |
{ |
{ |
4479 |
outrel[1].r_offset = rel[1].r_offset; |
/* The relocation field has been converted into a relative value of |
4480 |
outrel[2].r_offset = rel[2].r_offset; |
some sort. Functions like _bfd_elf_write_section_eh_frame expect |
4481 |
|
the field to be fully relocated, so add in the symbol's value. */ |
4482 |
|
*addendp += symbol; |
4483 |
|
return TRUE; |
4484 |
} |
} |
4485 |
else |
|
4486 |
|
/* We must now calculate the dynamic symbol table index to use |
4487 |
|
in the relocation. */ |
4488 |
|
if (h != NULL |
4489 |
|
&& (! info->symbolic || !h->root.def_regular) |
4490 |
|
/* h->root.dynindx may be -1 if this symbol was marked to |
4491 |
|
become local. */ |
4492 |
|
&& h->root.dynindx != -1) |
4493 |
{ |
{ |
4494 |
/* Except that in a stab section things are more complex. |
indx = h->root.dynindx; |
4495 |
Because we compress stab information, the offset given in the |
if (SGI_COMPAT (output_bfd)) |
4496 |
relocation may not be the one we want; we must let the stabs |
defined_p = h->root.def_regular; |
4497 |
machinery tell us the offset. */ |
else |
4498 |
outrel[1].r_offset = outrel[0].r_offset; |
/* ??? glibc's ld.so just adds the final GOT entry to the |
4499 |
outrel[2].r_offset = outrel[0].r_offset; |
relocation field. It therefore treats relocs against |
4500 |
/* If we didn't need the relocation at all, this value will be |
defined symbols in the same way as relocs against |
4501 |
-1. */ |
undefined symbols. */ |
4502 |
if (outrel[0].r_offset == (bfd_vma) -1) |
defined_p = FALSE; |
|
skip = true; |
|
4503 |
} |
} |
|
#endif |
|
|
|
|
|
if (outrel[0].r_offset == (bfd_vma) -1) |
|
|
skip = true; |
|
|
/* FIXME: For -2 runtime relocation needs to be skipped, but |
|
|
properly resolved statically and installed. */ |
|
|
BFD_ASSERT (outrel[0].r_offset != (bfd_vma) -2); |
|
|
|
|
|
/* If we've decided to skip this relocation, just output an empty |
|
|
record. Note that R_MIPS_NONE == 0, so that this call to memset |
|
|
is a way of setting R_TYPE to R_MIPS_NONE. */ |
|
|
if (skip) |
|
|
memset (outrel, 0, sizeof (Elf_Internal_Rel) * 3); |
|
4504 |
else |
else |
4505 |
{ |
{ |
4506 |
long indx; |
if (sec != NULL && bfd_is_abs_section (sec)) |
4507 |
bfd_vma section_offset; |
indx = 0; |
4508 |
|
else if (sec == NULL || sec->owner == NULL) |
|
/* We must now calculate the dynamic symbol table index to use |
|
|
in the relocation. */ |
|
|
if (h != NULL |
|
|
&& (! info->symbolic || (h->root.elf_link_hash_flags |
|
|
& ELF_LINK_HASH_DEF_REGULAR) == 0)) |
|
4509 |
{ |
{ |
4510 |
indx = h->root.dynindx; |
bfd_set_error (bfd_error_bad_value); |
4511 |
/* h->root.dynindx may be -1 if this symbol was marked to |
return FALSE; |
|
become local. */ |
|
|
if (indx == -1) |
|
|
indx = 0; |
|
4512 |
} |
} |
4513 |
else |
else |
4514 |
{ |
{ |
4515 |
if (sec != NULL && bfd_is_abs_section (sec)) |
indx = elf_section_data (sec->output_section)->dynindx; |
4516 |
indx = 0; |
if (indx == 0) |
4517 |
else if (sec == NULL || sec->owner == NULL) |
abort (); |
4518 |
{ |
} |
4519 |
bfd_set_error (bfd_error_bad_value); |
|
4520 |
return false; |
/* Instead of generating a relocation using the section |
4521 |
} |
symbol, we may as well make it a fully relative |
4522 |
else |
relocation. We want to avoid generating relocations to |
4523 |
{ |
local symbols because we used to generate them |
4524 |
indx = elf_section_data (sec->output_section)->dynindx; |
incorrectly, without adding the original symbol value, |
4525 |
if (indx == 0) |
which is mandated by the ABI for section symbols. In |
4526 |
abort (); |
order to give dynamic loaders and applications time to |
4527 |
} |
phase out the incorrect use, we refrain from emitting |
4528 |
|
section-relative relocations. It's not like they're |
4529 |
/* Figure out how far the target of the relocation is from |
useful, after all. This should be a bit more efficient |
4530 |
the beginning of its section. */ |
as well. */ |
4531 |
section_offset = symbol - sec->output_section->vma; |
/* ??? Although this behavior is compatible with glibc's ld.so, |
4532 |
/* The relocation we're building is section-relative. |
the ABI says that relocations against STN_UNDEF should have |
4533 |
Therefore, the original addend must be adjusted by the |
a symbol value of 0. Irix rld honors this, so relocations |
4534 |
section offset. */ |
against STN_UNDEF have no effect. */ |
4535 |
*addendp += section_offset; |
if (!SGI_COMPAT (output_bfd)) |
4536 |
/* Now, the relocation is just against the section. */ |
indx = 0; |
4537 |
symbol = sec->output_section->vma; |
defined_p = TRUE; |
4538 |
} |
} |
4539 |
|
|
4540 |
/* If the relocation was previously an absolute relocation and |
/* If the relocation was previously an absolute relocation and |
4541 |
this symbol will not be referred to by the relocation, we must |
this symbol will not be referred to by the relocation, we must |
4542 |
adjust it by the value we give it in the dynamic symbol table. |
adjust it by the value we give it in the dynamic symbol table. |
4543 |
Otherwise leave the job up to the dynamic linker. */ |
Otherwise leave the job up to the dynamic linker. */ |
4544 |
if (!indx && r_type != R_MIPS_REL32) |
if (defined_p && r_type != R_MIPS_REL32) |
4545 |
*addendp += symbol; |
*addendp += symbol; |
4546 |
|
|
4547 |
/* The relocation is always an REL32 relocation because we don't |
/* The relocation is always an REL32 relocation because we don't |
4548 |
know where the shared library will wind up at load-time. */ |
know where the shared library will wind up at load-time. */ |
4549 |
outrel[0].r_info = ELF_R_INFO (output_bfd, indx, R_MIPS_REL32); |
outrel[0].r_info = ELF_R_INFO (output_bfd, (unsigned long) indx, |
4550 |
|
R_MIPS_REL32); |
4551 |
/* Adjust the output offset of the relocation to reference the |
/* For strict adherence to the ABI specification, we should |
4552 |
correct location in the output file. */ |
generate a R_MIPS_64 relocation record by itself before the |
4553 |
outrel[0].r_offset += (input_section->output_section->vma |
_REL32/_64 record as well, such that the addend is read in as |
4554 |
+ input_section->output_offset); |
a 64-bit value (REL32 is a 32-bit relocation, after all). |
4555 |
outrel[1].r_offset += (input_section->output_section->vma |
However, since none of the existing ELF64 MIPS dynamic |
4556 |
+ input_section->output_offset); |
loaders seems to care, we don't waste space with these |
4557 |
outrel[2].r_offset += (input_section->output_section->vma |
artificial relocations. If this turns out to not be true, |
4558 |
+ input_section->output_offset); |
mips_elf_allocate_dynamic_relocation() should be tweaked so |
4559 |
} |
as to make room for a pair of dynamic relocations per |
4560 |
|
invocation if ABI_64_P, and here we should generate an |
4561 |
|
additional relocation record with R_MIPS_64 by itself for a |
4562 |
|
NULL symbol before this relocation record. */ |
4563 |
|
outrel[1].r_info = ELF_R_INFO (output_bfd, 0, |
4564 |
|
ABI_64_P (output_bfd) |
4565 |
|
? R_MIPS_64 |
4566 |
|
: R_MIPS_NONE); |
4567 |
|
outrel[2].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_NONE); |
4568 |
|
|
4569 |
|
/* Adjust the output offset of the relocation to reference the |
4570 |
|
correct location in the output file. */ |
4571 |
|
outrel[0].r_offset += (input_section->output_section->vma |
4572 |
|
+ input_section->output_offset); |
4573 |
|
outrel[1].r_offset += (input_section->output_section->vma |
4574 |
|
+ input_section->output_offset); |
4575 |
|
outrel[2].r_offset += (input_section->output_section->vma |
4576 |
|
+ input_section->output_offset); |
4577 |
|
|
4578 |
/* Put the relocation back out. We have to use the special |
/* Put the relocation back out. We have to use the special |
4579 |
relocation outputter in the 64-bit case since the 64-bit |
relocation outputter in the 64-bit case since the 64-bit |
4586 |
+ sreloc->reloc_count * sizeof (Elf64_Mips_External_Rel))); |
+ sreloc->reloc_count * sizeof (Elf64_Mips_External_Rel))); |
4587 |
} |
} |
4588 |
else |
else |
4589 |
bfd_elf32_swap_reloc_out (output_bfd, &outrel[0], |
bfd_elf32_swap_reloc_out |
4590 |
(((Elf32_External_Rel *) |
(output_bfd, &outrel[0], |
4591 |
sreloc->contents) |
(sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel))); |
|
+ sreloc->reloc_count)); |
|
|
|
|
|
/* Record the index of the first relocation referencing H. This |
|
|
information is later emitted in the .msym section. */ |
|
|
if (h != NULL |
|
|
&& (h->min_dyn_reloc_index == 0 |
|
|
|| sreloc->reloc_count < h->min_dyn_reloc_index)) |
|
|
h->min_dyn_reloc_index = sreloc->reloc_count; |
|
4592 |
|
|
4593 |
/* We've now added another relocation. */ |
/* We've now added another relocation. */ |
4594 |
++sreloc->reloc_count; |
++sreloc->reloc_count; |
4599 |
|= SHF_WRITE; |
|= SHF_WRITE; |
4600 |
|
|
4601 |
/* On IRIX5, make an entry of compact relocation info. */ |
/* On IRIX5, make an entry of compact relocation info. */ |
4602 |
if (! skip && IRIX_COMPAT (output_bfd) == ict_irix5) |
if (IRIX_COMPAT (output_bfd) == ict_irix5) |
4603 |
{ |
{ |
4604 |
asection *scpt = bfd_get_section_by_name (dynobj, ".compact_rel"); |
asection *scpt = bfd_get_section_by_name (dynobj, ".compact_rel"); |
4605 |
bfd_byte *cr; |
bfd_byte *cr; |
4621 |
|
|
4622 |
cr = (scpt->contents |
cr = (scpt->contents |
4623 |
+ sizeof (Elf32_External_compact_rel)); |
+ sizeof (Elf32_External_compact_rel)); |
4624 |
|
mips_elf_set_cr_relvaddr (cptrel, 0); |
4625 |
bfd_elf32_swap_crinfo_out (output_bfd, &cptrel, |
bfd_elf32_swap_crinfo_out (output_bfd, &cptrel, |
4626 |
((Elf32_External_crinfo *) cr |
((Elf32_External_crinfo *) cr |
4627 |
+ scpt->reloc_count)); |
+ scpt->reloc_count)); |
4629 |
} |
} |
4630 |
} |
} |
4631 |
|
|
4632 |
return true; |
return TRUE; |
4633 |
} |
} |
4634 |
|
|
|
/* Return the ISA for a MIPS e_flags value. */ |
|
|
|
|
|
static INLINE int |
|
|
elf_mips_isa (flags) |
|
|
flagword flags; |
|
|
{ |
|
|
switch (flags & EF_MIPS_ARCH) |
|
|
{ |
|
|
case E_MIPS_ARCH_1: |
|
|
return 1; |
|
|
case E_MIPS_ARCH_2: |
|
|
return 2; |
|
|
case E_MIPS_ARCH_3: |
|
|
return 3; |
|
|
case E_MIPS_ARCH_4: |
|
|
return 4; |
|
|
case E_MIPS_ARCH_5: |
|
|
return 5; |
|
|
case E_MIPS_ARCH_32: |
|
|
return 32; |
|
|
case E_MIPS_ARCH_64: |
|
|
return 64; |
|
|
} |
|
|
return 4; |
|
|
} |
|
|
|
|
4635 |
/* Return the MACH for a MIPS e_flags value. */ |
/* Return the MACH for a MIPS e_flags value. */ |
4636 |
|
|
4637 |
unsigned long |
unsigned long |
4638 |
_bfd_elf_mips_mach (flags) |
_bfd_elf_mips_mach (flagword flags) |
|
flagword flags; |
|
4639 |
{ |
{ |
4640 |
switch (flags & EF_MIPS_MACH) |
switch (flags & EF_MIPS_MACH) |
4641 |
{ |
{ |
4651 |
case E_MIPS_MACH_4111: |
case E_MIPS_MACH_4111: |
4652 |
return bfd_mach_mips4111; |
return bfd_mach_mips4111; |
4653 |
|
|
4654 |
|
case E_MIPS_MACH_4120: |
4655 |
|
return bfd_mach_mips4120; |
4656 |
|
|
4657 |
case E_MIPS_MACH_4650: |
case E_MIPS_MACH_4650: |
4658 |
return bfd_mach_mips4650; |
return bfd_mach_mips4650; |
4659 |
|
|
4660 |
|
case E_MIPS_MACH_5400: |
4661 |
|
return bfd_mach_mips5400; |
4662 |
|
|
4663 |
|
case E_MIPS_MACH_5500: |
4664 |
|
return bfd_mach_mips5500; |
4665 |
|
|
4666 |
|
case E_MIPS_MACH_9000: |
4667 |
|
return bfd_mach_mips9000; |
4668 |
|
|
4669 |
case E_MIPS_MACH_SB1: |
case E_MIPS_MACH_SB1: |
4670 |
return bfd_mach_mips_sb1; |
return bfd_mach_mips_sb1; |
4671 |
|
|
4700 |
case E_MIPS_ARCH_64: |
case E_MIPS_ARCH_64: |
4701 |
return bfd_mach_mipsisa64; |
return bfd_mach_mipsisa64; |
4702 |
break; |
break; |
4703 |
|
|
4704 |
|
case E_MIPS_ARCH_32R2: |
4705 |
|
return bfd_mach_mipsisa32r2; |
4706 |
|
break; |
4707 |
|
|
4708 |
|
case E_MIPS_ARCH_64R2: |
4709 |
|
return bfd_mach_mipsisa64r2; |
4710 |
|
break; |
4711 |
} |
} |
4712 |
} |
} |
4713 |
|
|
4717 |
/* Return printable name for ABI. */ |
/* Return printable name for ABI. */ |
4718 |
|
|
4719 |
static INLINE char * |
static INLINE char * |
4720 |
elf_mips_abi_name (abfd) |
elf_mips_abi_name (bfd *abfd) |
|
bfd *abfd; |
|
4721 |
{ |
{ |
4722 |
flagword flags; |
flagword flags; |
4723 |
|
|
4764 |
This is used for both the 32-bit and the 64-bit ABI. */ |
This is used for both the 32-bit and the 64-bit ABI. */ |
4765 |
|
|
4766 |
void |
void |
4767 |
_bfd_mips_elf_symbol_processing (abfd, asym) |
_bfd_mips_elf_symbol_processing (bfd *abfd, asymbol *asym) |
|
bfd *abfd; |
|
|
asymbol *asym; |
|
4768 |
{ |
{ |
4769 |
elf_symbol_type *elfsym; |
elf_symbol_type *elfsym; |
4770 |
|
|
4822 |
asym->section = bfd_und_section_ptr; |
asym->section = bfd_und_section_ptr; |
4823 |
break; |
break; |
4824 |
|
|
|
#if 0 /* for SGI_COMPAT */ |
|
4825 |
case SHN_MIPS_TEXT: |
case SHN_MIPS_TEXT: |
4826 |
asym->section = mips_elf_text_section_ptr; |
{ |
4827 |
|
asection *section = bfd_get_section_by_name (abfd, ".text"); |
4828 |
|
|
4829 |
|
BFD_ASSERT (SGI_COMPAT (abfd)); |
4830 |
|
if (section != NULL) |
4831 |
|
{ |
4832 |
|
asym->section = section; |
4833 |
|
/* MIPS_TEXT is a bit special, the address is not an offset |
4834 |
|
to the base of the .text section. So substract the section |
4835 |
|
base address to make it an offset. */ |
4836 |
|
asym->value -= section->vma; |
4837 |
|
} |
4838 |
|
} |
4839 |
break; |
break; |
4840 |
|
|
4841 |
case SHN_MIPS_DATA: |
case SHN_MIPS_DATA: |
4842 |
asym->section = mips_elf_data_section_ptr; |
{ |
4843 |
|
asection *section = bfd_get_section_by_name (abfd, ".data"); |
4844 |
|
|
4845 |
|
BFD_ASSERT (SGI_COMPAT (abfd)); |
4846 |
|
if (section != NULL) |
4847 |
|
{ |
4848 |
|
asym->section = section; |
4849 |
|
/* MIPS_DATA is a bit special, the address is not an offset |
4850 |
|
to the base of the .data section. So substract the section |
4851 |
|
base address to make it an offset. */ |
4852 |
|
asym->value -= section->vma; |
4853 |
|
} |
4854 |
|
} |
4855 |
break; |
break; |
|
#endif |
|
4856 |
} |
} |
4857 |
} |
} |
4858 |
|
|
4859 |
|
/* Implement elf_backend_eh_frame_address_size. This differs from |
4860 |
|
the default in the way it handles EABI64. |
4861 |
|
|
4862 |
|
EABI64 was originally specified as an LP64 ABI, and that is what |
4863 |
|
-mabi=eabi normally gives on a 64-bit target. However, gcc has |
4864 |
|
historically accepted the combination of -mabi=eabi and -mlong32, |
4865 |
|
and this ILP32 variation has become semi-official over time. |
4866 |
|
Both forms use elf32 and have pointer-sized FDE addresses. |
4867 |
|
|
4868 |
|
If an EABI object was generated by GCC 4.0 or above, it will have |
4869 |
|
an empty .gcc_compiled_longXX section, where XX is the size of longs |
4870 |
|
in bits. Unfortunately, ILP32 objects generated by earlier compilers |
4871 |
|
have no special marking to distinguish them from LP64 objects. |
4872 |
|
|
4873 |
|
We don't want users of the official LP64 ABI to be punished for the |
4874 |
|
existence of the ILP32 variant, but at the same time, we don't want |
4875 |
|
to mistakenly interpret pre-4.0 ILP32 objects as being LP64 objects. |
4876 |
|
We therefore take the following approach: |
4877 |
|
|
4878 |
|
- If ABFD contains a .gcc_compiled_longXX section, use it to |
4879 |
|
determine the pointer size. |
4880 |
|
|
4881 |
|
- Otherwise check the type of the first relocation. Assume that |
4882 |
|
the LP64 ABI is being used if the relocation is of type R_MIPS_64. |
4883 |
|
|
4884 |
|
- Otherwise punt. |
4885 |
|
|
4886 |
|
The second check is enough to detect LP64 objects generated by pre-4.0 |
4887 |
|
compilers because, in the kind of output generated by those compilers, |
4888 |
|
the first relocation will be associated with either a CIE personality |
4889 |
|
routine or an FDE start address. Furthermore, the compilers never |
4890 |
|
used a special (non-pointer) encoding for this ABI. |
4891 |
|
|
4892 |
|
Checking the relocation type should also be safe because there is no |
4893 |
|
reason to use R_MIPS_64 in an ILP32 object. Pre-4.0 compilers never |
4894 |
|
did so. */ |
4895 |
|
|
4896 |
|
unsigned int |
4897 |
|
_bfd_mips_elf_eh_frame_address_size (bfd *abfd, asection *sec) |
4898 |
|
{ |
4899 |
|
if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64) |
4900 |
|
return 8; |
4901 |
|
if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64) |
4902 |
|
{ |
4903 |
|
bfd_boolean long32_p, long64_p; |
4904 |
|
|
4905 |
|
long32_p = bfd_get_section_by_name (abfd, ".gcc_compiled_long32") != 0; |
4906 |
|
long64_p = bfd_get_section_by_name (abfd, ".gcc_compiled_long64") != 0; |
4907 |
|
if (long32_p && long64_p) |
4908 |
|
return 0; |
4909 |
|
if (long32_p) |
4910 |
|
return 4; |
4911 |
|
if (long64_p) |
4912 |
|
return 8; |
4913 |
|
|
4914 |
|
if (sec->reloc_count > 0 |
4915 |
|
&& elf_section_data (sec)->relocs != NULL |
4916 |
|
&& (ELF32_R_TYPE (elf_section_data (sec)->relocs[0].r_info) |
4917 |
|
== R_MIPS_64)) |
4918 |
|
return 8; |
4919 |
|
|
4920 |
|
return 0; |
4921 |
|
} |
4922 |
|
return 4; |
4923 |
|
} |
4924 |
|
|
4925 |
|
/* There appears to be a bug in the MIPSpro linker that causes GOT_DISP |
4926 |
|
relocations against two unnamed section symbols to resolve to the |
4927 |
|
same address. For example, if we have code like: |
4928 |
|
|
4929 |
|
lw $4,%got_disp(.data)($gp) |
4930 |
|
lw $25,%got_disp(.text)($gp) |
4931 |
|
jalr $25 |
4932 |
|
|
4933 |
|
then the linker will resolve both relocations to .data and the program |
4934 |
|
will jump there rather than to .text. |
4935 |
|
|
4936 |
|
We can work around this problem by giving names to local section symbols. |
4937 |
|
This is also what the MIPSpro tools do. */ |
4938 |
|
|
4939 |
|
bfd_boolean |
4940 |
|
_bfd_mips_elf_name_local_section_symbols (bfd *abfd) |
4941 |
|
{ |
4942 |
|
return SGI_COMPAT (abfd); |
4943 |
|
} |
4944 |
|
|
4945 |
/* Work over a section just before writing it out. This routine is |
/* Work over a section just before writing it out. This routine is |
4946 |
used by both the 32-bit and the 64-bit ABI. FIXME: We recognize |
used by both the 32-bit and the 64-bit ABI. FIXME: We recognize |
4947 |
sections that need the SHF_MIPS_GPREL flag by name; there has to be |
sections that need the SHF_MIPS_GPREL flag by name; there has to be |
4948 |
a better way. */ |
a better way. */ |
4949 |
|
|
4950 |
boolean |
bfd_boolean |
4951 |
_bfd_mips_elf_section_processing (abfd, hdr) |
_bfd_mips_elf_section_processing (bfd *abfd, Elf_Internal_Shdr *hdr) |
|
bfd *abfd; |
|
|
Elf_Internal_Shdr *hdr; |
|
4952 |
{ |
{ |
4953 |
if (hdr->sh_type == SHT_MIPS_REGINFO |
if (hdr->sh_type == SHT_MIPS_REGINFO |
4954 |
&& hdr->sh_size > 0) |
&& hdr->sh_size > 0) |
4961 |
if (bfd_seek (abfd, |
if (bfd_seek (abfd, |
4962 |
hdr->sh_offset + sizeof (Elf32_External_RegInfo) - 4, |
hdr->sh_offset + sizeof (Elf32_External_RegInfo) - 4, |
4963 |
SEEK_SET) != 0) |
SEEK_SET) != 0) |
4964 |
return false; |
return FALSE; |
4965 |
H_PUT_32 (abfd, elf_gp (abfd), buf); |
H_PUT_32 (abfd, elf_gp (abfd), buf); |
4966 |
if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4) |
if (bfd_bwrite (buf, 4, abfd) != 4) |
4967 |
return false; |
return FALSE; |
4968 |
} |
} |
4969 |
|
|
4970 |
if (hdr->sh_type == SHT_MIPS_OPTIONS |
if (hdr->sh_type == SHT_MIPS_OPTIONS |
4971 |
&& hdr->bfd_section != NULL |
&& hdr->bfd_section != NULL |
4972 |
&& elf_section_data (hdr->bfd_section) != NULL |
&& mips_elf_section_data (hdr->bfd_section) != NULL |
4973 |
&& elf_section_data (hdr->bfd_section)->tdata != NULL) |
&& mips_elf_section_data (hdr->bfd_section)->u.tdata != NULL) |
4974 |
{ |
{ |
4975 |
bfd_byte *contents, *l, *lend; |
bfd_byte *contents, *l, *lend; |
4976 |
|
|
4977 |
/* We stored the section contents in the elf_section_data tdata |
/* We stored the section contents in the tdata field in the |
4978 |
field in the set_section_contents routine. We save the |
set_section_contents routine. We save the section contents |
4979 |
section contents so that we don't have to read them again. |
so that we don't have to read them again. |
4980 |
At this point we know that elf_gp is set, so we can look |
At this point we know that elf_gp is set, so we can look |
4981 |
through the section contents to see if there is an |
through the section contents to see if there is an |
4982 |
ODK_REGINFO structure. */ |
ODK_REGINFO structure. */ |
4983 |
|
|
4984 |
contents = (bfd_byte *) elf_section_data (hdr->bfd_section)->tdata; |
contents = mips_elf_section_data (hdr->bfd_section)->u.tdata; |
4985 |
l = contents; |
l = contents; |
4986 |
lend = contents + hdr->sh_size; |
lend = contents + hdr->sh_size; |
4987 |
while (l + sizeof (Elf_External_Options) <= lend) |
while (l + sizeof (Elf_External_Options) <= lend) |
4990 |
|
|
4991 |
bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l, |
bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l, |
4992 |
&intopt); |
&intopt); |
4993 |
|
if (intopt.size < sizeof (Elf_External_Options)) |
4994 |
|
{ |
4995 |
|
(*_bfd_error_handler) |
4996 |
|
(_("%B: Warning: bad `%s' option size %u smaller than its header"), |
4997 |
|
abfd, MIPS_ELF_OPTIONS_SECTION_NAME (abfd), intopt.size); |
4998 |
|
break; |
4999 |
|
} |
5000 |
if (ABI_64_P (abfd) && intopt.kind == ODK_REGINFO) |
if (ABI_64_P (abfd) && intopt.kind == ODK_REGINFO) |
5001 |
{ |
{ |
5002 |
bfd_byte buf[8]; |
bfd_byte buf[8]; |
5007 |
+ sizeof (Elf_External_Options) |
+ sizeof (Elf_External_Options) |
5008 |
+ (sizeof (Elf64_External_RegInfo) - 8)), |
+ (sizeof (Elf64_External_RegInfo) - 8)), |
5009 |
SEEK_SET) != 0) |
SEEK_SET) != 0) |
5010 |
return false; |
return FALSE; |
5011 |
H_PUT_64 (abfd, elf_gp (abfd), buf); |
H_PUT_64 (abfd, elf_gp (abfd), buf); |
5012 |
if (bfd_bwrite (buf, (bfd_size_type) 8, abfd) != 8) |
if (bfd_bwrite (buf, 8, abfd) != 8) |
5013 |
return false; |
return FALSE; |
5014 |
} |
} |
5015 |
else if (intopt.kind == ODK_REGINFO) |
else if (intopt.kind == ODK_REGINFO) |
5016 |
{ |
{ |
5022 |
+ sizeof (Elf_External_Options) |
+ sizeof (Elf_External_Options) |
5023 |
+ (sizeof (Elf32_External_RegInfo) - 4)), |
+ (sizeof (Elf32_External_RegInfo) - 4)), |
5024 |
SEEK_SET) != 0) |
SEEK_SET) != 0) |
5025 |
return false; |
return FALSE; |
5026 |
H_PUT_32 (abfd, elf_gp (abfd), buf); |
H_PUT_32 (abfd, elf_gp (abfd), buf); |
5027 |
if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4) |
if (bfd_bwrite (buf, 4, abfd) != 4) |
5028 |
return false; |
return FALSE; |
5029 |
} |
} |
5030 |
l += intopt.size; |
l += intopt.size; |
5031 |
} |
} |
5070 |
} |
} |
5071 |
} |
} |
5072 |
|
|
5073 |
return true; |
return TRUE; |
5074 |
} |
} |
5075 |
|
|
5076 |
/* Handle a MIPS specific section when reading an object file. This |
/* Handle a MIPS specific section when reading an object file. This |
5080 |
FIXME: We need to handle the SHF_MIPS_GPREL flag, but I'm not sure |
FIXME: We need to handle the SHF_MIPS_GPREL flag, but I'm not sure |
5081 |
how to. */ |
how to. */ |
5082 |
|
|
5083 |
boolean |
bfd_boolean |
5084 |
_bfd_mips_elf_section_from_shdr (abfd, hdr, name) |
_bfd_mips_elf_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr, |
5085 |
bfd *abfd; |
const char *name) |
|
Elf_Internal_Shdr *hdr; |
|
|
const char *name; |
|
5086 |
{ |
{ |
5087 |
flagword flags = 0; |
flagword flags = 0; |
5088 |
|
|
5095 |
{ |
{ |
5096 |
case SHT_MIPS_LIBLIST: |
case SHT_MIPS_LIBLIST: |
5097 |
if (strcmp (name, ".liblist") != 0) |
if (strcmp (name, ".liblist") != 0) |
5098 |
return false; |
return FALSE; |
5099 |
break; |
break; |
5100 |
case SHT_MIPS_MSYM: |
case SHT_MIPS_MSYM: |
5101 |
if (strcmp (name, ".msym") != 0) |
if (strcmp (name, ".msym") != 0) |
5102 |
return false; |
return FALSE; |
5103 |
break; |
break; |
5104 |
case SHT_MIPS_CONFLICT: |
case SHT_MIPS_CONFLICT: |
5105 |
if (strcmp (name, ".conflict") != 0) |
if (strcmp (name, ".conflict") != 0) |
5106 |
return false; |
return FALSE; |
5107 |
break; |
break; |
5108 |
case SHT_MIPS_GPTAB: |
case SHT_MIPS_GPTAB: |
5109 |
if (strncmp (name, ".gptab.", sizeof ".gptab." - 1) != 0) |
if (strncmp (name, ".gptab.", sizeof ".gptab." - 1) != 0) |
5110 |
return false; |
return FALSE; |
5111 |
break; |
break; |
5112 |
case SHT_MIPS_UCODE: |
case SHT_MIPS_UCODE: |
5113 |
if (strcmp (name, ".ucode") != 0) |
if (strcmp (name, ".ucode") != 0) |
5114 |
return false; |
return FALSE; |
5115 |
break; |
break; |
5116 |
case SHT_MIPS_DEBUG: |
case SHT_MIPS_DEBUG: |
5117 |
if (strcmp (name, ".mdebug") != 0) |
if (strcmp (name, ".mdebug") != 0) |
5118 |
return false; |
return FALSE; |
5119 |
flags = SEC_DEBUGGING; |
flags = SEC_DEBUGGING; |
5120 |
break; |
break; |
5121 |
case SHT_MIPS_REGINFO: |
case SHT_MIPS_REGINFO: |
5122 |
if (strcmp (name, ".reginfo") != 0 |
if (strcmp (name, ".reginfo") != 0 |
5123 |
|| hdr->sh_size != sizeof (Elf32_External_RegInfo)) |
|| hdr->sh_size != sizeof (Elf32_External_RegInfo)) |
5124 |
return false; |
return FALSE; |
5125 |
flags = (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_SIZE); |
flags = (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_SIZE); |
5126 |
break; |
break; |
5127 |
case SHT_MIPS_IFACE: |
case SHT_MIPS_IFACE: |
5128 |
if (strcmp (name, ".MIPS.interfaces") != 0) |
if (strcmp (name, ".MIPS.interfaces") != 0) |
5129 |
return false; |
return FALSE; |
5130 |
break; |
break; |
5131 |
case SHT_MIPS_CONTENT: |
case SHT_MIPS_CONTENT: |
5132 |
if (strncmp (name, ".MIPS.content", sizeof ".MIPS.content" - 1) != 0) |
if (strncmp (name, ".MIPS.content", sizeof ".MIPS.content" - 1) != 0) |
5133 |
return false; |
return FALSE; |
5134 |
break; |
break; |
5135 |
case SHT_MIPS_OPTIONS: |
case SHT_MIPS_OPTIONS: |
5136 |
if (strcmp (name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) != 0) |
if (!MIPS_ELF_OPTIONS_SECTION_NAME_P (name)) |
5137 |
return false; |
return FALSE; |
5138 |
break; |
break; |
5139 |
case SHT_MIPS_DWARF: |
case SHT_MIPS_DWARF: |
5140 |
if (strncmp (name, ".debug_", sizeof ".debug_" - 1) != 0) |
if (strncmp (name, ".debug_", sizeof ".debug_" - 1) != 0) |
5141 |
return false; |
return FALSE; |
5142 |
break; |
break; |
5143 |
case SHT_MIPS_SYMBOL_LIB: |
case SHT_MIPS_SYMBOL_LIB: |
5144 |
if (strcmp (name, ".MIPS.symlib") != 0) |
if (strcmp (name, ".MIPS.symlib") != 0) |
5145 |
return false; |
return FALSE; |
5146 |
break; |
break; |
5147 |
case SHT_MIPS_EVENTS: |
case SHT_MIPS_EVENTS: |
5148 |
if (strncmp (name, ".MIPS.events", sizeof ".MIPS.events" - 1) != 0 |
if (strncmp (name, ".MIPS.events", sizeof ".MIPS.events" - 1) != 0 |
5149 |
&& strncmp (name, ".MIPS.post_rel", |
&& strncmp (name, ".MIPS.post_rel", |
5150 |
sizeof ".MIPS.post_rel" - 1) != 0) |
sizeof ".MIPS.post_rel" - 1) != 0) |
5151 |
return false; |
return FALSE; |
5152 |
break; |
break; |
5153 |
default: |
default: |
5154 |
return false; |
break; |
5155 |
} |
} |
5156 |
|
|
5157 |
if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) |
if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) |
5158 |
return false; |
return FALSE; |
5159 |
|
|
5160 |
if (flags) |
if (flags) |
5161 |
{ |
{ |
5163 |
(bfd_get_section_flags (abfd, |
(bfd_get_section_flags (abfd, |
5164 |
hdr->bfd_section) |
hdr->bfd_section) |
5165 |
| flags))) |
| flags))) |
5166 |
return false; |
return FALSE; |
5167 |
} |
} |
5168 |
|
|
5169 |
/* FIXME: We should record sh_info for a .gptab section. */ |
/* FIXME: We should record sh_info for a .gptab section. */ |
5177 |
Elf32_External_RegInfo ext; |
Elf32_External_RegInfo ext; |
5178 |
Elf32_RegInfo s; |
Elf32_RegInfo s; |
5179 |
|
|
5180 |
if (! bfd_get_section_contents (abfd, hdr->bfd_section, (PTR) &ext, |
if (! bfd_get_section_contents (abfd, hdr->bfd_section, |
5181 |
(file_ptr) 0, |
&ext, 0, sizeof ext)) |
5182 |
(bfd_size_type) sizeof ext)) |
return FALSE; |
|
return false; |
|
5183 |
bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s); |
bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s); |
5184 |
elf_gp (abfd) = s.ri_gp_value; |
elf_gp (abfd) = s.ri_gp_value; |
5185 |
} |
} |
5192 |
{ |
{ |
5193 |
bfd_byte *contents, *l, *lend; |
bfd_byte *contents, *l, *lend; |
5194 |
|
|
5195 |
contents = (bfd_byte *) bfd_malloc (hdr->sh_size); |
contents = bfd_malloc (hdr->sh_size); |
5196 |
if (contents == NULL) |
if (contents == NULL) |
5197 |
return false; |
return FALSE; |
5198 |
if (! bfd_get_section_contents (abfd, hdr->bfd_section, contents, |
if (! bfd_get_section_contents (abfd, hdr->bfd_section, contents, |
5199 |
(file_ptr) 0, hdr->sh_size)) |
0, hdr->sh_size)) |
5200 |
{ |
{ |
5201 |
free (contents); |
free (contents); |
5202 |
return false; |
return FALSE; |
5203 |
} |
} |
5204 |
l = contents; |
l = contents; |
5205 |
lend = contents + hdr->sh_size; |
lend = contents + hdr->sh_size; |
5209 |
|
|
5210 |
bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l, |
bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l, |
5211 |
&intopt); |
&intopt); |
5212 |
|
if (intopt.size < sizeof (Elf_External_Options)) |
5213 |
|
{ |
5214 |
|
(*_bfd_error_handler) |
5215 |
|
(_("%B: Warning: bad `%s' option size %u smaller than its header"), |
5216 |
|
abfd, MIPS_ELF_OPTIONS_SECTION_NAME (abfd), intopt.size); |
5217 |
|
break; |
5218 |
|
} |
5219 |
if (ABI_64_P (abfd) && intopt.kind == ODK_REGINFO) |
if (ABI_64_P (abfd) && intopt.kind == ODK_REGINFO) |
5220 |
{ |
{ |
5221 |
Elf64_Internal_RegInfo intreg; |
Elf64_Internal_RegInfo intreg; |
5243 |
free (contents); |
free (contents); |
5244 |
} |
} |
5245 |
|
|
5246 |
return true; |
return TRUE; |
5247 |
} |
} |
5248 |
|
|
5249 |
/* Set the correct type for a MIPS ELF section. We do this by the |
/* Set the correct type for a MIPS ELF section. We do this by the |
5250 |
section name, which is a hack, but ought to work. This routine is |
section name, which is a hack, but ought to work. This routine is |
5251 |
used by both the 32-bit and the 64-bit ABI. */ |
used by both the 32-bit and the 64-bit ABI. */ |
5252 |
|
|
5253 |
boolean |
bfd_boolean |
5254 |
_bfd_mips_elf_fake_sections (abfd, hdr, sec) |
_bfd_mips_elf_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec) |
|
bfd *abfd; |
|
|
Elf32_Internal_Shdr *hdr; |
|
|
asection *sec; |
|
5255 |
{ |
{ |
5256 |
register const char *name; |
register const char *name; |
5257 |
|
unsigned int sh_type; |
5258 |
|
|
5259 |
name = bfd_get_section_name (abfd, sec); |
name = bfd_get_section_name (abfd, sec); |
5260 |
|
sh_type = hdr->sh_type; |
5261 |
|
|
5262 |
if (strcmp (name, ".liblist") == 0) |
if (strcmp (name, ".liblist") == 0) |
5263 |
{ |
{ |
5264 |
hdr->sh_type = SHT_MIPS_LIBLIST; |
hdr->sh_type = SHT_MIPS_LIBLIST; |
5265 |
hdr->sh_info = sec->_raw_size / sizeof (Elf32_Lib); |
hdr->sh_info = sec->size / sizeof (Elf32_Lib); |
5266 |
/* The sh_link field is set in final_write_processing. */ |
/* The sh_link field is set in final_write_processing. */ |
5267 |
} |
} |
5268 |
else if (strcmp (name, ".conflict") == 0) |
else if (strcmp (name, ".conflict") == 0) |
5330 |
hdr->sh_flags |= SHF_MIPS_NOSTRIP; |
hdr->sh_flags |= SHF_MIPS_NOSTRIP; |
5331 |
/* The sh_info field is set in final_write_processing. */ |
/* The sh_info field is set in final_write_processing. */ |
5332 |
} |
} |
5333 |
else if (strcmp (name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0) |
else if (MIPS_ELF_OPTIONS_SECTION_NAME_P (name)) |
5334 |
{ |
{ |
5335 |
hdr->sh_type = SHT_MIPS_OPTIONS; |
hdr->sh_type = SHT_MIPS_OPTIONS; |
5336 |
hdr->sh_entsize = 1; |
hdr->sh_entsize = 1; |
5359 |
hdr->sh_entsize = 8; |
hdr->sh_entsize = 8; |
5360 |
} |
} |
5361 |
|
|
5362 |
/* The generic elf_fake_sections will set up REL_HDR using the |
/* In the unlikely event a special section is empty it has to lose its |
5363 |
default kind of relocations. But, we may actually need both |
special meaning. This may happen e.g. when using `strip' with the |
5364 |
kinds of relocations, so we set up the second header here. |
"--only-keep-debug" option. */ |
5365 |
|
if (sec->size > 0 && !(sec->flags & SEC_HAS_CONTENTS)) |
5366 |
This is not necessary for the O32 ABI since that only uses Elf32_Rel |
hdr->sh_type = sh_type; |
5367 |
relocations (cf. System V ABI, MIPS RISC Processor Supplement, |
|
5368 |
3rd Edition, p. 4-17). It breaks the IRIX 5/6 32-bit ld, since one |
/* The generic elf_fake_sections will set up REL_HDR using the default |
5369 |
of the resulting empty .rela.<section> sections starts with |
kind of relocations. We used to set up a second header for the |
5370 |
sh_offset == object size, and ld doesn't allow that. While the check |
non-default kind of relocations here, but only NewABI would use |
5371 |
is arguably bogus for empty or SHT_NOBITS sections, it can easily be |
these, and the IRIX ld doesn't like resulting empty RELA sections. |
5372 |
avoided by not emitting those useless sections in the first place. */ |
Thus we create those header only on demand now. */ |
|
if ((IRIX_COMPAT (abfd) != ict_irix5 && (IRIX_COMPAT (abfd) != ict_irix6)) |
|
|
&& (sec->flags & SEC_RELOC) != 0) |
|
|
{ |
|
|
struct bfd_elf_section_data *esd; |
|
|
bfd_size_type amt = sizeof (Elf_Internal_Shdr); |
|
|
|
|
|
esd = elf_section_data (sec); |
|
|
BFD_ASSERT (esd->rel_hdr2 == NULL); |
|
|
esd->rel_hdr2 = (Elf_Internal_Shdr *) bfd_zalloc (abfd, amt); |
|
|
if (!esd->rel_hdr2) |
|
|
return false; |
|
|
_bfd_elf_init_reloc_shdr (abfd, esd->rel_hdr2, sec, |
|
|
!elf_section_data (sec)->use_rela_p); |
|
|
} |
|
5373 |
|
|
5374 |
return true; |
return TRUE; |
5375 |
} |
} |
5376 |
|
|
5377 |
/* Given a BFD section, try to locate the corresponding ELF section |
/* Given a BFD section, try to locate the corresponding ELF section |
5380 |
but for non-PIC objects we will certainly want support for at least |
but for non-PIC objects we will certainly want support for at least |
5381 |
the .scommon section. */ |
the .scommon section. */ |
5382 |
|
|
5383 |
boolean |
bfd_boolean |
5384 |
_bfd_mips_elf_section_from_bfd_section (abfd, sec, retval) |
_bfd_mips_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED, |
5385 |
bfd *abfd ATTRIBUTE_UNUSED; |
asection *sec, int *retval) |
|
asection *sec; |
|
|
int *retval; |
|
5386 |
{ |
{ |
5387 |
if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0) |
if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0) |
5388 |
{ |
{ |
5389 |
*retval = SHN_MIPS_SCOMMON; |
*retval = SHN_MIPS_SCOMMON; |
5390 |
return true; |
return TRUE; |
5391 |
} |
} |
5392 |
if (strcmp (bfd_get_section_name (abfd, sec), ".acommon") == 0) |
if (strcmp (bfd_get_section_name (abfd, sec), ".acommon") == 0) |
5393 |
{ |
{ |
5394 |
*retval = SHN_MIPS_ACOMMON; |
*retval = SHN_MIPS_ACOMMON; |
5395 |
return true; |
return TRUE; |
5396 |
} |
} |
5397 |
return false; |
return FALSE; |
5398 |
} |
} |
5399 |
|
|
5400 |
/* Hook called by the linker routine which adds symbols from an object |
/* Hook called by the linker routine which adds symbols from an object |
5401 |
file. We must handle the special MIPS section numbers here. */ |
file. We must handle the special MIPS section numbers here. */ |
5402 |
|
|
5403 |
boolean |
bfd_boolean |
5404 |
_bfd_mips_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) |
_bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, |
5405 |
bfd *abfd; |
Elf_Internal_Sym *sym, const char **namep, |
5406 |
struct bfd_link_info *info; |
flagword *flagsp ATTRIBUTE_UNUSED, |
5407 |
const Elf_Internal_Sym *sym; |
asection **secp, bfd_vma *valp) |
|
const char **namep; |
|
|
flagword *flagsp ATTRIBUTE_UNUSED; |
|
|
asection **secp; |
|
|
bfd_vma *valp; |
|
5408 |
{ |
{ |
5409 |
if (SGI_COMPAT (abfd) |
if (SGI_COMPAT (abfd) |
5410 |
&& (abfd->flags & DYNAMIC) != 0 |
&& (abfd->flags & DYNAMIC) != 0 |
5412 |
{ |
{ |
5413 |
/* Skip IRIX5 rld entry name. */ |
/* Skip IRIX5 rld entry name. */ |
5414 |
*namep = NULL; |
*namep = NULL; |
5415 |
return true; |
return TRUE; |
5416 |
} |
} |
5417 |
|
|
5418 |
switch (sym->st_shndx) |
switch (sym->st_shndx) |
5440 |
|
|
5441 |
elf_text_section = bfd_zalloc (abfd, amt); |
elf_text_section = bfd_zalloc (abfd, amt); |
5442 |
if (elf_text_section == NULL) |
if (elf_text_section == NULL) |
5443 |
return false; |
return FALSE; |
5444 |
|
|
5445 |
amt = sizeof (asymbol); |
amt = sizeof (asymbol); |
5446 |
elf_text_symbol = bfd_zalloc (abfd, amt); |
elf_text_symbol = bfd_zalloc (abfd, amt); |
5447 |
if (elf_text_symbol == NULL) |
if (elf_text_symbol == NULL) |
5448 |
return false; |
return FALSE; |
5449 |
|
|
5450 |
/* Initialize the section. */ |
/* Initialize the section. */ |
5451 |
|
|
5481 |
|
|
5482 |
elf_data_section = bfd_zalloc (abfd, amt); |
elf_data_section = bfd_zalloc (abfd, amt); |
5483 |
if (elf_data_section == NULL) |
if (elf_data_section == NULL) |
5484 |
return false; |
return FALSE; |
5485 |
|
|
5486 |
amt = sizeof (asymbol); |
amt = sizeof (asymbol); |
5487 |
elf_data_symbol = bfd_zalloc (abfd, amt); |
elf_data_symbol = bfd_zalloc (abfd, amt); |
5488 |
if (elf_data_symbol == NULL) |
if (elf_data_symbol == NULL) |
5489 |
return false; |
return FALSE; |
5490 |
|
|
5491 |
/* Initialize the section. */ |
/* Initialize the section. */ |
5492 |
|
|
5521 |
&& strcmp (*namep, "__rld_obj_head") == 0) |
&& strcmp (*namep, "__rld_obj_head") == 0) |
5522 |
{ |
{ |
5523 |
struct elf_link_hash_entry *h; |
struct elf_link_hash_entry *h; |
5524 |
|
struct bfd_link_hash_entry *bh; |
5525 |
|
|
5526 |
/* Mark __rld_obj_head as dynamic. */ |
/* Mark __rld_obj_head as dynamic. */ |
5527 |
h = NULL; |
bh = NULL; |
5528 |
if (! (_bfd_generic_link_add_one_symbol |
if (! (_bfd_generic_link_add_one_symbol |
5529 |
(info, abfd, *namep, BSF_GLOBAL, *secp, |
(info, abfd, *namep, BSF_GLOBAL, *secp, *valp, NULL, FALSE, |
5530 |
(bfd_vma) *valp, (const char *) NULL, false, |
get_elf_backend_data (abfd)->collect, &bh))) |
5531 |
get_elf_backend_data (abfd)->collect, |
return FALSE; |
5532 |
(struct bfd_link_hash_entry **) &h))) |
|
5533 |
return false; |
h = (struct elf_link_hash_entry *) bh; |
5534 |
h->elf_link_hash_flags &= ~ELF_LINK_NON_ELF; |
h->non_elf = 0; |
5535 |
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; |
h->def_regular = 1; |
5536 |
h->type = STT_OBJECT; |
h->type = STT_OBJECT; |
5537 |
|
|
5538 |
if (! bfd_elf32_link_record_dynamic_symbol (info, h)) |
if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
5539 |
return false; |
return FALSE; |
5540 |
|
|
5541 |
mips_elf_hash_table (info)->use_rld_obj_head = true; |
mips_elf_hash_table (info)->use_rld_obj_head = TRUE; |
5542 |
} |
} |
5543 |
|
|
5544 |
/* If this is a mips16 text symbol, add 1 to the value to make it |
/* If this is a mips16 text symbol, add 1 to the value to make it |
5547 |
if (sym->st_other == STO_MIPS16) |
if (sym->st_other == STO_MIPS16) |
5548 |
++*valp; |
++*valp; |
5549 |
|
|
5550 |
return true; |
return TRUE; |
5551 |
} |
} |
5552 |
|
|
5553 |
/* This hook function is called before the linker writes out a global |
/* This hook function is called before the linker writes out a global |
5554 |
symbol. We mark symbols as small common if appropriate. This is |
symbol. We mark symbols as small common if appropriate. This is |
5555 |
also where we undo the increment of the value for a mips16 symbol. */ |
also where we undo the increment of the value for a mips16 symbol. */ |
5556 |
|
|
5557 |
boolean |
bfd_boolean |
5558 |
_bfd_mips_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec) |
_bfd_mips_elf_link_output_symbol_hook |
5559 |
bfd *abfd ATTRIBUTE_UNUSED; |
(struct bfd_link_info *info ATTRIBUTE_UNUSED, |
5560 |
struct bfd_link_info *info ATTRIBUTE_UNUSED; |
const char *name ATTRIBUTE_UNUSED, Elf_Internal_Sym *sym, |
5561 |
const char *name ATTRIBUTE_UNUSED; |
asection *input_sec, struct elf_link_hash_entry *h ATTRIBUTE_UNUSED) |
|
Elf_Internal_Sym *sym; |
|
|
asection *input_sec; |
|
5562 |
{ |
{ |
5563 |
/* If we see a common symbol, which implies a relocatable link, then |
/* If we see a common symbol, which implies a relocatable link, then |
5564 |
if a symbol was small common in an input file, mark it as small |
if a symbol was small common in an input file, mark it as small |
5567 |
&& strcmp (input_sec->name, ".scommon") == 0) |
&& strcmp (input_sec->name, ".scommon") == 0) |
5568 |
sym->st_shndx = SHN_MIPS_SCOMMON; |
sym->st_shndx = SHN_MIPS_SCOMMON; |
5569 |
|
|
5570 |
if (sym->st_other == STO_MIPS16 |
if (sym->st_other == STO_MIPS16) |
5571 |
&& (sym->st_value & 1) != 0) |
sym->st_value &= ~1; |
|
--sym->st_value; |
|
5572 |
|
|
5573 |
return true; |
return TRUE; |
5574 |
} |
} |
5575 |
|
|
5576 |
/* Functions for the dynamic linker. */ |
/* Functions for the dynamic linker. */ |
5577 |
|
|
5578 |
/* Create dynamic sections when linking against a dynamic object. */ |
/* Create dynamic sections when linking against a dynamic object. */ |
5579 |
|
|
5580 |
boolean |
bfd_boolean |
5581 |
_bfd_mips_elf_create_dynamic_sections (abfd, info) |
_bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) |
|
bfd *abfd; |
|
|
struct bfd_link_info *info; |
|
5582 |
{ |
{ |
5583 |
struct elf_link_hash_entry *h; |
struct elf_link_hash_entry *h; |
5584 |
|
struct bfd_link_hash_entry *bh; |
5585 |
flagword flags; |
flagword flags; |
5586 |
register asection *s; |
register asection *s; |
5587 |
const char * const *namep; |
const char * const *namep; |
5594 |
if (s != NULL) |
if (s != NULL) |
5595 |
{ |
{ |
5596 |
if (! bfd_set_section_flags (abfd, s, flags)) |
if (! bfd_set_section_flags (abfd, s, flags)) |
5597 |
return false; |
return FALSE; |
5598 |
} |
} |
5599 |
|
|
5600 |
/* We need to create .got section. */ |
/* We need to create .got section. */ |
5601 |
if (! mips_elf_create_got_section (abfd, info)) |
if (! mips_elf_create_got_section (abfd, info, FALSE)) |
5602 |
return false; |
return FALSE; |
5603 |
|
|
5604 |
/* Create the .msym section on IRIX6. It is used by the dynamic |
if (! mips_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE)) |
5605 |
linker to speed up dynamic relocations, and to avoid computing |
return FALSE; |
|
the ELF hash for symbols. */ |
|
|
if (IRIX_COMPAT (abfd) == ict_irix6 |
|
|
&& !mips_elf_create_msym_section (abfd)) |
|
|
return false; |
|
5606 |
|
|
5607 |
/* Create .stub section. */ |
/* Create .stub section. */ |
5608 |
if (bfd_get_section_by_name (abfd, |
if (bfd_get_section_by_name (abfd, |
5613 |
|| ! bfd_set_section_flags (abfd, s, flags | SEC_CODE) |
|| ! bfd_set_section_flags (abfd, s, flags | SEC_CODE) |
5614 |
|| ! bfd_set_section_alignment (abfd, s, |
|| ! bfd_set_section_alignment (abfd, s, |
5615 |
MIPS_ELF_LOG_FILE_ALIGN (abfd))) |
MIPS_ELF_LOG_FILE_ALIGN (abfd))) |
5616 |
return false; |
return FALSE; |
5617 |
} |
} |
5618 |
|
|
5619 |
if ((IRIX_COMPAT (abfd) == ict_irix5 || IRIX_COMPAT (abfd) == ict_none) |
if ((IRIX_COMPAT (abfd) == ict_irix5 || IRIX_COMPAT (abfd) == ict_none) |
5625 |
|| ! bfd_set_section_flags (abfd, s, flags &~ (flagword) SEC_READONLY) |
|| ! bfd_set_section_flags (abfd, s, flags &~ (flagword) SEC_READONLY) |
5626 |
|| ! bfd_set_section_alignment (abfd, s, |
|| ! bfd_set_section_alignment (abfd, s, |
5627 |
MIPS_ELF_LOG_FILE_ALIGN (abfd))) |
MIPS_ELF_LOG_FILE_ALIGN (abfd))) |
5628 |
return false; |
return FALSE; |
5629 |
} |
} |
5630 |
|
|
5631 |
/* On IRIX5, we adjust add some additional symbols and change the |
/* On IRIX5, we adjust add some additional symbols and change the |
5636 |
{ |
{ |
5637 |
for (namep = mips_elf_dynsym_rtproc_names; *namep != NULL; namep++) |
for (namep = mips_elf_dynsym_rtproc_names; *namep != NULL; namep++) |
5638 |
{ |
{ |
5639 |
h = NULL; |
bh = NULL; |
5640 |
if (! (_bfd_generic_link_add_one_symbol |
if (! (_bfd_generic_link_add_one_symbol |
5641 |
(info, abfd, *namep, BSF_GLOBAL, bfd_und_section_ptr, |
(info, abfd, *namep, BSF_GLOBAL, bfd_und_section_ptr, 0, |
5642 |
(bfd_vma) 0, (const char *) NULL, false, |
NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh))) |
5643 |
get_elf_backend_data (abfd)->collect, |
return FALSE; |
5644 |
(struct bfd_link_hash_entry **) &h))) |
|
5645 |
return false; |
h = (struct elf_link_hash_entry *) bh; |
5646 |
h->elf_link_hash_flags &= ~ELF_LINK_NON_ELF; |
h->non_elf = 0; |
5647 |
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; |
h->def_regular = 1; |
5648 |
h->type = STT_SECTION; |
h->type = STT_SECTION; |
5649 |
|
|
5650 |
if (! bfd_elf32_link_record_dynamic_symbol (info, h)) |
if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
5651 |
return false; |
return FALSE; |
5652 |
} |
} |
5653 |
|
|
5654 |
/* We need to create a .compact_rel section. */ |
/* We need to create a .compact_rel section. */ |
5655 |
if (SGI_COMPAT (abfd)) |
if (SGI_COMPAT (abfd)) |
5656 |
{ |
{ |
5657 |
if (!mips_elf_create_compact_rel_section (abfd, info)) |
if (!mips_elf_create_compact_rel_section (abfd, info)) |
5658 |
return false; |
return FALSE; |
5659 |
} |
} |
5660 |
|
|
5661 |
/* Change aligments of some sections. */ |
/* Change alignments of some sections. */ |
5662 |
s = bfd_get_section_by_name (abfd, ".hash"); |
s = bfd_get_section_by_name (abfd, ".hash"); |
5663 |
if (s != NULL) |
if (s != NULL) |
5664 |
bfd_set_section_alignment (abfd, s, 4); |
bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd)); |
5665 |
s = bfd_get_section_by_name (abfd, ".dynsym"); |
s = bfd_get_section_by_name (abfd, ".dynsym"); |
5666 |
if (s != NULL) |
if (s != NULL) |
5667 |
bfd_set_section_alignment (abfd, s, 4); |
bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd)); |
5668 |
s = bfd_get_section_by_name (abfd, ".dynstr"); |
s = bfd_get_section_by_name (abfd, ".dynstr"); |
5669 |
if (s != NULL) |
if (s != NULL) |
5670 |
bfd_set_section_alignment (abfd, s, 4); |
bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd)); |
5671 |
s = bfd_get_section_by_name (abfd, ".reginfo"); |
s = bfd_get_section_by_name (abfd, ".reginfo"); |
5672 |
if (s != NULL) |
if (s != NULL) |
5673 |
bfd_set_section_alignment (abfd, s, 4); |
bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd)); |
5674 |
s = bfd_get_section_by_name (abfd, ".dynamic"); |
s = bfd_get_section_by_name (abfd, ".dynamic"); |
5675 |
if (s != NULL) |
if (s != NULL) |
5676 |
bfd_set_section_alignment (abfd, s, 4); |
bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd)); |
5677 |
} |
} |
5678 |
|
|
5679 |
if (!info->shared) |
if (!info->shared) |
5680 |
{ |
{ |
5681 |
h = NULL; |
const char *name; |
5682 |
if (SGI_COMPAT (abfd)) |
|
5683 |
{ |
name = SGI_COMPAT (abfd) ? "_DYNAMIC_LINK" : "_DYNAMIC_LINKING"; |
5684 |
if (!(_bfd_generic_link_add_one_symbol |
bh = NULL; |
5685 |
(info, abfd, "_DYNAMIC_LINK", BSF_GLOBAL, bfd_abs_section_ptr, |
if (!(_bfd_generic_link_add_one_symbol |
5686 |
(bfd_vma) 0, (const char *) NULL, false, |
(info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr, 0, |
5687 |
get_elf_backend_data (abfd)->collect, |
NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh))) |
5688 |
(struct bfd_link_hash_entry **) &h))) |
return FALSE; |
5689 |
return false; |
|
5690 |
} |
h = (struct elf_link_hash_entry *) bh; |
5691 |
else |
h->non_elf = 0; |
5692 |
{ |
h->def_regular = 1; |
|
/* For normal mips it is _DYNAMIC_LINKING. */ |
|
|
if (!(_bfd_generic_link_add_one_symbol |
|
|
(info, abfd, "_DYNAMIC_LINKING", BSF_GLOBAL, |
|
|
bfd_abs_section_ptr, (bfd_vma) 0, (const char *) NULL, false, |
|
|
get_elf_backend_data (abfd)->collect, |
|
|
(struct bfd_link_hash_entry **) &h))) |
|
|
return false; |
|
|
} |
|
|
h->elf_link_hash_flags &= ~ELF_LINK_NON_ELF; |
|
|
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; |
|
5693 |
h->type = STT_SECTION; |
h->type = STT_SECTION; |
5694 |
|
|
5695 |
if (! bfd_elf32_link_record_dynamic_symbol (info, h)) |
if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
5696 |
return false; |
return FALSE; |
5697 |
|
|
5698 |
if (! mips_elf_hash_table (info)->use_rld_obj_head) |
if (! mips_elf_hash_table (info)->use_rld_obj_head) |
5699 |
{ |
{ |
5704 |
s = bfd_get_section_by_name (abfd, ".rld_map"); |
s = bfd_get_section_by_name (abfd, ".rld_map"); |
5705 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
5706 |
|
|
5707 |
h = NULL; |
name = SGI_COMPAT (abfd) ? "__rld_map" : "__RLD_MAP"; |
5708 |
if (SGI_COMPAT (abfd)) |
bh = NULL; |
5709 |
{ |
if (!(_bfd_generic_link_add_one_symbol |
5710 |
if (!(_bfd_generic_link_add_one_symbol |
(info, abfd, name, BSF_GLOBAL, s, 0, NULL, FALSE, |
5711 |
(info, abfd, "__rld_map", BSF_GLOBAL, s, |
get_elf_backend_data (abfd)->collect, &bh))) |
5712 |
(bfd_vma) 0, (const char *) NULL, false, |
return FALSE; |
5713 |
get_elf_backend_data (abfd)->collect, |
|
5714 |
(struct bfd_link_hash_entry **) &h))) |
h = (struct elf_link_hash_entry *) bh; |
5715 |
return false; |
h->non_elf = 0; |
5716 |
} |
h->def_regular = 1; |
|
else |
|
|
{ |
|
|
/* For normal mips the symbol is __RLD_MAP. */ |
|
|
if (!(_bfd_generic_link_add_one_symbol |
|
|
(info, abfd, "__RLD_MAP", BSF_GLOBAL, s, |
|
|
(bfd_vma) 0, (const char *) NULL, false, |
|
|
get_elf_backend_data (abfd)->collect, |
|
|
(struct bfd_link_hash_entry **) &h))) |
|
|
return false; |
|
|
} |
|
|
h->elf_link_hash_flags &= ~ELF_LINK_NON_ELF; |
|
|
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; |
|
5717 |
h->type = STT_OBJECT; |
h->type = STT_OBJECT; |
5718 |
|
|
5719 |
if (! bfd_elf32_link_record_dynamic_symbol (info, h)) |
if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
5720 |
return false; |
return FALSE; |
5721 |
} |
} |
5722 |
} |
} |
5723 |
|
|
5724 |
return true; |
return TRUE; |
5725 |
} |
} |
5726 |
|
|
5727 |
/* Look through the relocs for a section during the first phase, and |
/* Look through the relocs for a section during the first phase, and |
5728 |
allocate space in the global offset table. */ |
allocate space in the global offset table. */ |
5729 |
|
|
5730 |
boolean |
bfd_boolean |
5731 |
_bfd_mips_elf_check_relocs (abfd, info, sec, relocs) |
_bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, |
5732 |
bfd *abfd; |
asection *sec, const Elf_Internal_Rela *relocs) |
|
struct bfd_link_info *info; |
|
|
asection *sec; |
|
|
const Elf_Internal_Rela *relocs; |
|
5733 |
{ |
{ |
5734 |
const char *name; |
const char *name; |
5735 |
bfd *dynobj; |
bfd *dynobj; |
5741 |
const Elf_Internal_Rela *rel_end; |
const Elf_Internal_Rela *rel_end; |
5742 |
asection *sgot; |
asection *sgot; |
5743 |
asection *sreloc; |
asection *sreloc; |
5744 |
struct elf_backend_data *bed; |
const struct elf_backend_data *bed; |
5745 |
|
|
5746 |
if (info->relocateable) |
if (info->relocatable) |
5747 |
return true; |
return TRUE; |
5748 |
|
|
5749 |
dynobj = elf_hash_table (info)->dynobj; |
dynobj = elf_hash_table (info)->dynobj; |
5750 |
symtab_hdr = &elf_tdata (abfd)->symtab_hdr; |
symtab_hdr = &elf_tdata (abfd)->symtab_hdr; |
5787 |
sizeof CALL_FP_STUB - 1) == 0) |
sizeof CALL_FP_STUB - 1) == 0) |
5788 |
continue; |
continue; |
5789 |
|
|
5790 |
sec_relocs = (_bfd_elf32_link_read_relocs |
sec_relocs |
5791 |
(abfd, o, (PTR) NULL, |
= _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, |
5792 |
(Elf_Internal_Rela *) NULL, |
info->keep_memory); |
|
info->keep_memory)); |
|
5793 |
if (sec_relocs == NULL) |
if (sec_relocs == NULL) |
5794 |
return false; |
return FALSE; |
5795 |
|
|
5796 |
rend = sec_relocs + o->reloc_count; |
rend = sec_relocs + o->reloc_count; |
5797 |
for (r = sec_relocs; r < rend; r++) |
for (r = sec_relocs; r < rend; r++) |
5814 |
can easily discard it by setting the SEC_EXCLUDE |
can easily discard it by setting the SEC_EXCLUDE |
5815 |
flag. */ |
flag. */ |
5816 |
sec->flags |= SEC_EXCLUDE; |
sec->flags |= SEC_EXCLUDE; |
5817 |
return true; |
return TRUE; |
5818 |
} |
} |
5819 |
|
|
5820 |
/* Record this stub in an array of local symbol stubs for |
/* Record this stub in an array of local symbol stubs for |
5830 |
else |
else |
5831 |
symcount = symtab_hdr->sh_info; |
symcount = symtab_hdr->sh_info; |
5832 |
amt = symcount * sizeof (asection *); |
amt = symcount * sizeof (asection *); |
5833 |
n = (asection **) bfd_zalloc (abfd, amt); |
n = bfd_zalloc (abfd, amt); |
5834 |
if (n == NULL) |
if (n == NULL) |
5835 |
return false; |
return FALSE; |
5836 |
elf_tdata (abfd)->local_stubs = n; |
elf_tdata (abfd)->local_stubs = n; |
5837 |
} |
} |
5838 |
|
|
5853 |
/* H is the symbol this stub is for. */ |
/* H is the symbol this stub is for. */ |
5854 |
|
|
5855 |
h->fn_stub = sec; |
h->fn_stub = sec; |
5856 |
mips_elf_hash_table (info)->mips16_stubs_seen = true; |
mips_elf_hash_table (info)->mips16_stubs_seen = TRUE; |
5857 |
} |
} |
5858 |
} |
} |
5859 |
else if (strncmp (name, CALL_STUB, sizeof CALL_STUB - 1) == 0 |
else if (strncmp (name, CALL_STUB, sizeof CALL_STUB - 1) == 0 |
5878 |
the linker maps input sections to output sections, we can |
the linker maps input sections to output sections, we can |
5879 |
easily discard it by setting the SEC_EXCLUDE flag. */ |
easily discard it by setting the SEC_EXCLUDE flag. */ |
5880 |
sec->flags |= SEC_EXCLUDE; |
sec->flags |= SEC_EXCLUDE; |
5881 |
return true; |
return TRUE; |
5882 |
} |
} |
5883 |
|
|
5884 |
h = ((struct mips_elf_link_hash_entry *) |
h = ((struct mips_elf_link_hash_entry *) |
5902 |
if (*loc != NULL || h->root.other == STO_MIPS16) |
if (*loc != NULL || h->root.other == STO_MIPS16) |
5903 |
{ |
{ |
5904 |
sec->flags |= SEC_EXCLUDE; |
sec->flags |= SEC_EXCLUDE; |
5905 |
return true; |
return TRUE; |
5906 |
} |
} |
5907 |
|
|
5908 |
*loc = sec; |
*loc = sec; |
5909 |
mips_elf_hash_table (info)->mips16_stubs_seen = true; |
mips_elf_hash_table (info)->mips16_stubs_seen = TRUE; |
5910 |
} |
} |
5911 |
|
|
5912 |
if (dynobj == NULL) |
if (dynobj == NULL) |
5916 |
} |
} |
5917 |
else |
else |
5918 |
{ |
{ |
5919 |
sgot = mips_elf_got_section (dynobj); |
sgot = mips_elf_got_section (dynobj, FALSE); |
5920 |
if (sgot == NULL) |
if (sgot == NULL) |
5921 |
g = NULL; |
g = NULL; |
5922 |
else |
else |
5923 |
{ |
{ |
5924 |
BFD_ASSERT (elf_section_data (sgot) != NULL); |
BFD_ASSERT (mips_elf_section_data (sgot) != NULL); |
5925 |
g = (struct mips_got_info *) elf_section_data (sgot)->tdata; |
g = mips_elf_section_data (sgot)->u.got_info; |
5926 |
BFD_ASSERT (g != NULL); |
BFD_ASSERT (g != NULL); |
5927 |
} |
} |
5928 |
} |
} |
5944 |
else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr)) |
else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr)) |
5945 |
{ |
{ |
5946 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
5947 |
(_("%s: Malformed reloc detected for section %s"), |
(_("%B: Malformed reloc detected for section %s"), |
5948 |
bfd_archive_filename (abfd), name); |
abfd, name); |
5949 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
5950 |
return false; |
return FALSE; |
5951 |
} |
} |
5952 |
else |
else |
5953 |
{ |
{ |
5975 |
case R_MIPS_GOT_PAGE: |
case R_MIPS_GOT_PAGE: |
5976 |
case R_MIPS_GOT_OFST: |
case R_MIPS_GOT_OFST: |
5977 |
case R_MIPS_GOT_DISP: |
case R_MIPS_GOT_DISP: |
5978 |
|
case R_MIPS_TLS_GD: |
5979 |
|
case R_MIPS_TLS_LDM: |
5980 |
if (dynobj == NULL) |
if (dynobj == NULL) |
5981 |
elf_hash_table (info)->dynobj = dynobj = abfd; |
elf_hash_table (info)->dynobj = dynobj = abfd; |
5982 |
if (! mips_elf_create_got_section (dynobj, info)) |
if (! mips_elf_create_got_section (dynobj, info, FALSE)) |
5983 |
return false; |
return FALSE; |
5984 |
g = mips_elf_got_info (dynobj, &sgot); |
g = mips_elf_got_info (dynobj, &sgot); |
5985 |
break; |
break; |
5986 |
|
|
6008 |
the segment. Similar comments apply to R_MIPS_GOT16 and |
the segment. Similar comments apply to R_MIPS_GOT16 and |
6009 |
R_MIPS_CALL16. We don't count R_MIPS_GOT_HI16, or |
R_MIPS_CALL16. We don't count R_MIPS_GOT_HI16, or |
6010 |
R_MIPS_CALL_HI16 because these are always followed by an |
R_MIPS_CALL_HI16 because these are always followed by an |
6011 |
R_MIPS_GOT_LO16 or R_MIPS_CALL_LO16. |
R_MIPS_GOT_LO16 or R_MIPS_CALL_LO16. */ |
6012 |
|
if (! mips_elf_record_local_got_symbol (abfd, r_symndx, |
6013 |
This estimation is very conservative since we can merge |
rel->r_addend, g, 0)) |
6014 |
duplicate entries in the GOT. In order to be less |
return FALSE; |
|
conservative, we could actually build the GOT here, |
|
|
rather than in relocate_section. */ |
|
|
g->local_gotno++; |
|
|
sgot->_raw_size += MIPS_ELF_GOT_SIZE (dynobj); |
|
6015 |
} |
} |
6016 |
|
|
6017 |
switch (r_type) |
switch (r_type) |
6020 |
if (h == NULL) |
if (h == NULL) |
6021 |
{ |
{ |
6022 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
6023 |
(_("%s: CALL16 reloc at 0x%lx not against global symbol"), |
(_("%B: CALL16 reloc at 0x%lx not against global symbol"), |
6024 |
bfd_archive_filename (abfd), (unsigned long) rel->r_offset); |
abfd, (unsigned long) rel->r_offset); |
6025 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
6026 |
return false; |
return FALSE; |
6027 |
} |
} |
6028 |
/* Fall through. */ |
/* Fall through. */ |
6029 |
|
|
6032 |
if (h != NULL) |
if (h != NULL) |
6033 |
{ |
{ |
6034 |
/* This symbol requires a global offset table entry. */ |
/* This symbol requires a global offset table entry. */ |
6035 |
if (! mips_elf_record_global_got_symbol (h, info, g)) |
if (! mips_elf_record_global_got_symbol (h, abfd, info, g, 0)) |
6036 |
return false; |
return FALSE; |
6037 |
|
|
6038 |
/* We need a stub, not a plt entry for the undefined |
/* We need a stub, not a plt entry for the undefined |
6039 |
function. But we record it as if it needs plt. See |
function. But we record it as if it needs plt. See |
6040 |
elf_adjust_dynamic_symbol in elflink.h. */ |
_bfd_elf_adjust_dynamic_symbol. */ |
6041 |
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; |
h->needs_plt = 1; |
6042 |
h->type = STT_FUNC; |
h->type = STT_FUNC; |
6043 |
} |
} |
6044 |
break; |
break; |
6045 |
|
|
6046 |
|
case R_MIPS_GOT_PAGE: |
6047 |
|
/* If this is a global, overridable symbol, GOT_PAGE will |
6048 |
|
decay to GOT_DISP, so we'll need a GOT entry for it. */ |
6049 |
|
if (h == NULL) |
6050 |
|
break; |
6051 |
|
else |
6052 |
|
{ |
6053 |
|
struct mips_elf_link_hash_entry *hmips = |
6054 |
|
(struct mips_elf_link_hash_entry *) h; |
6055 |
|
|
6056 |
|
while (hmips->root.root.type == bfd_link_hash_indirect |
6057 |
|
|| hmips->root.root.type == bfd_link_hash_warning) |
6058 |
|
hmips = (struct mips_elf_link_hash_entry *) |
6059 |
|
hmips->root.root.u.i.link; |
6060 |
|
|
6061 |
|
if (hmips->root.def_regular |
6062 |
|
&& ! (info->shared && ! info->symbolic |
6063 |
|
&& ! hmips->root.forced_local)) |
6064 |
|
break; |
6065 |
|
} |
6066 |
|
/* Fall through. */ |
6067 |
|
|
6068 |
case R_MIPS_GOT16: |
case R_MIPS_GOT16: |
6069 |
case R_MIPS_GOT_HI16: |
case R_MIPS_GOT_HI16: |
6070 |
case R_MIPS_GOT_LO16: |
case R_MIPS_GOT_LO16: |
6071 |
case R_MIPS_GOT_DISP: |
case R_MIPS_GOT_DISP: |
6072 |
/* This symbol requires a global offset table entry. */ |
if (h && ! mips_elf_record_global_got_symbol (h, abfd, info, g, 0)) |
6073 |
if (h && ! mips_elf_record_global_got_symbol (h, info, g)) |
return FALSE; |
6074 |
return false; |
break; |
6075 |
|
|
6076 |
|
case R_MIPS_TLS_GOTTPREL: |
6077 |
|
if (info->shared) |
6078 |
|
info->flags |= DF_STATIC_TLS; |
6079 |
|
/* Fall through */ |
6080 |
|
|
6081 |
|
case R_MIPS_TLS_LDM: |
6082 |
|
if (r_type == R_MIPS_TLS_LDM) |
6083 |
|
{ |
6084 |
|
r_symndx = 0; |
6085 |
|
h = NULL; |
6086 |
|
} |
6087 |
|
/* Fall through */ |
6088 |
|
|
6089 |
|
case R_MIPS_TLS_GD: |
6090 |
|
/* This symbol requires a global offset table entry, or two |
6091 |
|
for TLS GD relocations. */ |
6092 |
|
{ |
6093 |
|
unsigned char flag = (r_type == R_MIPS_TLS_GD |
6094 |
|
? GOT_TLS_GD |
6095 |
|
: r_type == R_MIPS_TLS_LDM |
6096 |
|
? GOT_TLS_LDM |
6097 |
|
: GOT_TLS_IE); |
6098 |
|
if (h != NULL) |
6099 |
|
{ |
6100 |
|
struct mips_elf_link_hash_entry *hmips = |
6101 |
|
(struct mips_elf_link_hash_entry *) h; |
6102 |
|
hmips->tls_type |= flag; |
6103 |
|
|
6104 |
|
if (h && ! mips_elf_record_global_got_symbol (h, abfd, info, g, flag)) |
6105 |
|
return FALSE; |
6106 |
|
} |
6107 |
|
else |
6108 |
|
{ |
6109 |
|
BFD_ASSERT (flag == GOT_TLS_LDM || r_symndx != 0); |
6110 |
|
|
6111 |
|
if (! mips_elf_record_local_got_symbol (abfd, r_symndx, |
6112 |
|
rel->r_addend, g, flag)) |
6113 |
|
return FALSE; |
6114 |
|
} |
6115 |
|
} |
6116 |
break; |
break; |
6117 |
|
|
6118 |
case R_MIPS_32: |
case R_MIPS_32: |
6123 |
{ |
{ |
6124 |
if (sreloc == NULL) |
if (sreloc == NULL) |
6125 |
{ |
{ |
6126 |
const char *dname = ".rel.dyn"; |
sreloc = mips_elf_rel_dyn_section (dynobj, TRUE); |
|
|
|
|
sreloc = bfd_get_section_by_name (dynobj, dname); |
|
6127 |
if (sreloc == NULL) |
if (sreloc == NULL) |
6128 |
{ |
return FALSE; |
|
sreloc = bfd_make_section (dynobj, dname); |
|
|
if (sreloc == NULL |
|
|
|| ! bfd_set_section_flags (dynobj, sreloc, |
|
|
(SEC_ALLOC |
|
|
| SEC_LOAD |
|
|
| SEC_HAS_CONTENTS |
|
|
| SEC_IN_MEMORY |
|
|
| SEC_LINKER_CREATED |
|
|
| SEC_READONLY)) |
|
|
|| ! bfd_set_section_alignment (dynobj, sreloc, |
|
|
4)) |
|
|
return false; |
|
|
} |
|
6129 |
} |
} |
6130 |
#define MIPS_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY) |
#define MIPS_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY) |
6131 |
if (info->shared) |
if (info->shared) |
6153 |
== MIPS_READONLY_SECTION) |
== MIPS_READONLY_SECTION) |
6154 |
/* We need it to tell the dynamic linker if there |
/* We need it to tell the dynamic linker if there |
6155 |
are relocations against the text segment. */ |
are relocations against the text segment. */ |
6156 |
hmips->readonly_reloc = true; |
hmips->readonly_reloc = TRUE; |
6157 |
} |
} |
6158 |
|
|
6159 |
/* Even though we don't directly need a GOT entry for |
/* Even though we don't directly need a GOT entry for |
6160 |
this symbol, a symbol must have a dynamic symbol |
this symbol, a symbol must have a dynamic symbol |
6161 |
table index greater that DT_MIPS_GOTSYM if there are |
table index greater that DT_MIPS_GOTSYM if there are |
6162 |
dynamic relocations against it. */ |
dynamic relocations against it. */ |
6163 |
if (h != NULL |
if (h != NULL) |
6164 |
&& ! mips_elf_record_global_got_symbol (h, info, g)) |
{ |
6165 |
return false; |
if (dynobj == NULL) |
6166 |
|
elf_hash_table (info)->dynobj = dynobj = abfd; |
6167 |
|
if (! mips_elf_create_got_section (dynobj, info, TRUE)) |
6168 |
|
return FALSE; |
6169 |
|
g = mips_elf_got_info (dynobj, &sgot); |
6170 |
|
if (! mips_elf_record_global_got_symbol (h, abfd, info, g, 0)) |
6171 |
|
return FALSE; |
6172 |
|
} |
6173 |
} |
} |
6174 |
|
|
6175 |
if (SGI_COMPAT (abfd)) |
if (SGI_COMPAT (abfd)) |
6189 |
/* This relocation describes the C++ object vtable hierarchy. |
/* This relocation describes the C++ object vtable hierarchy. |
6190 |
Reconstruct it for later use during GC. */ |
Reconstruct it for later use during GC. */ |
6191 |
case R_MIPS_GNU_VTINHERIT: |
case R_MIPS_GNU_VTINHERIT: |
6192 |
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) |
if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) |
6193 |
return false; |
return FALSE; |
6194 |
break; |
break; |
6195 |
|
|
6196 |
/* This relocation describes which C++ vtable entries are actually |
/* This relocation describes which C++ vtable entries are actually |
6197 |
used. Record for later use during GC. */ |
used. Record for later use during GC. */ |
6198 |
case R_MIPS_GNU_VTENTRY: |
case R_MIPS_GNU_VTENTRY: |
6199 |
if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset)) |
if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset)) |
6200 |
return false; |
return FALSE; |
6201 |
break; |
break; |
6202 |
|
|
6203 |
default: |
default: |
6214 |
struct mips_elf_link_hash_entry *mh; |
struct mips_elf_link_hash_entry *mh; |
6215 |
|
|
6216 |
mh = (struct mips_elf_link_hash_entry *) h; |
mh = (struct mips_elf_link_hash_entry *) h; |
6217 |
mh->no_fn_stub = true; |
mh->no_fn_stub = TRUE; |
6218 |
} |
} |
6219 |
break; |
break; |
6220 |
case R_MIPS_CALL16: |
case R_MIPS_CALL16: |
6221 |
case R_MIPS_CALL_HI16: |
case R_MIPS_CALL_HI16: |
6222 |
case R_MIPS_CALL_LO16: |
case R_MIPS_CALL_LO16: |
6223 |
|
case R_MIPS_JALR: |
6224 |
break; |
break; |
6225 |
} |
} |
6226 |
|
|
6239 |
struct mips_elf_link_hash_entry *mh; |
struct mips_elf_link_hash_entry *mh; |
6240 |
|
|
6241 |
mh = (struct mips_elf_link_hash_entry *) h; |
mh = (struct mips_elf_link_hash_entry *) h; |
6242 |
mh->need_fn_stub = true; |
mh->need_fn_stub = TRUE; |
6243 |
|
} |
6244 |
|
} |
6245 |
|
|
6246 |
|
return TRUE; |
6247 |
|
} |
6248 |
|
|
6249 |
|
bfd_boolean |
6250 |
|
_bfd_mips_relax_section (bfd *abfd, asection *sec, |
6251 |
|
struct bfd_link_info *link_info, |
6252 |
|
bfd_boolean *again) |
6253 |
|
{ |
6254 |
|
Elf_Internal_Rela *internal_relocs; |
6255 |
|
Elf_Internal_Rela *irel, *irelend; |
6256 |
|
Elf_Internal_Shdr *symtab_hdr; |
6257 |
|
bfd_byte *contents = NULL; |
6258 |
|
size_t extsymoff; |
6259 |
|
bfd_boolean changed_contents = FALSE; |
6260 |
|
bfd_vma sec_start = sec->output_section->vma + sec->output_offset; |
6261 |
|
Elf_Internal_Sym *isymbuf = NULL; |
6262 |
|
|
6263 |
|
/* We are not currently changing any sizes, so only one pass. */ |
6264 |
|
*again = FALSE; |
6265 |
|
|
6266 |
|
if (link_info->relocatable) |
6267 |
|
return TRUE; |
6268 |
|
|
6269 |
|
internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, |
6270 |
|
link_info->keep_memory); |
6271 |
|
if (internal_relocs == NULL) |
6272 |
|
return TRUE; |
6273 |
|
|
6274 |
|
irelend = internal_relocs + sec->reloc_count |
6275 |
|
* get_elf_backend_data (abfd)->s->int_rels_per_ext_rel; |
6276 |
|
symtab_hdr = &elf_tdata (abfd)->symtab_hdr; |
6277 |
|
extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info; |
6278 |
|
|
6279 |
|
for (irel = internal_relocs; irel < irelend; irel++) |
6280 |
|
{ |
6281 |
|
bfd_vma symval; |
6282 |
|
bfd_signed_vma sym_offset; |
6283 |
|
unsigned int r_type; |
6284 |
|
unsigned long r_symndx; |
6285 |
|
asection *sym_sec; |
6286 |
|
unsigned long instruction; |
6287 |
|
|
6288 |
|
/* Turn jalr into bgezal, and jr into beq, if they're marked |
6289 |
|
with a JALR relocation, that indicate where they jump to. |
6290 |
|
This saves some pipeline bubbles. */ |
6291 |
|
r_type = ELF_R_TYPE (abfd, irel->r_info); |
6292 |
|
if (r_type != R_MIPS_JALR) |
6293 |
|
continue; |
6294 |
|
|
6295 |
|
r_symndx = ELF_R_SYM (abfd, irel->r_info); |
6296 |
|
/* Compute the address of the jump target. */ |
6297 |
|
if (r_symndx >= extsymoff) |
6298 |
|
{ |
6299 |
|
struct mips_elf_link_hash_entry *h |
6300 |
|
= ((struct mips_elf_link_hash_entry *) |
6301 |
|
elf_sym_hashes (abfd) [r_symndx - extsymoff]); |
6302 |
|
|
6303 |
|
while (h->root.root.type == bfd_link_hash_indirect |
6304 |
|
|| h->root.root.type == bfd_link_hash_warning) |
6305 |
|
h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link; |
6306 |
|
|
6307 |
|
/* If a symbol is undefined, or if it may be overridden, |
6308 |
|
skip it. */ |
6309 |
|
if (! ((h->root.root.type == bfd_link_hash_defined |
6310 |
|
|| h->root.root.type == bfd_link_hash_defweak) |
6311 |
|
&& h->root.root.u.def.section) |
6312 |
|
|| (link_info->shared && ! link_info->symbolic |
6313 |
|
&& !h->root.forced_local)) |
6314 |
|
continue; |
6315 |
|
|
6316 |
|
sym_sec = h->root.root.u.def.section; |
6317 |
|
if (sym_sec->output_section) |
6318 |
|
symval = (h->root.root.u.def.value |
6319 |
|
+ sym_sec->output_section->vma |
6320 |
|
+ sym_sec->output_offset); |
6321 |
|
else |
6322 |
|
symval = h->root.root.u.def.value; |
6323 |
|
} |
6324 |
|
else |
6325 |
|
{ |
6326 |
|
Elf_Internal_Sym *isym; |
6327 |
|
|
6328 |
|
/* Read this BFD's symbols if we haven't done so already. */ |
6329 |
|
if (isymbuf == NULL && symtab_hdr->sh_info != 0) |
6330 |
|
{ |
6331 |
|
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; |
6332 |
|
if (isymbuf == NULL) |
6333 |
|
isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, |
6334 |
|
symtab_hdr->sh_info, 0, |
6335 |
|
NULL, NULL, NULL); |
6336 |
|
if (isymbuf == NULL) |
6337 |
|
goto relax_return; |
6338 |
|
} |
6339 |
|
|
6340 |
|
isym = isymbuf + r_symndx; |
6341 |
|
if (isym->st_shndx == SHN_UNDEF) |
6342 |
|
continue; |
6343 |
|
else if (isym->st_shndx == SHN_ABS) |
6344 |
|
sym_sec = bfd_abs_section_ptr; |
6345 |
|
else if (isym->st_shndx == SHN_COMMON) |
6346 |
|
sym_sec = bfd_com_section_ptr; |
6347 |
|
else |
6348 |
|
sym_sec |
6349 |
|
= bfd_section_from_elf_index (abfd, isym->st_shndx); |
6350 |
|
symval = isym->st_value |
6351 |
|
+ sym_sec->output_section->vma |
6352 |
|
+ sym_sec->output_offset; |
6353 |
|
} |
6354 |
|
|
6355 |
|
/* Compute branch offset, from delay slot of the jump to the |
6356 |
|
branch target. */ |
6357 |
|
sym_offset = (symval + irel->r_addend) |
6358 |
|
- (sec_start + irel->r_offset + 4); |
6359 |
|
|
6360 |
|
/* Branch offset must be properly aligned. */ |
6361 |
|
if ((sym_offset & 3) != 0) |
6362 |
|
continue; |
6363 |
|
|
6364 |
|
sym_offset >>= 2; |
6365 |
|
|
6366 |
|
/* Check that it's in range. */ |
6367 |
|
if (sym_offset < -0x8000 || sym_offset >= 0x8000) |
6368 |
|
continue; |
6369 |
|
|
6370 |
|
/* Get the section contents if we haven't done so already. */ |
6371 |
|
if (contents == NULL) |
6372 |
|
{ |
6373 |
|
/* Get cached copy if it exists. */ |
6374 |
|
if (elf_section_data (sec)->this_hdr.contents != NULL) |
6375 |
|
contents = elf_section_data (sec)->this_hdr.contents; |
6376 |
|
else |
6377 |
|
{ |
6378 |
|
if (!bfd_malloc_and_get_section (abfd, sec, &contents)) |
6379 |
|
goto relax_return; |
6380 |
|
} |
6381 |
} |
} |
6382 |
|
|
6383 |
|
instruction = bfd_get_32 (abfd, contents + irel->r_offset); |
6384 |
|
|
6385 |
|
/* If it was jalr <reg>, turn it into bgezal $zero, <target>. */ |
6386 |
|
if ((instruction & 0xfc1fffff) == 0x0000f809) |
6387 |
|
instruction = 0x04110000; |
6388 |
|
/* If it was jr <reg>, turn it into b <target>. */ |
6389 |
|
else if ((instruction & 0xfc1fffff) == 0x00000008) |
6390 |
|
instruction = 0x10000000; |
6391 |
|
else |
6392 |
|
continue; |
6393 |
|
|
6394 |
|
instruction |= (sym_offset & 0xffff); |
6395 |
|
bfd_put_32 (abfd, instruction, contents + irel->r_offset); |
6396 |
|
changed_contents = TRUE; |
6397 |
} |
} |
6398 |
|
|
6399 |
return true; |
if (contents != NULL |
6400 |
|
&& elf_section_data (sec)->this_hdr.contents != contents) |
6401 |
|
{ |
6402 |
|
if (!changed_contents && !link_info->keep_memory) |
6403 |
|
free (contents); |
6404 |
|
else |
6405 |
|
{ |
6406 |
|
/* Cache the section contents for elf_link_input_bfd. */ |
6407 |
|
elf_section_data (sec)->this_hdr.contents = contents; |
6408 |
|
} |
6409 |
|
} |
6410 |
|
return TRUE; |
6411 |
|
|
6412 |
|
relax_return: |
6413 |
|
if (contents != NULL |
6414 |
|
&& elf_section_data (sec)->this_hdr.contents != contents) |
6415 |
|
free (contents); |
6416 |
|
return FALSE; |
6417 |
} |
} |
6418 |
|
|
6419 |
/* Adjust a symbol defined by a dynamic object and referenced by a |
/* Adjust a symbol defined by a dynamic object and referenced by a |
6422 |
change the definition to something the rest of the link can |
change the definition to something the rest of the link can |
6423 |
understand. */ |
understand. */ |
6424 |
|
|
6425 |
boolean |
bfd_boolean |
6426 |
_bfd_mips_elf_adjust_dynamic_symbol (info, h) |
_bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info, |
6427 |
struct bfd_link_info *info; |
struct elf_link_hash_entry *h) |
|
struct elf_link_hash_entry *h; |
|
6428 |
{ |
{ |
6429 |
bfd *dynobj; |
bfd *dynobj; |
6430 |
struct mips_elf_link_hash_entry *hmips; |
struct mips_elf_link_hash_entry *hmips; |
6434 |
|
|
6435 |
/* Make sure we know what is going on here. */ |
/* Make sure we know what is going on here. */ |
6436 |
BFD_ASSERT (dynobj != NULL |
BFD_ASSERT (dynobj != NULL |
6437 |
&& ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) |
&& (h->needs_plt |
6438 |
|| h->weakdef != NULL |
|| h->u.weakdef != NULL |
6439 |
|| ((h->elf_link_hash_flags |
|| (h->def_dynamic |
6440 |
& ELF_LINK_HASH_DEF_DYNAMIC) != 0 |
&& h->ref_regular |
6441 |
&& (h->elf_link_hash_flags |
&& !h->def_regular))); |
|
& ELF_LINK_HASH_REF_REGULAR) != 0 |
|
|
&& (h->elf_link_hash_flags |
|
|
& ELF_LINK_HASH_DEF_REGULAR) == 0))); |
|
6442 |
|
|
6443 |
/* If this symbol is defined in a dynamic object, we need to copy |
/* If this symbol is defined in a dynamic object, we need to copy |
6444 |
any R_MIPS_32 or R_MIPS_REL32 relocs against it into the output |
any R_MIPS_32 or R_MIPS_REL32 relocs against it into the output |
6445 |
file. */ |
file. */ |
6446 |
hmips = (struct mips_elf_link_hash_entry *) h; |
hmips = (struct mips_elf_link_hash_entry *) h; |
6447 |
if (! info->relocateable |
if (! info->relocatable |
6448 |
&& hmips->possibly_dynamic_relocs != 0 |
&& hmips->possibly_dynamic_relocs != 0 |
6449 |
&& (h->root.type == bfd_link_hash_defweak |
&& (h->root.type == bfd_link_hash_defweak |
6450 |
|| (h->elf_link_hash_flags |
|| !h->def_regular)) |
|
& ELF_LINK_HASH_DEF_REGULAR) == 0)) |
|
6451 |
{ |
{ |
6452 |
mips_elf_allocate_dynamic_relocations (dynobj, |
mips_elf_allocate_dynamic_relocations (dynobj, |
6453 |
hmips->possibly_dynamic_relocs); |
hmips->possibly_dynamic_relocs); |
6459 |
|
|
6460 |
/* For a function, create a stub, if allowed. */ |
/* For a function, create a stub, if allowed. */ |
6461 |
if (! hmips->no_fn_stub |
if (! hmips->no_fn_stub |
6462 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) |
&& h->needs_plt) |
6463 |
{ |
{ |
6464 |
if (! elf_hash_table (info)->dynamic_sections_created) |
if (! elf_hash_table (info)->dynamic_sections_created) |
6465 |
return true; |
return TRUE; |
6466 |
|
|
6467 |
/* If this symbol is not defined in a regular file, then set |
/* If this symbol is not defined in a regular file, then set |
6468 |
the symbol to the stub location. This is required to make |
the symbol to the stub location. This is required to make |
6469 |
function pointers compare as equal between the normal |
function pointers compare as equal between the normal |
6470 |
executable and the shared library. */ |
executable and the shared library. */ |
6471 |
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) |
if (!h->def_regular) |
6472 |
{ |
{ |
6473 |
/* We need .stub section. */ |
/* We need .stub section. */ |
6474 |
s = bfd_get_section_by_name (dynobj, |
s = bfd_get_section_by_name (dynobj, |
6476 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
6477 |
|
|
6478 |
h->root.u.def.section = s; |
h->root.u.def.section = s; |
6479 |
h->root.u.def.value = s->_raw_size; |
h->root.u.def.value = s->size; |
6480 |
|
|
6481 |
/* XXX Write this stub address somewhere. */ |
/* XXX Write this stub address somewhere. */ |
6482 |
h->plt.offset = s->_raw_size; |
h->plt.offset = s->size; |
6483 |
|
|
6484 |
/* Make room for this stub code. */ |
/* Make room for this stub code. */ |
6485 |
s->_raw_size += MIPS_FUNCTION_STUB_SIZE; |
s->size += MIPS_FUNCTION_STUB_SIZE; |
6486 |
|
|
6487 |
/* The last half word of the stub will be filled with the index |
/* The last half word of the stub will be filled with the index |
6488 |
of this symbol in .dynsym section. */ |
of this symbol in .dynsym section. */ |
6489 |
return true; |
return TRUE; |
6490 |
} |
} |
6491 |
} |
} |
6492 |
else if ((h->type == STT_FUNC) |
else if ((h->type == STT_FUNC) |
6493 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) == 0) |
&& !h->needs_plt) |
6494 |
{ |
{ |
6495 |
/* This will set the entry for this symbol in the GOT to 0, and |
/* This will set the entry for this symbol in the GOT to 0, and |
6496 |
the dynamic linker will take care of this. */ |
the dynamic linker will take care of this. */ |
6497 |
h->root.u.def.value = 0; |
h->root.u.def.value = 0; |
6498 |
return true; |
return TRUE; |
6499 |
} |
} |
6500 |
|
|
6501 |
/* If this is a weak symbol, and there is a real definition, the |
/* If this is a weak symbol, and there is a real definition, the |
6502 |
processor independent code will have arranged for us to see the |
processor independent code will have arranged for us to see the |
6503 |
real definition first, and we can just use the same value. */ |
real definition first, and we can just use the same value. */ |
6504 |
if (h->weakdef != NULL) |
if (h->u.weakdef != NULL) |
6505 |
{ |
{ |
6506 |
BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined |
BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined |
6507 |
|| h->weakdef->root.type == bfd_link_hash_defweak); |
|| h->u.weakdef->root.type == bfd_link_hash_defweak); |
6508 |
h->root.u.def.section = h->weakdef->root.u.def.section; |
h->root.u.def.section = h->u.weakdef->root.u.def.section; |
6509 |
h->root.u.def.value = h->weakdef->root.u.def.value; |
h->root.u.def.value = h->u.weakdef->root.u.def.value; |
6510 |
return true; |
return TRUE; |
6511 |
} |
} |
6512 |
|
|
6513 |
/* This is a reference to a symbol defined by a dynamic object which |
/* This is a reference to a symbol defined by a dynamic object which |
6514 |
is not a function. */ |
is not a function. */ |
6515 |
|
|
6516 |
return true; |
return TRUE; |
6517 |
} |
} |
6518 |
|
|
6519 |
/* This function is called after all the input files have been read, |
/* This function is called after all the input files have been read, |
6520 |
and the input sections have been assigned to output sections. We |
and the input sections have been assigned to output sections. We |
6521 |
check for any mips16 stub sections that we can discard. */ |
check for any mips16 stub sections that we can discard. */ |
6522 |
|
|
6523 |
boolean |
bfd_boolean |
6524 |
_bfd_mips_elf_always_size_sections (output_bfd, info) |
_bfd_mips_elf_always_size_sections (bfd *output_bfd, |
6525 |
bfd *output_bfd; |
struct bfd_link_info *info) |
|
struct bfd_link_info *info; |
|
6526 |
{ |
{ |
6527 |
asection *ri; |
asection *ri; |
6528 |
|
|
6529 |
|
bfd *dynobj; |
6530 |
|
asection *s; |
6531 |
|
struct mips_got_info *g; |
6532 |
|
int i; |
6533 |
|
bfd_size_type loadable_size = 0; |
6534 |
|
bfd_size_type local_gotno; |
6535 |
|
bfd *sub; |
6536 |
|
struct mips_elf_count_tls_arg count_tls_arg; |
6537 |
|
|
6538 |
/* The .reginfo section has a fixed size. */ |
/* The .reginfo section has a fixed size. */ |
6539 |
ri = bfd_get_section_by_name (output_bfd, ".reginfo"); |
ri = bfd_get_section_by_name (output_bfd, ".reginfo"); |
6540 |
if (ri != NULL) |
if (ri != NULL) |
6541 |
bfd_set_section_size (output_bfd, ri, |
bfd_set_section_size (output_bfd, ri, sizeof (Elf32_External_RegInfo)); |
6542 |
(bfd_size_type) sizeof (Elf32_External_RegInfo)); |
|
6543 |
|
if (! (info->relocatable |
6544 |
|
|| ! mips_elf_hash_table (info)->mips16_stubs_seen)) |
6545 |
|
mips_elf_link_hash_traverse (mips_elf_hash_table (info), |
6546 |
|
mips_elf_check_mips16_stubs, NULL); |
6547 |
|
|
6548 |
|
dynobj = elf_hash_table (info)->dynobj; |
6549 |
|
if (dynobj == NULL) |
6550 |
|
/* Relocatable links don't have it. */ |
6551 |
|
return TRUE; |
6552 |
|
|
6553 |
|
g = mips_elf_got_info (dynobj, &s); |
6554 |
|
if (s == NULL) |
6555 |
|
return TRUE; |
6556 |
|
|
6557 |
if (info->relocateable |
/* Calculate the total loadable size of the output. That |
6558 |
|| ! mips_elf_hash_table (info)->mips16_stubs_seen) |
will give us the maximum number of GOT_PAGE entries |
6559 |
return true; |
required. */ |
6560 |
|
for (sub = info->input_bfds; sub; sub = sub->link_next) |
6561 |
mips_elf_link_hash_traverse (mips_elf_hash_table (info), |
{ |
6562 |
mips_elf_check_mips16_stubs, |
asection *subsection; |
6563 |
(PTR) NULL); |
|
6564 |
|
for (subsection = sub->sections; |
6565 |
|
subsection; |
6566 |
|
subsection = subsection->next) |
6567 |
|
{ |
6568 |
|
if ((subsection->flags & SEC_ALLOC) == 0) |
6569 |
|
continue; |
6570 |
|
loadable_size += ((subsection->size + 0xf) |
6571 |
|
&~ (bfd_size_type) 0xf); |
6572 |
|
} |
6573 |
|
} |
6574 |
|
|
6575 |
|
/* There has to be a global GOT entry for every symbol with |
6576 |
|
a dynamic symbol table index of DT_MIPS_GOTSYM or |
6577 |
|
higher. Therefore, it make sense to put those symbols |
6578 |
|
that need GOT entries at the end of the symbol table. We |
6579 |
|
do that here. */ |
6580 |
|
if (! mips_elf_sort_hash_table (info, 1)) |
6581 |
|
return FALSE; |
6582 |
|
|
6583 |
|
if (g->global_gotsym != NULL) |
6584 |
|
i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx; |
6585 |
|
else |
6586 |
|
/* If there are no global symbols, or none requiring |
6587 |
|
relocations, then GLOBAL_GOTSYM will be NULL. */ |
6588 |
|
i = 0; |
6589 |
|
|
6590 |
|
/* In the worst case, we'll get one stub per dynamic symbol, plus |
6591 |
|
one to account for the dummy entry at the end required by IRIX |
6592 |
|
rld. */ |
6593 |
|
loadable_size += MIPS_FUNCTION_STUB_SIZE * (i + 1); |
6594 |
|
|
6595 |
|
/* Assume there are two loadable segments consisting of |
6596 |
|
contiguous sections. Is 5 enough? */ |
6597 |
|
local_gotno = (loadable_size >> 16) + 5; |
6598 |
|
|
6599 |
|
g->local_gotno += local_gotno; |
6600 |
|
s->size += g->local_gotno * MIPS_ELF_GOT_SIZE (output_bfd); |
6601 |
|
|
6602 |
|
g->global_gotno = i; |
6603 |
|
s->size += i * MIPS_ELF_GOT_SIZE (output_bfd); |
6604 |
|
|
6605 |
|
/* We need to calculate tls_gotno for global symbols at this point |
6606 |
|
instead of building it up earlier, to avoid doublecounting |
6607 |
|
entries for one global symbol from multiple input files. */ |
6608 |
|
count_tls_arg.info = info; |
6609 |
|
count_tls_arg.needed = 0; |
6610 |
|
elf_link_hash_traverse (elf_hash_table (info), |
6611 |
|
mips_elf_count_global_tls_entries, |
6612 |
|
&count_tls_arg); |
6613 |
|
g->tls_gotno += count_tls_arg.needed; |
6614 |
|
s->size += g->tls_gotno * MIPS_ELF_GOT_SIZE (output_bfd); |
6615 |
|
|
6616 |
return true; |
mips_elf_resolve_final_got_entries (g); |
6617 |
|
|
6618 |
|
if (s->size > MIPS_ELF_GOT_MAX_SIZE (output_bfd)) |
6619 |
|
{ |
6620 |
|
if (! mips_elf_multi_got (output_bfd, info, g, s, local_gotno)) |
6621 |
|
return FALSE; |
6622 |
|
} |
6623 |
|
else |
6624 |
|
{ |
6625 |
|
/* Set up TLS entries for the first GOT. */ |
6626 |
|
g->tls_assigned_gotno = g->global_gotno + g->local_gotno; |
6627 |
|
htab_traverse (g->got_entries, mips_elf_initialize_tls_index, g); |
6628 |
|
} |
6629 |
|
|
6630 |
|
return TRUE; |
6631 |
} |
} |
6632 |
|
|
6633 |
/* Set the sizes of the dynamic sections. */ |
/* Set the sizes of the dynamic sections. */ |
6634 |
|
|
6635 |
boolean |
bfd_boolean |
6636 |
_bfd_mips_elf_size_dynamic_sections (output_bfd, info) |
_bfd_mips_elf_size_dynamic_sections (bfd *output_bfd, |
6637 |
bfd *output_bfd; |
struct bfd_link_info *info) |
|
struct bfd_link_info *info; |
|
6638 |
{ |
{ |
6639 |
bfd *dynobj; |
bfd *dynobj; |
6640 |
asection *s; |
asection *s; |
6641 |
boolean reltext; |
bfd_boolean reltext; |
|
struct mips_got_info *g = NULL; |
|
6642 |
|
|
6643 |
dynobj = elf_hash_table (info)->dynobj; |
dynobj = elf_hash_table (info)->dynobj; |
6644 |
BFD_ASSERT (dynobj != NULL); |
BFD_ASSERT (dynobj != NULL); |
6646 |
if (elf_hash_table (info)->dynamic_sections_created) |
if (elf_hash_table (info)->dynamic_sections_created) |
6647 |
{ |
{ |
6648 |
/* Set the contents of the .interp section to the interpreter. */ |
/* Set the contents of the .interp section to the interpreter. */ |
6649 |
if (! info->shared) |
if (info->executable) |
6650 |
{ |
{ |
6651 |
s = bfd_get_section_by_name (dynobj, ".interp"); |
s = bfd_get_section_by_name (dynobj, ".interp"); |
6652 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
6653 |
s->_raw_size |
s->size |
6654 |
= strlen (ELF_DYNAMIC_INTERPRETER (output_bfd)) + 1; |
= strlen (ELF_DYNAMIC_INTERPRETER (output_bfd)) + 1; |
6655 |
s->contents |
s->contents |
6656 |
= (bfd_byte *) ELF_DYNAMIC_INTERPRETER (output_bfd); |
= (bfd_byte *) ELF_DYNAMIC_INTERPRETER (output_bfd); |
6660 |
/* The check_relocs and adjust_dynamic_symbol entry points have |
/* The check_relocs and adjust_dynamic_symbol entry points have |
6661 |
determined the sizes of the various dynamic sections. Allocate |
determined the sizes of the various dynamic sections. Allocate |
6662 |
memory for them. */ |
memory for them. */ |
6663 |
reltext = false; |
reltext = FALSE; |
6664 |
for (s = dynobj->sections; s != NULL; s = s->next) |
for (s = dynobj->sections; s != NULL; s = s->next) |
6665 |
{ |
{ |
6666 |
const char *name; |
const char *name; |
6667 |
boolean strip; |
bfd_boolean strip; |
6668 |
|
|
6669 |
/* It's OK to base decisions on the section name, because none |
/* It's OK to base decisions on the section name, because none |
6670 |
of the dynobj section names depend upon the input files. */ |
of the dynobj section names depend upon the input files. */ |
6673 |
if ((s->flags & SEC_LINKER_CREATED) == 0) |
if ((s->flags & SEC_LINKER_CREATED) == 0) |
6674 |
continue; |
continue; |
6675 |
|
|
6676 |
strip = false; |
strip = FALSE; |
6677 |
|
|
6678 |
if (strncmp (name, ".rel", 4) == 0) |
if (strncmp (name, ".rel", 4) == 0) |
6679 |
{ |
{ |
6680 |
if (s->_raw_size == 0) |
if (s->size == 0) |
6681 |
{ |
{ |
6682 |
/* We only strip the section if the output section name |
/* We only strip the section if the output section name |
6683 |
has the same name. Otherwise, there might be several |
has the same name. Otherwise, there might be several |
6688 |
&& strcmp (name, |
&& strcmp (name, |
6689 |
bfd_get_section_name (s->output_section->owner, |
bfd_get_section_name (s->output_section->owner, |
6690 |
s->output_section)) == 0) |
s->output_section)) == 0) |
6691 |
strip = true; |
strip = TRUE; |
6692 |
} |
} |
6693 |
else |
else |
6694 |
{ |
{ |
6708 |
&& (target->flags & SEC_READONLY) != 0 |
&& (target->flags & SEC_READONLY) != 0 |
6709 |
&& (target->flags & SEC_ALLOC) != 0) |
&& (target->flags & SEC_ALLOC) != 0) |
6710 |
|| strcmp (outname, ".rel.dyn") == 0) |
|| strcmp (outname, ".rel.dyn") == 0) |
6711 |
reltext = true; |
reltext = TRUE; |
6712 |
|
|
6713 |
/* We use the reloc_count field as a counter if we need |
/* We use the reloc_count field as a counter if we need |
6714 |
to copy relocs into the output file. */ |
to copy relocs into the output file. */ |
6715 |
if (strcmp (name, ".rel.dyn") != 0) |
if (strcmp (name, ".rel.dyn") != 0) |
6716 |
s->reloc_count = 0; |
s->reloc_count = 0; |
6717 |
|
|
6718 |
|
/* If combreloc is enabled, elf_link_sort_relocs() will |
6719 |
|
sort relocations, but in a different way than we do, |
6720 |
|
and before we're done creating relocations. Also, it |
6721 |
|
will move them around between input sections' |
6722 |
|
relocation's contents, so our sorting would be |
6723 |
|
broken, so don't let it run. */ |
6724 |
|
info->combreloc = 0; |
6725 |
} |
} |
6726 |
} |
} |
6727 |
else if (strncmp (name, ".got", 4) == 0) |
else if (strncmp (name, ".got", 4) == 0) |
6728 |
{ |
{ |
6729 |
int i; |
/* _bfd_mips_elf_always_size_sections() has already done |
6730 |
bfd_size_type loadable_size = 0; |
most of the work, but some symbols may have been mapped |
6731 |
bfd_size_type local_gotno; |
to versions that we must now resolve in the got_entries |
6732 |
bfd *sub; |
hash tables. */ |
6733 |
|
struct mips_got_info *gg = mips_elf_got_info (dynobj, NULL); |
6734 |
|
struct mips_got_info *g = gg; |
6735 |
|
struct mips_elf_set_global_got_offset_arg set_got_offset_arg; |
6736 |
|
unsigned int needed_relocs = 0; |
6737 |
|
|
6738 |
|
if (gg->next) |
6739 |
|
{ |
6740 |
|
set_got_offset_arg.value = MIPS_ELF_GOT_SIZE (output_bfd); |
6741 |
|
set_got_offset_arg.info = info; |
6742 |
|
|
6743 |
|
/* NOTE 2005-02-03: How can this call, or the next, ever |
6744 |
|
find any indirect entries to resolve? They were all |
6745 |
|
resolved in mips_elf_multi_got. */ |
6746 |
|
mips_elf_resolve_final_got_entries (gg); |
6747 |
|
for (g = gg->next; g && g->next != gg; g = g->next) |
6748 |
|
{ |
6749 |
|
unsigned int save_assign; |
6750 |
|
|
6751 |
BFD_ASSERT (elf_section_data (s) != NULL); |
mips_elf_resolve_final_got_entries (g); |
|
g = (struct mips_got_info *) elf_section_data (s)->tdata; |
|
|
BFD_ASSERT (g != NULL); |
|
6752 |
|
|
6753 |
/* Calculate the total loadable size of the output. That |
/* Assign offsets to global GOT entries. */ |
6754 |
will give us the maximum number of GOT_PAGE entries |
save_assign = g->assigned_gotno; |
6755 |
required. */ |
g->assigned_gotno = g->local_gotno; |
6756 |
for (sub = info->input_bfds; sub; sub = sub->link_next) |
set_got_offset_arg.g = g; |
6757 |
{ |
set_got_offset_arg.needed_relocs = 0; |
6758 |
asection *subsection; |
htab_traverse (g->got_entries, |
6759 |
|
mips_elf_set_global_got_offset, |
6760 |
for (subsection = sub->sections; |
&set_got_offset_arg); |
6761 |
subsection; |
needed_relocs += set_got_offset_arg.needed_relocs; |
6762 |
subsection = subsection->next) |
BFD_ASSERT (g->assigned_gotno - g->local_gotno |
6763 |
{ |
<= g->global_gotno); |
6764 |
if ((subsection->flags & SEC_ALLOC) == 0) |
|
6765 |
continue; |
g->assigned_gotno = save_assign; |
6766 |
loadable_size += ((subsection->_raw_size + 0xf) |
if (info->shared) |
6767 |
&~ (bfd_size_type) 0xf); |
{ |
6768 |
|
needed_relocs += g->local_gotno - g->assigned_gotno; |
6769 |
|
BFD_ASSERT (g->assigned_gotno == g->next->local_gotno |
6770 |
|
+ g->next->global_gotno |
6771 |
|
+ g->next->tls_gotno |
6772 |
|
+ MIPS_RESERVED_GOTNO); |
6773 |
|
} |
6774 |
} |
} |
6775 |
} |
} |
6776 |
loadable_size += MIPS_FUNCTION_STUB_SIZE; |
else |
6777 |
|
{ |
6778 |
|
struct mips_elf_count_tls_arg arg; |
6779 |
|
arg.info = info; |
6780 |
|
arg.needed = 0; |
6781 |
|
|
6782 |
/* Assume there are two loadable segments consisting of |
htab_traverse (gg->got_entries, mips_elf_count_local_tls_relocs, |
6783 |
contiguous sections. Is 5 enough? */ |
&arg); |
6784 |
local_gotno = (loadable_size >> 16) + 5; |
elf_link_hash_traverse (elf_hash_table (info), |
6785 |
if (NEWABI_P (output_bfd)) |
mips_elf_count_global_tls_relocs, |
6786 |
/* It's possible we will need GOT_PAGE entries as well as |
&arg); |
|
GOT16 entries. Often, these will be able to share GOT |
|
|
entries, but not always. */ |
|
|
local_gotno *= 2; |
|
|
|
|
|
g->local_gotno += local_gotno; |
|
|
s->_raw_size += local_gotno * MIPS_ELF_GOT_SIZE (dynobj); |
|
|
|
|
|
/* There has to be a global GOT entry for every symbol with |
|
|
a dynamic symbol table index of DT_MIPS_GOTSYM or |
|
|
higher. Therefore, it make sense to put those symbols |
|
|
that need GOT entries at the end of the symbol table. We |
|
|
do that here. */ |
|
|
if (! mips_elf_sort_hash_table (info, 1)) |
|
|
return false; |
|
6787 |
|
|
6788 |
if (g->global_gotsym != NULL) |
needed_relocs += arg.needed; |
6789 |
i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx; |
} |
6790 |
else |
|
6791 |
/* If there are no global symbols, or none requiring |
if (needed_relocs) |
6792 |
relocations, then GLOBAL_GOTSYM will be NULL. */ |
mips_elf_allocate_dynamic_relocations (dynobj, needed_relocs); |
|
i = 0; |
|
|
g->global_gotno = i; |
|
|
s->_raw_size += i * MIPS_ELF_GOT_SIZE (dynobj); |
|
6793 |
} |
} |
6794 |
else if (strcmp (name, MIPS_ELF_STUB_SECTION_NAME (output_bfd)) == 0) |
else if (strcmp (name, MIPS_ELF_STUB_SECTION_NAME (output_bfd)) == 0) |
6795 |
{ |
{ |
6796 |
/* IRIX rld assumes that the function stub isn't at the end |
/* IRIX rld assumes that the function stub isn't at the end |
6797 |
of .text section. So put a dummy. XXX */ |
of .text section. So put a dummy. XXX */ |
6798 |
s->_raw_size += MIPS_FUNCTION_STUB_SIZE; |
s->size += MIPS_FUNCTION_STUB_SIZE; |
6799 |
} |
} |
6800 |
else if (! info->shared |
else if (! info->shared |
6801 |
&& ! mips_elf_hash_table (info)->use_rld_obj_head |
&& ! mips_elf_hash_table (info)->use_rld_obj_head |
6803 |
{ |
{ |
6804 |
/* We add a room for __rld_map. It will be filled in by the |
/* We add a room for __rld_map. It will be filled in by the |
6805 |
rtld to contain a pointer to the _r_debug structure. */ |
rtld to contain a pointer to the _r_debug structure. */ |
6806 |
s->_raw_size += 4; |
s->size += 4; |
6807 |
} |
} |
6808 |
else if (SGI_COMPAT (output_bfd) |
else if (SGI_COMPAT (output_bfd) |
6809 |
&& strncmp (name, ".compact_rel", 12) == 0) |
&& strncmp (name, ".compact_rel", 12) == 0) |
6810 |
s->_raw_size += mips_elf_hash_table (info)->compact_rel_size; |
s->size += mips_elf_hash_table (info)->compact_rel_size; |
|
else if (strcmp (name, ".msym") == 0) |
|
|
s->_raw_size = (sizeof (Elf32_External_Msym) |
|
|
* (elf_hash_table (info)->dynsymcount |
|
|
+ bfd_count_sections (output_bfd))); |
|
6811 |
else if (strncmp (name, ".init", 5) != 0) |
else if (strncmp (name, ".init", 5) != 0) |
6812 |
{ |
{ |
6813 |
/* It's not one of our sections, so don't allocate space. */ |
/* It's not one of our sections, so don't allocate space. */ |
6821 |
} |
} |
6822 |
|
|
6823 |
/* Allocate memory for the section contents. */ |
/* Allocate memory for the section contents. */ |
6824 |
s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size); |
s->contents = bfd_zalloc (dynobj, s->size); |
6825 |
if (s->contents == NULL && s->_raw_size != 0) |
if (s->contents == NULL && s->size != 0) |
6826 |
{ |
{ |
6827 |
bfd_set_error (bfd_error_no_memory); |
bfd_set_error (bfd_error_no_memory); |
6828 |
return false; |
return FALSE; |
6829 |
} |
} |
6830 |
} |
} |
6831 |
|
|
6841 |
/* SGI object has the equivalence of DT_DEBUG in the |
/* SGI object has the equivalence of DT_DEBUG in the |
6842 |
DT_MIPS_RLD_MAP entry. */ |
DT_MIPS_RLD_MAP entry. */ |
6843 |
if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_MAP, 0)) |
if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_MAP, 0)) |
6844 |
return false; |
return FALSE; |
6845 |
if (!SGI_COMPAT (output_bfd)) |
if (!SGI_COMPAT (output_bfd)) |
6846 |
{ |
{ |
6847 |
if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0)) |
if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0)) |
6848 |
return false; |
return FALSE; |
6849 |
} |
} |
6850 |
} |
} |
6851 |
else |
else |
6854 |
if (!SGI_COMPAT (output_bfd)) |
if (!SGI_COMPAT (output_bfd)) |
6855 |
{ |
{ |
6856 |
if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0)) |
if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0)) |
6857 |
return false; |
return FALSE; |
6858 |
} |
} |
6859 |
} |
} |
6860 |
|
|
6864 |
if ((info->flags & DF_TEXTREL) != 0) |
if ((info->flags & DF_TEXTREL) != 0) |
6865 |
{ |
{ |
6866 |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0)) |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0)) |
6867 |
return false; |
return FALSE; |
6868 |
} |
} |
6869 |
|
|
6870 |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0)) |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0)) |
6871 |
return false; |
return FALSE; |
6872 |
|
|
6873 |
if (bfd_get_section_by_name (dynobj, ".rel.dyn")) |
if (mips_elf_rel_dyn_section (dynobj, FALSE)) |
6874 |
{ |
{ |
6875 |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0)) |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0)) |
6876 |
return false; |
return FALSE; |
6877 |
|
|
6878 |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0)) |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0)) |
6879 |
return false; |
return FALSE; |
6880 |
|
|
6881 |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0)) |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0)) |
6882 |
return false; |
return FALSE; |
|
} |
|
|
|
|
|
if (SGI_COMPAT (output_bfd)) |
|
|
{ |
|
|
if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_CONFLICTNO, 0)) |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (SGI_COMPAT (output_bfd)) |
|
|
{ |
|
|
if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_LIBLISTNO, 0)) |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (bfd_get_section_by_name (dynobj, ".conflict") != NULL) |
|
|
{ |
|
|
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_CONFLICT, 0)) |
|
|
return false; |
|
|
|
|
|
s = bfd_get_section_by_name (dynobj, ".liblist"); |
|
|
BFD_ASSERT (s != NULL); |
|
|
|
|
|
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_LIBLIST, 0)) |
|
|
return false; |
|
6883 |
} |
} |
6884 |
|
|
6885 |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_VERSION, 0)) |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_VERSION, 0)) |
6886 |
return false; |
return FALSE; |
6887 |
|
|
6888 |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_FLAGS, 0)) |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_FLAGS, 0)) |
6889 |
return false; |
return FALSE; |
|
|
|
|
#if 0 |
|
|
/* Time stamps in executable files are a bad idea. */ |
|
|
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_TIME_STAMP, 0)) |
|
|
return false; |
|
|
#endif |
|
|
|
|
|
#if 0 /* FIXME */ |
|
|
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_ICHECKSUM, 0)) |
|
|
return false; |
|
|
#endif |
|
|
|
|
|
#if 0 /* FIXME */ |
|
|
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_IVERSION, 0)) |
|
|
return false; |
|
|
#endif |
|
6890 |
|
|
6891 |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_BASE_ADDRESS, 0)) |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_BASE_ADDRESS, 0)) |
6892 |
return false; |
return FALSE; |
6893 |
|
|
6894 |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_LOCAL_GOTNO, 0)) |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_LOCAL_GOTNO, 0)) |
6895 |
return false; |
return FALSE; |
6896 |
|
|
6897 |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_SYMTABNO, 0)) |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_SYMTABNO, 0)) |
6898 |
return false; |
return FALSE; |
6899 |
|
|
6900 |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_UNREFEXTNO, 0)) |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_UNREFEXTNO, 0)) |
6901 |
return false; |
return FALSE; |
6902 |
|
|
6903 |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_GOTSYM, 0)) |
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_GOTSYM, 0)) |
6904 |
return false; |
return FALSE; |
6905 |
|
|
6906 |
if (IRIX_COMPAT (dynobj) == ict_irix5 |
if (IRIX_COMPAT (dynobj) == ict_irix5 |
6907 |
&& ! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_HIPAGENO, 0)) |
&& ! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_HIPAGENO, 0)) |
6908 |
return false; |
return FALSE; |
6909 |
|
|
6910 |
if (IRIX_COMPAT (dynobj) == ict_irix6 |
if (IRIX_COMPAT (dynobj) == ict_irix6 |
6911 |
&& (bfd_get_section_by_name |
&& (bfd_get_section_by_name |
6912 |
(dynobj, MIPS_ELF_OPTIONS_SECTION_NAME (dynobj))) |
(dynobj, MIPS_ELF_OPTIONS_SECTION_NAME (dynobj))) |
6913 |
&& !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_OPTIONS, 0)) |
&& !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_OPTIONS, 0)) |
6914 |
return false; |
return FALSE; |
|
|
|
|
if (bfd_get_section_by_name (dynobj, ".msym") |
|
|
&& !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_MSYM, 0)) |
|
|
return false; |
|
6915 |
} |
} |
6916 |
|
|
6917 |
return true; |
return TRUE; |
6918 |
} |
} |
6919 |
|
|
6920 |
/* Relocate a MIPS ELF section. */ |
/* Relocate a MIPS ELF section. */ |
6921 |
|
|
6922 |
boolean |
bfd_boolean |
6923 |
_bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section, |
_bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, |
6924 |
contents, relocs, local_syms, local_sections) |
bfd *input_bfd, asection *input_section, |
6925 |
bfd *output_bfd; |
bfd_byte *contents, Elf_Internal_Rela *relocs, |
6926 |
struct bfd_link_info *info; |
Elf_Internal_Sym *local_syms, |
6927 |
bfd *input_bfd; |
asection **local_sections) |
|
asection *input_section; |
|
|
bfd_byte *contents; |
|
|
Elf_Internal_Rela *relocs; |
|
|
Elf_Internal_Sym *local_syms; |
|
|
asection **local_sections; |
|
6928 |
{ |
{ |
6929 |
Elf_Internal_Rela *rel; |
Elf_Internal_Rela *rel; |
6930 |
const Elf_Internal_Rela *relend; |
const Elf_Internal_Rela *relend; |
6931 |
bfd_vma addend = 0; |
bfd_vma addend = 0; |
6932 |
boolean use_saved_addend_p = false; |
bfd_boolean use_saved_addend_p = FALSE; |
6933 |
struct elf_backend_data *bed; |
const struct elf_backend_data *bed; |
6934 |
|
|
6935 |
bed = get_elf_backend_data (output_bfd); |
bed = get_elf_backend_data (output_bfd); |
6936 |
relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel; |
relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel; |
6939 |
const char *name; |
const char *name; |
6940 |
bfd_vma value; |
bfd_vma value; |
6941 |
reloc_howto_type *howto; |
reloc_howto_type *howto; |
6942 |
boolean require_jalx; |
bfd_boolean require_jalx; |
6943 |
/* True if the relocation is a RELA relocation, rather than a |
/* TRUE if the relocation is a RELA relocation, rather than a |
6944 |
REL relocation. */ |
REL relocation. */ |
6945 |
boolean rela_relocation_p = true; |
bfd_boolean rela_relocation_p = TRUE; |
6946 |
unsigned int r_type = ELF_R_TYPE (output_bfd, rel->r_info); |
unsigned int r_type = ELF_R_TYPE (output_bfd, rel->r_info); |
6947 |
const char * msg = (const char *) NULL; |
const char *msg; |
6948 |
|
|
6949 |
/* Find the relocation howto for this relocation. */ |
/* Find the relocation howto for this relocation. */ |
6950 |
if (r_type == R_MIPS_64 && ! NEWABI_P (input_bfd)) |
if (r_type == R_MIPS_64 && ! NEWABI_P (input_bfd)) |
6955 |
space. Thus, when they use an R_MIPS_64 they mean what is |
space. Thus, when they use an R_MIPS_64 they mean what is |
6956 |
usually meant by R_MIPS_32, with the exception that the |
usually meant by R_MIPS_32, with the exception that the |
6957 |
stored value is sign-extended to 64 bits. */ |
stored value is sign-extended to 64 bits. */ |
6958 |
howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, R_MIPS_32, false); |
howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, R_MIPS_32, FALSE); |
6959 |
|
|
6960 |
/* On big-endian systems, we need to lie about the position |
/* On big-endian systems, we need to lie about the position |
6961 |
of the reloc. */ |
of the reloc. */ |
6965 |
else |
else |
6966 |
/* NewABI defaults to RELA relocations. */ |
/* NewABI defaults to RELA relocations. */ |
6967 |
howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, r_type, |
howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, r_type, |
6968 |
NEWABI_P (input_bfd)); |
NEWABI_P (input_bfd) |
6969 |
|
&& (MIPS_RELOC_RELA_P |
6970 |
|
(input_bfd, input_section, |
6971 |
|
rel - relocs))); |
6972 |
|
|
6973 |
if (!use_saved_addend_p) |
if (!use_saved_addend_p) |
6974 |
{ |
{ |
6986 |
rel_hdr = elf_section_data (input_section)->rel_hdr2; |
rel_hdr = elf_section_data (input_section)->rel_hdr2; |
6987 |
if (rel_hdr->sh_entsize == MIPS_ELF_REL_SIZE (input_bfd)) |
if (rel_hdr->sh_entsize == MIPS_ELF_REL_SIZE (input_bfd)) |
6988 |
{ |
{ |
6989 |
|
bfd_byte *location = contents + rel->r_offset; |
6990 |
|
|
6991 |
/* Note that this is a REL relocation. */ |
/* Note that this is a REL relocation. */ |
6992 |
rela_relocation_p = false; |
rela_relocation_p = FALSE; |
6993 |
|
|
6994 |
/* Get the addend, which is stored in the input file. */ |
/* Get the addend, which is stored in the input file. */ |
6995 |
|
_bfd_mips16_elf_reloc_unshuffle (input_bfd, r_type, FALSE, |
6996 |
|
location); |
6997 |
addend = mips_elf_obtain_contents (howto, rel, input_bfd, |
addend = mips_elf_obtain_contents (howto, rel, input_bfd, |
6998 |
contents); |
contents); |
6999 |
|
_bfd_mips16_elf_reloc_shuffle(input_bfd, r_type, FALSE, |
7000 |
|
location); |
7001 |
|
|
7002 |
addend &= howto->src_mask; |
addend &= howto->src_mask; |
|
addend <<= howto->rightshift; |
|
7003 |
|
|
7004 |
/* For some kinds of relocations, the ADDEND is a |
/* For some kinds of relocations, the ADDEND is a |
7005 |
combination of the addend stored in two different |
combination of the addend stored in two different |
7006 |
relocations. */ |
relocations. */ |
7007 |
if (r_type == R_MIPS_HI16 |
if (r_type == R_MIPS_HI16 || r_type == R_MIPS16_HI16 |
|
|| r_type == R_MIPS_GNU_REL_HI16 |
|
7008 |
|| (r_type == R_MIPS_GOT16 |
|| (r_type == R_MIPS_GOT16 |
7009 |
&& mips_elf_local_relocation_p (input_bfd, rel, |
&& mips_elf_local_relocation_p (input_bfd, rel, |
7010 |
local_sections, false))) |
local_sections, FALSE))) |
7011 |
{ |
{ |
7012 |
bfd_vma l; |
bfd_vma l; |
7013 |
const Elf_Internal_Rela *lo16_relocation; |
const Elf_Internal_Rela *lo16_relocation; |
7014 |
reloc_howto_type *lo16_howto; |
reloc_howto_type *lo16_howto; |
7015 |
unsigned int lo; |
bfd_byte *lo16_location; |
7016 |
|
int lo16_type; |
7017 |
|
|
7018 |
|
if (r_type == R_MIPS16_HI16) |
7019 |
|
lo16_type = R_MIPS16_LO16; |
7020 |
|
else |
7021 |
|
lo16_type = R_MIPS_LO16; |
7022 |
|
|
7023 |
/* The combined value is the sum of the HI16 addend, |
/* The combined value is the sum of the HI16 addend, |
7024 |
left-shifted by sixteen bits, and the LO16 |
left-shifted by sixteen bits, and the LO16 |
7026 |
a `lui' of the HI16 value, and then an `addiu' of |
a `lui' of the HI16 value, and then an `addiu' of |
7027 |
the LO16 value.) |
the LO16 value.) |
7028 |
|
|
7029 |
Scan ahead to find a matching LO16 relocation. */ |
Scan ahead to find a matching LO16 relocation. |
7030 |
if (r_type == R_MIPS_GNU_REL_HI16) |
|
7031 |
lo = R_MIPS_GNU_REL_LO16; |
According to the MIPS ELF ABI, the R_MIPS_LO16 |
7032 |
else |
relocation must be immediately following. |
7033 |
lo = R_MIPS_LO16; |
However, for the IRIX6 ABI, the next relocation |
7034 |
lo16_relocation = mips_elf_next_relocation (input_bfd, lo, |
may be a composed relocation consisting of |
7035 |
|
several relocations for the same address. In |
7036 |
|
that case, the R_MIPS_LO16 relocation may occur |
7037 |
|
as one of these. We permit a similar extension |
7038 |
|
in general, as that is useful for GCC. */ |
7039 |
|
lo16_relocation = mips_elf_next_relocation (input_bfd, |
7040 |
|
lo16_type, |
7041 |
rel, relend); |
rel, relend); |
7042 |
if (lo16_relocation == NULL) |
if (lo16_relocation == NULL) |
7043 |
return false; |
return FALSE; |
7044 |
|
|
7045 |
|
lo16_location = contents + lo16_relocation->r_offset; |
7046 |
|
|
7047 |
/* Obtain the addend kept there. */ |
/* Obtain the addend kept there. */ |
7048 |
lo16_howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, lo, false); |
lo16_howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, |
7049 |
|
lo16_type, FALSE); |
7050 |
|
_bfd_mips16_elf_reloc_unshuffle (input_bfd, lo16_type, FALSE, |
7051 |
|
lo16_location); |
7052 |
l = mips_elf_obtain_contents (lo16_howto, lo16_relocation, |
l = mips_elf_obtain_contents (lo16_howto, lo16_relocation, |
7053 |
input_bfd, contents); |
input_bfd, contents); |
7054 |
|
_bfd_mips16_elf_reloc_shuffle (input_bfd, lo16_type, FALSE, |
7055 |
|
lo16_location); |
7056 |
l &= lo16_howto->src_mask; |
l &= lo16_howto->src_mask; |
7057 |
l <<= lo16_howto->rightshift; |
l <<= lo16_howto->rightshift; |
7058 |
l = mips_elf_sign_extend (l, 16); |
l = _bfd_mips_elf_sign_extend (l, 16); |
7059 |
|
|
7060 |
addend <<= 16; |
addend <<= 16; |
7061 |
|
|
7062 |
/* Compute the combined addend. */ |
/* Compute the combined addend. */ |
7063 |
addend += l; |
addend += l; |
|
|
|
|
/* If PC-relative, subtract the difference between the |
|
|
address of the LO part of the reloc and the address of |
|
|
the HI part. The relocation is relative to the LO |
|
|
part, but mips_elf_calculate_relocation() doesn't |
|
|
know its address or the difference from the HI part, so |
|
|
we subtract that difference here. See also the |
|
|
comment in mips_elf_calculate_relocation(). */ |
|
|
if (r_type == R_MIPS_GNU_REL_HI16) |
|
|
addend -= (lo16_relocation->r_offset - rel->r_offset); |
|
|
} |
|
|
else if (r_type == R_MIPS16_GPREL) |
|
|
{ |
|
|
/* The addend is scrambled in the object file. See |
|
|
mips_elf_perform_relocation for details on the |
|
|
format. */ |
|
|
addend = (((addend & 0x1f0000) >> 5) |
|
|
| ((addend & 0x7e00000) >> 16) |
|
|
| (addend & 0x1f)); |
|
7064 |
} |
} |
7065 |
|
else |
7066 |
|
addend <<= howto->rightshift; |
7067 |
} |
} |
7068 |
else |
else |
7069 |
addend = rel->r_addend; |
addend = rel->r_addend; |
7070 |
} |
} |
7071 |
|
|
7072 |
if (info->relocateable) |
if (info->relocatable) |
7073 |
{ |
{ |
7074 |
Elf_Internal_Sym *sym; |
Elf_Internal_Sym *sym; |
7075 |
unsigned long r_symndx; |
unsigned long r_symndx; |
7083 |
they're against a section symbol, in which case we need |
they're against a section symbol, in which case we need |
7084 |
to adjust by the section offset, or unless they're GP |
to adjust by the section offset, or unless they're GP |
7085 |
relative in which case we need to adjust by the amount |
relative in which case we need to adjust by the amount |
7086 |
that we're adjusting GP in this relocateable object. */ |
that we're adjusting GP in this relocatable object. */ |
7087 |
|
|
7088 |
if (! mips_elf_local_relocation_p (input_bfd, rel, local_sections, |
if (! mips_elf_local_relocation_p (input_bfd, rel, local_sections, |
7089 |
false)) |
FALSE)) |
7090 |
/* There's nothing to do for non-local relocations. */ |
/* There's nothing to do for non-local relocations. */ |
7091 |
continue; |
continue; |
7092 |
|
|
7103 |
/* Adjust the addend appropriately. */ |
/* Adjust the addend appropriately. */ |
7104 |
addend += local_sections[r_symndx]->output_offset; |
addend += local_sections[r_symndx]->output_offset; |
7105 |
|
|
7106 |
if (howto->partial_inplace) |
if (rela_relocation_p) |
7107 |
|
/* If this is a RELA relocation, just update the addend. */ |
7108 |
|
rel->r_addend = addend; |
7109 |
|
else |
7110 |
{ |
{ |
7111 |
/* If the relocation is for a R_MIPS_HI16 or R_MIPS_GOT16, |
if (r_type == R_MIPS_HI16 |
7112 |
then we only want to write out the high-order 16 bits. |
|| r_type == R_MIPS_GOT16) |
|
The subsequent R_MIPS_LO16 will handle the low-order bits. |
|
|
*/ |
|
|
if (r_type == R_MIPS_HI16 || r_type == R_MIPS_GOT16 |
|
|
|| r_type == R_MIPS_GNU_REL_HI16) |
|
7113 |
addend = mips_elf_high (addend); |
addend = mips_elf_high (addend); |
7114 |
else if (r_type == R_MIPS_HIGHER) |
else if (r_type == R_MIPS_HIGHER) |
7115 |
addend = mips_elf_higher (addend); |
addend = mips_elf_higher (addend); |
7116 |
else if (r_type == R_MIPS_HIGHEST) |
else if (r_type == R_MIPS_HIGHEST) |
7117 |
addend = mips_elf_highest (addend); |
addend = mips_elf_highest (addend); |
7118 |
} |
else |
7119 |
|
addend >>= howto->rightshift; |
7120 |
|
|
7121 |
if (rela_relocation_p) |
/* We use the source mask, rather than the destination |
7122 |
/* If this is a RELA relocation, just update the addend. |
mask because the place to which we are writing will be |
7123 |
We have to cast away constness for REL. */ |
source of the addend in the final link. */ |
|
rel->r_addend = addend; |
|
|
else |
|
|
{ |
|
|
/* Otherwise, we have to write the value back out. Note |
|
|
that we use the source mask, rather than the |
|
|
destination mask because the place to which we are |
|
|
writing will be source of the addend in the final |
|
|
link. */ |
|
|
addend >>= howto->rightshift; |
|
7124 |
addend &= howto->src_mask; |
addend &= howto->src_mask; |
7125 |
|
|
7126 |
if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd)) |
if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd)) |
7165 |
|
|
7166 |
if (! mips_elf_perform_relocation (info, howto, rel, addend, |
if (! mips_elf_perform_relocation (info, howto, rel, addend, |
7167 |
input_bfd, input_section, |
input_bfd, input_section, |
7168 |
contents, false)) |
contents, FALSE)) |
7169 |
return false; |
return FALSE; |
7170 |
} |
} |
7171 |
|
|
7172 |
/* Go on to the next relocation. */ |
/* Go on to the next relocation. */ |
7180 |
if (rel + 1 < relend |
if (rel + 1 < relend |
7181 |
&& rel->r_offset == rel[1].r_offset |
&& rel->r_offset == rel[1].r_offset |
7182 |
&& ELF_R_TYPE (input_bfd, rel[1].r_info) != R_MIPS_NONE) |
&& ELF_R_TYPE (input_bfd, rel[1].r_info) != R_MIPS_NONE) |
7183 |
use_saved_addend_p = true; |
use_saved_addend_p = TRUE; |
7184 |
else |
else |
7185 |
use_saved_addend_p = false; |
use_saved_addend_p = FALSE; |
|
|
|
|
addend >>= howto->rightshift; |
|
7186 |
|
|
7187 |
/* Figure out what value we are supposed to relocate. */ |
/* Figure out what value we are supposed to relocate. */ |
7188 |
switch (mips_elf_calculate_relocation (output_bfd, input_bfd, |
switch (mips_elf_calculate_relocation (output_bfd, input_bfd, |
7189 |
input_section, info, rel, |
input_section, info, rel, |
7190 |
addend, howto, local_syms, |
addend, howto, local_syms, |
7191 |
local_sections, &value, |
local_sections, &value, |
7192 |
&name, &require_jalx)) |
&name, &require_jalx, |
7193 |
|
use_saved_addend_p)) |
7194 |
{ |
{ |
7195 |
case bfd_reloc_continue: |
case bfd_reloc_continue: |
7196 |
/* There's nothing to do. */ |
/* There's nothing to do. */ |
7207 |
msg = _("internal error: unsupported relocation error"); |
msg = _("internal error: unsupported relocation error"); |
7208 |
info->callbacks->warning |
info->callbacks->warning |
7209 |
(info, msg, name, input_bfd, input_section, rel->r_offset); |
(info, msg, name, input_bfd, input_section, rel->r_offset); |
7210 |
return false; |
return FALSE; |
7211 |
|
|
7212 |
case bfd_reloc_overflow: |
case bfd_reloc_overflow: |
7213 |
if (use_saved_addend_p) |
if (use_saved_addend_p) |
7218 |
{ |
{ |
7219 |
BFD_ASSERT (name != NULL); |
BFD_ASSERT (name != NULL); |
7220 |
if (! ((*info->callbacks->reloc_overflow) |
if (! ((*info->callbacks->reloc_overflow) |
7221 |
(info, name, howto->name, (bfd_vma) 0, |
(info, NULL, name, howto->name, (bfd_vma) 0, |
7222 |
input_bfd, input_section, rel->r_offset))) |
input_bfd, input_section, rel->r_offset))) |
7223 |
return false; |
return FALSE; |
7224 |
} |
} |
7225 |
break; |
break; |
7226 |
|
|
7289 |
if (! mips_elf_perform_relocation (info, howto, rel, value, |
if (! mips_elf_perform_relocation (info, howto, rel, value, |
7290 |
input_bfd, input_section, |
input_bfd, input_section, |
7291 |
contents, require_jalx)) |
contents, require_jalx)) |
7292 |
return false; |
return FALSE; |
7293 |
} |
} |
7294 |
|
|
7295 |
return true; |
return TRUE; |
7296 |
} |
} |
7297 |
|
|
7298 |
/* If NAME is one of the special IRIX6 symbols defined by the linker, |
/* If NAME is one of the special IRIX6 symbols defined by the linker, |
7299 |
adjust it appropriately now. */ |
adjust it appropriately now. */ |
7300 |
|
|
7301 |
static void |
static void |
7302 |
mips_elf_irix6_finish_dynamic_symbol (abfd, name, sym) |
mips_elf_irix6_finish_dynamic_symbol (bfd *abfd ATTRIBUTE_UNUSED, |
7303 |
bfd *abfd ATTRIBUTE_UNUSED; |
const char *name, Elf_Internal_Sym *sym) |
|
const char *name; |
|
|
Elf_Internal_Sym *sym; |
|
7304 |
{ |
{ |
7305 |
/* The linker script takes care of providing names and values for |
/* The linker script takes care of providing names and values for |
7306 |
these, but we must place them into the right sections. */ |
these, but we must place them into the right sections. */ |
7333 |
/* All of these symbols are given type STT_SECTION by the |
/* All of these symbols are given type STT_SECTION by the |
7334 |
IRIX6 linker. */ |
IRIX6 linker. */ |
7335 |
sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION); |
sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION); |
7336 |
|
sym->st_other = STO_PROTECTED; |
7337 |
|
|
7338 |
/* The IRIX linker puts these symbols in special sections. */ |
/* The IRIX linker puts these symbols in special sections. */ |
7339 |
if (i == 0) |
if (i == 0) |
7348 |
/* Finish up dynamic symbol handling. We set the contents of various |
/* Finish up dynamic symbol handling. We set the contents of various |
7349 |
dynamic sections here. */ |
dynamic sections here. */ |
7350 |
|
|
7351 |
boolean |
bfd_boolean |
7352 |
_bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym) |
_bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd, |
7353 |
bfd *output_bfd; |
struct bfd_link_info *info, |
7354 |
struct bfd_link_info *info; |
struct elf_link_hash_entry *h, |
7355 |
struct elf_link_hash_entry *h; |
Elf_Internal_Sym *sym) |
|
Elf_Internal_Sym *sym; |
|
7356 |
{ |
{ |
7357 |
bfd *dynobj; |
bfd *dynobj; |
|
bfd_vma gval; |
|
7358 |
asection *sgot; |
asection *sgot; |
7359 |
asection *smsym; |
struct mips_got_info *g, *gg; |
|
struct mips_got_info *g; |
|
7360 |
const char *name; |
const char *name; |
|
struct mips_elf_link_hash_entry *mh; |
|
7361 |
|
|
7362 |
dynobj = elf_hash_table (info)->dynobj; |
dynobj = elf_hash_table (info)->dynobj; |
|
gval = sym->st_value; |
|
|
mh = (struct mips_elf_link_hash_entry *) h; |
|
7363 |
|
|
7364 |
if (h->plt.offset != (bfd_vma) -1) |
if (h->plt.offset != MINUS_ONE) |
7365 |
{ |
{ |
7366 |
asection *s; |
asection *s; |
7367 |
bfd_byte stub[MIPS_FUNCTION_STUB_SIZE]; |
bfd_byte stub[MIPS_FUNCTION_STUB_SIZE]; |
7376 |
|
|
7377 |
/* FIXME: Can h->dynindex be more than 64K? */ |
/* FIXME: Can h->dynindex be more than 64K? */ |
7378 |
if (h->dynindx & 0xffff0000) |
if (h->dynindx & 0xffff0000) |
7379 |
return false; |
return FALSE; |
7380 |
|
|
7381 |
/* Fill the stub. */ |
/* Fill the stub. */ |
7382 |
bfd_put_32 (output_bfd, STUB_LW (output_bfd), stub); |
bfd_put_32 (output_bfd, STUB_LW (output_bfd), stub); |
7384 |
bfd_put_32 (output_bfd, STUB_JALR, stub + 8); |
bfd_put_32 (output_bfd, STUB_JALR, stub + 8); |
7385 |
bfd_put_32 (output_bfd, STUB_LI16 (output_bfd) + h->dynindx, stub + 12); |
bfd_put_32 (output_bfd, STUB_LI16 (output_bfd) + h->dynindx, stub + 12); |
7386 |
|
|
7387 |
BFD_ASSERT (h->plt.offset <= s->_raw_size); |
BFD_ASSERT (h->plt.offset <= s->size); |
7388 |
memcpy (s->contents + h->plt.offset, stub, MIPS_FUNCTION_STUB_SIZE); |
memcpy (s->contents + h->plt.offset, stub, MIPS_FUNCTION_STUB_SIZE); |
7389 |
|
|
7390 |
/* Mark the symbol as undefined. plt.offset != -1 occurs |
/* Mark the symbol as undefined. plt.offset != -1 occurs |
7394 |
/* The run-time linker uses the st_value field of the symbol |
/* The run-time linker uses the st_value field of the symbol |
7395 |
to reset the global offset table entry for this external |
to reset the global offset table entry for this external |
7396 |
to its stub address when unlinking a shared object. */ |
to its stub address when unlinking a shared object. */ |
7397 |
gval = s->output_section->vma + s->output_offset + h->plt.offset; |
sym->st_value = (s->output_section->vma + s->output_offset |
7398 |
sym->st_value = gval; |
+ h->plt.offset); |
7399 |
} |
} |
7400 |
|
|
7401 |
BFD_ASSERT (h->dynindx != -1 |
BFD_ASSERT (h->dynindx != -1 |
7402 |
|| (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0); |
|| h->forced_local); |
7403 |
|
|
7404 |
sgot = mips_elf_got_section (dynobj); |
sgot = mips_elf_got_section (dynobj, FALSE); |
7405 |
BFD_ASSERT (sgot != NULL); |
BFD_ASSERT (sgot != NULL); |
7406 |
BFD_ASSERT (elf_section_data (sgot) != NULL); |
BFD_ASSERT (mips_elf_section_data (sgot) != NULL); |
7407 |
g = (struct mips_got_info *) elf_section_data (sgot)->tdata; |
g = mips_elf_section_data (sgot)->u.got_info; |
7408 |
BFD_ASSERT (g != NULL); |
BFD_ASSERT (g != NULL); |
7409 |
|
|
7410 |
/* Run through the global symbol table, creating GOT entries for all |
/* Run through the global symbol table, creating GOT entries for all |
7415 |
bfd_vma offset; |
bfd_vma offset; |
7416 |
bfd_vma value; |
bfd_vma value; |
7417 |
|
|
7418 |
if (sym->st_value) |
value = sym->st_value; |
7419 |
value = sym->st_value; |
offset = mips_elf_global_got_index (dynobj, output_bfd, h, R_MIPS_GOT16, info); |
|
else |
|
|
{ |
|
|
/* For an entity defined in a shared object, this will be |
|
|
NULL. (For functions in shared objects for |
|
|
which we have created stubs, ST_VALUE will be non-NULL. |
|
|
That's because such the functions are now no longer defined |
|
|
in a shared object.) */ |
|
|
|
|
|
if (info->shared && h->root.type == bfd_link_hash_undefined) |
|
|
value = 0; |
|
|
else |
|
|
value = h->root.u.def.value; |
|
|
} |
|
|
offset = mips_elf_global_got_index (dynobj, h); |
|
7420 |
MIPS_ELF_PUT_WORD (output_bfd, value, sgot->contents + offset); |
MIPS_ELF_PUT_WORD (output_bfd, value, sgot->contents + offset); |
7421 |
} |
} |
7422 |
|
|
7423 |
/* Create a .msym entry, if appropriate. */ |
if (g->next && h->dynindx != -1 && h->type != STT_TLS) |
7424 |
smsym = bfd_get_section_by_name (dynobj, ".msym"); |
{ |
7425 |
if (smsym) |
struct mips_got_entry e, *p; |
7426 |
{ |
bfd_vma entry; |
7427 |
Elf32_Internal_Msym msym; |
bfd_vma offset; |
7428 |
|
|
7429 |
msym.ms_hash_value = bfd_elf_hash (h->root.root.string); |
gg = g; |
7430 |
/* It is undocumented what the `1' indicates, but IRIX6 uses |
|
7431 |
this value. */ |
e.abfd = output_bfd; |
7432 |
msym.ms_info = ELF32_MS_INFO (mh->min_dyn_reloc_index, 1); |
e.symndx = -1; |
7433 |
bfd_mips_elf_swap_msym_out |
e.d.h = (struct mips_elf_link_hash_entry *)h; |
7434 |
(dynobj, &msym, |
e.tls_type = 0; |
7435 |
((Elf32_External_Msym *) smsym->contents) + h->dynindx); |
|
7436 |
|
for (g = g->next; g->next != gg; g = g->next) |
7437 |
|
{ |
7438 |
|
if (g->got_entries |
7439 |
|
&& (p = (struct mips_got_entry *) htab_find (g->got_entries, |
7440 |
|
&e))) |
7441 |
|
{ |
7442 |
|
offset = p->gotidx; |
7443 |
|
if (info->shared |
7444 |
|
|| (elf_hash_table (info)->dynamic_sections_created |
7445 |
|
&& p->d.h != NULL |
7446 |
|
&& p->d.h->root.def_dynamic |
7447 |
|
&& !p->d.h->root.def_regular)) |
7448 |
|
{ |
7449 |
|
/* Create an R_MIPS_REL32 relocation for this entry. Due to |
7450 |
|
the various compatibility problems, it's easier to mock |
7451 |
|
up an R_MIPS_32 or R_MIPS_64 relocation and leave |
7452 |
|
mips_elf_create_dynamic_relocation to calculate the |
7453 |
|
appropriate addend. */ |
7454 |
|
Elf_Internal_Rela rel[3]; |
7455 |
|
|
7456 |
|
memset (rel, 0, sizeof (rel)); |
7457 |
|
if (ABI_64_P (output_bfd)) |
7458 |
|
rel[0].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_64); |
7459 |
|
else |
7460 |
|
rel[0].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_32); |
7461 |
|
rel[0].r_offset = rel[1].r_offset = rel[2].r_offset = offset; |
7462 |
|
|
7463 |
|
entry = 0; |
7464 |
|
if (! (mips_elf_create_dynamic_relocation |
7465 |
|
(output_bfd, info, rel, |
7466 |
|
e.d.h, NULL, sym->st_value, &entry, sgot))) |
7467 |
|
return FALSE; |
7468 |
|
} |
7469 |
|
else |
7470 |
|
entry = sym->st_value; |
7471 |
|
MIPS_ELF_PUT_WORD (output_bfd, entry, sgot->contents + offset); |
7472 |
|
} |
7473 |
|
} |
7474 |
} |
} |
7475 |
|
|
7476 |
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ |
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ |
7530 |
asection *s = bfd_get_section_by_name (dynobj, ".rld_map"); |
asection *s = bfd_get_section_by_name (dynobj, ".rld_map"); |
7531 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
7532 |
sym->st_value = s->output_section->vma + s->output_offset; |
sym->st_value = s->output_section->vma + s->output_offset; |
7533 |
bfd_put_32 (output_bfd, (bfd_vma) 0, s->contents); |
bfd_put_32 (output_bfd, 0, s->contents); |
7534 |
if (mips_elf_hash_table (info)->rld_value == 0) |
if (mips_elf_hash_table (info)->rld_value == 0) |
7535 |
mips_elf_hash_table (info)->rld_value = sym->st_value; |
mips_elf_hash_table (info)->rld_value = sym->st_value; |
7536 |
} |
} |
7547 |
} |
} |
7548 |
|
|
7549 |
/* If this is a mips16 symbol, force the value to be even. */ |
/* If this is a mips16 symbol, force the value to be even. */ |
7550 |
if (sym->st_other == STO_MIPS16 |
if (sym->st_other == STO_MIPS16) |
7551 |
&& (sym->st_value & 1) != 0) |
sym->st_value &= ~1; |
|
--sym->st_value; |
|
7552 |
|
|
7553 |
return true; |
return TRUE; |
7554 |
} |
} |
7555 |
|
|
7556 |
/* Finish up the dynamic sections. */ |
/* Finish up the dynamic sections. */ |
7557 |
|
|
7558 |
boolean |
bfd_boolean |
7559 |
_bfd_mips_elf_finish_dynamic_sections (output_bfd, info) |
_bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd, |
7560 |
bfd *output_bfd; |
struct bfd_link_info *info) |
|
struct bfd_link_info *info; |
|
7561 |
{ |
{ |
7562 |
bfd *dynobj; |
bfd *dynobj; |
7563 |
asection *sdyn; |
asection *sdyn; |
7564 |
asection *sgot; |
asection *sgot; |
7565 |
struct mips_got_info *g; |
struct mips_got_info *gg, *g; |
7566 |
|
|
7567 |
dynobj = elf_hash_table (info)->dynobj; |
dynobj = elf_hash_table (info)->dynobj; |
7568 |
|
|
7569 |
sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); |
sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); |
7570 |
|
|
7571 |
sgot = bfd_get_section_by_name (dynobj, ".got"); |
sgot = mips_elf_got_section (dynobj, FALSE); |
7572 |
if (sgot == NULL) |
if (sgot == NULL) |
7573 |
g = NULL; |
gg = g = NULL; |
7574 |
else |
else |
7575 |
{ |
{ |
7576 |
BFD_ASSERT (elf_section_data (sgot) != NULL); |
BFD_ASSERT (mips_elf_section_data (sgot) != NULL); |
7577 |
g = (struct mips_got_info *) elf_section_data (sgot)->tdata; |
gg = mips_elf_section_data (sgot)->u.got_info; |
7578 |
|
BFD_ASSERT (gg != NULL); |
7579 |
|
g = mips_elf_got_for_ibfd (gg, output_bfd); |
7580 |
BFD_ASSERT (g != NULL); |
BFD_ASSERT (g != NULL); |
7581 |
} |
} |
7582 |
|
|
7588 |
BFD_ASSERT (g != NULL); |
BFD_ASSERT (g != NULL); |
7589 |
|
|
7590 |
for (b = sdyn->contents; |
for (b = sdyn->contents; |
7591 |
b < sdyn->contents + sdyn->_raw_size; |
b < sdyn->contents + sdyn->size; |
7592 |
b += MIPS_ELF_DYN_SIZE (dynobj)) |
b += MIPS_ELF_DYN_SIZE (dynobj)) |
7593 |
{ |
{ |
7594 |
Elf_Internal_Dyn dyn; |
Elf_Internal_Dyn dyn; |
7595 |
const char *name; |
const char *name; |
7596 |
size_t elemsize; |
size_t elemsize; |
7597 |
asection *s; |
asection *s; |
7598 |
boolean swap_out_p; |
bfd_boolean swap_out_p; |
7599 |
|
|
7600 |
/* Read in the current dynamic entry. */ |
/* Read in the current dynamic entry. */ |
7601 |
(*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn); |
(*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn); |
7602 |
|
|
7603 |
/* Assume that we're going to modify it and write it out. */ |
/* Assume that we're going to modify it and write it out. */ |
7604 |
swap_out_p = true; |
swap_out_p = TRUE; |
7605 |
|
|
7606 |
switch (dyn.d_tag) |
switch (dyn.d_tag) |
7607 |
{ |
{ |
7608 |
case DT_RELENT: |
case DT_RELENT: |
7609 |
s = (bfd_get_section_by_name (dynobj, ".rel.dyn")); |
s = mips_elf_rel_dyn_section (dynobj, FALSE); |
7610 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
7611 |
dyn.d_un.d_val = MIPS_ELF_REL_SIZE (dynobj); |
dyn.d_un.d_val = MIPS_ELF_REL_SIZE (dynobj); |
7612 |
break; |
break; |
7619 |
|
|
7620 |
case DT_PLTGOT: |
case DT_PLTGOT: |
7621 |
name = ".got"; |
name = ".got"; |
|
goto get_vma; |
|
|
case DT_MIPS_CONFLICT: |
|
|
name = ".conflict"; |
|
|
goto get_vma; |
|
|
case DT_MIPS_LIBLIST: |
|
|
name = ".liblist"; |
|
|
get_vma: |
|
7622 |
s = bfd_get_section_by_name (output_bfd, name); |
s = bfd_get_section_by_name (output_bfd, name); |
7623 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
7624 |
dyn.d_un.d_ptr = s->vma; |
dyn.d_un.d_ptr = s->vma; |
7632 |
dyn.d_un.d_val = RHF_NOTPOT; /* XXX */ |
dyn.d_un.d_val = RHF_NOTPOT; /* XXX */ |
7633 |
break; |
break; |
7634 |
|
|
|
case DT_MIPS_CONFLICTNO: |
|
|
name = ".conflict"; |
|
|
elemsize = sizeof (Elf32_Conflict); |
|
|
goto set_elemno; |
|
|
|
|
|
case DT_MIPS_LIBLISTNO: |
|
|
name = ".liblist"; |
|
|
elemsize = sizeof (Elf32_Lib); |
|
|
set_elemno: |
|
|
s = bfd_get_section_by_name (output_bfd, name); |
|
|
if (s != NULL) |
|
|
{ |
|
|
if (s->_cooked_size != 0) |
|
|
dyn.d_un.d_val = s->_cooked_size / elemsize; |
|
|
else |
|
|
dyn.d_un.d_val = s->_raw_size / elemsize; |
|
|
} |
|
|
else |
|
|
dyn.d_un.d_val = 0; |
|
|
break; |
|
|
|
|
7635 |
case DT_MIPS_TIME_STAMP: |
case DT_MIPS_TIME_STAMP: |
7636 |
time ((time_t *) &dyn.d_un.d_val); |
time ((time_t *) &dyn.d_un.d_val); |
7637 |
break; |
break; |
7638 |
|
|
7639 |
case DT_MIPS_ICHECKSUM: |
case DT_MIPS_ICHECKSUM: |
7640 |
/* XXX FIXME: */ |
/* XXX FIXME: */ |
7641 |
swap_out_p = false; |
swap_out_p = FALSE; |
7642 |
break; |
break; |
7643 |
|
|
7644 |
case DT_MIPS_IVERSION: |
case DT_MIPS_IVERSION: |
7645 |
/* XXX FIXME: */ |
/* XXX FIXME: */ |
7646 |
swap_out_p = false; |
swap_out_p = FALSE; |
7647 |
break; |
break; |
7648 |
|
|
7649 |
case DT_MIPS_BASE_ADDRESS: |
case DT_MIPS_BASE_ADDRESS: |
7664 |
break; |
break; |
7665 |
|
|
7666 |
case DT_MIPS_GOTSYM: |
case DT_MIPS_GOTSYM: |
7667 |
if (g->global_gotsym) |
if (gg->global_gotsym) |
7668 |
{ |
{ |
7669 |
dyn.d_un.d_val = g->global_gotsym->dynindx; |
dyn.d_un.d_val = gg->global_gotsym->dynindx; |
7670 |
break; |
break; |
7671 |
} |
} |
7672 |
/* In case if we don't have global got symbols we default |
/* In case if we don't have global got symbols we default |
7679 |
s = bfd_get_section_by_name (output_bfd, name); |
s = bfd_get_section_by_name (output_bfd, name); |
7680 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
7681 |
|
|
7682 |
if (s->_cooked_size != 0) |
dyn.d_un.d_val = s->size / elemsize; |
|
dyn.d_un.d_val = s->_cooked_size / elemsize; |
|
|
else |
|
|
dyn.d_un.d_val = s->_raw_size / elemsize; |
|
7683 |
break; |
break; |
7684 |
|
|
7685 |
case DT_MIPS_HIPAGENO: |
case DT_MIPS_HIPAGENO: |
7696 |
dyn.d_un.d_ptr = s->vma; |
dyn.d_un.d_ptr = s->vma; |
7697 |
break; |
break; |
7698 |
|
|
|
case DT_MIPS_MSYM: |
|
|
s = (bfd_get_section_by_name (output_bfd, ".msym")); |
|
|
dyn.d_un.d_ptr = s->vma; |
|
|
break; |
|
|
|
|
7699 |
default: |
default: |
7700 |
swap_out_p = false; |
swap_out_p = FALSE; |
7701 |
break; |
break; |
7702 |
} |
} |
7703 |
|
|
7710 |
/* The first entry of the global offset table will be filled at |
/* The first entry of the global offset table will be filled at |
7711 |
runtime. The second entry will be used by some runtime loaders. |
runtime. The second entry will be used by some runtime loaders. |
7712 |
This isn't the case of IRIX rld. */ |
This isn't the case of IRIX rld. */ |
7713 |
if (sgot != NULL && sgot->_raw_size > 0) |
if (sgot != NULL && sgot->size > 0) |
7714 |
{ |
{ |
7715 |
MIPS_ELF_PUT_WORD (output_bfd, (bfd_vma) 0, sgot->contents); |
MIPS_ELF_PUT_WORD (output_bfd, 0, sgot->contents); |
7716 |
MIPS_ELF_PUT_WORD (output_bfd, (bfd_vma) 0x80000000, |
MIPS_ELF_PUT_WORD (output_bfd, 0x80000000, |
7717 |
sgot->contents + MIPS_ELF_GOT_SIZE (output_bfd)); |
sgot->contents + MIPS_ELF_GOT_SIZE (output_bfd)); |
7718 |
} |
} |
7719 |
|
|
7721 |
elf_section_data (sgot->output_section)->this_hdr.sh_entsize |
elf_section_data (sgot->output_section)->this_hdr.sh_entsize |
7722 |
= MIPS_ELF_GOT_SIZE (output_bfd); |
= MIPS_ELF_GOT_SIZE (output_bfd); |
7723 |
|
|
7724 |
{ |
/* Generate dynamic relocations for the non-primary gots. */ |
7725 |
asection *smsym; |
if (gg != NULL && gg->next) |
7726 |
asection *s; |
{ |
7727 |
Elf32_compact_rel cpt; |
Elf_Internal_Rela rel[3]; |
7728 |
|
bfd_vma addend = 0; |
7729 |
|
|
7730 |
/* ??? The section symbols for the output sections were set up in |
memset (rel, 0, sizeof (rel)); |
7731 |
_bfd_elf_final_link. SGI sets the STT_NOTYPE attribute for these |
rel[0].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_REL32); |
|
symbols. Should we do so? */ |
|
7732 |
|
|
7733 |
smsym = bfd_get_section_by_name (dynobj, ".msym"); |
for (g = gg->next; g->next != gg; g = g->next) |
7734 |
if (smsym != NULL) |
{ |
7735 |
{ |
bfd_vma index = g->next->local_gotno + g->next->global_gotno |
7736 |
Elf32_Internal_Msym msym; |
+ g->next->tls_gotno; |
7737 |
|
|
7738 |
msym.ms_hash_value = 0; |
MIPS_ELF_PUT_WORD (output_bfd, 0, sgot->contents |
7739 |
msym.ms_info = ELF32_MS_INFO (0, 1); |
+ index++ * MIPS_ELF_GOT_SIZE (output_bfd)); |
7740 |
|
MIPS_ELF_PUT_WORD (output_bfd, 0x80000000, sgot->contents |
7741 |
|
+ index++ * MIPS_ELF_GOT_SIZE (output_bfd)); |
7742 |
|
|
7743 |
for (s = output_bfd->sections; s != NULL; s = s->next) |
if (! info->shared) |
7744 |
{ |
continue; |
|
long dynindx = elf_section_data (s)->dynindx; |
|
7745 |
|
|
7746 |
bfd_mips_elf_swap_msym_out |
while (index < g->assigned_gotno) |
7747 |
(output_bfd, &msym, |
{ |
7748 |
(((Elf32_External_Msym *) smsym->contents) |
rel[0].r_offset = rel[1].r_offset = rel[2].r_offset |
7749 |
+ dynindx)); |
= index++ * MIPS_ELF_GOT_SIZE (output_bfd); |
7750 |
} |
if (!(mips_elf_create_dynamic_relocation |
7751 |
} |
(output_bfd, info, rel, NULL, |
7752 |
|
bfd_abs_section_ptr, |
7753 |
|
0, &addend, sgot))) |
7754 |
|
return FALSE; |
7755 |
|
BFD_ASSERT (addend == 0); |
7756 |
|
} |
7757 |
|
} |
7758 |
|
} |
7759 |
|
|
7760 |
|
/* The generation of dynamic relocations for the non-primary gots |
7761 |
|
adds more dynamic relocations. We cannot count them until |
7762 |
|
here. */ |
7763 |
|
|
7764 |
|
if (elf_hash_table (info)->dynamic_sections_created) |
7765 |
|
{ |
7766 |
|
bfd_byte *b; |
7767 |
|
bfd_boolean swap_out_p; |
7768 |
|
|
7769 |
|
BFD_ASSERT (sdyn != NULL); |
7770 |
|
|
7771 |
|
for (b = sdyn->contents; |
7772 |
|
b < sdyn->contents + sdyn->size; |
7773 |
|
b += MIPS_ELF_DYN_SIZE (dynobj)) |
7774 |
|
{ |
7775 |
|
Elf_Internal_Dyn dyn; |
7776 |
|
asection *s; |
7777 |
|
|
7778 |
|
/* Read in the current dynamic entry. */ |
7779 |
|
(*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn); |
7780 |
|
|
7781 |
|
/* Assume that we're going to modify it and write it out. */ |
7782 |
|
swap_out_p = TRUE; |
7783 |
|
|
7784 |
|
switch (dyn.d_tag) |
7785 |
|
{ |
7786 |
|
case DT_RELSZ: |
7787 |
|
/* Reduce DT_RELSZ to account for any relocations we |
7788 |
|
decided not to make. This is for the n64 irix rld, |
7789 |
|
which doesn't seem to apply any relocations if there |
7790 |
|
are trailing null entries. */ |
7791 |
|
s = mips_elf_rel_dyn_section (dynobj, FALSE); |
7792 |
|
dyn.d_un.d_val = (s->reloc_count |
7793 |
|
* (ABI_64_P (output_bfd) |
7794 |
|
? sizeof (Elf64_Mips_External_Rel) |
7795 |
|
: sizeof (Elf32_External_Rel))); |
7796 |
|
break; |
7797 |
|
|
7798 |
|
default: |
7799 |
|
swap_out_p = FALSE; |
7800 |
|
break; |
7801 |
|
} |
7802 |
|
|
7803 |
|
if (swap_out_p) |
7804 |
|
(*get_elf_backend_data (dynobj)->s->swap_dyn_out) |
7805 |
|
(dynobj, &dyn, b); |
7806 |
|
} |
7807 |
|
} |
7808 |
|
|
7809 |
|
{ |
7810 |
|
asection *s; |
7811 |
|
Elf32_compact_rel cpt; |
7812 |
|
|
7813 |
if (SGI_COMPAT (output_bfd)) |
if (SGI_COMPAT (output_bfd)) |
7814 |
{ |
{ |
7834 |
{ |
{ |
7835 |
file_ptr dummy_offset; |
file_ptr dummy_offset; |
7836 |
|
|
7837 |
BFD_ASSERT (s->_raw_size >= MIPS_FUNCTION_STUB_SIZE); |
BFD_ASSERT (s->size >= MIPS_FUNCTION_STUB_SIZE); |
7838 |
dummy_offset = s->_raw_size - MIPS_FUNCTION_STUB_SIZE; |
dummy_offset = s->size - MIPS_FUNCTION_STUB_SIZE; |
7839 |
memset (s->contents + dummy_offset, 0, |
memset (s->contents + dummy_offset, 0, |
7840 |
MIPS_FUNCTION_STUB_SIZE); |
MIPS_FUNCTION_STUB_SIZE); |
7841 |
} |
} |
7844 |
|
|
7845 |
/* We need to sort the entries of the dynamic relocation section. */ |
/* We need to sort the entries of the dynamic relocation section. */ |
7846 |
|
|
7847 |
if (!ABI_64_P (output_bfd)) |
s = mips_elf_rel_dyn_section (dynobj, FALSE); |
7848 |
|
|
7849 |
|
if (s != NULL |
7850 |
|
&& s->size > (bfd_vma)2 * MIPS_ELF_REL_SIZE (output_bfd)) |
7851 |
{ |
{ |
7852 |
asection *reldyn; |
reldyn_sorting_bfd = output_bfd; |
7853 |
|
|
7854 |
reldyn = bfd_get_section_by_name (dynobj, ".rel.dyn"); |
if (ABI_64_P (output_bfd)) |
7855 |
if (reldyn != NULL && reldyn->reloc_count > 2) |
qsort ((Elf64_External_Rel *) s->contents + 1, s->reloc_count - 1, |
7856 |
{ |
sizeof (Elf64_Mips_External_Rel), sort_dynamic_relocs_64); |
7857 |
reldyn_sorting_bfd = output_bfd; |
else |
7858 |
qsort ((Elf32_External_Rel *) reldyn->contents + 1, |
qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1, |
7859 |
(size_t) reldyn->reloc_count - 1, |
sizeof (Elf32_External_Rel), sort_dynamic_relocs); |
|
sizeof (Elf32_External_Rel), sort_dynamic_relocs); |
|
|
} |
|
7860 |
} |
} |
|
|
|
|
/* Clean up a first relocation in .rel.dyn. */ |
|
|
s = bfd_get_section_by_name (dynobj, ".rel.dyn"); |
|
|
if (s != NULL && s->_raw_size > 0) |
|
|
memset (s->contents, 0, MIPS_ELF_REL_SIZE (dynobj)); |
|
7861 |
} |
} |
7862 |
|
|
7863 |
return true; |
return TRUE; |
7864 |
} |
} |
7865 |
|
|
|
/* The final processing done just before writing out a MIPS ELF object |
|
|
file. This gets the MIPS architecture right based on the machine |
|
|
number. This is used by both the 32-bit and the 64-bit ABI. */ |
|
7866 |
|
|
7867 |
void |
/* Set ABFD's EF_MIPS_ARCH and EF_MIPS_MACH flags. */ |
7868 |
_bfd_mips_elf_final_write_processing (abfd, linker) |
|
7869 |
bfd *abfd; |
static void |
7870 |
boolean linker ATTRIBUTE_UNUSED; |
mips_set_isa_flags (bfd *abfd) |
7871 |
{ |
{ |
7872 |
unsigned long val; |
flagword val; |
|
unsigned int i; |
|
|
Elf_Internal_Shdr **hdrpp; |
|
|
const char *name; |
|
|
asection *sec; |
|
7873 |
|
|
7874 |
switch (bfd_get_mach (abfd)) |
switch (bfd_get_mach (abfd)) |
7875 |
{ |
{ |
7905 |
val = E_MIPS_ARCH_3 | E_MIPS_MACH_4111; |
val = E_MIPS_ARCH_3 | E_MIPS_MACH_4111; |
7906 |
break; |
break; |
7907 |
|
|
7908 |
|
case bfd_mach_mips4120: |
7909 |
|
val = E_MIPS_ARCH_3 | E_MIPS_MACH_4120; |
7910 |
|
break; |
7911 |
|
|
7912 |
case bfd_mach_mips4650: |
case bfd_mach_mips4650: |
7913 |
val = E_MIPS_ARCH_3 | E_MIPS_MACH_4650; |
val = E_MIPS_ARCH_3 | E_MIPS_MACH_4650; |
7914 |
break; |
break; |
7915 |
|
|
7916 |
|
case bfd_mach_mips5400: |
7917 |
|
val = E_MIPS_ARCH_4 | E_MIPS_MACH_5400; |
7918 |
|
break; |
7919 |
|
|
7920 |
|
case bfd_mach_mips5500: |
7921 |
|
val = E_MIPS_ARCH_4 | E_MIPS_MACH_5500; |
7922 |
|
break; |
7923 |
|
|
7924 |
|
case bfd_mach_mips9000: |
7925 |
|
val = E_MIPS_ARCH_4 | E_MIPS_MACH_9000; |
7926 |
|
break; |
7927 |
|
|
7928 |
case bfd_mach_mips5000: |
case bfd_mach_mips5000: |
7929 |
|
case bfd_mach_mips7000: |
7930 |
case bfd_mach_mips8000: |
case bfd_mach_mips8000: |
7931 |
case bfd_mach_mips10000: |
case bfd_mach_mips10000: |
7932 |
case bfd_mach_mips12000: |
case bfd_mach_mips12000: |
7947 |
|
|
7948 |
case bfd_mach_mipsisa64: |
case bfd_mach_mipsisa64: |
7949 |
val = E_MIPS_ARCH_64; |
val = E_MIPS_ARCH_64; |
7950 |
} |
break; |
7951 |
|
|
7952 |
|
case bfd_mach_mipsisa32r2: |
7953 |
|
val = E_MIPS_ARCH_32R2; |
7954 |
|
break; |
7955 |
|
|
7956 |
|
case bfd_mach_mipsisa64r2: |
7957 |
|
val = E_MIPS_ARCH_64R2; |
7958 |
|
break; |
7959 |
|
} |
7960 |
elf_elfheader (abfd)->e_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH); |
elf_elfheader (abfd)->e_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH); |
7961 |
elf_elfheader (abfd)->e_flags |= val; |
elf_elfheader (abfd)->e_flags |= val; |
7962 |
|
|
7963 |
|
} |
7964 |
|
|
7965 |
|
|
7966 |
|
/* The final processing done just before writing out a MIPS ELF object |
7967 |
|
file. This gets the MIPS architecture right based on the machine |
7968 |
|
number. This is used by both the 32-bit and the 64-bit ABI. */ |
7969 |
|
|
7970 |
|
void |
7971 |
|
_bfd_mips_elf_final_write_processing (bfd *abfd, |
7972 |
|
bfd_boolean linker ATTRIBUTE_UNUSED) |
7973 |
|
{ |
7974 |
|
unsigned int i; |
7975 |
|
Elf_Internal_Shdr **hdrpp; |
7976 |
|
const char *name; |
7977 |
|
asection *sec; |
7978 |
|
|
7979 |
|
/* Keep the existing EF_MIPS_MACH and EF_MIPS_ARCH flags if the former |
7980 |
|
is nonzero. This is for compatibility with old objects, which used |
7981 |
|
a combination of a 32-bit EF_MIPS_ARCH and a 64-bit EF_MIPS_MACH. */ |
7982 |
|
if ((elf_elfheader (abfd)->e_flags & EF_MIPS_MACH) == 0) |
7983 |
|
mips_set_isa_flags (abfd); |
7984 |
|
|
7985 |
/* Set the sh_info field for .gptab sections and other appropriate |
/* Set the sh_info field for .gptab sections and other appropriate |
7986 |
info for each special section. */ |
info for each special section. */ |
7987 |
for (i = 1, hdrpp = elf_elfsections (abfd) + 1; |
for (i = 1, hdrpp = elf_elfsections (abfd) + 1; |
8055 |
segments. */ |
segments. */ |
8056 |
|
|
8057 |
int |
int |
8058 |
_bfd_mips_elf_additional_program_headers (abfd) |
_bfd_mips_elf_additional_program_headers (bfd *abfd) |
|
bfd *abfd; |
|
8059 |
{ |
{ |
8060 |
asection *s; |
asection *s; |
8061 |
int ret = 0; |
int ret = 0; |
8082 |
|
|
8083 |
/* Modify the segment map for an IRIX5 executable. */ |
/* Modify the segment map for an IRIX5 executable. */ |
8084 |
|
|
8085 |
boolean |
bfd_boolean |
8086 |
_bfd_mips_elf_modify_segment_map (abfd) |
_bfd_mips_elf_modify_segment_map (bfd *abfd, |
8087 |
bfd *abfd; |
struct bfd_link_info *info ATTRIBUTE_UNUSED) |
8088 |
{ |
{ |
8089 |
asection *s; |
asection *s; |
8090 |
struct elf_segment_map *m, **pm; |
struct elf_segment_map *m, **pm; |
8101 |
if (m == NULL) |
if (m == NULL) |
8102 |
{ |
{ |
8103 |
amt = sizeof *m; |
amt = sizeof *m; |
8104 |
m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); |
m = bfd_zalloc (abfd, amt); |
8105 |
if (m == NULL) |
if (m == NULL) |
8106 |
return false; |
return FALSE; |
8107 |
|
|
8108 |
m->p_type = PT_MIPS_REGINFO; |
m->p_type = PT_MIPS_REGINFO; |
8109 |
m->count = 1; |
m->count = 1; |
8123 |
|
|
8124 |
/* For IRIX 6, we don't have .mdebug sections, nor does anything but |
/* For IRIX 6, we don't have .mdebug sections, nor does anything but |
8125 |
.dynamic end up in PT_DYNAMIC. However, we do have to insert a |
.dynamic end up in PT_DYNAMIC. However, we do have to insert a |
8126 |
PT_OPTIONS segement immediately following the program header |
PT_MIPS_OPTIONS segment immediately following the program header |
8127 |
table. */ |
table. */ |
8128 |
if (ABI_64_P (abfd)) |
if (NEWABI_P (abfd) |
8129 |
|
/* On non-IRIX6 new abi, we'll have already created a segment |
8130 |
|
for this section, so don't create another. I'm not sure this |
8131 |
|
is not also the case for IRIX 6, but I can't test it right |
8132 |
|
now. */ |
8133 |
|
&& IRIX_COMPAT (abfd) == ict_irix6) |
8134 |
{ |
{ |
8135 |
for (s = abfd->sections; s; s = s->next) |
for (s = abfd->sections; s; s = s->next) |
8136 |
if (elf_section_data (s)->this_hdr.sh_type == SHT_MIPS_OPTIONS) |
if (elf_section_data (s)->this_hdr.sh_type == SHT_MIPS_OPTIONS) |
8140 |
{ |
{ |
8141 |
struct elf_segment_map *options_segment; |
struct elf_segment_map *options_segment; |
8142 |
|
|
8143 |
/* Usually, there's a program header table. But, sometimes |
pm = &elf_tdata (abfd)->segment_map; |
8144 |
there's not (like when running the `ld' testsuite). So, |
while (*pm != NULL |
8145 |
if there's no program header table, we just put the |
&& ((*pm)->p_type == PT_PHDR |
8146 |
options segement at the end. */ |
|| (*pm)->p_type == PT_INTERP)) |
8147 |
for (pm = &elf_tdata (abfd)->segment_map; |
pm = &(*pm)->next; |
|
*pm != NULL; |
|
|
pm = &(*pm)->next) |
|
|
if ((*pm)->p_type == PT_PHDR) |
|
|
break; |
|
8148 |
|
|
8149 |
amt = sizeof (struct elf_segment_map); |
amt = sizeof (struct elf_segment_map); |
8150 |
options_segment = bfd_zalloc (abfd, amt); |
options_segment = bfd_zalloc (abfd, amt); |
8151 |
options_segment->next = *pm; |
options_segment->next = *pm; |
8152 |
options_segment->p_type = PT_MIPS_OPTIONS; |
options_segment->p_type = PT_MIPS_OPTIONS; |
8153 |
options_segment->p_flags = PF_R; |
options_segment->p_flags = PF_R; |
8154 |
options_segment->p_flags_valid = true; |
options_segment->p_flags_valid = TRUE; |
8155 |
options_segment->count = 1; |
options_segment->count = 1; |
8156 |
options_segment->sections[0] = s; |
options_segment->sections[0] = s; |
8157 |
*pm = options_segment; |
*pm = options_segment; |
8173 |
if (m == NULL) |
if (m == NULL) |
8174 |
{ |
{ |
8175 |
amt = sizeof *m; |
amt = sizeof *m; |
8176 |
m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); |
m = bfd_zalloc (abfd, amt); |
8177 |
if (m == NULL) |
if (m == NULL) |
8178 |
return false; |
return FALSE; |
8179 |
|
|
8180 |
m->p_type = PT_MIPS_RTPROC; |
m->p_type = PT_MIPS_RTPROC; |
8181 |
|
|
8235 |
unsigned int i, c; |
unsigned int i, c; |
8236 |
struct elf_segment_map *n; |
struct elf_segment_map *n; |
8237 |
|
|
8238 |
low = 0xffffffff; |
low = ~(bfd_vma) 0; |
8239 |
high = 0; |
high = 0; |
8240 |
for (i = 0; i < sizeof sec_names / sizeof sec_names[0]; i++) |
for (i = 0; i < sizeof sec_names / sizeof sec_names[0]; i++) |
8241 |
{ |
{ |
8246 |
|
|
8247 |
if (low > s->vma) |
if (low > s->vma) |
8248 |
low = s->vma; |
low = s->vma; |
8249 |
sz = s->_cooked_size; |
sz = s->size; |
|
if (sz == 0) |
|
|
sz = s->_raw_size; |
|
8250 |
if (high < s->vma + sz) |
if (high < s->vma + sz) |
8251 |
high = s->vma + sz; |
high = s->vma + sz; |
8252 |
} |
} |
8256 |
for (s = abfd->sections; s != NULL; s = s->next) |
for (s = abfd->sections; s != NULL; s = s->next) |
8257 |
if ((s->flags & SEC_LOAD) != 0 |
if ((s->flags & SEC_LOAD) != 0 |
8258 |
&& s->vma >= low |
&& s->vma >= low |
8259 |
&& ((s->vma |
&& s->vma + s->size <= high) |
|
+ (s->_cooked_size != |
|
|
0 ? s->_cooked_size : s->_raw_size)) <= high)) |
|
8260 |
++c; |
++c; |
8261 |
|
|
8262 |
amt = sizeof *n + (bfd_size_type) (c - 1) * sizeof (asection *); |
amt = sizeof *n + (bfd_size_type) (c - 1) * sizeof (asection *); |
8263 |
n = (struct elf_segment_map *) bfd_zalloc (abfd, amt); |
n = bfd_zalloc (abfd, amt); |
8264 |
if (n == NULL) |
if (n == NULL) |
8265 |
return false; |
return FALSE; |
8266 |
*n = *m; |
*n = *m; |
8267 |
n->count = c; |
n->count = c; |
8268 |
|
|
8271 |
{ |
{ |
8272 |
if ((s->flags & SEC_LOAD) != 0 |
if ((s->flags & SEC_LOAD) != 0 |
8273 |
&& s->vma >= low |
&& s->vma >= low |
8274 |
&& ((s->vma |
&& s->vma + s->size <= high) |
|
+ (s->_cooked_size != 0 ? |
|
|
s->_cooked_size : s->_raw_size)) <= high)) |
|
8275 |
{ |
{ |
8276 |
n->sections[i] = s; |
n->sections[i] = s; |
8277 |
++i; |
++i; |
8282 |
} |
} |
8283 |
} |
} |
8284 |
|
|
8285 |
return true; |
return TRUE; |
8286 |
} |
} |
8287 |
|
|
8288 |
/* Return the section that should be marked against GC for a given |
/* Return the section that should be marked against GC for a given |
8289 |
relocation. */ |
relocation. */ |
8290 |
|
|
8291 |
asection * |
asection * |
8292 |
_bfd_mips_elf_gc_mark_hook (sec, info, rel, h, sym) |
_bfd_mips_elf_gc_mark_hook (asection *sec, |
8293 |
asection *sec; |
struct bfd_link_info *info ATTRIBUTE_UNUSED, |
8294 |
struct bfd_link_info *info ATTRIBUTE_UNUSED; |
Elf_Internal_Rela *rel, |
8295 |
Elf_Internal_Rela *rel; |
struct elf_link_hash_entry *h, |
8296 |
struct elf_link_hash_entry *h; |
Elf_Internal_Sym *sym) |
|
Elf_Internal_Sym *sym; |
|
8297 |
{ |
{ |
8298 |
/* ??? Do mips16 stub sections need to be handled special? */ |
/* ??? Do mips16 stub sections need to be handled special? */ |
8299 |
|
|
8328 |
|
|
8329 |
/* Update the got entry reference counts for the section being removed. */ |
/* Update the got entry reference counts for the section being removed. */ |
8330 |
|
|
8331 |
boolean |
bfd_boolean |
8332 |
_bfd_mips_elf_gc_sweep_hook (abfd, info, sec, relocs) |
_bfd_mips_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, |
8333 |
bfd *abfd ATTRIBUTE_UNUSED; |
struct bfd_link_info *info ATTRIBUTE_UNUSED, |
8334 |
struct bfd_link_info *info ATTRIBUTE_UNUSED; |
asection *sec ATTRIBUTE_UNUSED, |
8335 |
asection *sec ATTRIBUTE_UNUSED; |
const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED) |
|
const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED; |
|
8336 |
{ |
{ |
8337 |
#if 0 |
#if 0 |
8338 |
Elf_Internal_Shdr *symtab_hdr; |
Elf_Internal_Shdr *symtab_hdr; |
8369 |
} |
} |
8370 |
#endif |
#endif |
8371 |
|
|
8372 |
return true; |
return TRUE; |
8373 |
} |
} |
8374 |
|
|
8375 |
/* Copy data from a MIPS ELF indirect symbol to its direct symbol, |
/* Copy data from a MIPS ELF indirect symbol to its direct symbol, |
8378 |
_bfd_elf_link_hash_copy_indirect copy the flags for us. */ |
_bfd_elf_link_hash_copy_indirect copy the flags for us. */ |
8379 |
|
|
8380 |
void |
void |
8381 |
_bfd_mips_elf_copy_indirect_symbol (dir, ind) |
_bfd_mips_elf_copy_indirect_symbol (const struct elf_backend_data *bed, |
8382 |
struct elf_link_hash_entry *dir, *ind; |
struct elf_link_hash_entry *dir, |
8383 |
|
struct elf_link_hash_entry *ind) |
8384 |
{ |
{ |
8385 |
struct mips_elf_link_hash_entry *dirmips, *indmips; |
struct mips_elf_link_hash_entry *dirmips, *indmips; |
8386 |
|
|
8387 |
_bfd_elf_link_hash_copy_indirect (dir, ind); |
_bfd_elf_link_hash_copy_indirect (bed, dir, ind); |
8388 |
|
|
8389 |
if (ind->root.type != bfd_link_hash_indirect) |
if (ind->root.type != bfd_link_hash_indirect) |
8390 |
return; |
return; |
8393 |
indmips = (struct mips_elf_link_hash_entry *) ind; |
indmips = (struct mips_elf_link_hash_entry *) ind; |
8394 |
dirmips->possibly_dynamic_relocs += indmips->possibly_dynamic_relocs; |
dirmips->possibly_dynamic_relocs += indmips->possibly_dynamic_relocs; |
8395 |
if (indmips->readonly_reloc) |
if (indmips->readonly_reloc) |
8396 |
dirmips->readonly_reloc = true; |
dirmips->readonly_reloc = TRUE; |
|
if (dirmips->min_dyn_reloc_index == 0 |
|
|
|| (indmips->min_dyn_reloc_index != 0 |
|
|
&& indmips->min_dyn_reloc_index < dirmips->min_dyn_reloc_index)) |
|
|
dirmips->min_dyn_reloc_index = indmips->min_dyn_reloc_index; |
|
8397 |
if (indmips->no_fn_stub) |
if (indmips->no_fn_stub) |
8398 |
dirmips->no_fn_stub = true; |
dirmips->no_fn_stub = TRUE; |
8399 |
|
|
8400 |
|
if (dirmips->tls_type == 0) |
8401 |
|
dirmips->tls_type = indmips->tls_type; |
8402 |
|
else |
8403 |
|
BFD_ASSERT (indmips->tls_type == 0); |
8404 |
} |
} |
8405 |
|
|
8406 |
void |
void |
8407 |
_bfd_mips_elf_hide_symbol (info, entry, force_local) |
_bfd_mips_elf_hide_symbol (struct bfd_link_info *info, |
8408 |
struct bfd_link_info *info; |
struct elf_link_hash_entry *entry, |
8409 |
struct elf_link_hash_entry *entry; |
bfd_boolean force_local) |
|
boolean force_local; |
|
8410 |
{ |
{ |
8411 |
bfd *dynobj; |
bfd *dynobj; |
8412 |
asection *got; |
asection *got; |
8416 |
h = (struct mips_elf_link_hash_entry *) entry; |
h = (struct mips_elf_link_hash_entry *) entry; |
8417 |
if (h->forced_local) |
if (h->forced_local) |
8418 |
return; |
return; |
8419 |
h->forced_local = true; |
h->forced_local = force_local; |
8420 |
|
|
8421 |
dynobj = elf_hash_table (info)->dynobj; |
dynobj = elf_hash_table (info)->dynobj; |
8422 |
got = bfd_get_section_by_name (dynobj, ".got"); |
if (dynobj != NULL && force_local && h->root.type != STT_TLS) |
8423 |
g = (struct mips_got_info *) elf_section_data (got)->tdata; |
{ |
8424 |
|
got = mips_elf_got_section (dynobj, FALSE); |
8425 |
|
g = mips_elf_section_data (got)->u.got_info; |
8426 |
|
|
8427 |
_bfd_elf_link_hash_hide_symbol (info, &h->root, force_local); |
if (g->next) |
8428 |
|
{ |
8429 |
|
struct mips_got_entry e; |
8430 |
|
struct mips_got_info *gg = g; |
8431 |
|
|
8432 |
|
/* Since we're turning what used to be a global symbol into a |
8433 |
|
local one, bump up the number of local entries of each GOT |
8434 |
|
that had an entry for it. This will automatically decrease |
8435 |
|
the number of global entries, since global_gotno is actually |
8436 |
|
the upper limit of global entries. */ |
8437 |
|
e.abfd = dynobj; |
8438 |
|
e.symndx = -1; |
8439 |
|
e.d.h = h; |
8440 |
|
e.tls_type = 0; |
8441 |
|
|
8442 |
|
for (g = g->next; g != gg; g = g->next) |
8443 |
|
if (htab_find (g->got_entries, &e)) |
8444 |
|
{ |
8445 |
|
BFD_ASSERT (g->global_gotno > 0); |
8446 |
|
g->local_gotno++; |
8447 |
|
g->global_gotno--; |
8448 |
|
} |
8449 |
|
|
8450 |
/* FIXME: Do we allocate too much GOT space here? */ |
/* If this was a global symbol forced into the primary GOT, we |
8451 |
g->local_gotno++; |
no longer need an entry for it. We can't release the entry |
8452 |
got->_raw_size += MIPS_ELF_GOT_SIZE (dynobj); |
at this point, but we must at least stop counting it as one |
8453 |
|
of the symbols that required a forced got entry. */ |
8454 |
|
if (h->root.got.offset == 2) |
8455 |
|
{ |
8456 |
|
BFD_ASSERT (gg->assigned_gotno > 0); |
8457 |
|
gg->assigned_gotno--; |
8458 |
|
} |
8459 |
|
} |
8460 |
|
else if (g->global_gotno == 0 && g->global_gotsym == NULL) |
8461 |
|
/* If we haven't got through GOT allocation yet, just bump up the |
8462 |
|
number of local entries, as this symbol won't be counted as |
8463 |
|
global. */ |
8464 |
|
g->local_gotno++; |
8465 |
|
else if (h->root.got.offset == 1) |
8466 |
|
{ |
8467 |
|
/* If we're past non-multi-GOT allocation and this symbol had |
8468 |
|
been marked for a global got entry, give it a local entry |
8469 |
|
instead. */ |
8470 |
|
BFD_ASSERT (g->global_gotno > 0); |
8471 |
|
g->local_gotno++; |
8472 |
|
g->global_gotno--; |
8473 |
|
} |
8474 |
|
} |
8475 |
|
|
8476 |
|
_bfd_elf_link_hash_hide_symbol (info, &h->root, force_local); |
8477 |
} |
} |
8478 |
|
|
8479 |
boolean |
#define PDR_SIZE 32 |
8480 |
_bfd_mips_elf_ignore_discarded_relocs (sec) |
|
8481 |
asection *sec; |
bfd_boolean |
8482 |
|
_bfd_mips_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie, |
8483 |
|
struct bfd_link_info *info) |
8484 |
|
{ |
8485 |
|
asection *o; |
8486 |
|
bfd_boolean ret = FALSE; |
8487 |
|
unsigned char *tdata; |
8488 |
|
size_t i, skip; |
8489 |
|
|
8490 |
|
o = bfd_get_section_by_name (abfd, ".pdr"); |
8491 |
|
if (! o) |
8492 |
|
return FALSE; |
8493 |
|
if (o->size == 0) |
8494 |
|
return FALSE; |
8495 |
|
if (o->size % PDR_SIZE != 0) |
8496 |
|
return FALSE; |
8497 |
|
if (o->output_section != NULL |
8498 |
|
&& bfd_is_abs_section (o->output_section)) |
8499 |
|
return FALSE; |
8500 |
|
|
8501 |
|
tdata = bfd_zmalloc (o->size / PDR_SIZE); |
8502 |
|
if (! tdata) |
8503 |
|
return FALSE; |
8504 |
|
|
8505 |
|
cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, |
8506 |
|
info->keep_memory); |
8507 |
|
if (!cookie->rels) |
8508 |
|
{ |
8509 |
|
free (tdata); |
8510 |
|
return FALSE; |
8511 |
|
} |
8512 |
|
|
8513 |
|
cookie->rel = cookie->rels; |
8514 |
|
cookie->relend = cookie->rels + o->reloc_count; |
8515 |
|
|
8516 |
|
for (i = 0, skip = 0; i < o->size / PDR_SIZE; i ++) |
8517 |
|
{ |
8518 |
|
if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie)) |
8519 |
|
{ |
8520 |
|
tdata[i] = 1; |
8521 |
|
skip ++; |
8522 |
|
} |
8523 |
|
} |
8524 |
|
|
8525 |
|
if (skip != 0) |
8526 |
|
{ |
8527 |
|
mips_elf_section_data (o)->u.tdata = tdata; |
8528 |
|
o->size -= skip * PDR_SIZE; |
8529 |
|
ret = TRUE; |
8530 |
|
} |
8531 |
|
else |
8532 |
|
free (tdata); |
8533 |
|
|
8534 |
|
if (! info->keep_memory) |
8535 |
|
free (cookie->rels); |
8536 |
|
|
8537 |
|
return ret; |
8538 |
|
} |
8539 |
|
|
8540 |
|
bfd_boolean |
8541 |
|
_bfd_mips_elf_ignore_discarded_relocs (asection *sec) |
8542 |
{ |
{ |
8543 |
if (strcmp (sec->name, ".pdr") == 0) |
if (strcmp (sec->name, ".pdr") == 0) |
8544 |
return true; |
return TRUE; |
8545 |
return false; |
return FALSE; |
8546 |
|
} |
8547 |
|
|
8548 |
|
bfd_boolean |
8549 |
|
_bfd_mips_elf_write_section (bfd *output_bfd, asection *sec, |
8550 |
|
bfd_byte *contents) |
8551 |
|
{ |
8552 |
|
bfd_byte *to, *from, *end; |
8553 |
|
int i; |
8554 |
|
|
8555 |
|
if (strcmp (sec->name, ".pdr") != 0) |
8556 |
|
return FALSE; |
8557 |
|
|
8558 |
|
if (mips_elf_section_data (sec)->u.tdata == NULL) |
8559 |
|
return FALSE; |
8560 |
|
|
8561 |
|
to = contents; |
8562 |
|
end = contents + sec->size; |
8563 |
|
for (from = contents, i = 0; |
8564 |
|
from < end; |
8565 |
|
from += PDR_SIZE, i++) |
8566 |
|
{ |
8567 |
|
if ((mips_elf_section_data (sec)->u.tdata)[i] == 1) |
8568 |
|
continue; |
8569 |
|
if (to != from) |
8570 |
|
memcpy (to, from, PDR_SIZE); |
8571 |
|
to += PDR_SIZE; |
8572 |
|
} |
8573 |
|
bfd_set_section_contents (output_bfd, sec->output_section, contents, |
8574 |
|
sec->output_offset, sec->size); |
8575 |
|
return TRUE; |
8576 |
} |
} |
8577 |
|
|
8578 |
/* MIPS ELF uses a special find_nearest_line routine in order the |
/* MIPS ELF uses a special find_nearest_line routine in order the |
8584 |
struct ecoff_find_line i; |
struct ecoff_find_line i; |
8585 |
}; |
}; |
8586 |
|
|
8587 |
boolean |
bfd_boolean |
8588 |
_bfd_mips_elf_find_nearest_line (abfd, section, symbols, offset, filename_ptr, |
_bfd_mips_elf_find_nearest_line (bfd *abfd, asection *section, |
8589 |
functionname_ptr, line_ptr) |
asymbol **symbols, bfd_vma offset, |
8590 |
bfd *abfd; |
const char **filename_ptr, |
8591 |
asection *section; |
const char **functionname_ptr, |
8592 |
asymbol **symbols; |
unsigned int *line_ptr) |
|
bfd_vma offset; |
|
|
const char **filename_ptr; |
|
|
const char **functionname_ptr; |
|
|
unsigned int *line_ptr; |
|
8593 |
{ |
{ |
8594 |
asection *msec; |
asection *msec; |
8595 |
|
|
8596 |
if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset, |
if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset, |
8597 |
filename_ptr, functionname_ptr, |
filename_ptr, functionname_ptr, |
8598 |
line_ptr)) |
line_ptr)) |
8599 |
return true; |
return TRUE; |
8600 |
|
|
8601 |
if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, |
if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, |
8602 |
filename_ptr, functionname_ptr, |
filename_ptr, functionname_ptr, |
8603 |
line_ptr, |
line_ptr, ABI_64_P (abfd) ? 8 : 0, |
|
(unsigned) (ABI_64_P (abfd) ? 8 : 0), |
|
8604 |
&elf_tdata (abfd)->dwarf2_find_line_info)) |
&elf_tdata (abfd)->dwarf2_find_line_info)) |
8605 |
return true; |
return TRUE; |
8606 |
|
|
8607 |
msec = bfd_get_section_by_name (abfd, ".mdebug"); |
msec = bfd_get_section_by_name (abfd, ".mdebug"); |
8608 |
if (msec != NULL) |
if (msec != NULL) |
8628 |
struct fdr *fdr_ptr; |
struct fdr *fdr_ptr; |
8629 |
bfd_size_type amt = sizeof (struct mips_elf_find_line); |
bfd_size_type amt = sizeof (struct mips_elf_find_line); |
8630 |
|
|
8631 |
fi = (struct mips_elf_find_line *) bfd_zalloc (abfd, amt); |
fi = bfd_zalloc (abfd, amt); |
8632 |
if (fi == NULL) |
if (fi == NULL) |
8633 |
{ |
{ |
8634 |
msec->flags = origflags; |
msec->flags = origflags; |
8635 |
return false; |
return FALSE; |
8636 |
} |
} |
8637 |
|
|
8638 |
if (! _bfd_mips_elf_read_ecoff_info (abfd, msec, &fi->d)) |
if (! _bfd_mips_elf_read_ecoff_info (abfd, msec, &fi->d)) |
8639 |
{ |
{ |
8640 |
msec->flags = origflags; |
msec->flags = origflags; |
8641 |
return false; |
return FALSE; |
8642 |
} |
} |
8643 |
|
|
8644 |
/* Swap in the FDR information. */ |
/* Swap in the FDR information. */ |
8645 |
amt = fi->d.symbolic_header.ifdMax * sizeof (struct fdr); |
amt = fi->d.symbolic_header.ifdMax * sizeof (struct fdr); |
8646 |
fi->d.fdr = (struct fdr *) bfd_alloc (abfd, amt); |
fi->d.fdr = bfd_alloc (abfd, amt); |
8647 |
if (fi->d.fdr == NULL) |
if (fi->d.fdr == NULL) |
8648 |
{ |
{ |
8649 |
msec->flags = origflags; |
msec->flags = origflags; |
8650 |
return false; |
return FALSE; |
8651 |
} |
} |
8652 |
external_fdr_size = swap->external_fdr_size; |
external_fdr_size = swap->external_fdr_size; |
8653 |
fdr_ptr = fi->d.fdr; |
fdr_ptr = fi->d.fdr; |
8655 |
fraw_end = (fraw_src |
fraw_end = (fraw_src |
8656 |
+ fi->d.symbolic_header.ifdMax * external_fdr_size); |
+ fi->d.symbolic_header.ifdMax * external_fdr_size); |
8657 |
for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++) |
for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++) |
8658 |
(*swap->swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr); |
(*swap->swap_fdr_in) (abfd, fraw_src, fdr_ptr); |
8659 |
|
|
8660 |
elf_tdata (abfd)->find_line_info = fi; |
elf_tdata (abfd)->find_line_info = fi; |
8661 |
|
|
8672 |
line_ptr)) |
line_ptr)) |
8673 |
{ |
{ |
8674 |
msec->flags = origflags; |
msec->flags = origflags; |
8675 |
return true; |
return TRUE; |
8676 |
} |
} |
8677 |
|
|
8678 |
msec->flags = origflags; |
msec->flags = origflags; |
8689 |
remember the bytes we are writing out, so that we can install the |
remember the bytes we are writing out, so that we can install the |
8690 |
GP value in the section_processing routine. */ |
GP value in the section_processing routine. */ |
8691 |
|
|
8692 |
boolean |
bfd_boolean |
8693 |
_bfd_mips_elf_set_section_contents (abfd, section, location, offset, count) |
_bfd_mips_elf_set_section_contents (bfd *abfd, sec_ptr section, |
8694 |
bfd *abfd; |
const void *location, |
8695 |
sec_ptr section; |
file_ptr offset, bfd_size_type count) |
|
PTR location; |
|
|
file_ptr offset; |
|
|
bfd_size_type count; |
|
8696 |
{ |
{ |
8697 |
if (strcmp (section->name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0) |
if (MIPS_ELF_OPTIONS_SECTION_NAME_P (section->name)) |
8698 |
{ |
{ |
8699 |
bfd_byte *c; |
bfd_byte *c; |
8700 |
|
|
8701 |
if (elf_section_data (section) == NULL) |
if (elf_section_data (section) == NULL) |
8702 |
{ |
{ |
8703 |
bfd_size_type amt = sizeof (struct bfd_elf_section_data); |
bfd_size_type amt = sizeof (struct bfd_elf_section_data); |
8704 |
section->used_by_bfd = (PTR) bfd_zalloc (abfd, amt); |
section->used_by_bfd = bfd_zalloc (abfd, amt); |
8705 |
if (elf_section_data (section) == NULL) |
if (elf_section_data (section) == NULL) |
8706 |
return false; |
return FALSE; |
8707 |
} |
} |
8708 |
c = (bfd_byte *) elf_section_data (section)->tdata; |
c = mips_elf_section_data (section)->u.tdata; |
8709 |
if (c == NULL) |
if (c == NULL) |
8710 |
{ |
{ |
8711 |
bfd_size_type size; |
c = bfd_zalloc (abfd, section->size); |
|
|
|
|
if (section->_cooked_size != 0) |
|
|
size = section->_cooked_size; |
|
|
else |
|
|
size = section->_raw_size; |
|
|
c = (bfd_byte *) bfd_zalloc (abfd, size); |
|
8712 |
if (c == NULL) |
if (c == NULL) |
8713 |
return false; |
return FALSE; |
8714 |
elf_section_data (section)->tdata = (PTR) c; |
mips_elf_section_data (section)->u.tdata = c; |
8715 |
} |
} |
8716 |
|
|
8717 |
memcpy (c + offset, location, (size_t) count); |
memcpy (c + offset, location, count); |
8718 |
} |
} |
8719 |
|
|
8720 |
return _bfd_elf_set_section_contents (abfd, section, location, offset, |
return _bfd_elf_set_section_contents (abfd, section, location, offset, |
8725 |
MIPS relocations need to be handled specially. Sigh. */ |
MIPS relocations need to be handled specially. Sigh. */ |
8726 |
|
|
8727 |
bfd_byte * |
bfd_byte * |
8728 |
_bfd_elf_mips_get_relocated_section_contents (abfd, link_info, link_order, |
_bfd_elf_mips_get_relocated_section_contents |
8729 |
data, relocateable, symbols) |
(bfd *abfd, |
8730 |
bfd *abfd; |
struct bfd_link_info *link_info, |
8731 |
struct bfd_link_info *link_info; |
struct bfd_link_order *link_order, |
8732 |
struct bfd_link_order *link_order; |
bfd_byte *data, |
8733 |
bfd_byte *data; |
bfd_boolean relocatable, |
8734 |
boolean relocateable; |
asymbol **symbols) |
|
asymbol **symbols; |
|
8735 |
{ |
{ |
8736 |
/* Get enough memory to hold the stuff */ |
/* Get enough memory to hold the stuff */ |
8737 |
bfd *input_bfd = link_order->u.indirect.section->owner; |
bfd *input_bfd = link_order->u.indirect.section->owner; |
8738 |
asection *input_section = link_order->u.indirect.section; |
asection *input_section = link_order->u.indirect.section; |
8739 |
|
bfd_size_type sz; |
8740 |
|
|
8741 |
long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); |
long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); |
8742 |
arelent **reloc_vector = NULL; |
arelent **reloc_vector = NULL; |
8745 |
if (reloc_size < 0) |
if (reloc_size < 0) |
8746 |
goto error_return; |
goto error_return; |
8747 |
|
|
8748 |
reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size); |
reloc_vector = bfd_malloc (reloc_size); |
8749 |
if (reloc_vector == NULL && reloc_size != 0) |
if (reloc_vector == NULL && reloc_size != 0) |
8750 |
goto error_return; |
goto error_return; |
8751 |
|
|
8752 |
/* read in the section */ |
/* read in the section */ |
8753 |
if (!bfd_get_section_contents (input_bfd, |
sz = input_section->rawsize ? input_section->rawsize : input_section->size; |
8754 |
input_section, |
if (!bfd_get_section_contents (input_bfd, input_section, data, 0, sz)) |
|
(PTR) data, |
|
|
(file_ptr) 0, |
|
|
input_section->_raw_size)) |
|
8755 |
goto error_return; |
goto error_return; |
8756 |
|
|
|
/* We're not relaxing the section, so just copy the size info */ |
|
|
input_section->_cooked_size = input_section->_raw_size; |
|
|
input_section->reloc_done = true; |
|
|
|
|
8757 |
reloc_count = bfd_canonicalize_reloc (input_bfd, |
reloc_count = bfd_canonicalize_reloc (input_bfd, |
8758 |
input_section, |
input_section, |
8759 |
reloc_vector, |
reloc_vector, |
8777 |
lh = 0; |
lh = 0; |
8778 |
else |
else |
8779 |
{ |
{ |
8780 |
h = bfd_hash_lookup (&link_info->hash->table, "_gp", false, false); |
h = bfd_hash_lookup (&link_info->hash->table, "_gp", FALSE, FALSE); |
8781 |
lh = (struct bfd_link_hash_entry *) h; |
lh = (struct bfd_link_hash_entry *) h; |
8782 |
} |
} |
8783 |
lookup: |
lookup: |
8809 |
gp_found = 0; |
gp_found = 0; |
8810 |
} |
} |
8811 |
/* end mips */ |
/* end mips */ |
8812 |
for (parent = reloc_vector; *parent != (arelent *) NULL; |
for (parent = reloc_vector; *parent != NULL; parent++) |
|
parent++) |
|
8813 |
{ |
{ |
8814 |
char *error_message = (char *) NULL; |
char *error_message = NULL; |
8815 |
bfd_reloc_status_type r; |
bfd_reloc_status_type r; |
8816 |
|
|
8817 |
/* Specific to MIPS: Deal with relocation types that require |
/* Specific to MIPS: Deal with relocation types that require |
8819 |
asymbol *sym = *(*parent)->sym_ptr_ptr; |
asymbol *sym = *(*parent)->sym_ptr_ptr; |
8820 |
if (bfd_is_abs_section (sym->section) && abfd) |
if (bfd_is_abs_section (sym->section) && abfd) |
8821 |
{ |
{ |
8822 |
/* The special_function wouldn't get called anyways. */ |
/* The special_function wouldn't get called anyway. */ |
8823 |
} |
} |
8824 |
else if (!gp_found) |
else if (!gp_found) |
8825 |
{ |
{ |
8831 |
{ |
{ |
8832 |
/* bypass special_function call */ |
/* bypass special_function call */ |
8833 |
r = _bfd_mips_elf_gprel16_with_gp (input_bfd, sym, *parent, |
r = _bfd_mips_elf_gprel16_with_gp (input_bfd, sym, *parent, |
8834 |
input_section, relocateable, |
input_section, relocatable, |
8835 |
(PTR) data, gp); |
data, gp); |
8836 |
goto skip_bfd_perform_relocation; |
goto skip_bfd_perform_relocation; |
8837 |
} |
} |
8838 |
/* end mips specific stuff */ |
/* end mips specific stuff */ |
8839 |
|
|
8840 |
r = bfd_perform_relocation (input_bfd, |
r = bfd_perform_relocation (input_bfd, *parent, data, input_section, |
8841 |
*parent, |
relocatable ? abfd : NULL, |
|
(PTR) data, |
|
|
input_section, |
|
|
relocateable ? abfd : (bfd *) NULL, |
|
8842 |
&error_message); |
&error_message); |
8843 |
skip_bfd_perform_relocation: |
skip_bfd_perform_relocation: |
8844 |
|
|
8845 |
if (relocateable) |
if (relocatable) |
8846 |
{ |
{ |
8847 |
asection *os = input_section->output_section; |
asection *os = input_section->output_section; |
8848 |
|
|
8859 |
if (!((*link_info->callbacks->undefined_symbol) |
if (!((*link_info->callbacks->undefined_symbol) |
8860 |
(link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), |
(link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), |
8861 |
input_bfd, input_section, (*parent)->address, |
input_bfd, input_section, (*parent)->address, |
8862 |
true))) |
TRUE))) |
8863 |
goto error_return; |
goto error_return; |
8864 |
break; |
break; |
8865 |
case bfd_reloc_dangerous: |
case bfd_reloc_dangerous: |
8866 |
BFD_ASSERT (error_message != (char *) NULL); |
BFD_ASSERT (error_message != NULL); |
8867 |
if (!((*link_info->callbacks->reloc_dangerous) |
if (!((*link_info->callbacks->reloc_dangerous) |
8868 |
(link_info, error_message, input_bfd, input_section, |
(link_info, error_message, input_bfd, input_section, |
8869 |
(*parent)->address))) |
(*parent)->address))) |
8871 |
break; |
break; |
8872 |
case bfd_reloc_overflow: |
case bfd_reloc_overflow: |
8873 |
if (!((*link_info->callbacks->reloc_overflow) |
if (!((*link_info->callbacks->reloc_overflow) |
8874 |
(link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), |
(link_info, NULL, |
8875 |
|
bfd_asymbol_name (*(*parent)->sym_ptr_ptr), |
8876 |
(*parent)->howto->name, (*parent)->addend, |
(*parent)->howto->name, (*parent)->addend, |
8877 |
input_bfd, input_section, (*parent)->address))) |
input_bfd, input_section, (*parent)->address))) |
8878 |
goto error_return; |
goto error_return; |
8899 |
/* Create a MIPS ELF linker hash table. */ |
/* Create a MIPS ELF linker hash table. */ |
8900 |
|
|
8901 |
struct bfd_link_hash_table * |
struct bfd_link_hash_table * |
8902 |
_bfd_mips_elf_link_hash_table_create (abfd) |
_bfd_mips_elf_link_hash_table_create (bfd *abfd) |
|
bfd *abfd; |
|
8903 |
{ |
{ |
8904 |
struct mips_elf_link_hash_table *ret; |
struct mips_elf_link_hash_table *ret; |
8905 |
bfd_size_type amt = sizeof (struct mips_elf_link_hash_table); |
bfd_size_type amt = sizeof (struct mips_elf_link_hash_table); |
8906 |
|
|
8907 |
ret = (struct mips_elf_link_hash_table *) bfd_malloc (amt); |
ret = bfd_malloc (amt); |
8908 |
if (ret == (struct mips_elf_link_hash_table *) NULL) |
if (ret == NULL) |
8909 |
return NULL; |
return NULL; |
8910 |
|
|
8911 |
if (! _bfd_elf_link_hash_table_init (&ret->root, abfd, |
if (! _bfd_elf_link_hash_table_init (&ret->root, abfd, |
8922 |
#endif |
#endif |
8923 |
ret->procedure_count = 0; |
ret->procedure_count = 0; |
8924 |
ret->compact_rel_size = 0; |
ret->compact_rel_size = 0; |
8925 |
ret->use_rld_obj_head = false; |
ret->use_rld_obj_head = FALSE; |
8926 |
ret->rld_value = 0; |
ret->rld_value = 0; |
8927 |
ret->mips16_stubs_seen = false; |
ret->mips16_stubs_seen = FALSE; |
8928 |
|
|
8929 |
return &ret->root.root; |
return &ret->root.root; |
8930 |
} |
} |
8933 |
the .mdebug sections. We need to merge all instances of these |
the .mdebug sections. We need to merge all instances of these |
8934 |
sections together, not write them all out sequentially. */ |
sections together, not write them all out sequentially. */ |
8935 |
|
|
8936 |
boolean |
bfd_boolean |
8937 |
_bfd_mips_elf_final_link (abfd, info) |
_bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info) |
|
bfd *abfd; |
|
|
struct bfd_link_info *info; |
|
8938 |
{ |
{ |
8939 |
asection **secpp; |
asection **secpp; |
8940 |
asection *o; |
asection *o; |
8943 |
asection *rtproc_sec; |
asection *rtproc_sec; |
8944 |
Elf32_RegInfo reginfo; |
Elf32_RegInfo reginfo; |
8945 |
struct ecoff_debug_info debug; |
struct ecoff_debug_info debug; |
8946 |
const struct ecoff_debug_swap *swap |
const struct elf_backend_data *bed = get_elf_backend_data (abfd); |
8947 |
= get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; |
const struct ecoff_debug_swap *swap = bed->elf_backend_ecoff_debug_swap; |
8948 |
HDRR *symhdr = &debug.symbolic_header; |
HDRR *symhdr = &debug.symbolic_header; |
8949 |
PTR mdebug_handle = NULL; |
void *mdebug_handle = NULL; |
8950 |
asection *s; |
asection *s; |
8951 |
EXTR esym; |
EXTR esym; |
8952 |
unsigned int i; |
unsigned int i; |
8963 |
scRData, scSData, scSBss, scBss |
scRData, scSData, scSBss, scBss |
8964 |
}; |
}; |
8965 |
|
|
|
/* If all the things we linked together were PIC, but we're |
|
|
producing an executable (rather than a shared object), then the |
|
|
resulting file is CPIC (i.e., it calls PIC code.) */ |
|
|
if (!info->shared |
|
|
&& !info->relocateable |
|
|
&& elf_elfheader (abfd)->e_flags & EF_MIPS_PIC) |
|
|
{ |
|
|
elf_elfheader (abfd)->e_flags &= ~EF_MIPS_PIC; |
|
|
elf_elfheader (abfd)->e_flags |= EF_MIPS_CPIC; |
|
|
} |
|
|
|
|
8966 |
/* We'd carefully arranged the dynamic symbol indices, and then the |
/* We'd carefully arranged the dynamic symbol indices, and then the |
8967 |
generic size_dynamic_sections renumbered them out from under us. |
generic size_dynamic_sections renumbered them out from under us. |
8968 |
Rather than trying somehow to prevent the renumbering, just do |
Rather than trying somehow to prevent the renumbering, just do |
8972 |
bfd *dynobj; |
bfd *dynobj; |
8973 |
asection *got; |
asection *got; |
8974 |
struct mips_got_info *g; |
struct mips_got_info *g; |
8975 |
|
bfd_size_type dynsecsymcount; |
8976 |
|
|
8977 |
/* When we resort, we must tell mips_elf_sort_hash_table what |
/* When we resort, we must tell mips_elf_sort_hash_table what |
8978 |
the lowest index it may use is. That's the number of section |
the lowest index it may use is. That's the number of section |
8980 |
adds these symbols when building a shared object. Note that |
adds these symbols when building a shared object. Note that |
8981 |
we count the sections after (possibly) removing the .options |
we count the sections after (possibly) removing the .options |
8982 |
section above. */ |
section above. */ |
8983 |
if (! mips_elf_sort_hash_table (info, (info->shared |
|
8984 |
? bfd_count_sections (abfd) + 1 |
dynsecsymcount = 0; |
8985 |
: 1))) |
if (info->shared) |
8986 |
return false; |
{ |
8987 |
|
asection * p; |
8988 |
|
|
8989 |
|
for (p = abfd->sections; p ; p = p->next) |
8990 |
|
if ((p->flags & SEC_EXCLUDE) == 0 |
8991 |
|
&& (p->flags & SEC_ALLOC) != 0 |
8992 |
|
&& !(*bed->elf_backend_omit_section_dynsym) (abfd, info, p)) |
8993 |
|
++ dynsecsymcount; |
8994 |
|
} |
8995 |
|
|
8996 |
|
if (! mips_elf_sort_hash_table (info, dynsecsymcount + 1)) |
8997 |
|
return FALSE; |
8998 |
|
|
8999 |
/* Make sure we didn't grow the global .got region. */ |
/* Make sure we didn't grow the global .got region. */ |
9000 |
dynobj = elf_hash_table (info)->dynobj; |
dynobj = elf_hash_table (info)->dynobj; |
9001 |
got = bfd_get_section_by_name (dynobj, ".got"); |
got = mips_elf_got_section (dynobj, FALSE); |
9002 |
g = (struct mips_got_info *) elf_section_data (got)->tdata; |
g = mips_elf_section_data (got)->u.got_info; |
9003 |
|
|
9004 |
if (g->global_gotsym != NULL) |
if (g->global_gotsym != NULL) |
9005 |
BFD_ASSERT ((elf_hash_table (info)->dynsymcount |
BFD_ASSERT ((elf_hash_table (info)->dynsymcount |
9007 |
<= g->global_gotno); |
<= g->global_gotno); |
9008 |
} |
} |
9009 |
|
|
|
/* On IRIX5, we omit the .options section. On IRIX6, however, we |
|
|
include it, even though we don't process it quite right. (Some |
|
|
entries are supposed to be merged.) Empirically, we seem to be |
|
|
better off including it then not. */ |
|
|
if (IRIX_COMPAT (abfd) == ict_irix5 || IRIX_COMPAT (abfd) == ict_none) |
|
|
for (secpp = &abfd->sections; *secpp != NULL; secpp = &(*secpp)->next) |
|
|
{ |
|
|
if (strcmp ((*secpp)->name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0) |
|
|
{ |
|
|
for (p = (*secpp)->link_order_head; p != NULL; p = p->next) |
|
|
if (p->type == bfd_indirect_link_order) |
|
|
p->u.indirect.section->flags &= ~SEC_HAS_CONTENTS; |
|
|
(*secpp)->link_order_head = NULL; |
|
|
bfd_section_list_remove (abfd, secpp); |
|
|
--abfd->section_count; |
|
|
|
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
/* We include .MIPS.options, even though we don't process it quite right. |
|
|
(Some entries are supposed to be merged.) At IRIX6 empirically we seem |
|
|
to be better off including it than not. */ |
|
|
for (secpp = &abfd->sections; *secpp != NULL; secpp = &(*secpp)->next) |
|
|
{ |
|
|
if (strcmp ((*secpp)->name, ".MIPS.options") == 0) |
|
|
{ |
|
|
for (p = (*secpp)->link_order_head; p != NULL; p = p->next) |
|
|
if (p->type == bfd_indirect_link_order) |
|
|
p->u.indirect.section->flags &=~ SEC_HAS_CONTENTS; |
|
|
(*secpp)->link_order_head = NULL; |
|
|
bfd_section_list_remove (abfd, secpp); |
|
|
--abfd->section_count; |
|
|
|
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
9010 |
/* Get a value for the GP register. */ |
/* Get a value for the GP register. */ |
9011 |
if (elf_gp (abfd) == 0) |
if (elf_gp (abfd) == 0) |
9012 |
{ |
{ |
9013 |
struct bfd_link_hash_entry *h; |
struct bfd_link_hash_entry *h; |
9014 |
|
|
9015 |
h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true); |
h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE); |
9016 |
if (h != (struct bfd_link_hash_entry *) NULL |
if (h != NULL && h->type == bfd_link_hash_defined) |
|
&& h->type == bfd_link_hash_defined) |
|
9017 |
elf_gp (abfd) = (h->u.def.value |
elf_gp (abfd) = (h->u.def.value |
9018 |
+ h->u.def.section->output_section->vma |
+ h->u.def.section->output_section->vma |
9019 |
+ h->u.def.section->output_offset); |
+ h->u.def.section->output_offset); |
9020 |
else if (info->relocateable) |
else if (info->relocatable) |
9021 |
{ |
{ |
9022 |
bfd_vma lo = MINUS_ONE; |
bfd_vma lo = MINUS_ONE; |
9023 |
|
|
9024 |
/* Find the GP-relative section with the lowest offset. */ |
/* Find the GP-relative section with the lowest offset. */ |
9025 |
for (o = abfd->sections; o != (asection *) NULL; o = o->next) |
for (o = abfd->sections; o != NULL; o = o->next) |
9026 |
if (o->vma < lo |
if (o->vma < lo |
9027 |
&& (elf_section_data (o)->this_hdr.sh_flags & SHF_MIPS_GPREL)) |
&& (elf_section_data (o)->this_hdr.sh_flags & SHF_MIPS_GPREL)) |
9028 |
lo = o->vma; |
lo = o->vma; |
9044 |
mdebug_sec = NULL; |
mdebug_sec = NULL; |
9045 |
gptab_data_sec = NULL; |
gptab_data_sec = NULL; |
9046 |
gptab_bss_sec = NULL; |
gptab_bss_sec = NULL; |
9047 |
for (o = abfd->sections; o != (asection *) NULL; o = o->next) |
for (o = abfd->sections; o != NULL; o = o->next) |
9048 |
{ |
{ |
9049 |
if (strcmp (o->name, ".reginfo") == 0) |
if (strcmp (o->name, ".reginfo") == 0) |
9050 |
{ |
{ |
9053 |
/* We have found the .reginfo section in the output file. |
/* We have found the .reginfo section in the output file. |
9054 |
Look through all the link_orders comprising it and merge |
Look through all the link_orders comprising it and merge |
9055 |
the information together. */ |
the information together. */ |
9056 |
for (p = o->link_order_head; |
for (p = o->link_order_head; p != NULL; p = p->next) |
|
p != (struct bfd_link_order *) NULL; |
|
|
p = p->next) |
|
9057 |
{ |
{ |
9058 |
asection *input_section; |
asection *input_section; |
9059 |
bfd *input_bfd; |
bfd *input_bfd; |
9070 |
input_section = p->u.indirect.section; |
input_section = p->u.indirect.section; |
9071 |
input_bfd = input_section->owner; |
input_bfd = input_section->owner; |
9072 |
|
|
|
/* The linker emulation code has probably clobbered the |
|
|
size to be zero bytes. */ |
|
|
if (input_section->_raw_size == 0) |
|
|
input_section->_raw_size = sizeof (Elf32_External_RegInfo); |
|
|
|
|
9073 |
if (! bfd_get_section_contents (input_bfd, input_section, |
if (! bfd_get_section_contents (input_bfd, input_section, |
9074 |
(PTR) &ext, |
&ext, 0, sizeof ext)) |
9075 |
(file_ptr) 0, |
return FALSE; |
|
(bfd_size_type) sizeof ext)) |
|
|
return false; |
|
9076 |
|
|
9077 |
bfd_mips_elf32_swap_reginfo_in (input_bfd, &ext, &sub); |
bfd_mips_elf32_swap_reginfo_in (input_bfd, &ext, &sub); |
9078 |
|
|
9092 |
} |
} |
9093 |
|
|
9094 |
/* Size has been set in _bfd_mips_elf_always_size_sections. */ |
/* Size has been set in _bfd_mips_elf_always_size_sections. */ |
9095 |
BFD_ASSERT(o->_raw_size == sizeof (Elf32_External_RegInfo)); |
BFD_ASSERT(o->size == sizeof (Elf32_External_RegInfo)); |
9096 |
|
|
9097 |
/* Skip this section later on (I don't think this currently |
/* Skip this section later on (I don't think this currently |
9098 |
matters, but someday it might). */ |
matters, but someday it might). */ |
9099 |
o->link_order_head = (struct bfd_link_order *) NULL; |
o->link_order_head = NULL; |
9100 |
|
|
9101 |
reginfo_sec = o; |
reginfo_sec = o; |
9102 |
} |
} |
9140 |
debug.external_ext = debug.external_ext_end = NULL; |
debug.external_ext = debug.external_ext_end = NULL; |
9141 |
|
|
9142 |
mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info); |
mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info); |
9143 |
if (mdebug_handle == (PTR) NULL) |
if (mdebug_handle == NULL) |
9144 |
return false; |
return FALSE; |
9145 |
|
|
9146 |
esym.jmptbl = 0; |
esym.jmptbl = 0; |
9147 |
esym.cobol_main = 0; |
esym.cobol_main = 0; |
9160 |
if (s != NULL) |
if (s != NULL) |
9161 |
{ |
{ |
9162 |
esym.asym.value = s->vma; |
esym.asym.value = s->vma; |
9163 |
last = s->vma + s->_raw_size; |
last = s->vma + s->size; |
9164 |
} |
} |
9165 |
else |
else |
9166 |
esym.asym.value = last; |
esym.asym.value = last; |
9167 |
if (!bfd_ecoff_debug_one_external (abfd, &debug, swap, |
if (!bfd_ecoff_debug_one_external (abfd, &debug, swap, |
9168 |
secname[i], &esym)) |
secname[i], &esym)) |
9169 |
return false; |
return FALSE; |
9170 |
} |
} |
9171 |
|
|
9172 |
for (p = o->link_order_head; |
for (p = o->link_order_head; p != NULL; p = p->next) |
|
p != (struct bfd_link_order *) NULL; |
|
|
p = p->next) |
|
9173 |
{ |
{ |
9174 |
asection *input_section; |
asection *input_section; |
9175 |
bfd *input_bfd; |
bfd *input_bfd; |
9201 |
input_swap = (get_elf_backend_data (input_bfd) |
input_swap = (get_elf_backend_data (input_bfd) |
9202 |
->elf_backend_ecoff_debug_swap); |
->elf_backend_ecoff_debug_swap); |
9203 |
|
|
9204 |
BFD_ASSERT (p->size == input_section->_raw_size); |
BFD_ASSERT (p->size == input_section->size); |
9205 |
|
|
9206 |
/* The ECOFF linking code expects that we have already |
/* The ECOFF linking code expects that we have already |
9207 |
read in the debugging information and set up an |
read in the debugging information and set up an |
9208 |
ecoff_debug_info structure, so we do that now. */ |
ecoff_debug_info structure, so we do that now. */ |
9209 |
if (! _bfd_mips_elf_read_ecoff_info (input_bfd, input_section, |
if (! _bfd_mips_elf_read_ecoff_info (input_bfd, input_section, |
9210 |
&input_debug)) |
&input_debug)) |
9211 |
return false; |
return FALSE; |
9212 |
|
|
9213 |
if (! (bfd_ecoff_debug_accumulate |
if (! (bfd_ecoff_debug_accumulate |
9214 |
(mdebug_handle, abfd, &debug, swap, input_bfd, |
(mdebug_handle, abfd, &debug, swap, input_bfd, |
9215 |
&input_debug, input_swap, info))) |
&input_debug, input_swap, info))) |
9216 |
return false; |
return FALSE; |
9217 |
|
|
9218 |
/* Loop through the external symbols. For each one with |
/* Loop through the external symbols. For each one with |
9219 |
interesting information, try to find the symbol in |
interesting information, try to find the symbol in |
9231 |
const char *name; |
const char *name; |
9232 |
struct mips_elf_link_hash_entry *h; |
struct mips_elf_link_hash_entry *h; |
9233 |
|
|
9234 |
(*input_swap->swap_ext_in) (input_bfd, (PTR) eraw_src, &ext); |
(*input_swap->swap_ext_in) (input_bfd, eraw_src, &ext); |
9235 |
if (ext.asym.sc == scNil |
if (ext.asym.sc == scNil |
9236 |
|| ext.asym.sc == scUndefined |
|| ext.asym.sc == scUndefined |
9237 |
|| ext.asym.sc == scSUndefined) |
|| ext.asym.sc == scSUndefined) |
9239 |
|
|
9240 |
name = input_debug.ssext + ext.asym.iss; |
name = input_debug.ssext + ext.asym.iss; |
9241 |
h = mips_elf_link_hash_lookup (mips_elf_hash_table (info), |
h = mips_elf_link_hash_lookup (mips_elf_hash_table (info), |
9242 |
name, false, false, true); |
name, FALSE, FALSE, TRUE); |
9243 |
if (h == NULL || h->esym.ifd != -2) |
if (h == NULL || h->esym.ifd != -2) |
9244 |
continue; |
continue; |
9245 |
|
|
9284 |
if (rtproc_sec == NULL |
if (rtproc_sec == NULL |
9285 |
|| ! bfd_set_section_flags (abfd, rtproc_sec, flags) |
|| ! bfd_set_section_flags (abfd, rtproc_sec, flags) |
9286 |
|| ! bfd_set_section_alignment (abfd, rtproc_sec, 4)) |
|| ! bfd_set_section_alignment (abfd, rtproc_sec, 4)) |
9287 |
return false; |
return FALSE; |
9288 |
} |
} |
9289 |
|
|
9290 |
if (! mips_elf_create_procedure_table (mdebug_handle, abfd, |
if (! mips_elf_create_procedure_table (mdebug_handle, abfd, |
9291 |
info, rtproc_sec, |
info, rtproc_sec, |
9292 |
&debug)) |
&debug)) |
9293 |
return false; |
return FALSE; |
9294 |
} |
} |
9295 |
|
|
9296 |
/* Build the external symbol information. */ |
/* Build the external symbol information. */ |
9298 |
einfo.info = info; |
einfo.info = info; |
9299 |
einfo.debug = &debug; |
einfo.debug = &debug; |
9300 |
einfo.swap = swap; |
einfo.swap = swap; |
9301 |
einfo.failed = false; |
einfo.failed = FALSE; |
9302 |
mips_elf_link_hash_traverse (mips_elf_hash_table (info), |
mips_elf_link_hash_traverse (mips_elf_hash_table (info), |
9303 |
mips_elf_output_extsym, |
mips_elf_output_extsym, &einfo); |
|
(PTR) &einfo); |
|
9304 |
if (einfo.failed) |
if (einfo.failed) |
9305 |
return false; |
return FALSE; |
9306 |
|
|
9307 |
/* Set the size of the .mdebug section. */ |
/* Set the size of the .mdebug section. */ |
9308 |
o->_raw_size = bfd_ecoff_debug_size (abfd, &debug, swap); |
o->size = bfd_ecoff_debug_size (abfd, &debug, swap); |
9309 |
|
|
9310 |
/* Skip this section later on (I don't think this currently |
/* Skip this section later on (I don't think this currently |
9311 |
matters, but someday it might). */ |
matters, but someday it might). */ |
9312 |
o->link_order_head = (struct bfd_link_order *) NULL; |
o->link_order_head = NULL; |
9313 |
|
|
9314 |
mdebug_sec = o; |
mdebug_sec = o; |
9315 |
} |
} |
9326 |
information describing how the small data area would |
information describing how the small data area would |
9327 |
change depending upon the -G switch. These sections |
change depending upon the -G switch. These sections |
9328 |
not used in executables files. */ |
not used in executables files. */ |
9329 |
if (! info->relocateable) |
if (! info->relocatable) |
9330 |
{ |
{ |
9331 |
for (p = o->link_order_head; |
for (p = o->link_order_head; p != NULL; p = p->next) |
|
p != (struct bfd_link_order *) NULL; |
|
|
p = p->next) |
|
9332 |
{ |
{ |
9333 |
asection *input_section; |
asection *input_section; |
9334 |
|
|
9348 |
|
|
9349 |
/* Skip this section later on (I don't think this |
/* Skip this section later on (I don't think this |
9350 |
currently matters, but someday it might). */ |
currently matters, but someday it might). */ |
9351 |
o->link_order_head = (struct bfd_link_order *) NULL; |
o->link_order_head = NULL; |
9352 |
|
|
9353 |
/* Really remove the section. */ |
/* Really remove the section. */ |
9354 |
for (secpp = &abfd->sections; |
for (secpp = &abfd->sections; |
9373 |
(_("%s: illegal section name `%s'"), |
(_("%s: illegal section name `%s'"), |
9374 |
bfd_get_filename (abfd), o->name); |
bfd_get_filename (abfd), o->name); |
9375 |
bfd_set_error (bfd_error_nonrepresentable_section); |
bfd_set_error (bfd_error_nonrepresentable_section); |
9376 |
return false; |
return FALSE; |
9377 |
} |
} |
9378 |
|
|
9379 |
/* The linker script always combines .gptab.data and |
/* The linker script always combines .gptab.data and |
9395 |
/* Set up the first entry. */ |
/* Set up the first entry. */ |
9396 |
c = 1; |
c = 1; |
9397 |
amt = c * sizeof (Elf32_gptab); |
amt = c * sizeof (Elf32_gptab); |
9398 |
tab = (Elf32_gptab *) bfd_malloc (amt); |
tab = bfd_malloc (amt); |
9399 |
if (tab == NULL) |
if (tab == NULL) |
9400 |
return false; |
return FALSE; |
9401 |
tab[0].gt_header.gt_current_g_value = elf_gp_size (abfd); |
tab[0].gt_header.gt_current_g_value = elf_gp_size (abfd); |
9402 |
tab[0].gt_header.gt_unused = 0; |
tab[0].gt_header.gt_unused = 0; |
9403 |
|
|
9404 |
/* Combine the input sections. */ |
/* Combine the input sections. */ |
9405 |
for (p = o->link_order_head; |
for (p = o->link_order_head; p != NULL; p = p->next) |
|
p != (struct bfd_link_order *) NULL; |
|
|
p = p->next) |
|
9406 |
{ |
{ |
9407 |
asection *input_section; |
asection *input_section; |
9408 |
bfd *input_bfd; |
bfd *input_bfd; |
9423 |
/* Combine the gptab entries for this input section one |
/* Combine the gptab entries for this input section one |
9424 |
by one. We know that the input gptab entries are |
by one. We know that the input gptab entries are |
9425 |
sorted by ascending -G value. */ |
sorted by ascending -G value. */ |
9426 |
size = bfd_section_size (input_bfd, input_section); |
size = input_section->size; |
9427 |
last = 0; |
last = 0; |
9428 |
for (gpentry = sizeof (Elf32_External_gptab); |
for (gpentry = sizeof (Elf32_External_gptab); |
9429 |
gpentry < size; |
gpentry < size; |
9433 |
Elf32_gptab int_gptab; |
Elf32_gptab int_gptab; |
9434 |
unsigned long val; |
unsigned long val; |
9435 |
unsigned long add; |
unsigned long add; |
9436 |
boolean exact; |
bfd_boolean exact; |
9437 |
unsigned int look; |
unsigned int look; |
9438 |
|
|
9439 |
if (! (bfd_get_section_contents |
if (! (bfd_get_section_contents |
9440 |
(input_bfd, input_section, (PTR) &ext_gptab, |
(input_bfd, input_section, &ext_gptab, gpentry, |
9441 |
(file_ptr) gpentry, |
sizeof (Elf32_External_gptab)))) |
|
(bfd_size_type) sizeof (Elf32_External_gptab)))) |
|
9442 |
{ |
{ |
9443 |
free (tab); |
free (tab); |
9444 |
return false; |
return FALSE; |
9445 |
} |
} |
9446 |
|
|
9447 |
bfd_mips_elf32_swap_gptab_in (input_bfd, &ext_gptab, |
bfd_mips_elf32_swap_gptab_in (input_bfd, &ext_gptab, |
9449 |
val = int_gptab.gt_entry.gt_g_value; |
val = int_gptab.gt_entry.gt_g_value; |
9450 |
add = int_gptab.gt_entry.gt_bytes - last; |
add = int_gptab.gt_entry.gt_bytes - last; |
9451 |
|
|
9452 |
exact = false; |
exact = FALSE; |
9453 |
for (look = 1; look < c; look++) |
for (look = 1; look < c; look++) |
9454 |
{ |
{ |
9455 |
if (tab[look].gt_entry.gt_g_value >= val) |
if (tab[look].gt_entry.gt_g_value >= val) |
9456 |
tab[look].gt_entry.gt_bytes += add; |
tab[look].gt_entry.gt_bytes += add; |
9457 |
|
|
9458 |
if (tab[look].gt_entry.gt_g_value == val) |
if (tab[look].gt_entry.gt_g_value == val) |
9459 |
exact = true; |
exact = TRUE; |
9460 |
} |
} |
9461 |
|
|
9462 |
if (! exact) |
if (! exact) |
9466 |
|
|
9467 |
/* We need a new table entry. */ |
/* We need a new table entry. */ |
9468 |
amt = (bfd_size_type) (c + 1) * sizeof (Elf32_gptab); |
amt = (bfd_size_type) (c + 1) * sizeof (Elf32_gptab); |
9469 |
new_tab = (Elf32_gptab *) bfd_realloc ((PTR) tab, amt); |
new_tab = bfd_realloc (tab, amt); |
9470 |
if (new_tab == NULL) |
if (new_tab == NULL) |
9471 |
{ |
{ |
9472 |
free (tab); |
free (tab); |
9473 |
return false; |
return FALSE; |
9474 |
} |
} |
9475 |
tab = new_tab; |
tab = new_tab; |
9476 |
tab[c].gt_entry.gt_g_value = val; |
tab[c].gt_entry.gt_g_value = val; |
9509 |
|
|
9510 |
/* Swap out the table. */ |
/* Swap out the table. */ |
9511 |
amt = (bfd_size_type) c * sizeof (Elf32_External_gptab); |
amt = (bfd_size_type) c * sizeof (Elf32_External_gptab); |
9512 |
ext_tab = (Elf32_External_gptab *) bfd_alloc (abfd, amt); |
ext_tab = bfd_alloc (abfd, amt); |
9513 |
if (ext_tab == NULL) |
if (ext_tab == NULL) |
9514 |
{ |
{ |
9515 |
free (tab); |
free (tab); |
9516 |
return false; |
return FALSE; |
9517 |
} |
} |
9518 |
|
|
9519 |
for (j = 0; j < c; j++) |
for (j = 0; j < c; j++) |
9520 |
bfd_mips_elf32_swap_gptab_out (abfd, tab + j, ext_tab + j); |
bfd_mips_elf32_swap_gptab_out (abfd, tab + j, ext_tab + j); |
9521 |
free (tab); |
free (tab); |
9522 |
|
|
9523 |
o->_raw_size = c * sizeof (Elf32_External_gptab); |
o->size = c * sizeof (Elf32_External_gptab); |
9524 |
o->contents = (bfd_byte *) ext_tab; |
o->contents = (bfd_byte *) ext_tab; |
9525 |
|
|
9526 |
/* Skip this section later on (I don't think this currently |
/* Skip this section later on (I don't think this currently |
9527 |
matters, but someday it might). */ |
matters, but someday it might). */ |
9528 |
o->link_order_head = (struct bfd_link_order *) NULL; |
o->link_order_head = NULL; |
9529 |
} |
} |
9530 |
} |
} |
9531 |
|
|
9532 |
/* Invoke the regular ELF backend linker to do all the work. */ |
/* Invoke the regular ELF backend linker to do all the work. */ |
9533 |
if (ABI_64_P (abfd)) |
if (!bfd_elf_final_link (abfd, info)) |
9534 |
{ |
return FALSE; |
|
#ifdef BFD64 |
|
|
if (!bfd_elf64_bfd_final_link (abfd, info)) |
|
|
return false; |
|
|
#else |
|
|
abort (); |
|
|
return false; |
|
|
#endif /* BFD64 */ |
|
|
} |
|
|
else if (!bfd_elf32_bfd_final_link (abfd, info)) |
|
|
return false; |
|
9535 |
|
|
9536 |
/* Now write out the computed sections. */ |
/* Now write out the computed sections. */ |
9537 |
|
|
9538 |
if (reginfo_sec != (asection *) NULL) |
if (reginfo_sec != NULL) |
9539 |
{ |
{ |
9540 |
Elf32_External_RegInfo ext; |
Elf32_External_RegInfo ext; |
9541 |
|
|
9542 |
bfd_mips_elf32_swap_reginfo_out (abfd, ®info, &ext); |
bfd_mips_elf32_swap_reginfo_out (abfd, ®info, &ext); |
9543 |
if (! bfd_set_section_contents (abfd, reginfo_sec, (PTR) &ext, |
if (! bfd_set_section_contents (abfd, reginfo_sec, &ext, 0, sizeof ext)) |
9544 |
(file_ptr) 0, |
return FALSE; |
|
(bfd_size_type) sizeof ext)) |
|
|
return false; |
|
9545 |
} |
} |
9546 |
|
|
9547 |
if (mdebug_sec != (asection *) NULL) |
if (mdebug_sec != NULL) |
9548 |
{ |
{ |
9549 |
BFD_ASSERT (abfd->output_has_begun); |
BFD_ASSERT (abfd->output_has_begun); |
9550 |
if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug, |
if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug, |
9551 |
swap, info, |
swap, info, |
9552 |
mdebug_sec->filepos)) |
mdebug_sec->filepos)) |
9553 |
return false; |
return FALSE; |
9554 |
|
|
9555 |
bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info); |
bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info); |
9556 |
} |
} |
9557 |
|
|
9558 |
if (gptab_data_sec != (asection *) NULL) |
if (gptab_data_sec != NULL) |
9559 |
{ |
{ |
9560 |
if (! bfd_set_section_contents (abfd, gptab_data_sec, |
if (! bfd_set_section_contents (abfd, gptab_data_sec, |
9561 |
gptab_data_sec->contents, |
gptab_data_sec->contents, |
9562 |
(file_ptr) 0, |
0, gptab_data_sec->size)) |
9563 |
gptab_data_sec->_raw_size)) |
return FALSE; |
|
return false; |
|
9564 |
} |
} |
9565 |
|
|
9566 |
if (gptab_bss_sec != (asection *) NULL) |
if (gptab_bss_sec != NULL) |
9567 |
{ |
{ |
9568 |
if (! bfd_set_section_contents (abfd, gptab_bss_sec, |
if (! bfd_set_section_contents (abfd, gptab_bss_sec, |
9569 |
gptab_bss_sec->contents, |
gptab_bss_sec->contents, |
9570 |
(file_ptr) 0, |
0, gptab_bss_sec->size)) |
9571 |
gptab_bss_sec->_raw_size)) |
return FALSE; |
|
return false; |
|
9572 |
} |
} |
9573 |
|
|
9574 |
if (SGI_COMPAT (abfd)) |
if (SGI_COMPAT (abfd)) |
9578 |
{ |
{ |
9579 |
if (! bfd_set_section_contents (abfd, rtproc_sec, |
if (! bfd_set_section_contents (abfd, rtproc_sec, |
9580 |
rtproc_sec->contents, |
rtproc_sec->contents, |
9581 |
(file_ptr) 0, |
0, rtproc_sec->size)) |
9582 |
rtproc_sec->_raw_size)) |
return FALSE; |
|
return false; |
|
9583 |
} |
} |
9584 |
} |
} |
9585 |
|
|
9586 |
return true; |
return TRUE; |
9587 |
} |
} |
9588 |
|
|
9589 |
|
/* Structure for saying that BFD machine EXTENSION extends BASE. */ |
9590 |
|
|
9591 |
|
struct mips_mach_extension { |
9592 |
|
unsigned long extension, base; |
9593 |
|
}; |
9594 |
|
|
9595 |
|
|
9596 |
|
/* An array describing how BFD machines relate to one another. The entries |
9597 |
|
are ordered topologically with MIPS I extensions listed last. */ |
9598 |
|
|
9599 |
|
static const struct mips_mach_extension mips_mach_extensions[] = { |
9600 |
|
/* MIPS64 extensions. */ |
9601 |
|
{ bfd_mach_mipsisa64r2, bfd_mach_mipsisa64 }, |
9602 |
|
{ bfd_mach_mips_sb1, bfd_mach_mipsisa64 }, |
9603 |
|
|
9604 |
|
/* MIPS V extensions. */ |
9605 |
|
{ bfd_mach_mipsisa64, bfd_mach_mips5 }, |
9606 |
|
|
9607 |
|
/* R10000 extensions. */ |
9608 |
|
{ bfd_mach_mips12000, bfd_mach_mips10000 }, |
9609 |
|
|
9610 |
|
/* R5000 extensions. Note: the vr5500 ISA is an extension of the core |
9611 |
|
vr5400 ISA, but doesn't include the multimedia stuff. It seems |
9612 |
|
better to allow vr5400 and vr5500 code to be merged anyway, since |
9613 |
|
many libraries will just use the core ISA. Perhaps we could add |
9614 |
|
some sort of ASE flag if this ever proves a problem. */ |
9615 |
|
{ bfd_mach_mips5500, bfd_mach_mips5400 }, |
9616 |
|
{ bfd_mach_mips5400, bfd_mach_mips5000 }, |
9617 |
|
|
9618 |
|
/* MIPS IV extensions. */ |
9619 |
|
{ bfd_mach_mips5, bfd_mach_mips8000 }, |
9620 |
|
{ bfd_mach_mips10000, bfd_mach_mips8000 }, |
9621 |
|
{ bfd_mach_mips5000, bfd_mach_mips8000 }, |
9622 |
|
{ bfd_mach_mips7000, bfd_mach_mips8000 }, |
9623 |
|
{ bfd_mach_mips9000, bfd_mach_mips8000 }, |
9624 |
|
|
9625 |
|
/* VR4100 extensions. */ |
9626 |
|
{ bfd_mach_mips4120, bfd_mach_mips4100 }, |
9627 |
|
{ bfd_mach_mips4111, bfd_mach_mips4100 }, |
9628 |
|
|
9629 |
|
/* MIPS III extensions. */ |
9630 |
|
{ bfd_mach_mips8000, bfd_mach_mips4000 }, |
9631 |
|
{ bfd_mach_mips4650, bfd_mach_mips4000 }, |
9632 |
|
{ bfd_mach_mips4600, bfd_mach_mips4000 }, |
9633 |
|
{ bfd_mach_mips4400, bfd_mach_mips4000 }, |
9634 |
|
{ bfd_mach_mips4300, bfd_mach_mips4000 }, |
9635 |
|
{ bfd_mach_mips4100, bfd_mach_mips4000 }, |
9636 |
|
{ bfd_mach_mips4010, bfd_mach_mips4000 }, |
9637 |
|
|
9638 |
|
/* MIPS32 extensions. */ |
9639 |
|
{ bfd_mach_mipsisa32r2, bfd_mach_mipsisa32 }, |
9640 |
|
|
9641 |
|
/* MIPS II extensions. */ |
9642 |
|
{ bfd_mach_mips4000, bfd_mach_mips6000 }, |
9643 |
|
{ bfd_mach_mipsisa32, bfd_mach_mips6000 }, |
9644 |
|
|
9645 |
|
/* MIPS I extensions. */ |
9646 |
|
{ bfd_mach_mips6000, bfd_mach_mips3000 }, |
9647 |
|
{ bfd_mach_mips3900, bfd_mach_mips3000 } |
9648 |
|
}; |
9649 |
|
|
9650 |
|
|
9651 |
|
/* Return true if bfd machine EXTENSION is an extension of machine BASE. */ |
9652 |
|
|
9653 |
|
static bfd_boolean |
9654 |
|
mips_mach_extends_p (unsigned long base, unsigned long extension) |
9655 |
|
{ |
9656 |
|
size_t i; |
9657 |
|
|
9658 |
|
for (i = 0; extension != base && i < ARRAY_SIZE (mips_mach_extensions); i++) |
9659 |
|
if (extension == mips_mach_extensions[i].extension) |
9660 |
|
extension = mips_mach_extensions[i].base; |
9661 |
|
|
9662 |
|
return extension == base; |
9663 |
|
} |
9664 |
|
|
9665 |
|
|
9666 |
|
/* Return true if the given ELF header flags describe a 32-bit binary. */ |
9667 |
|
|
9668 |
|
static bfd_boolean |
9669 |
|
mips_32bit_flags_p (flagword flags) |
9670 |
|
{ |
9671 |
|
return ((flags & EF_MIPS_32BITMODE) != 0 |
9672 |
|
|| (flags & EF_MIPS_ABI) == E_MIPS_ABI_O32 |
9673 |
|
|| (flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI32 |
9674 |
|
|| (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1 |
9675 |
|
|| (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2 |
9676 |
|
|| (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32 |
9677 |
|
|| (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32R2); |
9678 |
|
} |
9679 |
|
|
9680 |
|
|
9681 |
/* Merge backend specific data from an object file to the output |
/* Merge backend specific data from an object file to the output |
9682 |
object file when linking. */ |
object file when linking. */ |
9683 |
|
|
9684 |
boolean |
bfd_boolean |
9685 |
_bfd_mips_elf_merge_private_bfd_data (ibfd, obfd) |
_bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) |
|
bfd *ibfd; |
|
|
bfd *obfd; |
|
9686 |
{ |
{ |
9687 |
flagword old_flags; |
flagword old_flags; |
9688 |
flagword new_flags; |
flagword new_flags; |
9689 |
boolean ok; |
bfd_boolean ok; |
9690 |
boolean null_input_bfd = true; |
bfd_boolean null_input_bfd = TRUE; |
9691 |
asection *sec; |
asection *sec; |
9692 |
|
|
9693 |
/* Check if we have the same endianess */ |
/* Check if we have the same endianess */ |
9694 |
if (! _bfd_generic_verify_endian_match (ibfd, obfd)) |
if (! _bfd_generic_verify_endian_match (ibfd, obfd)) |
9695 |
return false; |
{ |
9696 |
|
(*_bfd_error_handler) |
9697 |
|
(_("%B: endianness incompatible with that of the selected emulation"), |
9698 |
|
ibfd); |
9699 |
|
return FALSE; |
9700 |
|
} |
9701 |
|
|
9702 |
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour |
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour |
9703 |
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour) |
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour) |
9704 |
return true; |
return TRUE; |
9705 |
|
|
9706 |
|
if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0) |
9707 |
|
{ |
9708 |
|
(*_bfd_error_handler) |
9709 |
|
(_("%B: ABI is incompatible with that of the selected emulation"), |
9710 |
|
ibfd); |
9711 |
|
return FALSE; |
9712 |
|
} |
9713 |
|
|
9714 |
new_flags = elf_elfheader (ibfd)->e_flags; |
new_flags = elf_elfheader (ibfd)->e_flags; |
9715 |
elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_NOREORDER; |
elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_NOREORDER; |
9717 |
|
|
9718 |
if (! elf_flags_init (obfd)) |
if (! elf_flags_init (obfd)) |
9719 |
{ |
{ |
9720 |
elf_flags_init (obfd) = true; |
elf_flags_init (obfd) = TRUE; |
9721 |
elf_elfheader (obfd)->e_flags = new_flags; |
elf_elfheader (obfd)->e_flags = new_flags; |
9722 |
elf_elfheader (obfd)->e_ident[EI_CLASS] |
elf_elfheader (obfd)->e_ident[EI_CLASS] |
9723 |
= elf_elfheader (ibfd)->e_ident[EI_CLASS]; |
= elf_elfheader (ibfd)->e_ident[EI_CLASS]; |
9727 |
{ |
{ |
9728 |
if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), |
if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), |
9729 |
bfd_get_mach (ibfd))) |
bfd_get_mach (ibfd))) |
9730 |
return false; |
return FALSE; |
9731 |
} |
} |
9732 |
|
|
9733 |
return true; |
return TRUE; |
9734 |
} |
} |
9735 |
|
|
9736 |
/* Check flag compatibility. */ |
/* Check flag compatibility. */ |
9738 |
new_flags &= ~EF_MIPS_NOREORDER; |
new_flags &= ~EF_MIPS_NOREORDER; |
9739 |
old_flags &= ~EF_MIPS_NOREORDER; |
old_flags &= ~EF_MIPS_NOREORDER; |
9740 |
|
|
9741 |
|
/* Some IRIX 6 BSD-compatibility objects have this bit set. It |
9742 |
|
doesn't seem to matter. */ |
9743 |
|
new_flags &= ~EF_MIPS_XGOT; |
9744 |
|
old_flags &= ~EF_MIPS_XGOT; |
9745 |
|
|
9746 |
|
/* MIPSpro generates ucode info in n64 objects. Again, we should |
9747 |
|
just be able to ignore this. */ |
9748 |
|
new_flags &= ~EF_MIPS_UCODE; |
9749 |
|
old_flags &= ~EF_MIPS_UCODE; |
9750 |
|
|
9751 |
if (new_flags == old_flags) |
if (new_flags == old_flags) |
9752 |
return true; |
return TRUE; |
9753 |
|
|
9754 |
/* Check to see if the input BFD actually contains any sections. |
/* Check to see if the input BFD actually contains any sections. |
9755 |
If not, its flags may not have been initialised either, but it cannot |
If not, its flags may not have been initialised either, but it cannot |
9760 |
which are automatically generated by gas. */ |
which are automatically generated by gas. */ |
9761 |
if (strcmp (sec->name, ".reginfo") |
if (strcmp (sec->name, ".reginfo") |
9762 |
&& strcmp (sec->name, ".mdebug") |
&& strcmp (sec->name, ".mdebug") |
9763 |
&& ((!strcmp (sec->name, ".text") |
&& (sec->size != 0 |
9764 |
|| !strcmp (sec->name, ".data") |
|| (strcmp (sec->name, ".text") |
9765 |
|| !strcmp (sec->name, ".bss")) |
&& strcmp (sec->name, ".data") |
9766 |
&& sec->_raw_size != 0)) |
&& strcmp (sec->name, ".bss")))) |
9767 |
{ |
{ |
9768 |
null_input_bfd = false; |
null_input_bfd = FALSE; |
9769 |
break; |
break; |
9770 |
} |
} |
9771 |
} |
} |
9772 |
if (null_input_bfd) |
if (null_input_bfd) |
9773 |
return true; |
return TRUE; |
9774 |
|
|
9775 |
ok = true; |
ok = TRUE; |
9776 |
|
|
9777 |
if ((new_flags & EF_MIPS_PIC) != (old_flags & EF_MIPS_PIC)) |
if (((new_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0) |
9778 |
|
!= ((old_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0)) |
9779 |
{ |
{ |
|
new_flags &= ~EF_MIPS_PIC; |
|
|
old_flags &= ~EF_MIPS_PIC; |
|
9780 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
9781 |
(_("%s: linking PIC files with non-PIC files"), |
(_("%B: warning: linking PIC files with non-PIC files"), |
9782 |
bfd_archive_filename (ibfd)); |
ibfd); |
9783 |
ok = false; |
ok = TRUE; |
9784 |
} |
} |
9785 |
|
|
9786 |
if ((new_flags & EF_MIPS_CPIC) != (old_flags & EF_MIPS_CPIC)) |
if (new_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) |
9787 |
{ |
elf_elfheader (obfd)->e_flags |= EF_MIPS_CPIC; |
9788 |
new_flags &= ~EF_MIPS_CPIC; |
if (! (new_flags & EF_MIPS_PIC)) |
9789 |
old_flags &= ~EF_MIPS_CPIC; |
elf_elfheader (obfd)->e_flags &= ~EF_MIPS_PIC; |
|
(*_bfd_error_handler) |
|
|
(_("%s: linking abicalls files with non-abicalls files"), |
|
|
bfd_archive_filename (ibfd)); |
|
|
ok = false; |
|
|
} |
|
|
|
|
|
/* Compare the ISA's. */ |
|
|
if ((new_flags & (EF_MIPS_ARCH | EF_MIPS_MACH)) |
|
|
!= (old_flags & (EF_MIPS_ARCH | EF_MIPS_MACH))) |
|
|
{ |
|
|
int new_mach = new_flags & EF_MIPS_MACH; |
|
|
int old_mach = old_flags & EF_MIPS_MACH; |
|
|
int new_isa = elf_mips_isa (new_flags); |
|
|
int old_isa = elf_mips_isa (old_flags); |
|
|
|
|
|
/* If either has no machine specified, just compare the general isa's. |
|
|
Some combinations of machines are ok, if the isa's match. */ |
|
|
if (! new_mach |
|
|
|| ! old_mach |
|
|
|| new_mach == old_mach |
|
|
) |
|
|
{ |
|
|
/* Don't warn about mixing code using 32-bit ISAs, or mixing code |
|
|
using 64-bit ISAs. They will normally use the same data sizes |
|
|
and calling conventions. */ |
|
9790 |
|
|
9791 |
if (( (new_isa == 1 || new_isa == 2 || new_isa == 32) |
new_flags &= ~ (EF_MIPS_PIC | EF_MIPS_CPIC); |
9792 |
^ (old_isa == 1 || old_isa == 2 || old_isa == 32)) != 0) |
old_flags &= ~ (EF_MIPS_PIC | EF_MIPS_CPIC); |
|
{ |
|
|
(*_bfd_error_handler) |
|
|
(_("%s: ISA mismatch (-mips%d) with previous modules (-mips%d)"), |
|
|
bfd_archive_filename (ibfd), new_isa, old_isa); |
|
|
ok = false; |
|
|
} |
|
|
else |
|
|
{ |
|
|
/* Do we need to update the mach field? */ |
|
|
if (old_mach == 0 && new_mach != 0) |
|
|
elf_elfheader (obfd)->e_flags |= new_mach; |
|
9793 |
|
|
9794 |
/* Do we need to update the ISA field? */ |
/* Compare the ISAs. */ |
9795 |
if (new_isa > old_isa) |
if (mips_32bit_flags_p (old_flags) != mips_32bit_flags_p (new_flags)) |
9796 |
{ |
{ |
9797 |
elf_elfheader (obfd)->e_flags &= ~EF_MIPS_ARCH; |
(*_bfd_error_handler) |
9798 |
elf_elfheader (obfd)->e_flags |
(_("%B: linking 32-bit code with 64-bit code"), |
9799 |
|= new_flags & EF_MIPS_ARCH; |
ibfd); |
9800 |
} |
ok = FALSE; |
9801 |
} |
} |
9802 |
|
else if (!mips_mach_extends_p (bfd_get_mach (ibfd), bfd_get_mach (obfd))) |
9803 |
|
{ |
9804 |
|
/* OBFD's ISA isn't the same as, or an extension of, IBFD's. */ |
9805 |
|
if (mips_mach_extends_p (bfd_get_mach (obfd), bfd_get_mach (ibfd))) |
9806 |
|
{ |
9807 |
|
/* Copy the architecture info from IBFD to OBFD. Also copy |
9808 |
|
the 32-bit flag (if set) so that we continue to recognise |
9809 |
|
OBFD as a 32-bit binary. */ |
9810 |
|
bfd_set_arch_info (obfd, bfd_get_arch_info (ibfd)); |
9811 |
|
elf_elfheader (obfd)->e_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH); |
9812 |
|
elf_elfheader (obfd)->e_flags |
9813 |
|
|= new_flags & (EF_MIPS_ARCH | EF_MIPS_MACH | EF_MIPS_32BITMODE); |
9814 |
|
|
9815 |
|
/* Copy across the ABI flags if OBFD doesn't use them |
9816 |
|
and if that was what caused us to treat IBFD as 32-bit. */ |
9817 |
|
if ((old_flags & EF_MIPS_ABI) == 0 |
9818 |
|
&& mips_32bit_flags_p (new_flags) |
9819 |
|
&& !mips_32bit_flags_p (new_flags & ~EF_MIPS_ABI)) |
9820 |
|
elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_ABI; |
9821 |
} |
} |
9822 |
else |
else |
9823 |
{ |
{ |
9824 |
|
/* The ISAs aren't compatible. */ |
9825 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
9826 |
(_("%s: ISA mismatch (%d) with previous modules (%d)"), |
(_("%B: linking %s module with previous %s modules"), |
9827 |
bfd_archive_filename (ibfd), |
ibfd, |
9828 |
_bfd_elf_mips_mach (new_flags), |
bfd_printable_name (ibfd), |
9829 |
_bfd_elf_mips_mach (old_flags)); |
bfd_printable_name (obfd)); |
9830 |
ok = false; |
ok = FALSE; |
9831 |
} |
} |
|
|
|
|
new_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH); |
|
|
old_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH); |
|
9832 |
} |
} |
9833 |
|
|
9834 |
/* Compare ABI's. The 64-bit ABI does not use EF_MIPS_ABI. But, it |
new_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH | EF_MIPS_32BITMODE); |
9835 |
|
old_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH | EF_MIPS_32BITMODE); |
9836 |
|
|
9837 |
|
/* Compare ABIs. The 64-bit ABI does not use EF_MIPS_ABI. But, it |
9838 |
does set EI_CLASS differently from any 32-bit ABI. */ |
does set EI_CLASS differently from any 32-bit ABI. */ |
9839 |
if ((new_flags & EF_MIPS_ABI) != (old_flags & EF_MIPS_ABI) |
if ((new_flags & EF_MIPS_ABI) != (old_flags & EF_MIPS_ABI) |
9840 |
|| (elf_elfheader (ibfd)->e_ident[EI_CLASS] |
|| (elf_elfheader (ibfd)->e_ident[EI_CLASS] |
9846 |
!= elf_elfheader (obfd)->e_ident[EI_CLASS])) |
!= elf_elfheader (obfd)->e_ident[EI_CLASS])) |
9847 |
{ |
{ |
9848 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
9849 |
(_("%s: ABI mismatch: linking %s module with previous %s modules"), |
(_("%B: ABI mismatch: linking %s module with previous %s modules"), |
9850 |
bfd_archive_filename (ibfd), |
ibfd, |
9851 |
elf_mips_abi_name (ibfd), |
elf_mips_abi_name (ibfd), |
9852 |
elf_mips_abi_name (obfd)); |
elf_mips_abi_name (obfd)); |
9853 |
ok = false; |
ok = FALSE; |
9854 |
} |
} |
9855 |
new_flags &= ~EF_MIPS_ABI; |
new_flags &= ~EF_MIPS_ABI; |
9856 |
old_flags &= ~EF_MIPS_ABI; |
old_flags &= ~EF_MIPS_ABI; |
9857 |
} |
} |
9858 |
|
|
9859 |
|
/* For now, allow arbitrary mixing of ASEs (retain the union). */ |
9860 |
|
if ((new_flags & EF_MIPS_ARCH_ASE) != (old_flags & EF_MIPS_ARCH_ASE)) |
9861 |
|
{ |
9862 |
|
elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_ARCH_ASE; |
9863 |
|
|
9864 |
|
new_flags &= ~ EF_MIPS_ARCH_ASE; |
9865 |
|
old_flags &= ~ EF_MIPS_ARCH_ASE; |
9866 |
|
} |
9867 |
|
|
9868 |
/* Warn about any other mismatches */ |
/* Warn about any other mismatches */ |
9869 |
if (new_flags != old_flags) |
if (new_flags != old_flags) |
9870 |
{ |
{ |
9871 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
9872 |
(_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"), |
(_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"), |
9873 |
bfd_archive_filename (ibfd), (unsigned long) new_flags, |
ibfd, (unsigned long) new_flags, |
9874 |
(unsigned long) old_flags); |
(unsigned long) old_flags); |
9875 |
ok = false; |
ok = FALSE; |
9876 |
} |
} |
9877 |
|
|
9878 |
if (! ok) |
if (! ok) |
9879 |
{ |
{ |
9880 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
9881 |
return false; |
return FALSE; |
9882 |
} |
} |
9883 |
|
|
9884 |
return true; |
return TRUE; |
9885 |
} |
} |
9886 |
|
|
9887 |
/* Function to keep MIPS specific file flags like as EF_MIPS_PIC. */ |
/* Function to keep MIPS specific file flags like as EF_MIPS_PIC. */ |
9888 |
|
|
9889 |
boolean |
bfd_boolean |
9890 |
_bfd_mips_elf_set_private_flags (abfd, flags) |
_bfd_mips_elf_set_private_flags (bfd *abfd, flagword flags) |
|
bfd *abfd; |
|
|
flagword flags; |
|
9891 |
{ |
{ |
9892 |
BFD_ASSERT (!elf_flags_init (abfd) |
BFD_ASSERT (!elf_flags_init (abfd) |
9893 |
|| elf_elfheader (abfd)->e_flags == flags); |
|| elf_elfheader (abfd)->e_flags == flags); |
9894 |
|
|
9895 |
elf_elfheader (abfd)->e_flags = flags; |
elf_elfheader (abfd)->e_flags = flags; |
9896 |
elf_flags_init (abfd) = true; |
elf_flags_init (abfd) = TRUE; |
9897 |
return true; |
return TRUE; |
9898 |
} |
} |
9899 |
|
|
9900 |
boolean |
bfd_boolean |
9901 |
_bfd_mips_elf_print_private_bfd_data (abfd, ptr) |
_bfd_mips_elf_print_private_bfd_data (bfd *abfd, void *ptr) |
|
bfd *abfd; |
|
|
PTR ptr; |
|
9902 |
{ |
{ |
9903 |
FILE *file = (FILE *) ptr; |
FILE *file = ptr; |
9904 |
|
|
9905 |
BFD_ASSERT (abfd != NULL && ptr != NULL); |
BFD_ASSERT (abfd != NULL && ptr != NULL); |
9906 |
|
|
9941 |
fprintf (file, _(" [mips32]")); |
fprintf (file, _(" [mips32]")); |
9942 |
else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_64) |
else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_64) |
9943 |
fprintf (file, _(" [mips64]")); |
fprintf (file, _(" [mips64]")); |
9944 |
|
else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32R2) |
9945 |
|
fprintf (file, _(" [mips32r2]")); |
9946 |
|
else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_64R2) |
9947 |
|
fprintf (file, _(" [mips64r2]")); |
9948 |
else |
else |
9949 |
fprintf (file, _(" [unknown ISA]")); |
fprintf (file, _(" [unknown ISA]")); |
9950 |
|
|
9961 |
|
|
9962 |
fputc ('\n', file); |
fputc ('\n', file); |
9963 |
|
|
9964 |
return true; |
return TRUE; |
9965 |
} |
} |
9966 |
|
|
9967 |
|
struct bfd_elf_special_section const _bfd_mips_elf_special_sections[]= |
9968 |
|
{ |
9969 |
|
{ ".sdata", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL }, |
9970 |
|
{ ".sbss", 5, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL }, |
9971 |
|
{ ".lit4", 5, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL }, |
9972 |
|
{ ".lit8", 5, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL }, |
9973 |
|
{ ".ucode", 6, 0, SHT_MIPS_UCODE, 0 }, |
9974 |
|
{ ".mdebug", 7, 0, SHT_MIPS_DEBUG, 0 }, |
9975 |
|
{ NULL, 0, 0, 0, 0 } |
9976 |
|
}; |