This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi all, First attempt at producing a patch for this project for XCOFF support for AIX. I can't seem to find a contribution guide that explains the exact procedure for raising a PR so apologies if this is not the right thing to do...! See https://sourceware.org/bugzilla/show_bug.cgi?id=21700 for details and discussion. Bug summary: When creating a Linux / AIX cross-compiler I hit the following error: /tmp/ccLI9PmP.s:2660: Error: can't resolve `_ehpersonality.rw_[RW]' {.data section} - `__gcc_unwind_dbase' {*UND* section} This is caused by this line: .vbyte 4,LDFCM..0-__gcc_unwind_dbase The attached file "exceptions.cpp" when compiled with gcc 6.3.0 on an AIX 6.1 machine will produce "exceptions.s" that contains this line: g++ -S exceptions.cpp -o exceptions.s g++ -v Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/opt/freeware/libexec/gcc/powerpc-ibm- aix6.1.1.0/6.3.0/lto-wrapper Target: powerpc-ibm-aix6.1.1.0 Configured with: ../gcc-6.3.0/configure --with-as=/usr/bin/as --with-ld=/usr/bin/ld --enable-languages=c,c++,fortran --prefix=/opt/freeware --mandir=/opt/freeware/man --infodir=/opt/freeware/info --enable-version-specific-runtime-libs --disable-nls --enable-decimal-float=dpd --with-cloog=no --with-ppl=no --disable-libstdcxx-pch --enable__cxa_atexit --enable-bootstrap --host=powerpc-ibm-aix6.1.1.0 Thread model: aix gcc version 6.3.0 (GCC) The IBM as is able to compile this file to create relocations as: 103: R_POS _exceptions.rw_-0x150 103: R_NEG __gcc_unwind_dbase Additionally the IBM as creates relocations for .__cxa_throw (bl .__cxa_throw) and similar as: 00000040 R_RBR_26 .__cxa_throw whereas gas creates: 00000040 R_BR .__cxa_throw Lastly, the IBM as will correctly compile ".vbyte 4,LFB..0-$" to the correct section boundary. Changelog: 2018-02-19 James Reynolds <james.reynolds@cristie.com> * bfd/bfd-in2.h: Add new BFD_RELOC_PPC_NEG type * bfd/coff-rs6000.c: Fix relocation type RBR_26 and add PPC_NEG type * bfd/coff64-rs6000.c: Add PPC_NEG type * bfd/libbfd.h: Add PPC_NEG type * bfd/reloc.c: Add size calculations for PPC_NEG type * gas/config/tc-ppc.c: Allow creation of negative relocations and adjust for section boundaries * gas/config/tc-ppc.h: Allow negative relocations in TC_VALIDATE_FIX_SUB This was tested by compiling exceptions.s to produce matching relocations to the IBM as. This corrects bug 21700 but c++ exceptions are not correctly caught at present, further investigation and a new patch will be submitted to correct this. Thanks all, James ----- patch ----- diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 9742c1ac7f..e81d6810c2 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -3442,6 +3442,7 @@ instruction. */ BFD_RELOC_PPC64_ADDR16_HIGHA, BFD_RELOC_PPC64_ADDR64_LOCAL, BFD_RELOC_PPC64_ENTRY, + BFD_RELOC_PPC_NEG, /* PowerPC and PowerPC64 thread-local storage relocations. */ BFD_RELOC_PPC_TLS, diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index d8db1f3894..db61628990 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -981,7 +981,7 @@ reloc_howto_type xcoff_howto_table[] = 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 26, /* bitsize */ - FALSE, /* pc_relative */ + TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ 0, /* special_function */ @@ -1090,7 +1090,7 @@ _bfd_xcoff_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, switch (code) { case BFD_RELOC_PPC_B26: - return &xcoff_howto_table[0xa]; + return &xcoff_howto_table[0x1a]; case BFD_RELOC_PPC_BA16: return &xcoff_howto_table[0x1c]; case BFD_RELOC_PPC_BA26: @@ -1107,6 +1107,8 @@ _bfd_xcoff_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, return &xcoff_howto_table[0]; case BFD_RELOC_NONE: return &xcoff_howto_table[0xf]; + case BFD_RELOC_PPC_NEG: + return &xcoff_howto_table[0x1]; default: return NULL; } diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index 78f14a09f4..c395aaee07 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -1831,6 +1831,8 @@ xcoff64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, return &xcoff64_howto_table[0]; case BFD_RELOC_NONE: return &xcoff64_howto_table[0xf]; + case BFD_RELOC_PPC_NEG: + return &xcoff64_howto_table[0x1]; default: return NULL; } diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 0fba5bea3e..dbfb58c46b 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1425,6 +1425,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_PPC64_ADDR16_HIGHA", "BFD_RELOC_PPC64_ADDR64_LOCAL", "BFD_RELOC_PPC64_ENTRY", + "BFD_RELOC_PPC_NEG", "BFD_RELOC_PPC_TLS", "BFD_RELOC_PPC_TLSGD", "BFD_RELOC_PPC_TLSLD", diff --git a/bfd/reloc.c b/bfd/reloc.c index 42e35b91ed..bc197e67a4 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -441,6 +441,7 @@ bfd_get_reloc_size (reloc_howto_type *howto) case 8: return 16; case -1: return 2; case -2: return 4; + case -4: return 8; default: abort (); } } @@ -1351,6 +1352,14 @@ space consuming. For each target: bfd_put_64 (abfd, x, data); } break; + case -4: + { + bfd_vma x = bfd_get_64 (abfd, data); + relocation = -relocation; + DOIT (x); + bfd_put_64 (abfd, (bfd_vma) x, data); + } + break; default: return bfd_reloc_other; } @@ -3009,6 +3018,8 @@ ENUMX BFD_RELOC_PPC64_ADDR64_LOCAL ENUMX BFD_RELOC_PPC64_ENTRY +ENUMX + BFD_RELOC_PPC_NEG ENUMDOC Power(rs6000) and PowerPC relocations. diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index ff76221dc0..0107a28400 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -6279,6 +6279,40 @@ md_pcrel_from_section (fixS *fixp, segT sec ATTRIBUTE_UNUSED) #ifdef OBJ_XCOFF +/* Possibly adjust the reloc to be against the csect. */ +symbolS * +ppc_can_adjust_to_csect(symbolS *sym); +symbolS * +ppc_can_adjust_to_csect(symbolS *sym) +{ + segT symseg = sym ? S_GET_SEGMENT (sym) : 0; + TC_SYMFIELD_TYPE *tc = sym ? symbol_get_tc (sym) : NULL; + valueT val = sym ? resolve_symbol_value (sym) : 0; + if (sym + && tc->subseg == 0 + && tc->symbol_class != XMC_TC0 + && tc->symbol_class != XMC_TC + && symseg != bss_section + /* Don't adjust if this is a reloc in the toc section. */ + && (symseg != data_section + || ppc_toc_csect == NULL + || val < ppc_toc_frag->fr_address + || (ppc_after_toc_frag != NULL + && val >= ppc_after_toc_frag->fr_address))) + { + symbolS *csect = symbol_get_tc (sym)->within; + + /* If the symbol was not declared by a label (eg: a section symbol), + use the section instead of the csect. This doesn't happen in + normal AIX assembly code. */ + if (csect == NULL) + csect = seg_info (S_GET_SEGMENT (sym))->sym; + + return csect; + } + return NULL; +} + /* This is called to see whether a fixup should be adjusted to use a section symbol. We take the opportunity to change a fixup against a symbol in the TOC subsegment into a reloc against the @@ -6289,7 +6323,7 @@ ppc_fix_adjustable (fixS *fix) { valueT val = resolve_symbol_value (fix->fx_addsy); segT symseg = S_GET_SEGMENT (fix->fx_addsy); - TC_SYMFIELD_TYPE *tc; + symbolS *csect; if (symseg == absolute_section) return 0; @@ -6330,30 +6364,17 @@ ppc_fix_adjustable (fixS *fix) } /* Possibly adjust the reloc to be against the csect. */ - tc = symbol_get_tc (fix->fx_addsy); - if (tc->subseg == 0 - && tc->symbol_class != XMC_TC0 - && tc->symbol_class != XMC_TC - && symseg != bss_section - /* Don't adjust if this is a reloc in the toc section. */ - && (symseg != data_section - || ppc_toc_csect == NULL - || val < ppc_toc_frag->fr_address - || (ppc_after_toc_frag != NULL - && val >= ppc_after_toc_frag->fr_address))) + if ((csect = ppc_can_adjust_to_csect(fix->fx_addsy)) != NULL) { - symbolS *csect = tc->within; - - /* If the symbol was not declared by a label (eg: a section symbol), - use the section instead of the csect. This doesn't happen in - normal AIX assembly code. */ - if (csect == NULL) - csect = seg_info (symseg)->sym; - fix->fx_offset += val - symbol_get_frag (csect)->fr_address; fix->fx_addsy = csect; + } - return 0; + /* Possibly adjust the reloc to be against the csect. */ + if ((csect = ppc_can_adjust_to_csect(fix->fx_subsy)) != NULL) + { + fix->fx_offset += symbol_get_frag (csect)->fr_address - val; + fix->fx_subsy = csect; } /* Adjust a reloc against a .lcomm symbol to be against the base @@ -6585,6 +6606,20 @@ ppc_handle_align (struct frag *fragP) } } +/* + * If the resulting fix would be negative then force a relocation. + */ +int +ppc_force_relocation_sub_same(fixS *fixP, segT seg) +{ + if (!fixP->fx_addsy || !fixP->fx_subsy) return !SEG_NORMAL(seg); + if (S_GET_VALUE (fixP->fx_addsy) < S_GET_VALUE (fixP->fx_subsy)) + { + return TRUE; + } + return !SEG_NORMAL(seg); +} + /* Apply a fixup to the object code. This is called for all the fixups we generated by the calls to fix_new_exp, above. */ @@ -7224,27 +7259,71 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) /* Generate a reloc for a fixup. */ -arelent * +arelent ** tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp) { arelent *reloc; + static arelent *relocs[3]; - reloc = XNEW (arelent); + relocs[0] = reloc = XNEW (arelent); + relocs[1] = NULL; reloc->sym_ptr_ptr = XNEW (asymbol *); *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; + reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); if (reloc->howto == (reloc_howto_type *) NULL) { as_bad_where (fixp->fx_file, fixp->fx_line, _("reloc %d not supported by object file format"), (int) fixp->fx_r_type); - return NULL; + relocs[0] = NULL; + return relocs; } reloc->addend = fixp->fx_addnumber; - return reloc; + /* We expand a subtraction into an R_POS and R_NEG */ + if (fixp->fx_subsy && fixp->fx_addsy) + { + if (ppc_obj64) + { + reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_64); + } + + /* If this is negative then we should put the relocs the other way around */ + if (S_GET_VALUE (fixp->fx_addsy) < S_GET_VALUE (fixp->fx_subsy)) + { + relocs[1] = reloc; + relocs[0] = reloc = XNEW (arelent); + relocs[2] = NULL; + } + else + { + relocs[1] = reloc = XNEW (arelent); + relocs[2] = NULL; + } + + bfd_reloc_code_real_type code = BFD_RELOC_PPC_NEG; + + reloc->sym_ptr_ptr = XNEW (asymbol *); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy); + reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; + + reloc->howto = bfd_reloc_type_lookup (stdoutput, code); + reloc->addend = fixp->fx_addnumber; + + if (reloc->howto == (reloc_howto_type *) NULL) + { + as_bad_where (fixp->fx_file, fixp->fx_line, + _("reloc %d not supported by object file format"), + code); + relocs[0] = NULL; + return relocs; + } + } + + return relocs; } void diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h index cf627dec26..9c6b2af413 100644 --- a/gas/config/tc-ppc.h +++ b/gas/config/tc-ppc.h @@ -260,6 +260,11 @@ extern void ppc_elf_end (void); extern int ppc_force_relocation (struct fix *); #endif +#if defined (OBJ_XCOFF) +#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG) ppc_force_relocation_sub_same(FIX, SEG) +extern int ppc_force_relocation_sub_same(struct fix *, segT); +#endif + #ifdef OBJ_ELF /* Don't allow the generic code to convert fixups involving the subtraction of a label in the current section to pc-relative if we @@ -274,7 +279,9 @@ extern int ppc_force_relocation (struct fix *); || (FIX)->fx_r_type == BFD_RELOC_PPC_16DX_HA)) #endif -#define TC_VALIDATE_FIX_SUB(FIX, SEG) 0 +#define RELOC_EXPANSION_POSSIBLE +#define MAX_RELOC_EXPANSION 2 +#define UNDEFINED_DIFFERENCE_OK /* call md_pcrel_from_section, not md_pcrel_from */ #define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section(FIX, SEC)
Attachment:
testcase.tar.bz2
Description: testcase.tar.bz2
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |