diff -Nru binutils-2.11.2/bfd/bfd-in.h binutils.new/bfd/bfd-in.h --- binutils-2.11.2/bfd/bfd-in.h Sat Dec 29 12:02:45 2001 +++ binutils.new/bfd/bfd-in.h Sat Jan 26 02:13:40 2002 @@ -741,6 +741,10 @@ PARAMS ((bfd *, struct bfd_link_info *, struct sec *, struct sec *, char **)); +extern boolean bfd_h8300h_coff_create_embedded_relocs + PARAMS ((bfd *, struct bfd_link_info *, struct sec *, struct sec *, + struct sec *, struct sec *, char **)); + /* ARM Interworking support. Called from linker. */ extern boolean bfd_arm_allocate_interworking_sections PARAMS ((struct bfd_link_info *)); diff -Nru binutils-2.11.2/bfd/bfd-in2.h binutils.new/bfd/bfd-in2.h --- binutils-2.11.2/bfd/bfd-in2.h Sat Dec 29 12:02:43 2001 +++ binutils.new/bfd/bfd-in2.h Sat Jan 26 02:13:40 2002 @@ -741,6 +741,10 @@ PARAMS ((bfd *, struct bfd_link_info *, struct sec *, struct sec *, char **)); +extern boolean bfd_h8300h_coff_create_embedded_relocs + PARAMS ((bfd *, struct bfd_link_info *, struct sec *, struct sec *, + struct sec *, struct sec *, char **)); + /* ARM Interworking support. Called from linker. */ extern boolean bfd_arm_allocate_interworking_sections PARAMS ((struct bfd_link_info *)); diff -Nru binutils-2.11.2/bfd/coff-h8300.c binutils.new/bfd/coff-h8300.c --- binutils-2.11.2/bfd/coff-h8300.c Sat Dec 29 12:02:45 2001 +++ binutils.new/bfd/coff-h8300.c Sat Jan 26 02:13:40 2002 @@ -1319,9 +1319,129 @@ h8300_coff_hash_table (info)->vectors_sec->contents = bfd_malloc (h8300_coff_hash_table (info)->vectors_sec->_raw_size); } + return true; +} + +#if !defined ONLY_DECLARE_RELOCS && ! defined STATIC_RELOCS +/* Given a .data section and a .emreloc in-memory section, store + relocation information into the .emreloc section which can be + used at runtime to relocate the section. This is called by the + linker when the --embedded-relocs switch is used. This is called + after the add_symbols entry point has been called for all the + objects, and before the final_link entry point is called. */ + +bfd_byte *reloc_section(abfd,sec,relsec,p,errmsg) + bfd *abfd; + asection *sec; + asection *relsec; + bfd_byte *p; + char **errmsg; +{ + char *extsyms; + bfd_size_type symesz; + struct internal_reloc *irel, *irelend; + static char msg[256]; + + extsyms = obj_coff_external_syms (abfd); + symesz = bfd_coff_symesz (abfd); + + irel = _bfd_coff_read_internal_relocs (abfd, sec, true, NULL, false, + NULL); + irelend = irel + sec->reloc_count; + + for (; irel < irelend; irel++, p += 12) + { + asection *targetsec; + + /* We are going to write a four byte longword into the runtime + reloc section. The longword will be the address in the data + section which must be relocated. It is followed by the name + of the target section NUL-padded or truncated to 8 + characters. */ + /* We can only relocate absolute longword relocs at run time. */ + switch (irel -> r_type) { + case R_RELLONG: + case R_MOVL1: + case R_MOV24B1: + targetsec=sec; + bfd_put_32 (abfd, + (irel->r_vaddr - sec->vma + sec->output_offset), p); + memset (p + 4, 0, 8); + if (targetsec != NULL) + memcpy(p + 4,targetsec->output_section->name,8); + break; + case R_PCRBYTE: + case R_PCRWORD: + case R_PCRLONG: + memset (p , 0xff, 12); + break; + case R_JMPL1: + targetsec=sec; + bfd_put_32 (abfd, + (irel->r_vaddr - sec->vma + (sec->output_offset & 0x00ffffff)) + | (sec->output_offset & 0xff000000), p); + memset (p + 4, 0, 8); + if (targetsec != NULL) + memcpy(p + 4,targetsec->output_section->name,8); + break; + default: + /* *errmsg = _("unsupported reloc type"); */ + sprintf(msg,"unsupported reloc type %x at %x",irel->r_type,irel->r_vaddr); + *errmsg = msg; + bfd_set_error (bfd_error_bad_value); + return NULL; + } + } + return p; +} +boolean +bfd_h8300h_coff_create_embedded_relocs (abfd, info, textsec, rodatasec, datasec, relsec, errmsg) + bfd *abfd; + struct bfd_link_info *info; + asection *textsec; + asection *rodatasec; + asection *datasec; + asection *relsec; + char **errmsg; +{ + bfd_byte *p,*rop; + int reloc_count; + + BFD_ASSERT (! info->relocateable); + + *errmsg = NULL; + + reloc_count = 0; + if (datasec) + reloc_count += datasec->reloc_count; + if (textsec) + reloc_count += textsec->reloc_count; + if (rodatasec) + reloc_count += rodatasec->reloc_count; + if (reloc_count == 0) + return true; + relsec->contents = (bfd_byte *) bfd_alloc (abfd, reloc_count * 12); + if (relsec->contents == NULL) + return false; + + p = relsec->contents; + if (textsec) + { + p = reloc_section(abfd,textsec,relsec,p,errmsg); + if (p == NULL) + return false; + } + rop = NULL; + if (rodatasec) + rop = reloc_section(abfd,rodatasec,relsec,p,errmsg); + if (rop) + p = rop; + if (datasec) + reloc_section(abfd,datasec,relsec,p,errmsg); return true; } +#endif /* neither ONLY_DECLARE_RELOCS not STATIC_RELOCS */ #define coff_reloc16_extra_cases h8300_reloc16_extra_cases #define coff_reloc16_estimate h8300_reloc16_estimate diff -Nru binutils-2.11.2/bfd/cofflink.c binutils.new/bfd/cofflink.c --- binutils-2.11.2/bfd/cofflink.c Sat Dec 29 12:02:46 2001 +++ binutils.new/bfd/cofflink.c Sat Jan 26 02:13:40 2002 @@ -2843,6 +2843,17 @@ { struct internal_reloc *rel; struct internal_reloc *relend; + asection *embedded_reloc_section; + bfd_byte *erp; + + embedded_reloc_section = bfd_get_section_by_name (input_bfd, ".dreloc"); + if (embedded_reloc_section) + { + /* Find the first empty slot. (There is guaranteed to be one!) */ + erp = embedded_reloc_section->contents; + while (bfd_get_16 (input_bfd, erp) != 0) + erp += 8; + } rel = relocs; relend = rel + input_section->reloc_count; @@ -2852,6 +2863,7 @@ struct coff_link_hash_entry *h; struct internal_syment *sym; bfd_vma addend; + asection *sec; bfd_vma val; reloc_howto_type *howto; bfd_reloc_status_type rstat; @@ -2904,12 +2916,36 @@ addend += sym->n_value; } + if (howto->type == R_RELENDWORD) + { + /* We could avoid referring to `edata' and be a little more general + if we could use the size of the reloc's symbol's section's memory + region. Unfortunately all knowledge of memory regions is hidden + over in ../ld. */ + struct coff_link_hash_entry *edata; + + edata = coff_link_hash_lookup (coff_hash_table (info), "edata", + false, false, false); + + if (edata && (edata->root.type == bfd_link_hash_defined + || edata->root.type == bfd_link_hash_defweak)) + { + addend -= edata->root.u.def.value; + } + else + { + if (! ((*info->callbacks->warning) + (info, "relocation END16 failed without `edata'", + (h)? h->root.root.string : NULL, input_bfd, + input_section, rel->r_vaddr - input_section->vma))) + return false; + } + } + val = 0; if (h == NULL) { - asection *sec; - if (symndx == -1) { sec = bfd_abs_section_ptr; @@ -2930,8 +2966,6 @@ if (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) { - asection *sec; - sec = h->root.u.def.section; val = (h->root.u.def.value + sec->output_section->vma @@ -2976,6 +3010,26 @@ } } + /* Emit an embedded reloc if needed. */ + if ((input_section->flags & SEC_DATA) && embedded_reloc_section) + { + /* The .dreloc section consists of 8 byte structs as follows: + word type relocation type + word section data section index containing the relocation + word offset address within that section to be relocated + word symsection section index of the symbol to be added + The symbol offset can be found at the corresponding location to + be modified in the data section. */ + + bfd_put_16 (input_bfd, rel->r_type, erp); + bfd_put_16 (input_bfd, input_section->output_section->index, erp+2); + bfd_put_16 (input_bfd, (rel->r_vaddr - input_section->vma + + input_section->output_offset), erp+4); + bfd_put_16 (input_bfd, sec->output_section->index, erp+6); + + erp += 8; + } + rstat = _bfd_final_link_relocate (howto, input_bfd, input_section, contents, rel->r_vaddr - input_section->vma, diff -Nru binutils-2.11.2/bfd/configure.in binutils.new/bfd/configure.in --- binutils-2.11.2/bfd/configure.in Sat Dec 29 12:02:45 2001 +++ binutils.new/bfd/configure.in Sat Jan 26 02:13:40 2002 @@ -569,7 +569,7 @@ target64=true ;; go32coff_vec) tb="$tb coff-go32.lo cofflink.lo" ;; go32stubbedcoff_vec) tb="$tb coff-stgo32.lo cofflink.lo" ;; - h8300coff_vec) tb="$tb coff-h8300.lo reloc16.lo" ;; + h8300coff_vec) tb="$tb coff-h8300.lo cofflink.lo reloc16.lo" ;; h8500coff_vec) tb="$tb coff-h8500.lo reloc16.lo" ;; host_aout_vec) tb="$tb host-aout.lo aout32.lo" ;; hp300bsd_vec) tb="$tb hp300bsd.lo aout32.lo" ;; diff -Nru binutils-2.11.2/binutils/objcopy.c binutils.new/binutils/objcopy.c --- binutils-2.11.2/binutils/objcopy.c Sat Dec 29 12:03:01 2001 +++ binutils.new/binutils/objcopy.c Sat Jan 26 02:13:48 2002 @@ -73,6 +73,7 @@ static int copy_main PARAMS ((int, char **)); static const char *lookup_sym_redefinition PARAMS((const char *)); static void redefine_list_append PARAMS ((const char *, const char *)); +static void list_supported_architecture PARAMS((FILE *)); #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;} @@ -199,6 +200,10 @@ static boolean weaken = false; +/* Change Architecture/Machine */ +static enum bfd_architecture bfd_arch=bfd_arch_unknown; +static unsigned long bfd_mach=0xffffffff; + /* 150 isn't special; it's just an arbitrary non-ASCII char value. */ #define OPTION_ADD_SECTION 150 @@ -226,6 +231,8 @@ #define OPTION_LOCALIZE_SYMBOLS (OPTION_KEEP_SYMBOLS + 1) #define OPTION_KEEPGLOBAL_SYMBOLS (OPTION_LOCALIZE_SYMBOLS + 1) #define OPTION_WEAKEN_SYMBOLS (OPTION_KEEPGLOBAL_SYMBOLS + 1) +#define OPTION_CHANGE_ARCHITECTURE (OPTION_WEAKEN_SYMBOLS + 1) +#define OPTION_CHANGE_MACHINE (OPTION_CHANGE_ARCHITECTURE + 1) /* Options to handle if running as "strip". */ @@ -261,6 +268,8 @@ {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES}, {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS}, + {"adjust-arch",required_argument, 0, OPTION_CHANGE_ARCHITECTURE}, + {"adjust-mach",required_argument, 0, OPTION_CHANGE_MACHINE}, {"byte", required_argument, 0, 'b'}, {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES}, {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR}, @@ -390,6 +399,7 @@ -h --help Display this output\n\ ")); list_supported_targets (program_name, stream); + list_supported_architecture (stream); if (exit_status == 0) fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); exit (exit_status); @@ -422,11 +432,22 @@ ")); list_supported_targets (program_name, stream); + list_supported_architecture (stream); if (exit_status == 0) fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); exit (exit_status); } +static void list_supported_architecture(stream) + FILE *stream; +{ + const char **avec; + fprintf(stream, _("supported architecture: ")); + for (avec = bfd_arch_list(); *avec != NULL; avec++) + fprintf(stream, " %s", *avec); + fprintf(stream, "\n"); +} + /* Parse section flags into a flagword, with a fatal error if the string can't be parsed. */ @@ -938,12 +959,14 @@ & bfd_applicable_file_flags (obfd)))) RETURN_NONFATAL (bfd_get_filename (ibfd)); + if (bfd_arch == bfd_arch_unknown) + bfd_arch = bfd_get_arch(ibfd); + if (bfd_mach == 0xffffffff) + bfd_mach = bfd_get_mach(ibfd); /* Copy architecture of input file to output file */ - if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), - bfd_get_mach (ibfd))) + if (!bfd_set_arch_mach (obfd, bfd_arch, bfd_mach)) non_fatal (_("Warning: Output file cannot represent architecture %s"), - bfd_printable_arch_mach (bfd_get_arch (ibfd), - bfd_get_mach (ibfd))); + bfd_printable_arch_mach (bfd_arch, bfd_mach)); if (!bfd_set_format (obfd, bfd_get_format (ibfd))) RETURN_NONFATAL (bfd_get_filename (ibfd)); @@ -2328,6 +2351,20 @@ add_specific_symbols (optarg, &weaken_specific_list); break; + case OPTION_CHANGE_ARCHITECTURE: + { + const bfd_arch_info_type *p; + p = bfd_scan_arch(optarg); + if (p == NULL) + fatal(_("Illigal Architecture %s"),optarg); + bfd_arch = p->arch; + break; + } + + case OPTION_CHANGE_MACHINE: + bfd_mach=atoi(optarg); + break; + case 0: break; /* we've been given a long option */ diff -Nru binutils-2.11.2/binutils/objdump.c binutils.new/binutils/objdump.c --- binutils-2.11.2/binutils/objdump.c Sat Dec 29 12:03:01 2001 +++ binutils.new/binutils/objdump.c Sat Jan 26 02:13:48 2002 @@ -71,6 +71,7 @@ static int dump_debugging; /* --debugging */ static bfd_vma adjust_section_vma = 0; /* --adjust-vma */ static int file_start_context = 0; /* --file-start-context */ +static int dump_embedded_relocs = 0; /* --dump-embedded-relocs */ /* Extra info to pass to the disassembler address printing function. */ struct objdump_disasm_info { @@ -266,6 +267,7 @@ --prefix-addresses Print complete address alongside disassembly\n\ --[no-]show-raw-insn Display hex alongside symbolic disassembly\n\ --adjust-vma=OFFSET Add OFFSET to all displayed section addresses\n\ + --dump-embedded-relocs Display the Embedded Relocation Table(s)\n\ \n")); list_supported_targets (program_name, stream); @@ -282,6 +284,7 @@ #define OPTION_START_ADDRESS (OPTION_ENDIAN + 1) #define OPTION_STOP_ADDRESS (OPTION_START_ADDRESS + 1) #define OPTION_ADJUST_VMA (OPTION_STOP_ADDRESS + 1) +#define OPTION_DUMP_EMBEDDED_RELOCS (OPTION_ADJUST_VMA+1) static struct option long_options[]= { @@ -298,6 +301,7 @@ {"disassemble-zeroes", no_argument, NULL, 'z'}, {"dynamic-reloc", no_argument, NULL, 'R'}, {"dynamic-syms", no_argument, NULL, 'T'}, + {"dump-embedded-relocs", no_argument, NULL, OPTION_DUMP_EMBEDDED_RELOCS}, {"endian", required_argument, NULL, OPTION_ENDIAN}, {"file-headers", no_argument, NULL, 'f'}, {"file-start-context", no_argument, &file_start_context, 1}, @@ -2091,7 +2095,50 @@ { bfd_print_private_bfd_data (abfd, stdout); } + +static void +dump_embedded_reloc_table (abfd) +bfd *abfd; +{ + asection *relocs_sec; + bfd_byte *relocs,*rel; + bfd_size_type relocs_size; + relocs_sec = bfd_get_section_by_name (abfd, ".emreloc"); + if (relocs_sec == NULL) + { + non_fatal(_("not fount %s section"),".emreloc"); + return ; + } + relocs_size = bfd_section_size (abfd, relocs_sec); + if (!relocs_size) + { + non_fatal (_("can't read %s section"),".emreloc"); + return ; + } + relocs = (bfd_byte*) xmalloc (relocs_size); + if (!bfd_get_section_contents (abfd, relocs_sec, relocs, 0, relocs_size)) + { + non_fatal (_("can't read %s section"),".emreloc"); + free (relocs); + return ; + } + for ( rel = relocs; rel < relocs + relocs_size; rel += 12) + { + unsigned int reloffset; + asection *relsec; + char secname[16]; + reloffset = bfd_get_32 (abfd, rel); + if (reloffset == 0xffffffff) + continue; + memset(secname,0,sizeof(secname)); + memcpy(secname,(char *)rel+4,8); + relsec = bfd_get_section_by_name(abfd,secname); + printf("%s:0x%06lx\n",relsec->name,reloffset+relsec->vma); + } + free(relocs); +} + /* Dump selected contents of ABFD */ static void @@ -2145,6 +2192,8 @@ dump_data (abfd); if (disassemble) disassemble_data (abfd); + if (dump_embedded_relocs) + dump_embedded_reloc_table(abfd); if (dump_debugging) { PTR dhandle; @@ -2977,7 +3026,10 @@ show_version = true; seenflag = true; break; - + case OPTION_DUMP_EMBEDDED_RELOCS: + dump_embedded_relocs = true; + seenflag = true; + break; default: usage (stderr, 1); } diff -Nru binutils-2.11.2/ld/emulparams/h8300h.sh binutils.new/ld/emulparams/h8300h.sh --- binutils-2.11.2/ld/emulparams/h8300h.sh Sat Dec 29 12:02:38 2001 +++ binutils.new/ld/emulparams/h8300h.sh Sat Jan 26 02:13:39 2002 @@ -3,3 +3,4 @@ TEXT_START_ADDR=0x8000 TARGET_PAGE_SIZE=128 ARCH=h8300 +TEMPLATE_NAME=h8300h diff -Nru binutils-2.11.2/ld/emultempl/h8300h.em binutils.new/ld/emultempl/h8300h.em --- binutils-2.11.2/ld/emultempl/h8300h.em Thu Jan 1 09:00:00 1970 +++ binutils.new/ld/emultempl/h8300h.em Sat Jan 26 02:13:39 2002 @@ -0,0 +1,263 @@ +# This shell script emits a C file. -*- C -*- +# It does some substitutions. +cat >e${EMULATION_NAME}.c <link_next) + { + asection *textsec,*datasec,*rodatasec; + + /* As first-order business, make sure that each input BFD is COFF. It + better be, as we are directly calling a COFF backend function. */ + if (bfd_get_flavour (abfd) != bfd_target_coff_flavour) + einfo ("%F%B: all input objects must be COFF for --embedded-relocs\n"); + + textsec = bfd_get_section_by_name (abfd, ".text"); + datasec = bfd_get_section_by_name (abfd, ".data"); + rodatasec = bfd_get_section_by_name (abfd, ".rodata"); + + /* Note that we assume that the reloc_count field has already + been set up. We could call bfd_get_reloc_upper_bound, but + that returns the size of a memory buffer rather than a reloc + count. We do not want to call bfd_canonicalize_reloc, + because although it would always work it would force us to + read in the relocs into BFD canonical form, which would waste + a significant amount of time and memory. */ + if ((textsec != NULL && textsec->reloc_count > 0) || + (rodatasec != NULL && rodatasec->reloc_count > 0) || + (datasec != NULL && datasec->reloc_count > 0)) + { + asection *relsec; + int reloc_count = 0; + + if (textsec) + reloc_count += textsec->reloc_count; + if (datasec) + reloc_count += datasec->reloc_count; + if (rodatasec) + reloc_count += rodatasec->reloc_count; + + relsec = bfd_make_section (abfd, ".emreloc"); + if (relsec == NULL + || ! bfd_set_section_flags (abfd, relsec, + (SEC_DATA + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY)) + || ! bfd_set_section_alignment (abfd, relsec, 2) + || ! bfd_set_section_size (abfd, relsec, reloc_count * 12)) + einfo ("%F%B: can not create .emreloc section: %E\n"); + } + + /* Double check that all other data sections are empty, as is + required for embedded PIC code. */ + bfd_map_over_sections (abfd, check_sections, (PTR) datasec); + } +} + +/* Check that of the data sections, only the .data section has + relocs. This is called via bfd_map_over_sections. */ + +static void +check_sections (abfd, sec, datasec) + bfd *abfd; + asection *sec; + PTR datasec; +{ + if ((bfd_get_section_flags (abfd, sec) & SEC_DATA) + && sec != (asection *) datasec + && sec->reloc_count != 0) + einfo ("%B%X: section %s has relocs; can not use --embedded-relocs\n", + abfd, bfd_get_section_name (abfd, sec)); +} + +/* This function is called after the section sizes and offsets have + been set. If we are generating embedded relocs, it calls a special + BFD backend routine to do the work. */ + +static void +gld${EMULATION_NAME}_after_allocation () +{ + bfd *abfd; + + if (! command_line.embedded_relocs + || link_info.relocateable) + return; + + for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link_next) + { + asection *textsec,*rodatasec,*datasec, *relsec; + char *errmsg; + + textsec = bfd_get_section_by_name (abfd, ".text"); + rodatasec = bfd_get_section_by_name (abfd, ".rodata"); + datasec = bfd_get_section_by_name (abfd, ".data"); + + if ((textsec == NULL || textsec->reloc_count == 0) && + (rodatasec == NULL || rodatasec->reloc_count == 0) && + (datasec == NULL || datasec->reloc_count == 0)) + continue; + + + relsec = bfd_get_section_by_name (abfd, ".emreloc"); + ASSERT (relsec != NULL); + if (! bfd_h8300h_coff_create_embedded_relocs (abfd, &link_info, + textsec, rodatasec,datasec, + relsec,&errmsg)) + { + if (errmsg == NULL) + einfo ("%B%X: can not create runtime reloc information: %E\n", + abfd); + else + einfo ("%X%B: can not create runtime reloc information: %s\n", + abfd, errmsg); + } + + + } +} + +static char * +gld${EMULATION_NAME}_get_script(isfile) + int *isfile; +EOF + +if test -n "$COMPILE_IN" +then +# Scripts compiled in. + +# sed commands to quote an ld script as a C string. +sc="-f stringify.sed" + +cat >>e${EMULATION_NAME}.c <> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c + +else +# Scripts read from the filesystem. + +cat >>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <next) { + if (config.dynamic_link) + { + if (ldfile_open_file_search (arch->name, entry, "lib", ".sa")) + return; + } + found = ldfile_open_file_search (arch->name, entry, "lib", ".a"); if (found) break;