1 |
/* BFD back-end for mmo objects (MMIX-specific object-format). |
/* BFD back-end for mmo objects (MMIX-specific object-format). |
2 |
Copyright 2001, 2002 |
Copyright 2001, 2002, 2003, 2004, 2005 |
3 |
Free Software Foundation, Inc. |
Free Software Foundation, Inc. |
4 |
Written by Hans-Peter Nilsson (hp@bitrange.com). |
Written by Hans-Peter Nilsson (hp@bitrange.com). |
5 |
Infrastructure and other bits originally copied from srec.c and |
Infrastructure and other bits originally copied from srec.c and |
61 |
@samp{0x2000@dots{}00} to @samp{0x20ff@dots{}ff} is used for |
@samp{0x2000@dots{}00} to @samp{0x20ff@dots{}ff} is used for |
62 |
writable data. @xref{mmo section mapping}. |
writable data. @xref{mmo section mapping}. |
63 |
|
|
64 |
|
There is provision for specifying ``special data'' of 65536 |
65 |
|
different types. We use type 80 (decimal), arbitrarily chosen the |
66 |
|
same as the ELF <<e_machine>> number for MMIX, filling it with |
67 |
|
section information normally found in ELF objects. @xref{mmo |
68 |
|
section mapping}. |
69 |
|
|
70 |
Contents is entered as 32-bit words, xor:ed over previous |
Contents is entered as 32-bit words, xor:ed over previous |
71 |
contents, always zero-initialized. A word that starts with the |
contents, always zero-initialized. A word that starts with the |
72 |
byte @samp{0x98} forms a command called a @samp{lopcode}, where |
byte @samp{0x98} forms a command called a @samp{lopcode}, where |
77 |
@url{http://www-cs-faculty.stanford.edu/~knuth/mmixal-intro.ps.gz}, |
@url{http://www-cs-faculty.stanford.edu/~knuth/mmixal-intro.ps.gz}, |
78 |
the lopcodes are: |
the lopcodes are: |
79 |
|
|
|
There is provision for specifying ``special data'' of 65536 |
|
|
different types. We use type 80 (decimal), arbitrarily chosen the |
|
|
same as the ELF <<e_machine>> number for MMIX, filling it with |
|
|
section information normally found in ELF objects. @xref{mmo |
|
|
section mapping}. |
|
|
|
|
80 |
@table @code |
@table @code |
81 |
@item lop_quote |
@item lop_quote |
82 |
0x98000001. The next word is contents, regardless of whether it |
0x98000001. The next word is contents, regardless of whether it |
260 |
struct mmo_symbol |
struct mmo_symbol |
261 |
{ |
{ |
262 |
struct mmo_symbol *next; |
struct mmo_symbol *next; |
263 |
const char *name; |
char *name; |
264 |
bfd_vma value; |
bfd_vma value; |
265 |
enum mmo_sym_type sym_type; |
enum mmo_sym_type sym_type; |
266 |
unsigned int serno; |
unsigned int serno; |
302 |
|
|
303 |
/* When we're reading bytes recursively, check this occasionally. |
/* When we're reading bytes recursively, check this occasionally. |
304 |
Also holds write errors. */ |
Also holds write errors. */ |
305 |
boolean have_error; |
bfd_boolean have_error; |
306 |
|
|
307 |
/* Max symbol length that may appear in the lop_stab table. Note that |
/* Max symbol length that may appear in the lop_stab table. Note that |
308 |
this table might just hold a subset of symbols for not-really large |
this table might just hold a subset of symbols for not-really large |
335 |
mmo_data_list_type *tail; |
mmo_data_list_type *tail; |
336 |
}; |
}; |
337 |
|
|
338 |
|
#define mmo_section_data(sec) \ |
339 |
|
((struct mmo_section_data_struct *) (sec)->used_by_bfd) |
340 |
|
|
341 |
/* These structures are used in bfd_map_over_sections constructs. */ |
/* These structures are used in bfd_map_over_sections constructs. */ |
342 |
|
|
343 |
/* Used when writing out sections; all but the register contents section |
/* Used when writing out sections; all but the register contents section |
345 |
struct mmo_write_sec_info |
struct mmo_write_sec_info |
346 |
{ |
{ |
347 |
asection *reg_section; |
asection *reg_section; |
348 |
boolean retval; |
bfd_boolean retval; |
349 |
}; |
}; |
350 |
|
|
351 |
/* Used when trying to find a section corresponding to addr. */ |
/* Used when trying to find a section corresponding to addr. */ |
355 |
bfd_vma addr; |
bfd_vma addr; |
356 |
}; |
}; |
357 |
|
|
358 |
static boolean mmo_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *)); |
static bfd_boolean mmo_bfd_copy_private_bfd_data (bfd *, bfd *); |
359 |
static void mmo_write_section_unless_reg_contents |
static void mmo_write_section_unless_reg_contents (bfd *, asection *, void *); |
360 |
PARAMS ((bfd *, asection *, PTR)); |
static void mmo_find_sec_w_addr (bfd *, asection *, void *); |
361 |
static void mmo_find_sec_w_addr PARAMS ((bfd *, asection *, PTR)); |
static void mmo_find_sec_w_addr_grow (bfd *, asection *, void *); |
362 |
static void mmo_find_sec_w_addr_grow PARAMS ((bfd *, asection *, PTR)); |
static asection *mmo_make_section (bfd *, const char *); |
363 |
static asection *mmo_make_section PARAMS ((bfd *, const char *)); |
static void mmo_get_symbol_info (bfd *, asymbol *, symbol_info *); |
364 |
static void mmo_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *)); |
static void mmo_print_symbol (bfd *, void *, asymbol *, |
365 |
static void mmo_print_symbol |
bfd_print_symbol_type); |
366 |
PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type)); |
static void mmo_init (void); |
367 |
static void mmo_init PARAMS ((void)); |
static bfd_boolean mmo_mkobject (bfd *); |
368 |
static boolean mmo_mkobject PARAMS ((bfd *)); |
static bfd_boolean mmo_scan (bfd *); |
369 |
static boolean mmo_scan PARAMS ((bfd *)); |
static asection *mmo_decide_section (bfd *, bfd_vma); |
370 |
static asection *mmo_decide_section PARAMS ((bfd *, bfd_vma)); |
static asection *mmo_get_generic_spec_data_section (bfd *, int); |
371 |
static asection *mmo_get_generic_spec_data_section PARAMS ((bfd *, int)); |
static asection *mmo_get_spec_section (bfd *, int); |
372 |
static asection *mmo_get_spec_section PARAMS ((bfd *, int)); |
static INLINE bfd_byte *mmo_get_loc (asection *, bfd_vma, int); |
373 |
static INLINE bfd_byte *mmo_get_loc PARAMS ((asection *, bfd_vma, int)); |
static void mmo_xore_64 (asection *, bfd_vma vma, bfd_vma value); |
374 |
static void mmo_xore_64 PARAMS ((asection *, bfd_vma vma, bfd_vma value)); |
static void mmo_xore_32 (asection *, bfd_vma vma, unsigned int); |
375 |
static void mmo_xore_32 PARAMS ((asection *, bfd_vma vma, unsigned int)); |
static void mmo_xore_16 (asection *, bfd_vma vma, unsigned int); |
376 |
static void mmo_xore_16 PARAMS ((asection *, bfd_vma vma, unsigned int)); |
static const bfd_target *mmo_object_p (bfd *); |
377 |
static const bfd_target *mmo_object_p PARAMS ((bfd *)); |
static void mmo_map_set_sizes (bfd *, asection *, void *); |
378 |
static void mmo_map_set_sizes PARAMS ((bfd *, asection *, PTR)); |
static bfd_boolean mmo_get_symbols (bfd *); |
379 |
static boolean mmo_get_symbols PARAMS ((bfd *)); |
static bfd_boolean mmo_create_symbol (bfd *, const char *, bfd_vma, |
380 |
static boolean mmo_create_symbol PARAMS ((bfd *, const char *, bfd_vma, |
enum mmo_sym_type, unsigned int); |
381 |
enum mmo_sym_type, unsigned int)); |
static bfd_boolean mmo_get_section_contents (bfd *, asection *, void *, |
382 |
static boolean mmo_get_section_contents |
file_ptr, bfd_size_type); |
383 |
PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); |
static long mmo_get_symtab_upper_bound (bfd *); |
384 |
static long mmo_get_symtab_upper_bound PARAMS ((bfd *)); |
static long mmo_canonicalize_symtab (bfd *, asymbol **); |
385 |
static long mmo_get_symtab PARAMS ((bfd *, asymbol **)); |
static void mmo_get_symbol_info (bfd *, asymbol *, symbol_info *); |
386 |
static void mmo_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *)); |
static void mmo_print_symbol (bfd *, void *, asymbol *, |
387 |
static void mmo_print_symbol PARAMS ((bfd *, PTR, asymbol *, |
bfd_print_symbol_type); |
388 |
bfd_print_symbol_type)); |
static bfd_boolean mmo_set_section_contents (bfd *, sec_ptr, const void *, |
389 |
static boolean mmo_set_section_contents |
file_ptr, bfd_size_type); |
390 |
PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type)); |
static int mmo_sizeof_headers (bfd *, bfd_boolean); |
391 |
static int mmo_sizeof_headers PARAMS ((bfd *, boolean)); |
static long mmo_get_reloc_upper_bound (bfd *, asection *); |
392 |
static long mmo_get_reloc_upper_bound PARAMS ((bfd *, asection *)); |
static bfd_boolean mmo_internal_write_header (bfd *); |
393 |
|
static bfd_boolean mmo_internal_write_post (bfd *, int, asection *); |
394 |
static boolean mmo_internal_write_header PARAMS ((bfd *)); |
static bfd_boolean mmo_internal_add_3_sym (bfd *, struct mmo_symbol_trie *, |
395 |
static boolean mmo_internal_write_post PARAMS ((bfd *, int, asection *)); |
const struct mmo_symbol *); |
396 |
static boolean mmo_internal_add_3_sym |
static unsigned int mmo_internal_3_length (bfd *, struct mmo_symbol_trie *); |
397 |
PARAMS ((bfd *, struct mmo_symbol_trie *, const struct mmo_symbol *)); |
static void mmo_internal_3_dump (bfd *, struct mmo_symbol_trie *); |
398 |
static unsigned int mmo_internal_3_length |
static void mmo_beb128_out (bfd *, int, int); |
399 |
PARAMS ((bfd *, struct mmo_symbol_trie *)); |
static bfd_boolean mmo_internal_write_section (bfd *, asection *); |
400 |
static void mmo_internal_3_dump |
static void mmo_write_tetra (bfd *, unsigned int); |
401 |
PARAMS ((bfd *, struct mmo_symbol_trie *)); |
static void mmo_write_tetra_raw (bfd *, unsigned int); |
402 |
static void mmo_beb128_out PARAMS ((bfd *, int, int)); |
static void mmo_write_octa (bfd *, bfd_vma); |
403 |
static boolean mmo_internal_write_section |
static void mmo_write_octa_raw (bfd *, bfd_vma); |
404 |
PARAMS ((bfd *, asection *)); |
static bfd_boolean mmo_write_chunk (bfd *, const bfd_byte *, unsigned int); |
405 |
static void mmo_write_tetra PARAMS ((bfd *, unsigned int)); |
static bfd_boolean mmo_flush_chunk (bfd *); |
406 |
static void mmo_write_tetra_raw PARAMS ((bfd *, unsigned int)); |
static bfd_boolean mmo_write_loc_chunk (bfd *, bfd_vma, const bfd_byte *, |
407 |
static void mmo_write_octa PARAMS ((bfd *, bfd_vma)); |
unsigned int, bfd_vma *); |
408 |
static void mmo_write_octa_raw PARAMS ((bfd *, bfd_vma)); |
static bfd_boolean mmo_write_chunk_list (bfd *, mmo_data_list_type *); |
409 |
static boolean mmo_write_chunk |
static bfd_boolean mmo_write_loc_chunk_list (bfd *, mmo_data_list_type *); |
410 |
PARAMS ((bfd *, const bfd_byte *, unsigned int)); |
static bfd_boolean mmo_write_symbols_and_terminator (bfd *); |
411 |
static boolean mmo_flush_chunk PARAMS ((bfd *)); |
static flagword mmo_sec_flags_from_bfd_flags (flagword); |
412 |
static boolean mmo_write_loc_chunk |
static flagword bfd_sec_flags_from_mmo_flags (flagword); |
413 |
PARAMS ((bfd *, bfd_vma, const bfd_byte *, unsigned int, bfd_vma *)); |
static bfd_byte mmo_get_byte (bfd *); |
414 |
static boolean mmo_write_chunk_list PARAMS ((bfd *, mmo_data_list_type *)); |
static void mmo_write_byte (bfd *, bfd_byte); |
415 |
static boolean mmo_write_loc_chunk_list |
static bfd_boolean mmo_new_section_hook (bfd *, asection *); |
416 |
PARAMS ((bfd *, mmo_data_list_type *)); |
static int mmo_sort_mmo_symbols (const void *, const void *); |
417 |
static boolean mmo_write_symbols_and_terminator PARAMS ((bfd *)); |
static bfd_boolean mmo_write_object_contents (bfd *); |
418 |
static flagword mmo_sec_flags_from_bfd_flags PARAMS ((flagword)); |
static long mmo_canonicalize_reloc (bfd *, sec_ptr, arelent **, asymbol **); |
419 |
static flagword bfd_sec_flags_from_mmo_flags PARAMS ((flagword)); |
static bfd_boolean mmo_write_section_description (bfd *, asection *); |
420 |
static bfd_byte mmo_get_byte PARAMS ((bfd *)); |
static bfd_boolean mmo_has_leading_or_trailing_zero_tetra_p (bfd *, |
421 |
static void mmo_write_byte PARAMS ((bfd *, bfd_byte)); |
asection *); |
|
static boolean mmo_new_section_hook PARAMS ((bfd *, asection *)); |
|
|
static int mmo_sort_mmo_symbols PARAMS ((const PTR, const PTR)); |
|
|
static boolean mmo_write_object_contents PARAMS ((bfd *)); |
|
|
static long mmo_canonicalize_reloc |
|
|
PARAMS ((bfd *, sec_ptr, arelent **, asymbol **)); |
|
422 |
|
|
423 |
/* Global "const" variables initialized once. Must not depend on |
/* Global "const" variables initialized once. Must not depend on |
424 |
particular input or caller; put such things into the bfd or elsewhere. |
particular input or caller; put such things into the bfd or elsewhere. |
425 |
Look ma, no static per-invocation data! */ |
Look ma, no static per-invocation data! */ |
426 |
|
|
427 |
static unsigned |
static |
428 |
char valid_mmo_symbol_character_set[/* A-Z a-z (we assume consecutive |
char valid_mmo_symbol_character_set[/* A-Z a-z (we assume consecutive |
429 |
codes; sorry EBCDIC:ers!). */ |
codes; sorry EBCDIC:ers!). */ |
430 |
+ 'Z' - 'A' + 1 + 'z' - 'a' + 1 |
+ 'Z' - 'A' + 1 + 'z' - 'a' + 1 |
442 |
one, new memory for the name is allocated. */ |
one, new memory for the name is allocated. */ |
443 |
|
|
444 |
static asection * |
static asection * |
445 |
mmo_make_section (abfd, secname) |
mmo_make_section (bfd *abfd, const char *secname) |
|
bfd *abfd; |
|
|
const char *secname; |
|
446 |
{ |
{ |
447 |
asection *sec = bfd_get_section_by_name (abfd, secname); |
asection *sec = bfd_get_section_by_name (abfd, secname); |
448 |
|
|
469 |
here, nor must it be static. Add it to tdata information instead. */ |
here, nor must it be static. Add it to tdata information instead. */ |
470 |
|
|
471 |
static void |
static void |
472 |
mmo_init () |
mmo_init (void) |
473 |
{ |
{ |
474 |
static boolean inited = false; |
static bfd_boolean inited = FALSE; |
475 |
int i = 0; |
int i = 0; |
476 |
int j = 0; |
int j = 0; |
477 |
static const char letters[] |
static const char letters[] |
479 |
|
|
480 |
if (inited) |
if (inited) |
481 |
return; |
return; |
482 |
inited = true; |
inited = TRUE; |
483 |
|
|
484 |
/* Fill in the set of valid symbol characters. */ |
/* Fill in the set of valid symbol characters. */ |
485 |
strcpy (valid_mmo_symbol_character_set, letters); |
strcpy (valid_mmo_symbol_character_set, letters); |
492 |
/* Check whether an existing file is an mmo file. */ |
/* Check whether an existing file is an mmo file. */ |
493 |
|
|
494 |
static const bfd_target * |
static const bfd_target * |
495 |
mmo_object_p (abfd) |
mmo_object_p (bfd *abfd) |
|
bfd *abfd; |
|
496 |
{ |
{ |
497 |
struct stat statbuf; |
struct stat statbuf; |
498 |
bfd_byte b[4]; |
bfd_byte b[4]; |
558 |
|
|
559 |
/* Set up the mmo tdata information. */ |
/* Set up the mmo tdata information. */ |
560 |
|
|
561 |
static boolean |
static bfd_boolean |
562 |
mmo_mkobject (abfd) |
mmo_mkobject (bfd *abfd) |
|
bfd *abfd; |
|
563 |
{ |
{ |
564 |
mmo_init (); |
mmo_init (); |
565 |
|
|
571 |
initialize most. */ |
initialize most. */ |
572 |
tdata_type *tdata = (tdata_type *) bfd_zmalloc (sizeof (tdata_type)); |
tdata_type *tdata = (tdata_type *) bfd_zmalloc (sizeof (tdata_type)); |
573 |
if (tdata == NULL) |
if (tdata == NULL) |
574 |
return false; |
return FALSE; |
575 |
|
|
576 |
created = time (NULL); |
created = time (NULL); |
577 |
bfd_put_32 (abfd, created, tdata->created); |
bfd_put_32 (abfd, created, tdata->created); |
579 |
abfd->tdata.mmo_data = tdata; |
abfd->tdata.mmo_data = tdata; |
580 |
} |
} |
581 |
|
|
582 |
return true; |
return TRUE; |
583 |
} |
} |
584 |
|
|
585 |
static boolean |
static bfd_boolean |
586 |
mmo_bfd_copy_private_bfd_data (ibfd, obfd) |
mmo_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd) |
|
bfd *ibfd; |
|
|
bfd *obfd; |
|
587 |
{ |
{ |
588 |
if (bfd_get_flavour (ibfd) != bfd_target_mmo_flavour |
if (bfd_get_flavour (ibfd) != bfd_target_mmo_flavour |
589 |
|| bfd_get_flavour (obfd) != bfd_target_mmo_flavour) |
|| bfd_get_flavour (obfd) != bfd_target_mmo_flavour) |
590 |
return true; |
return TRUE; |
591 |
|
|
592 |
/* Copy the time the copied-from file was created. If people want the |
/* Copy the time the copied-from file was created. If people want the |
593 |
time the file was last *modified*, they have that in the normal file |
time the file was last *modified*, they have that in the normal file |
594 |
information. */ |
information. */ |
595 |
memcpy (obfd->tdata.mmo_data->created, ibfd->tdata.mmo_data->created, |
memcpy (obfd->tdata.mmo_data->created, ibfd->tdata.mmo_data->created, |
596 |
sizeof (obfd->tdata.mmo_data->created)); |
sizeof (obfd->tdata.mmo_data->created)); |
597 |
return true; |
return TRUE; |
598 |
} |
} |
599 |
|
|
600 |
/* Helper functions for mmo_decide_section, used through |
/* Helper functions for mmo_decide_section, used through |
601 |
bfd_map_over_sections. */ |
bfd_map_over_sections. */ |
602 |
|
|
603 |
static void |
static void |
604 |
mmo_find_sec_w_addr (abfd, sec, p) |
mmo_find_sec_w_addr (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *p) |
|
bfd *abfd ATTRIBUTE_UNUSED; |
|
|
asection *sec; |
|
|
PTR p; |
|
605 |
{ |
{ |
606 |
struct mmo_find_sec_info *infop = (struct mmo_find_sec_info *) p; |
struct mmo_find_sec_info *infop = (struct mmo_find_sec_info *) p; |
607 |
bfd_vma vma = bfd_get_section_vma (abfd, sec); |
bfd_vma vma = bfd_get_section_vma (abfd, sec); |
611 |
!= (SEC_LOAD | SEC_ALLOC)) |
!= (SEC_LOAD | SEC_ALLOC)) |
612 |
return; |
return; |
613 |
|
|
614 |
if (infop->addr >= vma && infop->addr < vma + sec->_raw_size) |
if (infop->addr >= vma && infop->addr < vma + sec->size) |
615 |
infop->sec = sec; |
infop->sec = sec; |
616 |
} |
} |
617 |
|
|
618 |
static void |
static void |
619 |
mmo_find_sec_w_addr_grow (abfd, sec, p) |
mmo_find_sec_w_addr_grow (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *p) |
|
bfd *abfd ATTRIBUTE_UNUSED; |
|
|
asection *sec; |
|
|
PTR p; |
|
620 |
{ |
{ |
621 |
struct mmo_find_sec_info *infop = (struct mmo_find_sec_info *) p; |
struct mmo_find_sec_info *infop = (struct mmo_find_sec_info *) p; |
622 |
bfd_vma vma = bfd_get_section_vma (abfd, sec); |
bfd_vma vma = bfd_get_section_vma (abfd, sec); |
636 |
increasing number. */ |
increasing number. */ |
637 |
|
|
638 |
static asection * |
static asection * |
639 |
mmo_decide_section (abfd, vma) |
mmo_decide_section (bfd *abfd, bfd_vma vma) |
|
bfd *abfd; |
|
|
bfd_vma vma; |
|
640 |
{ |
{ |
641 |
asection *sec = NULL; |
asection *sec = NULL; |
642 |
char sec_name[sizeof (".MMIX.sec.") + 20]; |
char sec_name[sizeof (".MMIX.sec.") + 20]; |
705 |
/* Xor in a 64-bit value VALUE at VMA. */ |
/* Xor in a 64-bit value VALUE at VMA. */ |
706 |
|
|
707 |
static INLINE void |
static INLINE void |
708 |
mmo_xore_64 (sec, vma, value) |
mmo_xore_64 (asection *sec, bfd_vma vma, bfd_vma value) |
|
asection *sec; |
|
|
bfd_vma vma; |
|
|
bfd_vma value; |
|
709 |
{ |
{ |
710 |
bfd_byte *loc = mmo_get_loc (sec, vma, 8); |
bfd_byte *loc = mmo_get_loc (sec, vma, 8); |
711 |
bfd_vma prev = bfd_get_64 (sec->owner, loc); |
bfd_vma prev = bfd_get_64 (sec->owner, loc); |
717 |
/* Xor in a 32-bit value VALUE at VMA. */ |
/* Xor in a 32-bit value VALUE at VMA. */ |
718 |
|
|
719 |
static INLINE void |
static INLINE void |
720 |
mmo_xore_32 (sec, vma, value) |
mmo_xore_32 (asection *sec, bfd_vma vma, unsigned int value) |
|
asection *sec; |
|
|
bfd_vma vma; |
|
|
unsigned int value; |
|
721 |
{ |
{ |
722 |
bfd_byte *loc = mmo_get_loc (sec, vma, 4); |
bfd_byte *loc = mmo_get_loc (sec, vma, 4); |
723 |
unsigned int prev = bfd_get_32 (sec->owner, loc); |
unsigned int prev = bfd_get_32 (sec->owner, loc); |
729 |
/* Xor in a 16-bit value VALUE at VMA. */ |
/* Xor in a 16-bit value VALUE at VMA. */ |
730 |
|
|
731 |
static INLINE void |
static INLINE void |
732 |
mmo_xore_16 (sec, vma, value) |
mmo_xore_16 (asection *sec, bfd_vma vma, unsigned int value) |
|
asection *sec; |
|
|
bfd_vma vma; |
|
|
unsigned int value; |
|
733 |
{ |
{ |
734 |
bfd_byte *loc = mmo_get_loc (sec, vma, 2); |
bfd_byte *loc = mmo_get_loc (sec, vma, 2); |
735 |
unsigned int prev = bfd_get_16 (sec->owner, loc); |
unsigned int prev = bfd_get_16 (sec->owner, loc); |
741 |
/* Write a 32-bit word to output file, no lop_quote generated. */ |
/* Write a 32-bit word to output file, no lop_quote generated. */ |
742 |
|
|
743 |
static INLINE void |
static INLINE void |
744 |
mmo_write_tetra_raw (abfd, value) |
mmo_write_tetra_raw (bfd *abfd, unsigned int value) |
|
bfd *abfd; |
|
|
unsigned int value; |
|
745 |
{ |
{ |
746 |
bfd_byte buf[4]; |
bfd_byte buf[4]; |
747 |
|
|
748 |
bfd_put_32 (abfd, value, buf); |
bfd_put_32 (abfd, value, buf); |
749 |
|
|
750 |
if (bfd_bwrite ((PTR) buf, 4, abfd) != 4) |
if (bfd_bwrite (buf, 4, abfd) != 4) |
751 |
abfd->tdata.mmo_data->have_error = true; |
abfd->tdata.mmo_data->have_error = TRUE; |
752 |
} |
} |
753 |
|
|
754 |
/* Write a 32-bit word to output file; lop_quote if necessary. */ |
/* Write a 32-bit word to output file; lop_quote if necessary. */ |
755 |
|
|
756 |
static INLINE void |
static INLINE void |
757 |
mmo_write_tetra (abfd, value) |
mmo_write_tetra (bfd *abfd, unsigned int value) |
|
bfd *abfd; |
|
|
unsigned int value; |
|
758 |
{ |
{ |
759 |
if (((value >> 24) & 0xff) == LOP) |
if (((value >> 24) & 0xff) == LOP) |
760 |
mmo_write_tetra_raw (abfd, LOP_QUOTE_NEXT); |
mmo_write_tetra_raw (abfd, LOP_QUOTE_NEXT); |
765 |
/* Write a 64-bit word to output file, perhaps with lop_quoting. */ |
/* Write a 64-bit word to output file, perhaps with lop_quoting. */ |
766 |
|
|
767 |
static INLINE void |
static INLINE void |
768 |
mmo_write_octa (abfd, value) |
mmo_write_octa (bfd *abfd, bfd_vma value) |
|
bfd *abfd; |
|
|
bfd_vma value; |
|
769 |
{ |
{ |
770 |
mmo_write_tetra (abfd, (unsigned int) (value >> 32)); |
mmo_write_tetra (abfd, (unsigned int) (value >> 32)); |
771 |
mmo_write_tetra (abfd, (unsigned int) value); |
mmo_write_tetra (abfd, (unsigned int) value); |
774 |
/* Write a 64-bit word to output file, without lop_quoting. */ |
/* Write a 64-bit word to output file, without lop_quoting. */ |
775 |
|
|
776 |
static INLINE void |
static INLINE void |
777 |
mmo_write_octa_raw (abfd, value) |
mmo_write_octa_raw (bfd *abfd, bfd_vma value) |
|
bfd *abfd; |
|
|
bfd_vma value; |
|
778 |
{ |
{ |
779 |
mmo_write_tetra_raw (abfd, (unsigned int) (value >> 32)); |
mmo_write_tetra_raw (abfd, (unsigned int) (value >> 32)); |
780 |
mmo_write_tetra_raw (abfd, (unsigned int) value); |
mmo_write_tetra_raw (abfd, (unsigned int) value); |
783 |
/* Write quoted contents. Intended to be called multiple times in |
/* Write quoted contents. Intended to be called multiple times in |
784 |
sequence, followed by a call to mmo_flush_chunk. */ |
sequence, followed by a call to mmo_flush_chunk. */ |
785 |
|
|
786 |
static INLINE boolean |
static INLINE bfd_boolean |
787 |
mmo_write_chunk (abfd, loc, len) |
mmo_write_chunk (bfd *abfd, const bfd_byte *loc, unsigned int len) |
|
bfd *abfd; |
|
|
const bfd_byte *loc; |
|
|
unsigned int len; |
|
788 |
{ |
{ |
789 |
boolean retval = true; |
bfd_boolean retval = TRUE; |
790 |
|
|
791 |
/* Fill up a tetra from bytes remaining from a previous chunk. */ |
/* Fill up a tetra from bytes remaining from a previous chunk. */ |
792 |
if (abfd->tdata.mmo_data->byte_no != 0) |
if (abfd->tdata.mmo_data->byte_no != 0) |
812 |
|
|
813 |
retval = (retval |
retval = (retval |
814 |
&& ! abfd->tdata.mmo_data->have_error |
&& ! abfd->tdata.mmo_data->have_error |
815 |
&& 4 == bfd_bwrite ((PTR) loc, 4, abfd)); |
&& 4 == bfd_bwrite (loc, 4, abfd)); |
816 |
|
|
817 |
loc += 4; |
loc += 4; |
818 |
len -= 4; |
len -= 4; |
825 |
} |
} |
826 |
|
|
827 |
if (! retval) |
if (! retval) |
828 |
abfd->tdata.mmo_data->have_error = true; |
abfd->tdata.mmo_data->have_error = TRUE; |
829 |
return retval; |
return retval; |
830 |
} |
} |
831 |
|
|
832 |
/* Flush remaining bytes, from a previous mmo_write_chunk, zero-padded to |
/* Flush remaining bytes, from a previous mmo_write_chunk, zero-padded to |
833 |
4 bytes. */ |
4 bytes. */ |
834 |
|
|
835 |
static INLINE boolean |
static INLINE bfd_boolean |
836 |
mmo_flush_chunk (abfd) |
mmo_flush_chunk (bfd *abfd) |
|
bfd *abfd; |
|
837 |
{ |
{ |
838 |
if (abfd->tdata.mmo_data->byte_no != 0) |
if (abfd->tdata.mmo_data->byte_no != 0) |
839 |
{ |
{ |
849 |
|
|
850 |
/* Same, but from a list. */ |
/* Same, but from a list. */ |
851 |
|
|
852 |
static INLINE boolean |
static INLINE bfd_boolean |
853 |
mmo_write_chunk_list (abfd, datap) |
mmo_write_chunk_list (bfd *abfd, mmo_data_list_type *datap) |
|
bfd *abfd; |
|
|
mmo_data_list_type *datap; |
|
854 |
{ |
{ |
855 |
for (; datap != NULL; datap = datap->next) |
for (; datap != NULL; datap = datap->next) |
856 |
if (! mmo_write_chunk (abfd, datap->data, datap->size)) |
if (! mmo_write_chunk (abfd, datap->data, datap->size)) |
857 |
return false; |
return FALSE; |
858 |
|
|
859 |
return mmo_flush_chunk (abfd); |
return mmo_flush_chunk (abfd); |
860 |
} |
} |
863 |
mmo_flush_chunk after calling this function. The location is only |
mmo_flush_chunk after calling this function. The location is only |
864 |
output if different than *LAST_VMAP, which is updated after this call. */ |
output if different than *LAST_VMAP, which is updated after this call. */ |
865 |
|
|
866 |
static boolean |
static bfd_boolean |
867 |
mmo_write_loc_chunk (abfd, vma, loc, len, last_vmap) |
mmo_write_loc_chunk (bfd *abfd, bfd_vma vma, const bfd_byte *loc, |
868 |
bfd *abfd; |
unsigned int len, bfd_vma *last_vmap) |
|
bfd_vma vma; |
|
|
const bfd_byte *loc; |
|
|
unsigned int len; |
|
|
bfd_vma *last_vmap; |
|
869 |
{ |
{ |
870 |
/* Find an initial and trailing section of zero tetras; we don't need to |
/* Find an initial and trailing section of zero tetras; we don't need to |
871 |
write out zeros. FIXME: When we do this, we should emit section size |
write out zeros. FIXME: When we do this, we should emit section size |
910 |
|
|
911 |
/* Same, but from a list. */ |
/* Same, but from a list. */ |
912 |
|
|
913 |
static INLINE boolean |
static INLINE bfd_boolean |
914 |
mmo_write_loc_chunk_list (abfd, datap) |
mmo_write_loc_chunk_list (bfd *abfd, mmo_data_list_type *datap) |
|
bfd *abfd; |
|
|
mmo_data_list_type *datap; |
|
915 |
{ |
{ |
916 |
/* Get an address different than the address of the first chunk. */ |
/* Get an address different than the address of the first chunk. */ |
917 |
bfd_vma last_vma = datap ? datap->where - 1 : 0; |
bfd_vma last_vma = datap ? datap->where - 1 : 0; |
919 |
for (; datap != NULL; datap = datap->next) |
for (; datap != NULL; datap = datap->next) |
920 |
if (! mmo_write_loc_chunk (abfd, datap->where, datap->data, datap->size, |
if (! mmo_write_loc_chunk (abfd, datap->where, datap->data, datap->size, |
921 |
&last_vma)) |
&last_vma)) |
922 |
return false; |
return FALSE; |
923 |
|
|
924 |
return mmo_flush_chunk (abfd); |
return mmo_flush_chunk (abfd); |
925 |
} |
} |
927 |
/* Make a .MMIX.spec_data.N section. */ |
/* Make a .MMIX.spec_data.N section. */ |
928 |
|
|
929 |
static asection * |
static asection * |
930 |
mmo_get_generic_spec_data_section (abfd, spec_data_number) |
mmo_get_generic_spec_data_section (bfd *abfd, int spec_data_number) |
|
bfd *abfd; |
|
|
int spec_data_number; |
|
931 |
{ |
{ |
932 |
asection *sec; |
asection *sec; |
933 |
char secname[sizeof (MMIX_OTHER_SPEC_SECTION_PREFIX) + 20] |
char secname[sizeof (MMIX_OTHER_SPEC_SECTION_PREFIX) + 20] |
945 |
ourselves, parse some of its data to get at the section name. */ |
ourselves, parse some of its data to get at the section name. */ |
946 |
|
|
947 |
static asection * |
static asection * |
948 |
mmo_get_spec_section (abfd, spec_data_number) |
mmo_get_spec_section (bfd *abfd, int spec_data_number) |
|
bfd *abfd; |
|
|
int spec_data_number; |
|
949 |
{ |
{ |
950 |
bfd_byte *secname; |
char *secname; |
951 |
asection *sec; |
asection *sec; |
952 |
bfd_byte buf[4]; |
bfd_byte buf[4]; |
953 |
unsigned int secname_length; |
unsigned int secname_length; |
996 |
if (bfd_bread (secname + i * 4, 4, abfd) != 4) |
if (bfd_bread (secname + i * 4, 4, abfd) != 4) |
997 |
goto format_error_free; |
goto format_error_free; |
998 |
|
|
999 |
if (secname[i * 4] == LOP) |
if (secname[i * 4] == (char) LOP) |
1000 |
{ |
{ |
1001 |
/* A bit of overkill, but we handle char 0x98 in a section name, |
/* A bit of overkill, but we handle char 0x98 in a section name, |
1002 |
and recognize misparsing. */ |
and recognize misparsing. */ |
1076 |
bfd_sec_flags_from_mmo_flags (flags) |
bfd_sec_flags_from_mmo_flags (flags) |
1077 |
| bfd_get_section_flags (abfd, sec) |
| bfd_get_section_flags (abfd, sec) |
1078 |
| (section_length != 0 ? SEC_HAS_CONTENTS : 0)) |
| (section_length != 0 ? SEC_HAS_CONTENTS : 0)) |
1079 |
|| ! bfd_set_section_size (abfd, sec, |
|| ! bfd_set_section_size (abfd, sec, sec->size + section_length) |
|
sec->_cooked_size + section_length) |
|
1080 |
/* Set VMA only for the first occurrence. */ |
/* Set VMA only for the first occurrence. */ |
1081 |
|| (! sec->user_set_vma |
|| (! sec->user_set_vma |
1082 |
&& ! bfd_set_section_vma (abfd, sec, section_vma))) |
&& ! bfd_set_section_vma (abfd, sec, section_vma))) |
1087 |
} |
} |
1088 |
|
|
1089 |
loc->next = NULL; |
loc->next = NULL; |
1090 |
if (((struct mmo_section_data_struct *) (sec->used_by_bfd))->tail != NULL) |
if (mmo_section_data (sec)->tail != NULL) |
1091 |
((struct mmo_section_data_struct *) (sec->used_by_bfd))->tail->next |
mmo_section_data (sec)->tail->next = loc; |
|
= loc; |
|
1092 |
else |
else |
1093 |
((struct mmo_section_data_struct *) (sec->used_by_bfd))->head = loc; |
mmo_section_data (sec)->head = loc; |
1094 |
((struct mmo_section_data_struct *) (sec->used_by_bfd))->tail = loc; |
mmo_section_data (sec)->tail = loc; |
1095 |
loc->where = section_vma; |
loc->where = section_vma; |
1096 |
|
|
1097 |
return sec; |
return sec; |
1108 |
/* Read a byte, but read from file in multiples of 32-bit words. */ |
/* Read a byte, but read from file in multiples of 32-bit words. */ |
1109 |
|
|
1110 |
static bfd_byte |
static bfd_byte |
1111 |
mmo_get_byte (abfd) |
mmo_get_byte (bfd *abfd) |
|
bfd *abfd; |
|
1112 |
{ |
{ |
1113 |
bfd_byte retval; |
bfd_byte retval; |
1114 |
|
|
1117 |
if (! abfd->tdata.mmo_data->have_error |
if (! abfd->tdata.mmo_data->have_error |
1118 |
&& bfd_bread (abfd->tdata.mmo_data->buf, 4, abfd) != 4) |
&& bfd_bread (abfd->tdata.mmo_data->buf, 4, abfd) != 4) |
1119 |
{ |
{ |
1120 |
abfd->tdata.mmo_data->have_error = true; |
abfd->tdata.mmo_data->have_error = TRUE; |
1121 |
|
|
1122 |
/* A value somewhat safe against tripping on some inconsistency |
/* A value somewhat safe against tripping on some inconsistency |
1123 |
when mopping up after this error. */ |
when mopping up after this error. */ |
1134 |
/* Write a byte, in multiples of 32-bit words. */ |
/* Write a byte, in multiples of 32-bit words. */ |
1135 |
|
|
1136 |
static void |
static void |
1137 |
mmo_write_byte (abfd, value) |
mmo_write_byte (bfd *abfd, bfd_byte value) |
|
bfd *abfd; |
|
|
bfd_byte value; |
|
1138 |
{ |
{ |
1139 |
abfd->tdata.mmo_data->buf[(abfd->tdata.mmo_data->byte_no++ % 4)] = value; |
abfd->tdata.mmo_data->buf[(abfd->tdata.mmo_data->byte_no++ % 4)] = value; |
1140 |
if ((abfd->tdata.mmo_data->byte_no % 4) == 0) |
if ((abfd->tdata.mmo_data->byte_no % 4) == 0) |
1141 |
{ |
{ |
1142 |
if (! abfd->tdata.mmo_data->have_error |
if (! abfd->tdata.mmo_data->have_error |
1143 |
&& bfd_bwrite (abfd->tdata.mmo_data->buf, 4, abfd) != 4) |
&& bfd_bwrite (abfd->tdata.mmo_data->buf, 4, abfd) != 4) |
1144 |
abfd->tdata.mmo_data->have_error = true; |
abfd->tdata.mmo_data->have_error = TRUE; |
1145 |
} |
} |
1146 |
} |
} |
1147 |
|
|
1148 |
/* Create a symbol. */ |
/* Create a symbol. */ |
1149 |
|
|
1150 |
static boolean |
static bfd_boolean |
1151 |
mmo_create_symbol (abfd, symname, addr, sym_type, serno) |
mmo_create_symbol (bfd *abfd, const char *symname, bfd_vma addr, enum |
1152 |
bfd *abfd; |
mmo_sym_type sym_type, unsigned int serno) |
|
const char *symname; |
|
|
bfd_vma addr; |
|
|
enum mmo_sym_type sym_type; |
|
|
unsigned int serno; |
|
1153 |
{ |
{ |
1154 |
struct mmo_symbol *n; |
struct mmo_symbol *n; |
1155 |
|
|
1156 |
n = (struct mmo_symbol *) bfd_alloc (abfd, sizeof (struct mmo_symbol)); |
n = (struct mmo_symbol *) bfd_alloc (abfd, sizeof (struct mmo_symbol)); |
1157 |
if (n == NULL) |
if (n == NULL) |
1158 |
return false; |
return FALSE; |
1159 |
|
|
1160 |
n->name = bfd_alloc (abfd, strlen (symname) + 1); |
n->name = bfd_alloc (abfd, strlen (symname) + 1); |
1161 |
if (n->name == NULL) |
if (n->name == NULL) |
1162 |
return false; |
return FALSE; |
1163 |
|
|
1164 |
strcpy ((PTR) n->name, symname); |
strcpy (n->name, symname); |
1165 |
|
|
1166 |
n->value = addr; |
n->value = addr; |
1167 |
n->sym_type = sym_type; |
n->sym_type = sym_type; |
1187 |
(_("%s: invalid mmo file: initialization value for $255 is not `Main'\n"), |
(_("%s: invalid mmo file: initialization value for $255 is not `Main'\n"), |
1188 |
bfd_get_filename (abfd)); |
bfd_get_filename (abfd)); |
1189 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
1190 |
return false; |
return FALSE; |
1191 |
} |
} |
1192 |
|
|
1193 |
return true; |
return TRUE; |
1194 |
} |
} |
1195 |
|
|
1196 |
/* Read in symbols. */ |
/* Read in symbols. */ |
1197 |
|
|
1198 |
static boolean |
static bfd_boolean |
1199 |
mmo_get_symbols (abfd) |
mmo_get_symbols (bfd *abfd) |
|
bfd *abfd; |
|
1200 |
{ |
{ |
1201 |
/* |
/* |
1202 |
INODE |
INODE |
1301 |
|
|
1302 |
/* Check first if we have a bad hair day. */ |
/* Check first if we have a bad hair day. */ |
1303 |
if (abfd->tdata.mmo_data->have_error) |
if (abfd->tdata.mmo_data->have_error) |
1304 |
return false; |
return FALSE; |
1305 |
|
|
1306 |
if (m & MMO3_LEFT) |
if (m & MMO3_LEFT) |
1307 |
/* Traverse left trie. */ |
/* Traverse left trie. */ |
1329 |
[abfd->tdata.mmo_data->symbol_position] = 0; |
[abfd->tdata.mmo_data->symbol_position] = 0; |
1330 |
|
|
1331 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
1332 |
(_("%s: unsupported wide character sequence\ |
(_("%s: unsupported wide character sequence" |
1333 |
0x%02X 0x%02X after symbol name starting with `%s'\n"), |
" 0x%02X 0x%02X after symbol name starting with `%s'\n"), |
1334 |
bfd_get_filename (abfd), c, c2, |
bfd_get_filename (abfd), c, c2, |
1335 |
abfd->tdata.mmo_data->lop_stab_symbol); |
abfd->tdata.mmo_data->lop_stab_symbol); |
1336 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
1337 |
abfd->tdata.mmo_data->have_error = true; |
abfd->tdata.mmo_data->have_error = TRUE; |
1338 |
return false; |
return FALSE; |
1339 |
} |
} |
1340 |
else |
else |
1341 |
c = c2; |
c = c2; |
1389 |
abfd->tdata.mmo_data->lop_stab_symbol |
abfd->tdata.mmo_data->lop_stab_symbol |
1390 |
+ 1, |
+ 1, |
1391 |
addr, sym_type, serno)) |
addr, sym_type, serno)) |
1392 |
abfd->tdata.mmo_data->have_error = true; |
abfd->tdata.mmo_data->have_error = TRUE; |
1393 |
} |
} |
1394 |
|
|
1395 |
if (m & MMO3_MIDDLE) |
if (m & MMO3_MIDDLE) |
1412 |
MMO_SEC_CONTENTS_CHUNK_SIZE. */ |
MMO_SEC_CONTENTS_CHUNK_SIZE. */ |
1413 |
|
|
1414 |
static INLINE bfd_byte * |
static INLINE bfd_byte * |
1415 |
mmo_get_loc (sec, vma, size) |
mmo_get_loc (asection *sec, bfd_vma vma, int size) |
|
asection *sec; |
|
|
bfd_vma vma; |
|
|
int size; |
|
1416 |
{ |
{ |
1417 |
bfd_size_type allocated_size; |
bfd_size_type allocated_size; |
1418 |
struct mmo_section_data_struct *sdatap |
struct mmo_section_data_struct *sdatap = mmo_section_data (sec); |
|
= (struct mmo_section_data_struct *) sec->used_by_bfd; |
|
1419 |
struct mmo_data_list_struct *datap = sdatap->head; |
struct mmo_data_list_struct *datap = sdatap->head; |
1420 |
struct mmo_data_list_struct *entry; |
struct mmo_data_list_struct *entry; |
1421 |
|
|
1441 |
non-32-bit-aligned sections should do all allocation and |
non-32-bit-aligned sections should do all allocation and |
1442 |
size-setting by themselves or at least set the section size |
size-setting by themselves or at least set the section size |
1443 |
after the last allocating call to this function. */ |
after the last allocating call to this function. */ |
1444 |
if (vma + size > sec->vma + sec->_raw_size) |
if (vma + size > sec->vma + sec->size) |
1445 |
sec->_raw_size += (vma + size) - (sec->vma + sec->_raw_size); |
sec->size += (vma + size) - (sec->vma + sec->size); |
1446 |
|
|
1447 |
return datap->data + vma - datap->where; |
return datap->data + vma - datap->where; |
1448 |
} |
} |
1504 |
|
|
1505 |
/* Update the section size. This happens only when we add contents and |
/* Update the section size. This happens only when we add contents and |
1506 |
re-size as we go. The section size will then be aligned to 32 bits. */ |
re-size as we go. The section size will then be aligned to 32 bits. */ |
1507 |
if (vma + size > sec->vma + sec->_raw_size) |
if (vma + size > sec->vma + sec->size) |
1508 |
sec->_raw_size += (vma + size) - (sec->vma + sec->_raw_size); |
sec->size += (vma + size) - (sec->vma + sec->size); |
1509 |
return entry->data; |
return entry->data; |
1510 |
} |
} |
1511 |
|
|
1512 |
/* Set sizes once we've read in all sections. */ |
/* Set sizes once we've read in all sections. */ |
1513 |
|
|
1514 |
static void |
static void |
1515 |
mmo_map_set_sizes (abfd, sec, ignored) |
mmo_map_set_sizes (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, |
1516 |
bfd *abfd ATTRIBUTE_UNUSED; |
void *ignored ATTRIBUTE_UNUSED) |
|
asection *sec; |
|
|
PTR ignored ATTRIBUTE_UNUSED; |
|
1517 |
{ |
{ |
|
sec->_cooked_size = sec->_raw_size; |
|
1518 |
sec->lma = sec->vma; |
sec->lma = sec->vma; |
1519 |
} |
} |
1520 |
|
|
1521 |
/* Read the mmo file and turn it into sections. */ |
/* Read the mmo file and turn it into sections. */ |
1522 |
|
|
1523 |
static boolean |
static bfd_boolean |
1524 |
mmo_scan (abfd) |
mmo_scan (bfd *abfd) |
|
bfd *abfd; |
|
1525 |
{ |
{ |
1526 |
unsigned int i; |
unsigned int i; |
1527 |
unsigned int lineno = 1; |
unsigned int lineno = 1; |
1528 |
boolean error = false; |
bfd_boolean error = FALSE; |
1529 |
bfd_vma vma = 0; |
bfd_vma vma = 0; |
1530 |
asection *sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME); |
asection *sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME); |
1531 |
asection *non_spec_sec = NULL; |
asection *non_spec_sec = NULL; |
1769 |
if (file_names[y] != NULL) |
if (file_names[y] != NULL) |
1770 |
{ |
{ |
1771 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
1772 |
(_("%s: invalid mmo file: file number %d `%s',\ |
(_("%s: invalid mmo file: file number %d `%s'," |
1773 |
was already entered as `%s'\n"), |
" was already entered as `%s'\n"), |
1774 |
bfd_get_filename (abfd), y, fname, file_names[y]); |
bfd_get_filename (abfd), y, fname, file_names[y]); |
1775 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
1776 |
goto error_return; |
goto error_return; |
1782 |
if (file_names[y] == NULL) |
if (file_names[y] == NULL) |
1783 |
{ |
{ |
1784 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
1785 |
(_("%s: invalid mmo file: file name for number %d\ |
(_("%s: invalid mmo file: file name for number %d" |
1786 |
was not specified before use\n"), |
" was not specified before use\n"), |
1787 |
bfd_get_filename (abfd), y); |
bfd_get_filename (abfd), y); |
1788 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
1789 |
goto error_return; |
goto error_return; |
1888 |
if (y != 0 || z != 0) |
if (y != 0 || z != 0) |
1889 |
{ |
{ |
1890 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
1891 |
(_("%s: invalid mmo file: fields y and z of lop_stab\ |
(_("%s: invalid mmo file: fields y and z of lop_stab" |
1892 |
non-zero, y: %d, z: %d\n"), |
" non-zero, y: %d, z: %d\n"), |
1893 |
bfd_get_filename (abfd), y, z); |
bfd_get_filename (abfd), y, z); |
1894 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
1895 |
goto error_return; |
goto error_return; |
1924 |
if (statbuf.st_size != curpos) |
if (statbuf.st_size != curpos) |
1925 |
{ |
{ |
1926 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
1927 |
(_("%s: invalid mmo file: lop_end not last item in\ |
(_("%s: invalid mmo file: lop_end not last item in" |
1928 |
file\n"), |
" file\n"), |
1929 |
bfd_get_filename (abfd)); |
bfd_get_filename (abfd)); |
1930 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
1931 |
goto error_return; |
goto error_return; |
1937 |
if ((long) (y * 256 + z) * 4 != (curpos - stab_loc) - 4) |
if ((long) (y * 256 + z) * 4 != (curpos - stab_loc) - 4) |
1938 |
{ |
{ |
1939 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
1940 |
(_("%s: invalid mmo file: YZ of lop_end (%ld)\ |
(_("%s: invalid mmo file: YZ of lop_end (%ld)" |
1941 |
not equal to the number of tetras to the preceding lop_stab (%ld)\n"), |
" not equal to the number of tetras to the preceding" |
1942 |
|
" lop_stab (%ld)\n"), |
1943 |
bfd_get_filename (abfd), (long) (y * 256 + z), |
bfd_get_filename (abfd), (long) (y * 256 + z), |
1944 |
(curpos - stab_loc - 4)/4); |
(curpos - stab_loc - 4)/4); |
1945 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
1973 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
1974 |
|
|
1975 |
error_return: |
error_return: |
1976 |
error = true; |
error = TRUE; |
1977 |
done: |
done: |
1978 |
/* Mark the .text and .data section with their normal attribute if they |
/* Mark the .text and .data section with their normal attribute if they |
1979 |
contain anything. This is not redundant wrt. mmo_decide_section, |
contain anything. This is not redundant wrt. mmo_decide_section, |
1985 |
&& ! bfd_set_section_flags (abfd, sec, |
&& ! bfd_set_section_flags (abfd, sec, |
1986 |
bfd_get_section_flags (abfd, sec) |
bfd_get_section_flags (abfd, sec) |
1987 |
| SEC_ALLOC | SEC_LOAD | SEC_CODE)) |
| SEC_ALLOC | SEC_LOAD | SEC_CODE)) |
1988 |
error = true; |
error = TRUE; |
1989 |
|
|
1990 |
sec = bfd_get_section_by_name (abfd, MMO_DATA_SECTION_NAME); |
sec = bfd_get_section_by_name (abfd, MMO_DATA_SECTION_NAME); |
1991 |
if (sec != NULL |
if (sec != NULL |
1993 |
&& ! bfd_set_section_flags (abfd, sec, |
&& ! bfd_set_section_flags (abfd, sec, |
1994 |
bfd_get_section_flags (abfd, sec) |
bfd_get_section_flags (abfd, sec) |
1995 |
| SEC_ALLOC | SEC_LOAD)) |
| SEC_ALLOC | SEC_LOAD)) |
1996 |
error = true; |
error = TRUE; |
1997 |
|
|
1998 |
/* Free whatever resources we took. */ |
/* Free whatever resources we took. */ |
1999 |
for (i = 0; i < sizeof (file_names) / sizeof (file_names[0]); i++) |
for (i = 0; i < sizeof (file_names) / sizeof (file_names[0]); i++) |
2005 |
/* A hook to set up object file dependent section information. For mmo, |
/* A hook to set up object file dependent section information. For mmo, |
2006 |
we point out the shape of allocated section contents. */ |
we point out the shape of allocated section contents. */ |
2007 |
|
|
2008 |
static boolean |
static bfd_boolean |
2009 |
mmo_new_section_hook (abfd, newsect) |
mmo_new_section_hook (bfd *abfd ATTRIBUTE_UNUSED, asection *newsect) |
|
bfd *abfd ATTRIBUTE_UNUSED; |
|
|
asection *newsect; |
|
2010 |
{ |
{ |
2011 |
/* We zero-fill all fields and assume NULL is represented by an all |
/* We zero-fill all fields and assume NULL is represented by an all |
2012 |
zero-bit pattern. */ |
zero-bit pattern. */ |
2013 |
newsect->used_by_bfd = |
newsect->used_by_bfd = |
2014 |
(PTR) bfd_zalloc (abfd, sizeof (struct mmo_section_data_struct)); |
bfd_zalloc (abfd, sizeof (struct mmo_section_data_struct)); |
2015 |
|
|
2016 |
if (!newsect->used_by_bfd) |
if (!newsect->used_by_bfd) |
2017 |
return false; |
return FALSE; |
2018 |
|
|
2019 |
/* Always align to at least 32-bit words. */ |
/* Always align to at least 32-bit words. */ |
2020 |
newsect->alignment_power = 2; |
newsect->alignment_power = 2; |
2021 |
return true; |
return TRUE; |
2022 |
} |
} |
2023 |
|
|
2024 |
/* We already have section contents loaded for sections that have |
/* We already have section contents loaded for sections that have |
2025 |
contents. */ |
contents. */ |
2026 |
|
|
2027 |
static boolean |
static bfd_boolean |
2028 |
mmo_get_section_contents (abfd, sec, location, offset, bytes_to_do) |
mmo_get_section_contents (bfd *abfd ATTRIBUTE_UNUSED, |
2029 |
bfd *abfd ATTRIBUTE_UNUSED; |
asection *sec, |
2030 |
asection *sec ATTRIBUTE_UNUSED; |
void * location, |
2031 |
PTR location ATTRIBUTE_UNUSED; |
file_ptr offset, |
2032 |
file_ptr offset ATTRIBUTE_UNUSED; |
bfd_size_type bytes_to_do) |
|
bfd_size_type bytes_to_do ATTRIBUTE_UNUSED; |
|
2033 |
{ |
{ |
2034 |
/* Iterate over diminishing chunk sizes, copying contents, like |
/* Iterate over diminishing chunk sizes, copying contents, like |
2035 |
mmo_set_section_contents. */ |
mmo_set_section_contents. */ |
2047 |
while (loc == NULL && (chunk_size /= 2) != 0); |
while (loc == NULL && (chunk_size /= 2) != 0); |
2048 |
|
|
2049 |
if (chunk_size == 0) |
if (chunk_size == 0) |
2050 |
return false; |
return FALSE; |
2051 |
|
|
2052 |
memcpy (location, loc, chunk_size); |
memcpy (location, loc, chunk_size); |
2053 |
|
|
2055 |
bytes_to_do -= chunk_size; |
bytes_to_do -= chunk_size; |
2056 |
offset += chunk_size; |
offset += chunk_size; |
2057 |
} |
} |
2058 |
return true; |
return TRUE; |
2059 |
} |
} |
2060 |
|
|
2061 |
/* Return the amount of memory needed to read the symbol table. */ |
/* Return the amount of memory needed to read the symbol table. */ |
2062 |
|
|
2063 |
static long |
static long |
2064 |
mmo_get_symtab_upper_bound (abfd) |
mmo_get_symtab_upper_bound (bfd *abfd) |
|
bfd *abfd ATTRIBUTE_UNUSED; |
|
2065 |
{ |
{ |
2066 |
return (abfd->symcount + 1) * sizeof (asymbol *); |
return (abfd->symcount + 1) * sizeof (asymbol *); |
2067 |
} |
} |
2069 |
/* Sort mmo symbols by serial number. */ |
/* Sort mmo symbols by serial number. */ |
2070 |
|
|
2071 |
static int |
static int |
2072 |
mmo_sort_mmo_symbols (arg1, arg2) |
mmo_sort_mmo_symbols (const void *arg1, const void *arg2) |
|
const PTR arg1; |
|
|
const PTR arg2; |
|
2073 |
{ |
{ |
2074 |
const struct mmo_symbol *sym1 = *(const struct mmo_symbol **) arg1; |
const struct mmo_symbol *sym1 = *(const struct mmo_symbol **) arg1; |
2075 |
const struct mmo_symbol *sym2 = *(const struct mmo_symbol **) arg2; |
const struct mmo_symbol *sym2 = *(const struct mmo_symbol **) arg2; |
2087 |
/* Translate the symbol table. */ |
/* Translate the symbol table. */ |
2088 |
|
|
2089 |
static long |
static long |
2090 |
mmo_get_symtab (abfd, alocation) |
mmo_canonicalize_symtab (bfd *abfd, asymbol **alocation) |
|
bfd *abfd; |
|
|
asymbol **alocation; |
|
2091 |
{ |
{ |
2092 |
unsigned int symcount = bfd_get_symcount (abfd); |
unsigned int symcount = bfd_get_symcount (abfd); |
2093 |
asymbol *csymbols; |
asymbol *csymbols; |
2117 |
|
|
2118 |
csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol)); |
csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol)); |
2119 |
if (csymbols == NULL && symcount != 0) |
if (csymbols == NULL && symcount != 0) |
2120 |
return false; |
return FALSE; |
2121 |
abfd->tdata.mmo_data->csymbols = csymbols; |
abfd->tdata.mmo_data->csymbols = csymbols; |
2122 |
|
|
2123 |
for (msp = (struct mmo_symbol **) alocation, c = csymbols; |
for (msp = (struct mmo_symbol **) alocation, c = csymbols; |
2151 |
{ |
{ |
2152 |
asection *textsec |
asection *textsec |
2153 |
= bfd_get_section_by_name (abfd, MMO_TEXT_SECTION_NAME); |
= bfd_get_section_by_name (abfd, MMO_TEXT_SECTION_NAME); |
2154 |
|
asection *datasec; |
2155 |
|
|
2156 |
if (textsec != NULL |
if (textsec != NULL |
2157 |
&& c->value >= textsec->vma |
&& c->value >= textsec->vma |
2158 |
&& c->value <= textsec->vma + textsec->_cooked_size) |
&& c->value <= textsec->vma + textsec->size) |
2159 |
{ |
{ |
2160 |
c->section = textsec; |
c->section = textsec; |
2161 |
c->value -= c->section->vma; |
c->value -= c->section->vma; |
2162 |
} |
} |
2163 |
|
/* In mmo, symbol types depend on the VMA. Therefore, if |
2164 |
|
the data section isn't within the usual bounds, its |
2165 |
|
symbols are marked as absolute. Correct that. This |
2166 |
|
means we can't have absolute symbols with values matching |
2167 |
|
data section addresses, but we also can't have with |
2168 |
|
absolute symbols with values matching text section |
2169 |
|
addresses. For such needs, use the ELF format. */ |
2170 |
|
else if ((datasec |
2171 |
|
= bfd_get_section_by_name (abfd, |
2172 |
|
MMO_DATA_SECTION_NAME)) |
2173 |
|
!= NULL |
2174 |
|
&& c->value >= datasec->vma |
2175 |
|
&& c->value <= datasec->vma + datasec->size) |
2176 |
|
{ |
2177 |
|
c->section = datasec; |
2178 |
|
c->value -= c->section->vma; |
2179 |
|
} |
2180 |
else |
else |
2181 |
c->section = bfd_abs_section_ptr; |
c->section = bfd_abs_section_ptr; |
2182 |
} |
} |
2196 |
/* Get information about a symbol. */ |
/* Get information about a symbol. */ |
2197 |
|
|
2198 |
static void |
static void |
2199 |
mmo_get_symbol_info (ignore_abfd, symbol, ret) |
mmo_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED, |
2200 |
bfd *ignore_abfd ATTRIBUTE_UNUSED; |
asymbol *symbol, symbol_info *ret) |
|
asymbol *symbol; |
|
|
symbol_info *ret; |
|
2201 |
{ |
{ |
2202 |
bfd_symbol_info (symbol, ret); |
bfd_symbol_info (symbol, ret); |
2203 |
} |
} |
2204 |
|
|
2205 |
static void |
static void |
2206 |
mmo_print_symbol (abfd, afile, symbol, how) |
mmo_print_symbol (bfd *abfd, void *afile, asymbol *symbol, |
2207 |
bfd *abfd; |
bfd_print_symbol_type how) |
|
PTR afile; |
|
|
asymbol *symbol; |
|
|
bfd_print_symbol_type how; |
|
2208 |
{ |
{ |
2209 |
FILE *file = (FILE *) afile; |
FILE *file = (FILE *) afile; |
2210 |
|
|
2214 |
fprintf (file, "%s", symbol->name); |
fprintf (file, "%s", symbol->name); |
2215 |
break; |
break; |
2216 |
default: |
default: |
2217 |
bfd_print_symbol_vandf (abfd, (PTR) file, symbol); |
bfd_print_symbol_vandf (abfd, file, symbol); |
2218 |
|
|
2219 |
fprintf (file, " %-5s %s", |
fprintf (file, " %-5s %s", |
2220 |
symbol->section->name, |
symbol->section->name, |
2226 |
size of header information is irrelevant. */ |
size of header information is irrelevant. */ |
2227 |
|
|
2228 |
static int |
static int |
2229 |
mmo_sizeof_headers (abfd, exec) |
mmo_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, |
2230 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd_boolean exec ATTRIBUTE_UNUSED) |
|
boolean exec ATTRIBUTE_UNUSED; |
|
2231 |
{ |
{ |
2232 |
return 0; |
return 0; |
2233 |
} |
} |
2234 |
|
|
2235 |
/* Write the (section-neutral) file preamble. */ |
/* Write the (section-neutral) file preamble. */ |
2236 |
|
|
2237 |
static boolean |
static bfd_boolean |
2238 |
mmo_internal_write_header (abfd) |
mmo_internal_write_header (bfd *abfd) |
|
bfd *abfd; |
|
2239 |
{ |
{ |
2240 |
const char lop_pre_bfd[] = { LOP, LOP_PRE, 1, 1}; |
const char lop_pre_bfd[] = { LOP, LOP_PRE, 1, 1}; |
2241 |
|
|
2242 |
if (bfd_bwrite (lop_pre_bfd, 4, abfd) != 4) |
if (bfd_bwrite (lop_pre_bfd, 4, abfd) != 4) |
2243 |
return false; |
return FALSE; |
2244 |
|
|
2245 |
/* Copy creation time of original file. */ |
/* Copy creation time of original file. */ |
2246 |
if (bfd_bwrite (abfd->tdata.mmo_data->created, 4, abfd) != 4) |
if (bfd_bwrite (abfd->tdata.mmo_data->created, 4, abfd) != 4) |
2247 |
return false; |
return FALSE; |
2248 |
|
|
2249 |
return true; |
return TRUE; |
2250 |
} |
} |
2251 |
|
|
2252 |
/* Write the LOP_POST record, with global register initializations. |
/* Write the LOP_POST record, with global register initializations. |
2254 |
registers at DATA. The Z = 255 field is filled in with the |
registers at DATA. The Z = 255 field is filled in with the |
2255 |
start-address. */ |
start-address. */ |
2256 |
|
|
2257 |
static boolean |
static bfd_boolean |
2258 |
mmo_internal_write_post (abfd, z, sec) |
mmo_internal_write_post (bfd *abfd, int z, asection *sec) |
|
bfd *abfd; |
|
|
int z; |
|
|
asection *sec; |
|
2259 |
{ |
{ |
2260 |
int i; |
int i; |
2261 |
bfd_byte buf[8]; |
bfd_byte buf[8]; |
2266 |
bfd_byte *data = mmo_get_loc (sec, i * 8, 8); |
bfd_byte *data = mmo_get_loc (sec, i * 8, 8); |
2267 |
|
|
2268 |
if (bfd_bwrite (data, 8, abfd) != 8) |
if (bfd_bwrite (data, 8, abfd) != 8) |
2269 |
return false; |
return FALSE; |
2270 |
} |
} |
2271 |
|
|
2272 |
/* For Z == $255, we always emit the start location; supposedly Main, |
/* For Z == $255, we always emit the start location; supposedly Main, |
2281 |
get bitten by BFD flag number changes. */ |
get bitten by BFD flag number changes. */ |
2282 |
|
|
2283 |
static flagword |
static flagword |
2284 |
mmo_sec_flags_from_bfd_flags (flags) |
mmo_sec_flags_from_bfd_flags (flagword flags) |
|
flagword flags; |
|
2285 |
{ |
{ |
2286 |
flagword oflags = 0; |
flagword oflags = 0; |
2287 |
|
|
2308 |
} |
} |
2309 |
|
|
2310 |
static flagword |
static flagword |
2311 |
bfd_sec_flags_from_mmo_flags (flags) |
bfd_sec_flags_from_mmo_flags (flagword flags) |
|
flagword flags; |
|
2312 |
{ |
{ |
2313 |
flagword oflags = 0; |
flagword oflags = 0; |
2314 |
|
|
2334 |
return oflags; |
return oflags; |
2335 |
} |
} |
2336 |
|
|
2337 |
|
/* Return TRUE iff the leading or trailing tetrabyte in SEC is defined and |
2338 |
|
is 0. */ |
2339 |
|
|
2340 |
|
static bfd_boolean |
2341 |
|
mmo_has_leading_or_trailing_zero_tetra_p (bfd *abfd, asection *sec) |
2342 |
|
{ |
2343 |
|
bfd_vma secaddr = bfd_get_section_vma (abfd, sec); |
2344 |
|
|
2345 |
|
if (sec->size < 4) |
2346 |
|
return FALSE; |
2347 |
|
|
2348 |
|
if (bfd_get_32 (abfd, mmo_get_loc (sec, secaddr, 4)) == 0 |
2349 |
|
&& bfd_get_32 (abfd, |
2350 |
|
mmo_get_loc (sec, secaddr + sec->size - 4, 4)) == 0) |
2351 |
|
return TRUE; |
2352 |
|
|
2353 |
|
return FALSE; |
2354 |
|
} |
2355 |
|
|
2356 |
/* Write a section. */ |
/* Write a section. */ |
2357 |
|
|
2358 |
static boolean |
static bfd_boolean |
2359 |
mmo_internal_write_section (abfd, sec) |
mmo_internal_write_section (bfd *abfd, asection *sec) |
|
bfd *abfd; |
|
|
asection *sec; |
|
2360 |
{ |
{ |
2361 |
/* We do it differently depending on what section this is: |
/* We do it differently depending on what section this is: |
2362 |
|
|
2371 |
above. */ |
above. */ |
2372 |
|
|
2373 |
if (strcmp (sec->name, MMO_TEXT_SECTION_NAME) == 0) |
if (strcmp (sec->name, MMO_TEXT_SECTION_NAME) == 0) |
2374 |
/* FIXME: Output source file name and line number. */ |
{ |
2375 |
return |
bfd_vma secaddr = bfd_get_section_vma (abfd, sec); |
2376 |
mmo_write_loc_chunk_list (abfd, |
|
2377 |
((struct mmo_section_data_struct *) |
/* Because leading and trailing zeros are omitted in output, we need to |
2378 |
(sec->used_by_bfd))->head); |
specify the section boundaries so they're correct when the file |
2379 |
|
is read in again. That's also the case if this section is |
2380 |
|
specified as not within its usual boundaries or alignments. */ |
2381 |
|
if (sec->size != 0 |
2382 |
|
&& (secaddr + sec->size >= (bfd_vma) 1 << 56 |
2383 |
|
|| (secaddr & 3) != 0 |
2384 |
|
|| (sec->size & 3) != 0 |
2385 |
|
|| mmo_has_leading_or_trailing_zero_tetra_p (abfd, sec))) |
2386 |
|
{ |
2387 |
|
if (!mmo_write_section_description (abfd, sec)) |
2388 |
|
return FALSE; |
2389 |
|
} |
2390 |
|
|
2391 |
|
/* FIXME: Output source file name and line number. */ |
2392 |
|
return mmo_write_loc_chunk_list (abfd, mmo_section_data (sec)->head); |
2393 |
|
} |
2394 |
else if (strcmp (sec->name, MMO_DATA_SECTION_NAME) == 0) |
else if (strcmp (sec->name, MMO_DATA_SECTION_NAME) == 0) |
2395 |
return |
{ |
2396 |
mmo_write_loc_chunk_list (abfd, |
bfd_vma secaddr = bfd_get_section_vma (abfd, sec); |
2397 |
((struct mmo_section_data_struct *) |
|
2398 |
(sec->used_by_bfd))->head); |
/* Same goes as for MMO_TEXT_SECTION_NAME above. */ |
2399 |
|
if (sec->size != 0 |
2400 |
|
&& (secaddr < (bfd_vma) 0x20 << 56 |
2401 |
|
|| secaddr + sec->size >= (bfd_vma) 0x21 << 56 |
2402 |
|
|| (secaddr & 3) != 0 |
2403 |
|
|| (sec->size & 3) != 0 |
2404 |
|
|| mmo_has_leading_or_trailing_zero_tetra_p (abfd, sec))) |
2405 |
|
{ |
2406 |
|
if (!mmo_write_section_description (abfd, sec)) |
2407 |
|
return FALSE; |
2408 |
|
} |
2409 |
|
|
2410 |
|
return mmo_write_loc_chunk_list (abfd, mmo_section_data (sec)->head); |
2411 |
|
} |
2412 |
else if (strcmp (sec->name, MMIX_REG_CONTENTS_SECTION_NAME) == 0) |
else if (strcmp (sec->name, MMIX_REG_CONTENTS_SECTION_NAME) == 0) |
2413 |
/* Not handled here. */ |
/* Not handled here. */ |
2414 |
{ |
{ |
2415 |
/* This would normally be an abort call since this can't happen, but |
/* This would normally be an abort call since this can't happen, but |
2416 |
we don't do that. */ |
we don't do that. */ |
2417 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
2418 |
return false; |
return FALSE; |
2419 |
} |
} |
2420 |
else if (strncmp (sec->name, MMIX_OTHER_SPEC_SECTION_PREFIX, |
else if (strncmp (sec->name, MMIX_OTHER_SPEC_SECTION_PREFIX, |
2421 |
strlen (MMIX_OTHER_SPEC_SECTION_PREFIX)) == 0) |
strlen (MMIX_OTHER_SPEC_SECTION_PREFIX)) == 0) |
2423 |
int n = atoi (sec->name + strlen (MMIX_OTHER_SPEC_SECTION_PREFIX)); |
int n = atoi (sec->name + strlen (MMIX_OTHER_SPEC_SECTION_PREFIX)); |
2424 |
mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_SPEC << 16) | n); |
mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_SPEC << 16) | n); |
2425 |
return (! abfd->tdata.mmo_data->have_error |
return (! abfd->tdata.mmo_data->have_error |
2426 |
&& mmo_write_chunk_list (abfd, |
&& mmo_write_chunk_list (abfd, mmo_section_data (sec)->head)); |
|
((struct mmo_section_data_struct *) |
|
|
(sec->used_by_bfd))->head)); |
|
2427 |
} |
} |
2428 |
/* Ignore sections that are just allocated or empty; we write out |
/* Ignore sections that are just allocated or empty; we write out |
2429 |
_contents_ here. */ |
_contents_ here. */ |
2430 |
else if ((bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS) != 0 |
else if ((bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS) != 0 |
2431 |
&& sec->_raw_size != 0) |
&& sec->size != 0) |
2432 |
{ |
{ |
2433 |
/* Keep the document-comment formatted the way it is. */ |
if (!mmo_write_section_description (abfd, sec)) |
2434 |
|
return FALSE; |
2435 |
|
|
2436 |
|
/* Writing a LOP_LOC ends the LOP_SPEC data, and makes data actually |
2437 |
|
loaded. */ |
2438 |
|
if (bfd_get_section_flags (abfd, sec) & SEC_LOAD) |
2439 |
|
return (! abfd->tdata.mmo_data->have_error |
2440 |
|
&& mmo_write_loc_chunk_list (abfd, |
2441 |
|
mmo_section_data (sec)->head)); |
2442 |
|
return (! abfd->tdata.mmo_data->have_error |
2443 |
|
&& mmo_write_chunk_list (abfd, mmo_section_data (sec)->head)); |
2444 |
|
} |
2445 |
|
|
2446 |
|
/* Some section without contents. */ |
2447 |
|
return TRUE; |
2448 |
|
} |
2449 |
|
|
2450 |
|
/* Write the description of a section, extended-mmo-style. */ |
2451 |
|
|
2452 |
|
static bfd_boolean |
2453 |
|
mmo_write_section_description (bfd *abfd, asection *sec) |
2454 |
|
{ |
2455 |
|
/* Keep the following document-comment formatted the way it is. */ |
2456 |
/* |
/* |
2457 |
INODE |
INODE |
2458 |
mmo section mapping, , Symbol-table, mmo |
mmo section mapping, , Symbol-table, mmo |
2545 |
special data. The address is usually unimportant but might |
special data. The address is usually unimportant but might |
2546 |
provide information for e.g.@: the DWARF 2 debugging format. */ |
provide information for e.g.@: the DWARF 2 debugging format. */ |
2547 |
|
|
2548 |
mmo_write_tetra_raw (abfd, LOP_SPEC_SECTION); |
mmo_write_tetra_raw (abfd, LOP_SPEC_SECTION); |
2549 |
mmo_write_tetra (abfd, (strlen (sec->name) + 3) / 4); |
mmo_write_tetra (abfd, (strlen (sec->name) + 3) / 4); |
2550 |
mmo_write_chunk (abfd, sec->name, strlen (sec->name)); |
mmo_write_chunk (abfd, (bfd_byte *) sec->name, strlen (sec->name)); |
2551 |
mmo_flush_chunk (abfd); |
mmo_flush_chunk (abfd); |
2552 |
/* FIXME: We can get debug sections (.debug_line & Co.) with a |
/* FIXME: We can get debug sections (.debug_line & Co.) with a section |
2553 |
section flag still having SEC_RELOC set. Investigate. This |
flag still having SEC_RELOC set. Investigate. This might be true |
2554 |
might be true for all alien sections; perhaps mmo.em should clear |
for all alien sections; perhaps mmo.em should clear that flag. Might |
2555 |
that flag. Might be related to weak references. */ |
be related to weak references. */ |
2556 |
mmo_write_tetra (abfd, |
mmo_write_tetra (abfd, |
2557 |
mmo_sec_flags_from_bfd_flags |
mmo_sec_flags_from_bfd_flags |
2558 |
(bfd_get_section_flags (abfd, sec))); |
(bfd_get_section_flags (abfd, sec))); |
2559 |
mmo_write_octa (abfd, sec->_raw_size); |
mmo_write_octa (abfd, sec->size); |
2560 |
mmo_write_octa (abfd, bfd_get_section_vma (abfd, sec)); |
mmo_write_octa (abfd, bfd_get_section_vma (abfd, sec)); |
2561 |
|
return TRUE; |
|
/* Writing a LOP_LOC ends the LOP_SPEC data, and makes data actually |
|
|
loaded. */ |
|
|
if (bfd_get_section_flags (abfd, sec) & SEC_LOAD) |
|
|
return |
|
|
! abfd->tdata.mmo_data->have_error |
|
|
&& mmo_write_loc_chunk_list (abfd, |
|
|
((struct mmo_section_data_struct *) |
|
|
(sec->used_by_bfd))->head); |
|
|
return |
|
|
! abfd->tdata.mmo_data->have_error |
|
|
&& mmo_write_chunk_list (abfd, |
|
|
((struct mmo_section_data_struct *) |
|
|
(sec->used_by_bfd))->head); |
|
|
} |
|
|
return true; |
|
2562 |
} |
} |
2563 |
|
|
2564 |
/* We save up all data before output. */ |
/* We save up all data before output. */ |
2565 |
|
|
2566 |
static boolean |
static bfd_boolean |
2567 |
mmo_set_section_contents (abfd, sec, location, offset, bytes_to_do) |
mmo_set_section_contents (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec, |
2568 |
bfd *abfd ATTRIBUTE_UNUSED; |
const void *location, file_ptr offset, |
2569 |
sec_ptr sec; |
bfd_size_type bytes_to_do) |
|
PTR location; |
|
|
file_ptr offset; |
|
|
bfd_size_type bytes_to_do; |
|
2570 |
{ |
{ |
2571 |
/* Iterate over diminishing chunk sizes, copying contents. */ |
/* Iterate over diminishing chunk sizes, copying contents. */ |
2572 |
while (bytes_to_do) |
while (bytes_to_do) |
2583 |
while (loc == NULL && (chunk_size /= 2) != 0); |
while (loc == NULL && (chunk_size /= 2) != 0); |
2584 |
|
|
2585 |
if (chunk_size == 0) |
if (chunk_size == 0) |
2586 |
return false; |
return FALSE; |
2587 |
|
|
2588 |
memcpy (loc, location, chunk_size); |
memcpy (loc, location, chunk_size); |
2589 |
|
|
2591 |
bytes_to_do -= chunk_size; |
bytes_to_do -= chunk_size; |
2592 |
offset += chunk_size; |
offset += chunk_size; |
2593 |
} |
} |
2594 |
return true; |
return TRUE; |
2595 |
} |
} |
2596 |
|
|
2597 |
/* Add a symbol to a trie-tree. */ |
/* Add a symbol to a trie-tree. */ |
2598 |
|
|
2599 |
static boolean |
static bfd_boolean |
2600 |
mmo_internal_add_3_sym (abfd, rootp, symp) |
mmo_internal_add_3_sym (bfd *abfd, struct mmo_symbol_trie *rootp, |
2601 |
bfd *abfd; |
const struct mmo_symbol *symp) |
|
struct mmo_symbol_trie *rootp; |
|
|
const struct mmo_symbol *symp; |
|
2602 |
{ |
{ |
2603 |
const char *name = symp->name; |
const char *name = symp->name; |
2604 |
struct mmo_symbol_trie *trie = rootp; |
struct mmo_symbol_trie *trie = rootp; |
2647 |
(_("%s: invalid symbol table: duplicate symbol `%s'\n"), |
(_("%s: invalid symbol table: duplicate symbol `%s'\n"), |
2648 |
bfd_get_filename (abfd), trie->sym.name); |
bfd_get_filename (abfd), trie->sym.name); |
2649 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
2650 |
return false; |
return FALSE; |
2651 |
} |
} |
2652 |
|
|
2653 |
memcpy (&trie->sym, symp, sizeof *symp); |
memcpy (&trie->sym, symp, sizeof *symp); |
2654 |
return true; |
return TRUE; |
2655 |
} |
} |
2656 |
|
|
2657 |
/* Find out the length of the serialized version of a trie in bytes. */ |
/* Find out the length of the serialized version of a trie in bytes. */ |
2658 |
|
|
2659 |
static unsigned int |
static unsigned int |
2660 |
mmo_internal_3_length (abfd, trie) |
mmo_internal_3_length (bfd *abfd, struct mmo_symbol_trie *trie) |
|
bfd *abfd; |
|
|
struct mmo_symbol_trie *trie; |
|
2661 |
{ |
{ |
2662 |
/* First, one for the control byte. */ |
/* First, one for the control byte. */ |
2663 |
unsigned int length = 1; |
unsigned int length = 1; |
2717 |
beb128. Using a helper function and recursion simplifies debugging. */ |
beb128. Using a helper function and recursion simplifies debugging. */ |
2718 |
|
|
2719 |
static void |
static void |
2720 |
mmo_beb128_out (abfd, serno, marker) |
mmo_beb128_out (bfd *abfd, int serno, int marker) |
|
bfd *abfd; |
|
|
int serno; |
|
|
int marker; |
|
2721 |
{ |
{ |
2722 |
if (serno & ~0x7f) |
if (serno & ~0x7f) |
2723 |
mmo_beb128_out (abfd, serno >> 7, 0); |
mmo_beb128_out (abfd, serno >> 7, 0); |
2727 |
/* Serialize a trie. */ |
/* Serialize a trie. */ |
2728 |
|
|
2729 |
static void |
static void |
2730 |
mmo_internal_3_dump (abfd, trie) |
mmo_internal_3_dump (bfd *abfd, struct mmo_symbol_trie *trie) |
|
bfd *abfd; |
|
|
struct mmo_symbol_trie *trie; |
|
2731 |
{ |
{ |
2732 |
bfd_byte control = 0; |
bfd_byte control = 0; |
2733 |
|
|
2819 |
|
|
2820 |
/* Write symbols in mmo format. Also write the lop_end terminator. */ |
/* Write symbols in mmo format. Also write the lop_end terminator. */ |
2821 |
|
|
2822 |
static boolean |
static bfd_boolean |
2823 |
mmo_write_symbols_and_terminator (abfd) |
mmo_write_symbols_and_terminator (bfd *abfd) |
|
bfd *abfd; |
|
2824 |
{ |
{ |
2825 |
int count = bfd_get_symcount (abfd); |
int count = bfd_get_symcount (abfd); |
2826 |
asymbol *maintable[2]; |
asymbol *maintable[2]; |
2851 |
symbols. Make sure we have room for it. */ |
symbols. Make sure we have room for it. */ |
2852 |
table = bfd_alloc (abfd, (count + 1) * sizeof (asymbol *)); |
table = bfd_alloc (abfd, (count + 1) * sizeof (asymbol *)); |
2853 |
if (table == NULL) |
if (table == NULL) |
2854 |
return false; |
return FALSE; |
2855 |
|
|
2856 |
memcpy (table, orig_table, count * sizeof (asymbol *)); |
memcpy (table, orig_table, count * sizeof (asymbol *)); |
2857 |
|
|
2887 |
sprintf_vma (vmas_start, vma_start); |
sprintf_vma (vmas_start, vma_start); |
2888 |
|
|
2889 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
2890 |
(_("%s: Bad symbol definition: `Main' set to %s rather\ |
(_("%s: Bad symbol definition: `Main' set to %s rather" |
2891 |
than the start address %s\n"), |
" than the start address %s\n"), |
2892 |
bfd_get_filename (abfd), vmas_main, vmas_start); |
bfd_get_filename (abfd), vmas_main, vmas_start); |
2893 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
2894 |
return false; |
return FALSE; |
2895 |
} |
} |
2896 |
break; |
break; |
2897 |
} |
} |
2920 |
struct mmo_symbol sym; |
struct mmo_symbol sym; |
2921 |
memset (&sym, 0, sizeof (sym)); |
memset (&sym, 0, sizeof (sym)); |
2922 |
|
|
2923 |
sym.name = s->name; |
/* Need to strip const here; strdup:ing would leak and the |
2924 |
|
existing string must be safe to reuse. */ |
2925 |
|
sym.name = (char *) s->name; |
2926 |
sym.value = |
sym.value = |
2927 |
s->value |
s->value |
2928 |
+ s->section->output_section->vma |
+ s->section->output_section->vma |
2956 |
sym.serno = serno++; |
sym.serno = serno++; |
2957 |
|
|
2958 |
if (! mmo_internal_add_3_sym (abfd, &root, &sym)) |
if (! mmo_internal_add_3_sym (abfd, &root, &sym)) |
2959 |
return false; |
return FALSE; |
2960 |
} |
} |
2961 |
} |
} |
2962 |
|
|
2979 |
struct mmo_symbol sym; |
struct mmo_symbol sym; |
2980 |
|
|
2981 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
2982 |
(_("%s: warning: symbol table too large for mmo, larger than 65535\ |
(_("%s: warning: symbol table too large for mmo, larger than 65535" |
2983 |
32-bit words: %d. Only `Main' will be emitted.\n"), |
" 32-bit words: %d. Only `Main' will be emitted.\n"), |
2984 |
bfd_get_filename (abfd), trie_len); |
bfd_get_filename (abfd), trie_len); |
2985 |
|
|
2986 |
memset (&sym, 0, sizeof (sym)); |
memset (&sym, 0, sizeof (sym)); |
2997 |
root.right = NULL; |
root.right = NULL; |
2998 |
|
|
2999 |
if (! mmo_internal_add_3_sym (abfd, &root, &sym)) |
if (! mmo_internal_add_3_sym (abfd, &root, &sym)) |
3000 |
return false; |
return FALSE; |
3001 |
|
|
3002 |
root.symchar = ':'; |
root.symchar = ':'; |
3003 |
root.middle = root.left; |
root.middle = root.left; |
3013 |
/* Put out the lop_stab mark. */ |
/* Put out the lop_stab mark. */ |
3014 |
bfd_put_32 (abfd, (LOP << 24) | (LOP_STAB << 16), buf); |
bfd_put_32 (abfd, (LOP << 24) | (LOP_STAB << 16), buf); |
3015 |
if (bfd_bwrite (buf, 4, abfd) != 4) |
if (bfd_bwrite (buf, 4, abfd) != 4) |
3016 |
return false; |
return FALSE; |
3017 |
|
|
3018 |
/* Dump out symbols. */ |
/* Dump out symbols. */ |
3019 |
mmo_internal_3_dump (abfd, &root); |
mmo_internal_3_dump (abfd, &root); |
3024 |
isn't debugged and abort if we get here. Instead emit a |
isn't debugged and abort if we get here. Instead emit a |
3025 |
diagnostic and fail "normally". */ |
diagnostic and fail "normally". */ |
3026 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
3027 |
(_("%s: internal error, symbol table changed size from %d to %d\ |
(_("%s: internal error, symbol table changed size from %d to %d" |
3028 |
words\n"), |
" words\n"), |
3029 |
bfd_get_filename (abfd), trie_len, |
bfd_get_filename (abfd), trie_len, |
3030 |
(abfd->tdata.mmo_data->byte_no + 3)/4); |
(abfd->tdata.mmo_data->byte_no + 3)/4); |
3031 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
3032 |
return false; |
return FALSE; |
3033 |
} |
} |
3034 |
|
|
3035 |
/* Dump out remaining bytes in the buffer and handle I/O errors by |
/* Dump out remaining bytes in the buffer and handle I/O errors by |
3042 |
|
|
3043 |
if (abfd->tdata.mmo_data->have_error |
if (abfd->tdata.mmo_data->have_error |
3044 |
|| bfd_bwrite (abfd->tdata.mmo_data->buf, 4, abfd) != 4) |
|| bfd_bwrite (abfd->tdata.mmo_data->buf, 4, abfd) != 4) |
3045 |
return false; |
return FALSE; |
3046 |
} |
} |
3047 |
|
|
3048 |
bfd_put_32 (abfd, (LOP << 24) | (LOP_END << 16) | trie_len, buf); |
bfd_put_32 (abfd, (LOP << 24) | (LOP_END << 16) | trie_len, buf); |
3054 |
used through bfd_map_over_sections. */ |
used through bfd_map_over_sections. */ |
3055 |
|
|
3056 |
static void |
static void |
3057 |
mmo_write_section_unless_reg_contents (abfd, sec, p) |
mmo_write_section_unless_reg_contents (bfd *abfd, asection *sec, void *p) |
|
bfd *abfd; |
|
|
asection *sec; |
|
|
PTR p; |
|
3058 |
{ |
{ |
3059 |
struct mmo_write_sec_info *infop = (struct mmo_write_sec_info *) p; |
struct mmo_write_sec_info *infop = (struct mmo_write_sec_info *) p; |
3060 |
|
|
3076 |
make it carry contents, so we don't have a test-case for |
make it carry contents, so we don't have a test-case for |
3077 |
this. */ |
this. */ |
3078 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
3079 |
(_("%s: internal error, internal register section %s had\ |
(_("%s: internal error, internal register section %s had" |
3080 |
contents\n"), |
" contents\n"), |
3081 |
bfd_get_filename (abfd), sec->name); |
bfd_get_filename (abfd), sec->name); |
3082 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
3083 |
infop->retval = false; |
infop->retval = FALSE; |
3084 |
return; |
return; |
3085 |
} |
} |
3086 |
|
|
3093 |
/* Do the actual output of a file. Assumes mmo_set_section_contents is |
/* Do the actual output of a file. Assumes mmo_set_section_contents is |
3094 |
already called. */ |
already called. */ |
3095 |
|
|
3096 |
static boolean |
static bfd_boolean |
3097 |
mmo_write_object_contents (abfd) |
mmo_write_object_contents (bfd *abfd) |
|
bfd *abfd; |
|
3098 |
{ |
{ |
3099 |
struct mmo_write_sec_info wsecinfo; |
struct mmo_write_sec_info wsecinfo; |
3100 |
|
|
3101 |
/* First, there are a few words of preamble. */ |
/* First, there are a few words of preamble. */ |
3102 |
if (! mmo_internal_write_header (abfd)) |
if (! mmo_internal_write_header (abfd)) |
3103 |
return false; |
return FALSE; |
3104 |
|
|
3105 |
wsecinfo.reg_section = NULL; |
wsecinfo.reg_section = NULL; |
3106 |
wsecinfo.retval = true; |
wsecinfo.retval = TRUE; |
3107 |
|
|
3108 |
bfd_map_over_sections (abfd, mmo_write_section_unless_reg_contents, |
bfd_map_over_sections (abfd, mmo_write_section_unless_reg_contents, |
3109 |
(PTR) &wsecinfo); |
&wsecinfo); |
3110 |
|
|
3111 |
if (! wsecinfo.retval) |
if (! wsecinfo.retval) |
3112 |
return false; |
return FALSE; |
3113 |
|
|
3114 |
if (wsecinfo.reg_section != NULL) |
if (wsecinfo.reg_section != NULL) |
3115 |
{ |
{ |
3120 |
of the register contents section and check that it corresponds to |
of the register contents section and check that it corresponds to |
3121 |
the length of the section. */ |
the length of the section. */ |
3122 |
if (z < 32 || z >= 255 || (sec->vma & 7) != 0 |
if (z < 32 || z >= 255 || (sec->vma & 7) != 0 |
3123 |
|| sec->vma != 256 * 8 - sec->_raw_size - 8) |
|| sec->vma != 256 * 8 - sec->size - 8) |
3124 |
{ |
{ |
3125 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
3126 |
|
|
3127 |
if (sec->_raw_size == 0) |
if (sec->size == 0) |
3128 |
/* There must always be at least one such register. */ |
/* There must always be at least one such register. */ |
3129 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
3130 |
(_("%s: no initialized registers; section length 0\n"), |
(_("%s: no initialized registers; section length 0\n"), |
3135 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
3136 |
(_("%s: too many initialized registers; section length %ld\n"), |
(_("%s: too many initialized registers; section length %ld\n"), |
3137 |
bfd_get_filename (abfd), |
bfd_get_filename (abfd), |
3138 |
(long) sec->_raw_size); |
(long) sec->size); |
3139 |
else |
else |
3140 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
3141 |
(_("%s: invalid start address for initialized registers of\ |
(_("%s: invalid start address for initialized registers of" |
3142 |
length %ld: 0x%lx%08lx\n"), |
" length %ld: 0x%lx%08lx\n"), |
3143 |
bfd_get_filename (abfd), |
bfd_get_filename (abfd), |
3144 |
(long) sec->_raw_size, |
(long) sec->size, |
3145 |
(unsigned long) (sec->vma >> 32), (unsigned long) (sec->vma)); |
(unsigned long) (sec->vma >> 32), (unsigned long) (sec->vma)); |
3146 |
|
|
3147 |
return false; |
return FALSE; |
3148 |
} |
} |
3149 |
|
|
3150 |
if (! mmo_internal_write_post (abfd, z, sec)) |
if (! mmo_internal_write_post (abfd, z, sec)) |
3151 |
return false; |
return FALSE; |
3152 |
} |
} |
3153 |
else |
else |
3154 |
if (! mmo_internal_write_post (abfd, 255, NULL)) |
if (! mmo_internal_write_post (abfd, 255, NULL)) |
3155 |
return false; |
return FALSE; |
3156 |
|
|
3157 |
return mmo_write_symbols_and_terminator (abfd); |
return mmo_write_symbols_and_terminator (abfd); |
3158 |
} |
} |
3161 |
object. */ |
object. */ |
3162 |
|
|
3163 |
static long |
static long |
3164 |
mmo_get_reloc_upper_bound (abfd, sec) |
mmo_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, |
3165 |
bfd *abfd ATTRIBUTE_UNUSED; |
asection *sec ATTRIBUTE_UNUSED) |
|
asection *sec ATTRIBUTE_UNUSED; |
|
3166 |
{ |
{ |
3167 |
return sizeof (PTR); |
return sizeof (void *); |
3168 |
} |
} |
3169 |
|
|
3170 |
/* Similarly canonicalize relocs to empty, filling in the terminating NULL |
/* Similarly canonicalize relocs to empty, filling in the terminating NULL |
3171 |
pointer. */ |
pointer. */ |
3172 |
|
|
3173 |
long |
long |
3174 |
mmo_canonicalize_reloc (abfd, section, relptr, symbols) |
mmo_canonicalize_reloc (bfd *abfd ATTRIBUTE_UNUSED, |
3175 |
bfd *abfd ATTRIBUTE_UNUSED; |
sec_ptr section ATTRIBUTE_UNUSED, arelent **relptr, |
3176 |
sec_ptr section ATTRIBUTE_UNUSED; |
asymbol **symbols ATTRIBUTE_UNUSED) |
|
arelent **relptr; |
|
|
asymbol **symbols ATTRIBUTE_UNUSED; |
|
3177 |
{ |
{ |
3178 |
*relptr = NULL; |
*relptr = NULL; |
3179 |
return 0; |
return 0; |
3193 |
/* Perhaps we need to adjust this one; mmo labels (originally) without a |
/* Perhaps we need to adjust this one; mmo labels (originally) without a |
3194 |
leading ':' might more appropriately be called local. */ |
leading ':' might more appropriately be called local. */ |
3195 |
#define mmo_bfd_is_local_label_name bfd_generic_is_local_label_name |
#define mmo_bfd_is_local_label_name bfd_generic_is_local_label_name |
3196 |
|
#define mmo_bfd_is_target_special_symbol \ |
3197 |
|
((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) |
3198 |
|
|
3199 |
/* Is this one really used or defined by anyone? */ |
/* Is this one really used or defined by anyone? */ |
3200 |
#define mmo_get_lineno _bfd_nosymbols_get_lineno |
#define mmo_get_lineno _bfd_nosymbols_get_lineno |
3224 |
#define mmo_set_arch_mach bfd_default_set_arch_mach |
#define mmo_set_arch_mach bfd_default_set_arch_mach |
3225 |
#define mmo_bfd_relax_section bfd_generic_relax_section |
#define mmo_bfd_relax_section bfd_generic_relax_section |
3226 |
#define mmo_bfd_merge_sections bfd_generic_merge_sections |
#define mmo_bfd_merge_sections bfd_generic_merge_sections |
3227 |
|
#define mmo_bfd_is_group_section bfd_generic_is_group_section |
3228 |
#define mmo_bfd_discard_group bfd_generic_discard_group |
#define mmo_bfd_discard_group bfd_generic_discard_group |
3229 |
|
#define mmo_section_already_linked \ |
3230 |
|
_bfd_generic_section_already_linked |
3231 |
|
|
3232 |
/* objcopy will be upset if we return -1 from bfd_get_reloc_upper_bound by |
/* objcopy will be upset if we return -1 from bfd_get_reloc_upper_bound by |
3233 |
using BFD_JUMP_TABLE_RELOCS (_bfd_norelocs) rather than 0. FIXME: Most |
using BFD_JUMP_TABLE_RELOCS (_bfd_norelocs) rather than 0. FIXME: Most |
3246 |
#define mmo_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data |
#define mmo_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data |
3247 |
#define mmo_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data |
#define mmo_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data |
3248 |
#define mmo_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data |
#define mmo_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data |
3249 |
|
#define mmo_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data |
3250 |
#define mmo_bfd_set_private_flags _bfd_generic_bfd_set_private_flags |
#define mmo_bfd_set_private_flags _bfd_generic_bfd_set_private_flags |
3251 |
#define mmo_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data |
#define mmo_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data |
3252 |
|
|