rename for <=14 chars
[binutils-gdb.git] / bfd / mipsbsd.c
1 /* BFD backend for MIPS BSD (a.out) binaries.
2 Copyright (C) 1993 Free Software Foundation, Inc.
3 Written by Ralph Campbell.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 #define BYTES_IN_WORD 4
22 #define ARCH 32
23 /* #define ENTRY_CAN_BE_ZERO */
24 #define N_HEADER_IN_TEXT(x) 1
25 #define N_SHARED_LIB(x) 0
26 #define N_TXTADDR(x) \
27 (N_MAGIC(x) != ZMAGIC ? (x).a_entry : /* object file or NMAGIC */\
28 TEXT_START_ADDR + EXEC_BYTES_SIZE /* no padding */\
29 )
30 #define N_DATADDR(x) (N_TXTADDR(x)+N_TXTSIZE(x))
31 #define TEXT_START_ADDR 4096
32 #define PAGE_SIZE 4096
33 #define SEGMENT_SIZE PAGE_SIZE
34 #define DEFAULT_ARCH bfd_arch_mips
35 #define MY_symbol_leading_char '\0'
36
37 #define MY(OP) CAT(mipsbsd_,OP)
38
39 #include "bfd.h"
40 #include "sysdep.h"
41 #include "libbfd.h"
42 #include "libaout.h"
43
44 #define SET_ARCH_MACH(ABFD, EXEC) \
45 MY(set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \
46 MY(choose_reloc_size)(ABFD);
47 void MY(set_arch_mach) PARAMS ((bfd *abfd, int machtype));
48 static void MY(choose_reloc_size) PARAMS ((bfd *abfd));
49
50 #define MY_write_object_contents MY(write_object_contents)
51 static boolean MY(write_object_contents) PARAMS ((bfd *abfd));
52
53 #define MY_reloc_howto_type_lookup MY(reloc_howto_type_lookup)
54 #define MY_canonicalize_reloc MY(canonicalize_reloc)
55
56 #define MY_backend_data &MY(backend_data)
57 #define MY_BFD_TARGET
58
59 #include "aout-target.h"
60
61 /*
62 * These really should be common to all BSD systems.
63 * Also, to reduce space, should ifdef the individual cases if MINIMIZE=1.
64 */
65 void
66 MY(set_arch_mach) (abfd, machtype)
67 bfd *abfd;
68 int machtype;
69 {
70 enum bfd_architecture arch;
71 long machine;
72
73 /* Determine the architecture and machine type of the object file. */
74 switch (machtype) {
75
76 case M_68010:
77 case M_HP200:
78 arch = bfd_arch_m68k;
79 machine = 68010;
80 break;
81
82 case M_68020:
83 case M_HP300:
84 arch = bfd_arch_m68k;
85 machine = 68020;
86 break;
87
88 case M_SPARC:
89 arch = bfd_arch_sparc;
90 machine = 0;
91 break;
92
93 case M_386:
94 arch = bfd_arch_i386;
95 machine = 0;
96 break;
97
98 case M_29K:
99 arch = bfd_arch_a29k;
100 machine = 0;
101 break;
102
103 case M_HPUX:
104 arch = bfd_arch_m68k;
105 machine = 0;
106 break;
107
108 case M_MIPS1:
109 arch = bfd_arch_mips;
110 machine = 3000;
111 break;
112
113 case M_MIPS2:
114 arch = bfd_arch_mips;
115 machine = 4000;
116 break;
117
118 default:
119 arch = bfd_arch_obscure;
120 machine = 0;
121 break;
122 }
123 bfd_set_arch_mach(abfd, arch, machine);
124 }
125
126 /* Determine the size of a relocation entry, based on the architecture */
127 static void
128 MY(choose_reloc_size) (abfd)
129 bfd *abfd;
130 {
131 switch (bfd_get_arch(abfd)) {
132 case bfd_arch_sparc:
133 case bfd_arch_a29k:
134 case bfd_arch_mips:
135 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
136 break;
137 default:
138 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
139 break;
140 }
141 }
142
143 /* Write an object file in BSD a.out format.
144 Section contents have already been written. We write the
145 file header, symbols, and relocation. */
146
147 static boolean
148 MY(write_object_contents) (abfd)
149 bfd *abfd;
150 {
151 struct external_exec exec_bytes;
152 struct internal_exec *execp = exec_hdr (abfd);
153
154 /* Magic number, maestro, please! */
155 switch (bfd_get_arch(abfd)) {
156 case bfd_arch_m68k:
157 switch (bfd_get_mach(abfd)) {
158 case 68010:
159 N_SET_MACHTYPE(*execp, M_68010);
160 break;
161 default:
162 case 68020:
163 N_SET_MACHTYPE(*execp, M_68020);
164 break;
165 }
166 break;
167 case bfd_arch_sparc:
168 N_SET_MACHTYPE(*execp, M_SPARC);
169 break;
170 case bfd_arch_i386:
171 N_SET_MACHTYPE(*execp, M_386);
172 break;
173 case bfd_arch_a29k:
174 N_SET_MACHTYPE(*execp, M_29K);
175 break;
176 case bfd_arch_mips:
177 switch (bfd_get_mach(abfd)) {
178 case 4000:
179 case 6000:
180 N_SET_MACHTYPE(*execp, M_MIPS2);
181 break;
182 default:
183 N_SET_MACHTYPE(*execp, M_MIPS1);
184 break;
185 }
186 break;
187 default:
188 N_SET_MACHTYPE(*execp, M_UNKNOWN);
189 }
190
191 MY(choose_reloc_size)(abfd);
192
193 WRITE_HEADERS(abfd, execp);
194
195 return true;
196 }
197
198 /*
199 * MIPS relocation types.
200 */
201 #define MIPS_RELOC_32 0
202 #define MIPS_RELOC_JMP 1
203 #define MIPS_RELOC_WDISP16 2
204 #define MIPS_RELOC_HI16 3
205 #define MIPS_RELOC_HI16_S 4
206 #define MIPS_RELOC_LO16 5
207
208 /*
209 * This is only called when performing a BFD_RELOC_HI16_S relocation.
210 * We need to see if bit 15 is set in the result. If it is, we add
211 * 0x10000 and continue normally. This will compensate for the sign extension
212 * when the low bits are added at run time.
213 */
214 bfd_reloc_status_type
215 mips_fix_hi16_s (abfd,reloc_entry,symbol,data,input_section,output_bfd)
216 bfd *abfd;
217 arelent *reloc_entry;
218 struct symbol_cache_entry *symbol;
219 PTR data;
220 asection *input_section;
221 bfd *output_bfd;
222 {
223 bfd_vma relocation;
224
225 /* If this is a partial relocation, just continue. */
226 if (output_bfd != (bfd *)NULL)
227 return bfd_reloc_continue;
228
229 /*
230 * Work out which section the relocation is targetted at and the
231 * initial relocation command value.
232 */
233 if (symbol->section == &bfd_com_section)
234 relocation = 0;
235 else
236 relocation = symbol->value;
237
238 relocation += symbol->section->output_section->vma;
239 relocation += symbol->section->output_offset;
240 relocation += reloc_entry->addend;
241
242 if (relocation & 0x8000)
243 reloc_entry->addend += 0x10000;
244
245 return bfd_reloc_continue;
246 }
247
248 static reloc_howto_type mips_howto_table_ext[] = {
249 MIPS_RELOC_32, 0, 2, 32, false, 0, true, true, 0,
250 "32", false, 0, 0xffffffff, false,
251 MIPS_RELOC_JMP, 2, 2, 26, false, 0, false, true, 0,
252 "MIPS_JMP", false, 0, 0x03ffffff, false,
253 MIPS_RELOC_WDISP16, 2, 1, 16, true, 0, false, true, 0,
254 "WDISP16", false, 0, 0x0000ffff, false,
255 MIPS_RELOC_HI16, 16, 1, 16, false, 0, false, true, 0,
256 "HI16", false, 0, 0x0000ffff, false,
257 MIPS_RELOC_HI16_S, 16, 1, 16, false, 0, false, true, mips_fix_hi16_s,
258 "HI16_S", false, 0, 0x0000ffff, false,
259 MIPS_RELOC_LO16, 0, 1, 16, false, 0, false, true, 0,
260 "LO16", false, 0, 0x0000ffff, false,
261 };
262
263 static reloc_howto_type *
264 MY(reloc_howto_type_lookup) (abfd, code)
265 bfd *abfd;
266 bfd_reloc_code_real_type code;
267 {
268 extern reloc_howto_type NAME(aout,ext_howto_table)[];
269
270 switch (bfd_get_arch (abfd))
271 {
272 case bfd_arch_sparc:
273 switch (code)
274 {
275 default:
276 return 0;
277 #define IDX(i,j) case i: return &NAME(aout,ext_howto_table)[j]
278 IDX (BFD_RELOC_CTOR, 2);
279 IDX (BFD_RELOC_32, 2);
280 IDX (BFD_RELOC_HI22, 8);
281 IDX (BFD_RELOC_LO10, 11);
282 IDX (BFD_RELOC_32_PCREL_S2, 6);
283 }
284 case bfd_arch_mips:
285 switch (code)
286 {
287 case BFD_RELOC_32:
288 return (&mips_howto_table_ext[MIPS_RELOC_32]);
289 case BFD_RELOC_MIPS_JMP:
290 return (&mips_howto_table_ext[MIPS_RELOC_JMP]);
291 case BFD_RELOC_16_PCREL_S2:
292 return (&mips_howto_table_ext[MIPS_RELOC_WDISP16]);
293 case BFD_RELOC_HI16:
294 return (&mips_howto_table_ext[MIPS_RELOC_HI16]);
295 case BFD_RELOC_HI16_S:
296 return (&mips_howto_table_ext[MIPS_RELOC_HI16_S]);
297 case BFD_RELOC_LO16:
298 return (&mips_howto_table_ext[MIPS_RELOC_LO16]);
299 default:
300 return 0;
301 }
302 default:
303 return 0;
304 }
305 }
306
307 /*
308 * This is just like the standard aoutx.h version but we need to do our
309 * own mapping of external reloc type values to howto entries.
310 */
311 unsigned int
312 MY(canonicalize_reloc)(abfd, section, relptr, symbols)
313 bfd *abfd;
314 sec_ptr section;
315 arelent **relptr;
316 asymbol **symbols;
317 {
318 arelent *tblptr = section->relocation;
319 unsigned int count, c;
320 extern reloc_howto_type NAME(aout,ext_howto_table)[];
321
322 /* If we have already read in the relocation table, return the values. */
323 if (section->flags & SEC_CONSTRUCTOR) {
324 arelent_chain *chain = section->constructor_chain;
325
326 for (count = 0; count < section->reloc_count; count++) {
327 *relptr++ = &chain->relent;
328 chain = chain->next;
329 }
330 *relptr = 0;
331 return section->reloc_count;
332 }
333 if (tblptr && section->reloc_count) {
334 for (count = 0; count++ < section->reloc_count;)
335 *relptr++ = tblptr++;
336 *relptr = 0;
337 return section->reloc_count;
338 }
339
340 if (!NAME(aout,slurp_reloc_table)(abfd, section, symbols))
341 return 0;
342 tblptr = section->relocation;
343 if (!tblptr)
344 return 0;
345
346 /* fix up howto entries */
347 for (count = 0; count++ < section->reloc_count;)
348 {
349 c = tblptr->howto - NAME(aout,ext_howto_table);
350 tblptr->howto = &mips_howto_table_ext[c];
351
352 *relptr++ = tblptr++;
353 }
354 *relptr = 0;
355 return section->reloc_count;
356 }
357
358 static CONST struct aout_backend_data MY(backend_data) = {
359 0, /* zmagic contiguous */
360 1, /* text incl header */
361 PAGE_SIZE, /* text vma */
362 MY_set_sizes,
363 0, /* text size includes exec header */
364 };
365
366 bfd_target aout_mips_little_vec =
367 {
368 "aout-mips-little", /* name */
369 bfd_target_aout_flavour,
370 false, /* target byte order (little) */
371 false, /* target headers byte order (little) */
372 (HAS_RELOC | EXEC_P | /* object flags */
373 HAS_LINENO | HAS_DEBUG |
374 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
375 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
376 MY_symbol_leading_char,
377 ' ', /* ar_pad_char */
378 15, /* ar_max_namelen */
379 1, /* minimum alignment */
380 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
381 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* hdrs */
382 {_bfd_dummy_target, MY_object_p, /* bfd_check_format */
383 bfd_generic_archive_p, MY_core_file_p},
384 {bfd_false, MY_mkobject, /* bfd_set_format */
385 _bfd_generic_mkarchive, bfd_false},
386 {bfd_false, MY_write_object_contents, /* bfd_write_contents */
387 _bfd_write_archive_contents, bfd_false},
388
389 MY_core_file_failing_command,
390 MY_core_file_failing_signal,
391 MY_core_file_matches_executable_p,
392 MY_slurp_armap,
393 MY_slurp_extended_name_table,
394 MY_truncate_arname,
395 MY_write_armap,
396 MY_close_and_cleanup,
397 MY_set_section_contents,
398 MY_get_section_contents,
399 MY_new_section_hook,
400 MY_get_symtab_upper_bound,
401 MY_get_symtab,
402 MY_get_reloc_upper_bound,
403 MY_canonicalize_reloc,
404 MY_make_empty_symbol,
405 MY_print_symbol,
406 MY_get_lineno,
407 MY_set_arch_mach,
408 MY_openr_next_archived_file,
409 MY_find_nearest_line,
410 MY_generic_stat_arch_elt,
411 MY_sizeof_headers,
412 MY_bfd_debug_info_start,
413 MY_bfd_debug_info_end,
414 MY_bfd_debug_info_accumulate,
415 bfd_generic_get_relocated_section_contents,
416 bfd_generic_relax_section,
417 bfd_generic_seclet_link,
418 MY_reloc_howto_type_lookup,
419 MY_make_debug_symbol,
420 (PTR) MY_backend_data,
421 };
422
423 bfd_target aout_mips_big_vec =
424 {
425 "aout-mips-big", /* name */
426 bfd_target_aout_flavour,
427 true, /* target byte order (big) */
428 true, /* target headers byte order (big) */
429 (HAS_RELOC | EXEC_P | /* object flags */
430 HAS_LINENO | HAS_DEBUG |
431 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
432 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
433 MY_symbol_leading_char,
434 ' ', /* ar_pad_char */
435 15, /* ar_max_namelen */
436 1, /* minimum alignment */
437 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
438 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
439 {_bfd_dummy_target, MY_object_p, /* bfd_check_format */
440 bfd_generic_archive_p, MY_core_file_p},
441 {bfd_false, MY_mkobject, /* bfd_set_format */
442 _bfd_generic_mkarchive, bfd_false},
443 {bfd_false, MY_write_object_contents, /* bfd_write_contents */
444 _bfd_write_archive_contents, bfd_false},
445
446 MY_core_file_failing_command,
447 MY_core_file_failing_signal,
448 MY_core_file_matches_executable_p,
449 MY_slurp_armap,
450 MY_slurp_extended_name_table,
451 MY_truncate_arname,
452 MY_write_armap,
453 MY_close_and_cleanup,
454 MY_set_section_contents,
455 MY_get_section_contents,
456 MY_new_section_hook,
457 MY_get_symtab_upper_bound,
458 MY_get_symtab,
459 MY_get_reloc_upper_bound,
460 MY_canonicalize_reloc,
461 MY_make_empty_symbol,
462 MY_print_symbol,
463 MY_get_lineno,
464 MY_set_arch_mach,
465 MY_openr_next_archived_file,
466 MY_find_nearest_line,
467 MY_generic_stat_arch_elt,
468 MY_sizeof_headers,
469 MY_bfd_debug_info_start,
470 MY_bfd_debug_info_end,
471 MY_bfd_debug_info_accumulate,
472 bfd_generic_get_relocated_section_contents,
473 bfd_generic_relax_section,
474 bfd_generic_seclet_link,
475 MY_reloc_howto_type_lookup,
476 MY_make_debug_symbol,
477 (PTR) MY_backend_data,
478 };