From 591a748af9fb110937669a59bcf60fee440f2042 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 16 Mar 2007 15:13:21 +0000 Subject: [PATCH] Use pc-relative relocation instead of an absolute relocation for x86_64-pc-mingw32 target. --- binutils/ChangeLog | 5 +++++ binutils/dlltool.c | 6 ++++++ binutils/readelf.c | 52 +++++++++++++++++++++++----------------------- ld/ChangeLog | 5 +++++ ld/ldlang.c | 39 +++++++++++++++++++++++++++------- ld/pe-dll.c | 6 +++++- 6 files changed, 79 insertions(+), 34 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index c831cee1306..91b5faefd0f 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,8 @@ +2007-03-16 Kai Tietz + + * dlltool.c (make_one_lib_file): Use pc-relative relocation + instead of an absolute relocation for x86_64-pc-mingw32 target. + 2007-03-15 H.J. Lu * Makefile.am (REPORT_BUGS_TO): Removed. diff --git a/binutils/dlltool.c b/binutils/dlltool.c index 1bcd97432fc..8ee61d32200 100644 --- a/binutils/dlltool.c +++ b/binutils/dlltool.c @@ -2412,6 +2412,12 @@ make_one_lib_file (export_type *exp, int i) BFD_RELOC_16_GOTOFF); rel->sym_ptr_ptr = iname_pp; } + else if (machine == MX86) + { + rel->howto = bfd_reloc_type_lookup (abfd, + BFD_RELOC_32_PCREL); + rel->sym_ptr_ptr = iname_pp; + } else { rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); diff --git a/binutils/readelf.c b/binutils/readelf.c index 4cde91bfc7e..359ddbefdec 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -711,7 +711,7 @@ slurp_rela_relocs (FILE *file, if (relas == NULL) { free (erelas); - error (_("out of memory parsing relocs")); + error (_("out of memory parsing relocs\n")); return 0; } @@ -739,7 +739,7 @@ slurp_rela_relocs (FILE *file, if (relas == NULL) { free (erelas); - error (_("out of memory parsing relocs")); + error (_("out of memory parsing relocs\n")); return 0; } @@ -783,7 +783,7 @@ slurp_rel_relocs (FILE *file, if (rels == NULL) { free (erels); - error (_("out of memory parsing relocs")); + error (_("out of memory parsing relocs\n")); return 0; } @@ -811,7 +811,7 @@ slurp_rel_relocs (FILE *file, if (rels == NULL) { free (erels); - error (_("out of memory parsing relocs")); + error (_("out of memory parsing relocs\n")); return 0; } @@ -2814,7 +2814,7 @@ request_dump (unsigned int section, int type) new_dump_sects = calloc (section + 1, 1); if (new_dump_sects == NULL) - error (_("Out of memory allocating dump request table.")); + error (_("Out of memory allocating dump request table.\n")); else { /* Copy current flag settings. */ @@ -2842,11 +2842,11 @@ request_dump_byname (const char *section, int type) new_request = malloc (sizeof (struct dump_list_entry)); if (!new_request) - error (_("Out of memory allocating dump request table.")); + error (_("Out of memory allocating dump request table.\n")); new_request->name = strdup (section); if (!new_request->name) - error (_("Out of memory allocating dump request table.")); + error (_("Out of memory allocating dump request table.\n")); new_request->type = type; @@ -3512,7 +3512,7 @@ process_program_headers (FILE *file) sec = find_section (".dynamic"); if (sec == NULL || sec->sh_size == 0) { - error (_("no .dynamic section in the dynamic segment")); + error (_("no .dynamic section in the dynamic segment\n")); break; } @@ -3521,9 +3521,9 @@ process_program_headers (FILE *file) if (dynamic_addr < segment->p_offset || dynamic_addr > segment->p_offset + segment->p_filesz) - warn (_("the .dynamic section is not contained within the dynamic segment")); + warn (_("the .dynamic section is not contained within the dynamic segment\n")); else if (dynamic_addr > segment->p_offset) - warn (_("the .dynamic section is not the first section in the dynamic segment.")); + warn (_("the .dynamic section is not the first section in the dynamic segment.\n")); } else { @@ -3544,7 +3544,7 @@ process_program_headers (FILE *file) int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX); if (ret >= (int) sizeof (fmt) || ret < 0) - error (_("Internal error: failed to create format string to display program interpreter")); + error (_("Internal error: failed to create format string to display program interpreter\n")); program_interpreter[0] = 0; if (fscanf (file, fmt, program_interpreter) <= 0) @@ -5865,7 +5865,7 @@ process_dynamic_section (FILE *file) else { if (fseek (file, 0, SEEK_END)) - error (_("Unable to seek to end of file!")); + error (_("Unable to seek to end of file!\n")); section.sh_size = ftell (file) - section.sh_offset; } @@ -7063,7 +7063,7 @@ process_symbol_table (FILE *file) sizeof nb + sizeof nc)), SEEK_SET)) { - error (_("Unable to seek to start of dynamic information")); + error (_("Unable to seek to start of dynamic information\n")); return 0; } @@ -7289,7 +7289,7 @@ process_symbol_table (FILE *file) check_def = 0; } else if (! is_nobits) - error (_("bad dynamic symbol")); + error (_("bad dynamic symbol\n")); else check_def = 1; } @@ -7372,7 +7372,7 @@ process_symbol_table (FILE *file) lengths = calloc (nbuckets, sizeof (*lengths)); if (lengths == NULL) { - error (_("Out of memory")); + error (_("Out of memory\n")); return 0; } for (hn = 0; hn < nbuckets; ++hn) @@ -7388,7 +7388,7 @@ process_symbol_table (FILE *file) counts = calloc (maxlength + 1, sizeof (*counts)); if (counts == NULL) { - error (_("Out of memory")); + error (_("Out of memory\n")); return 0; } @@ -7437,7 +7437,7 @@ process_symbol_table (FILE *file) sizeof nb)), SEEK_SET)) { - error (_("Unable to seek to start of dynamic information")); + error (_("Unable to seek to start of dynamic information\n")); return 0; } @@ -7461,7 +7461,7 @@ process_symbol_table (FILE *file) + offset_from_vma (file, buckets_vma, 4)), SEEK_SET)) { - error (_("Unable to seek to start of dynamic information")); + error (_("Unable to seek to start of dynamic information\n")); return 0; } @@ -7491,7 +7491,7 @@ process_symbol_table (FILE *file) + 4 * (ngnubuckets + maxchain), 4)), SEEK_SET)) { - error (_("Unable to seek to start of dynamic information")); + error (_("Unable to seek to start of dynamic information\n")); return 0; } @@ -7515,7 +7515,7 @@ process_symbol_table (FILE *file) + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)), SEEK_SET)) { - error (_("Unable to seek to start of dynamic information")); + error (_("Unable to seek to start of dynamic information\n")); return 0; } @@ -7527,7 +7527,7 @@ process_symbol_table (FILE *file) lengths = calloc (ngnubuckets, sizeof (*lengths)); if (lengths == NULL) { - error (_("Out of memory")); + error (_("Out of memory\n")); return 0; } @@ -7552,7 +7552,7 @@ process_symbol_table (FILE *file) counts = calloc (maxlength + 1, sizeof (*counts)); if (counts == NULL) { - error (_("Out of memory")); + error (_("Out of memory\n")); return 0; } @@ -8550,7 +8550,7 @@ process_mips_specific (FILE *file) iopt = cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (*iopt)); if (iopt == NULL) { - error (_("Out of memory")); + error (_("Out of memory\n")); return 0; } @@ -8735,14 +8735,14 @@ process_mips_specific (FILE *file) if (dynamic_symbols == NULL) { - error (_("conflict list found without a dynamic symbol table")); + error (_("conflict list found without a dynamic symbol table\n")); return 0; } iconf = cmalloc (conflictsno, sizeof (*iconf)); if (iconf == NULL) { - error (_("Out of memory")); + error (_("Out of memory\n")); return 0; } @@ -9699,7 +9699,7 @@ main (int argc, char **argv) /* Make a copy of the dump_sects array. */ cmdline_dump_sects = malloc (num_dump_sects); if (cmdline_dump_sects == NULL) - error (_("Out of memory allocating dump request table.")); + error (_("Out of memory allocating dump request table.\n")); else { memcpy (cmdline_dump_sects, dump_sects, num_dump_sects); diff --git a/ld/ChangeLog b/ld/ChangeLog index 116a4a2830e..3333f615fd9 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,8 @@ +2007-03-16 Kai Tietz + + * pe-dll.c (make_one): Use pc-relative relocation instead of an + absolute relocation for x86_64-pc-mingw32 target. + 2007-03-15 H.J. Lu * Makefile.am (ld_TEXINFOS): Remove ldver.texi. diff --git a/ld/ldlang.c b/ld/ldlang.c index 380f4875dad..6a25ea3a74d 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -4706,7 +4706,10 @@ lang_size_sections_1 return dot; } -/* Callback routine that is used in _bfd_elf_map_sections_to_segments. */ +/* Callback routine that is used in _bfd_elf_map_sections_to_segments. + The BFD library has set NEW_SEGMENT to TRUE iff it thinks that + CURRENT_SECTION and PREVIOUS_SECTION ought to be placed into different + segments. We are allowed an opportunity to override this decision. */ bfd_boolean ldlang_override_segment_assignment (struct bfd_link_info * info ATTRIBUTE_UNUSED, @@ -4717,7 +4720,9 @@ ldlang_override_segment_assignment (struct bfd_link_info * info ATTRIBUTE_UNUSED { lang_output_section_statement_type * cur; lang_output_section_statement_type * prev; - + + /* The checks below are only necessary when the BFD library has decided + that the two sections ought to be placed into the same segment. */ if (new_segment) return TRUE; @@ -4728,16 +4733,17 @@ ldlang_override_segment_assignment (struct bfd_link_info * info ATTRIBUTE_UNUSED /* Find the memory regions associated with the two sections. We call lang_output_section_find() here rather than scanning the list of output sections looking for a matching section pointer because if - we have a large number of sections a hash lookup is faster. */ + we have a large number of sections then a hash lookup is faster. */ cur = lang_output_section_find (current_section->name); prev = lang_output_section_find (previous_section->name); + /* More paranoia. */ if (cur == NULL || prev == NULL) return new_segment; /* If the regions are different then force the sections to live in - different segments. See the email thread starting here for the - reasons why this is necessary: + different segments. See the email thread starting at the following + URL for the reasons why this is necessary: http://sourceware.org/ml/binutils/2007-02/msg00216.html */ return cur->region != prev->region; } @@ -6211,6 +6217,7 @@ lang_record_phdrs (void) alc = 10; secs = xmalloc (alc * sizeof (asection *)); last = NULL; + for (l = lang_phdr_list; l != NULL; l = l->next) { unsigned int c; @@ -6236,7 +6243,26 @@ lang_record_phdrs (void) || os->bfd_section == NULL || (os->bfd_section->flags & SEC_ALLOC) == 0) continue; - pl = last; + + if (last) + pl = last; + else + { + lang_output_section_statement_type * tmp_os; + + /* If we have not run across a section with a program + header assigned to it yet, then scan forwards to find + one. This prevents inconsistencies in the linker's + behaviour when a script has specified just a single + header and there are sections in that script which are + not assigned to it, and which occur before the first + use of that header. See here for more details: + http://sourceware.org/ml/binutils/2007-02/msg00291.html */ + for (tmp_os = os; tmp_os; tmp_os = tmp_os->next) + if (tmp_os->phdrs) + break; + pl = tmp_os->phdrs; + } } if (os->bfd_section == NULL) @@ -6468,7 +6494,6 @@ lang_leave_overlay (etree_type *lma_expr, an LMA region was specified. */ if (l->next == 0) l->os->load_base = lma_expr; - if (phdrs != NULL && l->os->phdrs == NULL) l->os->phdrs = phdrs; diff --git a/ld/pe-dll.c b/ld/pe-dll.c index a7951c9f79a..e3d87a68cd4 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -1975,7 +1975,11 @@ make_one (def_file_export *exp, bfd *parent, bfd_boolean include_jmp_stub) switch (pe_details->pe_arch) { case PE_ARCH_i386: - quick_reloc (abfd, 2, BFD_RELOC_32, 2); +#ifdef pe_use_x86_64 + quick_reloc (abfd, 2, BFD_RELOC_32_PCREL, 2); +#else + quick_reloc (abfd, 2, BFD_RELOC_32, 2); +#endif break; case PE_ARCH_sh: quick_reloc (abfd, 8, BFD_RELOC_32, 2); -- 2.30.2