From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8194 invoked by alias); 25 Jul 2011 01:18:05 -0000 Received: (qmail 8164 invoked by uid 22791); 25 Jul 2011 01:18:02 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00,NORMAL_HTTP_TO_IP,TW_BJ,TW_JC X-Spam-Check-By: sourceware.org Received: from dair.pair.com (HELO dair.pair.com) (209.68.1.49) by sourceware.org (qpsmtpd/0.43rc1) with SMTP; Mon, 25 Jul 2011 01:17:44 +0000 Received: (qmail 28316 invoked by uid 20157); 25 Jul 2011 01:17:43 -0000 Received: from localhost (sendmail-bs@127.0.0.1) by localhost with SMTP; 25 Jul 2011 01:17:43 -0000 Date: Mon, 25 Jul 2011 12:25:00 -0000 From: Hans-Peter Nilsson To: binutils@sourceware.org Subject: Committed: "fix" ld/12815, SEGV on some inputs when linking to "binary" Message-ID: User-Agent: Alpine 2.00 (BSF 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-IsSubscribed: yes Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2011-07/txt/msg00201.txt.bz2 A graceful error is better than an abort, though even better would be to actually handle the case of emitting binary output while linking, even while doing some kind of relaxation. But generating binary output while linking is not the recommended way, so this still seems the appropriate action. ld/testsuite: PR ld/12815 * ld-mmix/pr12815-1.d, ld-mmix/pr12815-1.s, ld-mmix/pr12815-1.ld, ld-mmix/pr12815-2.d, ld-mmix/pr12815-2.s: New tests. bfd: PR ld/12815 * elf64-mmix.c (struct _mmix_elf_section_data): New members has_warned_bpo and has_warned_pushj. (mmix_final_link_relocate): Remove PARAMS and PTR macros, converting to ISO C. Add new parameter error_message. All callers changed. (mmix_elf_perform_relocation): Ditto. : Handle the case where mmix_elf_check_common_relocs has not been called, missing preparations for relocs of the respective type. Index: ld-mmix/pr12815-1.d =================================================================== RCS file: ld-mmix/pr12815-1.d diff -N ld-mmix/pr12815-1.d --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld-mmix/pr12815-1.d 25 Jul 2011 00:47:02 -0000 @@ -0,0 +1,7 @@ +#as: -no-predefined-syms -x +#ld: -e 0x1000 -m elf64mmix -T $srcdir/$subdir/pr12815-1.ld +#error: invalid input relocation.*objcopy.*"-mno-base-addresses".*truncated + +# Check that we emit a meaningful error message rather than SEGV when +# someone attempts linking to the "binary" output format with +# -mbase-addresses in effect. Index: ld-mmix/pr12815-1.ld =================================================================== RCS file: ld-mmix/pr12815-1.ld diff -N ld-mmix/pr12815-1.ld --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld-mmix/pr12815-1.ld 25 Jul 2011 00:47:02 -0000 @@ -0,0 +1,14 @@ +OUTPUT_FORMAT("binary") +ENTRY(start) +SECTIONS +{ + . = 0x8000000000100000; + .text : AT(ADDR(.text) - 0x8000000000100000) + { + *(.text) + *(.data) + *(.rodata*) + *(COMMON*) + *(.bss*) + } +} Index: ld-mmix/pr12815-1.s =================================================================== RCS file: ld-mmix/pr12815-1.s diff -N ld-mmix/pr12815-1.s --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld-mmix/pr12815-1.s 25 Jul 2011 00:47:02 -0000 @@ -0,0 +1,26 @@ +# 1 "m.c" +! mmixal:= 8H LOC Data_Section + .text ! mmixal:= 9H LOC 8B + .data ! mmixal:= 8H LOC 9B + .p2align 2 + LOC @+(4-@)&3 +foo IS @ + TETRA #2 + .text ! mmixal:= 9H LOC 8B + .p2align 2 + LOC @+(4-@)&3 + .global main +main IS @ + SUBU $254,$254,8 + STOU $253,$254,0 + ADDU $253,$254,8 + LDT $0,foo + ADDU $0,$0,1 + SET $0,$0 + STTU $0,foo + SETL $0,0 + LDO $253,$254,0 + ADDU $254,$254,8 + POP 1,0 + + .data ! mmixal:= 8H LOC 9B Index: ld-mmix/pr12815-2.d =================================================================== RCS file: ld-mmix/pr12815-2.d diff -N ld-mmix/pr12815-2.d --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld-mmix/pr12815-2.d 25 Jul 2011 00:47:02 -0000 @@ -0,0 +1,7 @@ +#as: -no-predefined-syms -x +#ld: -e 0x1000 --defsym bar=0x100000000 -m elf64mmix -T $srcdir/$subdir/pr12815-1.ld +#error: invalid input relocation.*objcopy.*"-no-expand".*truncated + +# Check that we emit a meaningful error message rather than SEGV when +# someone attempts linking to the "binary" output format with +# expanding PUSHJ insns, expecting relaxation to work. Index: ld-mmix/pr12815-2.s =================================================================== RCS file: ld-mmix/pr12815-2.s diff -N ld-mmix/pr12815-2.s --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld-mmix/pr12815-2.s 25 Jul 2011 00:47:02 -0000 @@ -0,0 +1,14 @@ +# 1 "m.c" +! mmixal:= 8H LOC Data_Section + .text ! mmixal:= 9H LOC 8B + .p2align 2 + LOC @+(4-@)&3 + .global main +main IS @ + GET $0,rJ + PUSHJ $1,bar + PUSHJ $1,bar + PUT rJ,$0 + POP 1,0 + + .data ! mmixal:= 8H LOC 9B Index: elf64-mmix.c =================================================================== RCS file: /cvs/src/src/bfd/elf64-mmix.c,v retrieving revision 1.63 diff -p -u -r1.63 elf64-mmix.c --- elf64-mmix.c 25 Oct 2010 15:54:15 -0000 1.63 +++ elf64-mmix.c 25 Jul 2011 00:53:27 -0000 @@ -75,6 +75,13 @@ struct _mmix_elf_section_data stubs_size_sum for relocation. */ bfd_size_type stub_offset; } pjs; + + /* Whether there has been a warning that this section could not be + linked due to a specific cause. FIXME: a way to access the + linker info or output section, then stuff the limiter guard + there. */ + bfd_boolean has_warned_bpo; + bfd_boolean has_warned_pushj; }; #define mmix_elf_section_data(sec) \ @@ -190,11 +197,11 @@ static bfd_boolean mmix_elf_relocate_sec Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); static bfd_reloc_status_type mmix_final_link_relocate - PARAMS ((reloc_howto_type *, asection *, bfd_byte *, - bfd_vma, bfd_signed_vma, bfd_vma, const char *, asection *)); + (reloc_howto_type *, asection *, bfd_byte *, bfd_vma, bfd_signed_vma, + bfd_vma, const char *, asection *, char **); static bfd_reloc_status_type mmix_elf_perform_relocation - PARAMS ((asection *, reloc_howto_type *, PTR, bfd_vma, bfd_vma)); + (asection *, reloc_howto_type *, void *, bfd_vma, bfd_vma, char **); static bfd_boolean mmix_elf_section_from_bfd_section PARAMS ((bfd *, asection *, int *)); @@ -934,12 +941,9 @@ mmix_elf_new_section_hook (abfd, sec) R_MMIX_ADDR19 and R_MMIX_ADDR27 are just filled in. */ static bfd_reloc_status_type -mmix_elf_perform_relocation (isec, howto, datap, addr, value) - asection *isec; - reloc_howto_type *howto; - PTR datap; - bfd_vma addr; - bfd_vma value; +mmix_elf_perform_relocation (asection *isec, reloc_howto_type *howto, + void *datap, bfd_vma addr, bfd_vma value, + char **error_message) { bfd *abfd = isec->owner; bfd_reloc_status_type flag = bfd_reloc_ok; @@ -1013,6 +1017,36 @@ mmix_elf_perform_relocation (isec, howto + mmix_elf_section_data (isec)->pjs.stub_offset); bfd_vma stubaddr; + if (mmix_elf_section_data (isec)->pjs.n_pushj_relocs == 0) + { + /* This shouldn't happen when linking to ELF or mmo, so + this is an attempt to link to "binary", right? We + can't access the output bfd, so we can't verify that + assumption. We only know that the critical + mmix_elf_check_common_relocs has not been called, + which happens when the output format is different + from the input format (and is not mmo). */ + if (! mmix_elf_section_data (isec)->has_warned_pushj) + { + /* For the first such error per input section, produce + a verbose message. */ + *error_message + = _("invalid input relocation when producing" + " non-ELF, non-mmo format output." + "\n Please use the objcopy program to convert from" + " ELF or mmo," + "\n or assemble using" + " \"-no-expand\" (for gcc, \"-Wa,-no-expand\""); + mmix_elf_section_data (isec)->has_warned_pushj = TRUE; + return bfd_reloc_dangerous; + } + + /* For subsequent errors, return this one, which is + rate-limited but looks a little bit different, + hopefully without affecting user-friendliness. */ + return bfd_reloc_overflow; + } + /* The address doesn't fit, so redirect the PUSHJ to the location of the stub. */ r = mmix_elf_perform_relocation (isec, @@ -1025,7 +1059,8 @@ mmix_elf_perform_relocation (isec, howto + size + (mmix_elf_section_data (isec) ->pjs.stub_offset) - - addr); + - addr, + error_message); if (r != bfd_reloc_ok) return r; @@ -1049,7 +1084,8 @@ mmix_elf_perform_relocation (isec, howto [R_MMIX_ADDR27], stubcontents, stubaddr, - value + addr - stubaddr); + value + addr - stubaddr, + error_message); mmix_elf_section_data (isec)->pjs.stub_offset += 4; if (size + mmix_elf_section_data (isec)->pjs.stub_offset @@ -1161,12 +1197,43 @@ mmix_elf_perform_relocation (isec, howto { struct bpo_reloc_section_info *bpodata = mmix_elf_section_data (isec)->bpo.reloc; - asection *bpo_greg_section - = bpodata->bpo_greg_section; - struct bpo_greg_section_info *gregdata - = mmix_elf_section_data (bpo_greg_section)->bpo.greg; - size_t bpo_index - = gregdata->bpo_reloc_indexes[bpodata->bpo_index++]; + asection *bpo_greg_section; + struct bpo_greg_section_info *gregdata; + size_t bpo_index; + + if (bpodata == NULL) + { + /* This shouldn't happen when linking to ELF or mmo, so + this is an attempt to link to "binary", right? We + can't access the output bfd, so we can't verify that + assumption. We only know that the critical + mmix_elf_check_common_relocs has not been called, which + happens when the output format is different from the + input format (and is not mmo). */ + if (! mmix_elf_section_data (isec)->has_warned_bpo) + { + /* For the first such error per input section, produce + a verbose message. */ + *error_message + = _("invalid input relocation when producing" + " non-ELF, non-mmo format output." + "\n Please use the objcopy program to convert from" + " ELF or mmo," + "\n or compile using the gcc-option" + " \"-mno-base-addresses\"."); + mmix_elf_section_data (isec)->has_warned_bpo = TRUE; + return bfd_reloc_dangerous; + } + + /* For subsequent errors, return this one, which is + rate-limited but looks a little bit different, + hopefully without affecting user-friendliness. */ + return bfd_reloc_overflow; + } + + bpo_greg_section = bpodata->bpo_greg_section; + gregdata = mmix_elf_section_data (bpo_greg_section)->bpo.greg; + bpo_index = gregdata->bpo_reloc_indexes[bpodata->bpo_index++]; /* A consistency check: The value we now have in "relocation" must be the same as the value we stored for that relocation. It @@ -1260,7 +1327,7 @@ mmix_elf_reloc (abfd, reloc_entry, symbo PTR data; asection *input_section; bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; + char **error_message; { bfd_vma relocation; bfd_reloc_status_type r; @@ -1322,7 +1389,8 @@ mmix_elf_reloc (abfd, reloc_entry, symbo data, reloc_entry->address, reloc_entry->addend, relocation, bfd_asymbol_name (symbol), - reloc_target_output_section); + reloc_target_output_section, + error_message); } /* Relocate an MMIX ELF section. Modified from elf32-fr30.c; look to it @@ -1454,7 +1522,7 @@ mmix_elf_relocate_section (output_bfd, i + size + mmix_elf_section_data (input_section) ->pjs.stub_offset, - NULL, NULL) != bfd_reloc_ok) + NULL, NULL, NULL) != bfd_reloc_ok) return FALSE; /* Put a JMP insn at the stub; it goes with the @@ -1494,7 +1562,7 @@ mmix_elf_relocate_section (output_bfd, i r = mmix_final_link_relocate (howto, input_section, contents, rel->r_offset, - rel->r_addend, relocation, name, sec); + rel->r_addend, relocation, name, sec, NULL); if (r != bfd_reloc_ok) { @@ -1551,16 +1619,11 @@ mmix_elf_relocate_section (output_bfd, i routines. A few relocs we have to do ourselves. */ static bfd_reloc_status_type -mmix_final_link_relocate (howto, input_section, contents, - r_offset, r_addend, relocation, symname, symsec) - reloc_howto_type *howto; - asection *input_section; - bfd_byte *contents; - bfd_vma r_offset; - bfd_signed_vma r_addend; - bfd_vma relocation; - const char *symname; - asection *symsec; +mmix_final_link_relocate (reloc_howto_type *howto, asection *input_section, + bfd_byte *contents, bfd_vma r_offset, + bfd_signed_vma r_addend, bfd_vma relocation, + const char *symname, asection *symsec, + char **error_message) { bfd_reloc_status_type r = bfd_reloc_ok; bfd_vma addr @@ -1587,7 +1650,7 @@ mmix_final_link_relocate (howto, input_s + r_offset); r = mmix_elf_perform_relocation (input_section, howto, contents, - addr, srel); + addr, srel, error_message); break; case R_MMIX_BASE_PLUS_OFFSET: @@ -1669,7 +1732,7 @@ mmix_final_link_relocate (howto, input_s do_mmix_reloc: contents += r_offset; r = mmix_elf_perform_relocation (input_section, howto, contents, - addr, srel); + addr, srel, error_message); break; case R_MMIX_LOCAL: brgds, H-P