diff options
-rw-r--r-- | bfd/ChangeLog | 15 | ||||
-rw-r--r-- | bfd/coff-rs6000.c | 323 | ||||
-rw-r--r-- | bfd/coff64-rs6000.c | 234 | ||||
-rw-r--r-- | bfd/libxcoff.h | 2 | ||||
-rw-r--r-- | binutils/ChangeLog | 4 | ||||
-rw-r--r-- | binutils/od-xcoff.c | 3 | ||||
-rw-r--r-- | include/ChangeLog | 5 | ||||
-rw-r--r-- | include/coff/xcoff.h | 53 |
8 files changed, 400 insertions, 239 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9c301d0..6c359ac 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,20 @@ 2021-03-12 Clément Chigot <clement.chigot@atos.net> + * coff-rs6000.c (xcoff_calculate_relocation): Correct and + add new relocations. + (xcoff_howto_table): Likewise. + (xcoff_rtype2howto): Increase r_type maximum value. + (xcoff_ppc_relocate_section): Reuse predefined HOWTOs instead + of create a new one from scratch. Enable only some relocations + to have a changing r_size. + * coff64-rs6000.c (xcoff64_calculate_relocation): Likewise. + (xcoff64_howto_table): Likewise. + (xcoff64_rtype2howto): Likewise. + (xcoff64_ppc_relocate_section): Likewise. + * libxcoff.h (XCOFF_MAX_CALCULATE_RELOCATION): Fix value. + +2021-03-12 Clément Chigot <clement.chigot@atos.net> + * coff64-rs6000.c (xcoff64_ppc_relocate_section): Move. 2021-03-12 Clément Chigot <clement.chigot@atos.net> diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 54fbf58..2cae299 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -158,34 +158,56 @@ static xcoff_complain_function xcoff_complain_overflow_unsigned_func; xcoff_reloc_function *const xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] = { - xcoff_reloc_type_pos, /* R_POS (0x00) */ - xcoff_reloc_type_neg, /* R_NEG (0x01) */ - xcoff_reloc_type_rel, /* R_REL (0x02) */ - xcoff_reloc_type_toc, /* R_TOC (0x03) */ - xcoff_reloc_type_fail, /* R_RTB (0x04) */ - xcoff_reloc_type_toc, /* R_GL (0x05) */ - xcoff_reloc_type_toc, /* R_TCL (0x06) */ - xcoff_reloc_type_fail, /* (0x07) */ - xcoff_reloc_type_ba, /* R_BA (0x08) */ - xcoff_reloc_type_fail, /* (0x09) */ - xcoff_reloc_type_br, /* R_BR (0x0a) */ - xcoff_reloc_type_fail, /* (0x0b) */ - xcoff_reloc_type_pos, /* R_RL (0x0c) */ - xcoff_reloc_type_pos, /* R_RLA (0x0d) */ - xcoff_reloc_type_fail, /* (0x0e) */ + xcoff_reloc_type_pos, /* R_POS (0x00) */ + xcoff_reloc_type_neg, /* R_NEG (0x01) */ + xcoff_reloc_type_rel, /* R_REL (0x02) */ + xcoff_reloc_type_toc, /* R_TOC (0x03) */ + xcoff_reloc_type_toc, /* R_TRL (0x04) */ + xcoff_reloc_type_toc, /* R_GL (0x05) */ + xcoff_reloc_type_toc, /* R_TCL (0x06) */ + xcoff_reloc_type_fail, /* (0x07) */ + xcoff_reloc_type_ba, /* R_BA (0x08) */ + xcoff_reloc_type_fail, /* (0x09) */ + xcoff_reloc_type_br, /* R_BR (0x0a) */ + xcoff_reloc_type_fail, /* (0x0b) */ + xcoff_reloc_type_pos, /* R_RL (0x0c) */ + xcoff_reloc_type_pos, /* R_RLA (0x0d) */ + xcoff_reloc_type_fail, /* (0x0e) */ xcoff_reloc_type_noop, /* R_REF (0x0f) */ - xcoff_reloc_type_fail, /* (0x10) */ - xcoff_reloc_type_fail, /* (0x11) */ - xcoff_reloc_type_toc, /* R_TRL (0x12) */ - xcoff_reloc_type_toc, /* R_TRLA (0x13) */ + xcoff_reloc_type_fail, /* (0x10) */ + xcoff_reloc_type_fail, /* (0x11) */ + xcoff_reloc_type_fail, /* (0x12) */ + xcoff_reloc_type_toc, /* R_TRLA (0x13) */ xcoff_reloc_type_fail, /* R_RRTBI (0x14) */ xcoff_reloc_type_fail, /* R_RRTBA (0x15) */ - xcoff_reloc_type_ba, /* R_CAI (0x16) */ + xcoff_reloc_type_ba, /* R_CAI (0x16) */ xcoff_reloc_type_crel, /* R_CREL (0x17) */ - xcoff_reloc_type_ba, /* R_RBA (0x18) */ - xcoff_reloc_type_ba, /* R_RBAC (0x19) */ - xcoff_reloc_type_br, /* R_RBR (0x1a) */ - xcoff_reloc_type_ba, /* R_RBRC (0x1b) */ + xcoff_reloc_type_ba, /* R_RBA (0x18) */ + xcoff_reloc_type_ba, /* R_RBAC (0x19) */ + xcoff_reloc_type_br, /* R_RBR (0x1a) */ + xcoff_reloc_type_ba, /* R_RBRC (0x1b) */ + xcoff_reloc_type_fail, /* (0x1c) */ + xcoff_reloc_type_fail, /* (0x1d) */ + xcoff_reloc_type_fail, /* (0x1e) */ + xcoff_reloc_type_fail, /* (0x1f) */ + xcoff_reloc_type_fail, /* R_TLS (0x20) */ + xcoff_reloc_type_fail, /* R_TLS_IE (0x21) */ + xcoff_reloc_type_fail, /* R_TLS_LD (0x22) */ + xcoff_reloc_type_fail, /* R_TLS_LE (0x23) */ + xcoff_reloc_type_fail, /* R_TLSM (0x24) */ + xcoff_reloc_type_fail, /* R_TLSML (0x25) */ + xcoff_reloc_type_fail, /* (0x26) */ + xcoff_reloc_type_fail, /* (0x27) */ + xcoff_reloc_type_fail, /* (0x28) */ + xcoff_reloc_type_fail, /* (0x29) */ + xcoff_reloc_type_fail, /* (0x2a) */ + xcoff_reloc_type_fail, /* (0x2b) */ + xcoff_reloc_type_fail, /* (0x2c) */ + xcoff_reloc_type_fail, /* (0x2d) */ + xcoff_reloc_type_fail, /* (0x2e) */ + xcoff_reloc_type_fail, /* (0x2f) */ + xcoff_reloc_type_fail, /* R_TOCU (0x30) */ + xcoff_reloc_type_fail, /* R_TOCL (0x31) */ }; xcoff_complain_function *const @@ -652,11 +674,18 @@ _bfd_xcoff_swap_aux_out (bfd *abfd, void * inp, int type, int in_class, return bfd_coff_auxesz (abfd); } -/* The XCOFF reloc table. Actually, XCOFF relocations specify the - bitsize and whether they are signed or not, along with a - conventional type. This table is for the types, which are used for - different algorithms for putting in the reloc. Many of these - relocs need special_function entries, which I have not written. */ +/* The XCOFF reloc table. + XCOFF relocations aren't defined only by the type field r_type. + The bitsize and whether they are signed or not, are defined by + r_size field. Thus, it's complicated to create a constant + table reference every possible relocation. + This table contains the "default" relocation and few modified + relocations what were already there. It's enough when + xcoff_rtype2howto is called. + For relocations from an input bfd to an output bfd, the default + relocation is retrieved and when manually adapted. + + For now, it seems to be enought. */ reloc_howto_type xcoff_howto_table[] = { @@ -720,19 +749,19 @@ reloc_howto_type xcoff_howto_table[] = 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* 0x04: I don't really know what this is. */ - HOWTO (R_RTB, /* type */ - 1, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ + /* 0x04: Same as R_TOC */ + HOWTO (R_TRL, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ 0, /* special_function */ - "R_RTB", /* name */ + "R_TRL", /* name */ TRUE, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ /* 0x05: External TOC relative symbol. */ @@ -767,7 +796,7 @@ reloc_howto_type xcoff_howto_table[] = EMPTY_HOWTO (7), - /* 0x08: Non modifiable absolute branch. */ + /* 0x08: Same as R_RBA. */ HOWTO (R_BA, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -784,7 +813,7 @@ reloc_howto_type xcoff_howto_table[] = EMPTY_HOWTO (9), - /* 0x0a: Non modifiable relative branch. */ + /* 0x0a: Same as R_RBR. */ HOWTO (R_BR, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -801,34 +830,34 @@ reloc_howto_type xcoff_howto_table[] = EMPTY_HOWTO (0xb), - /* 0x0c: Indirect load. */ + /* 0x0c: Same as R_POS. */ HOWTO (R_RL, /* type */ 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ 0, /* special_function */ "R_RL", /* name */ TRUE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* 0x0d: Load address. */ + /* 0x0d: Same as R_POS. */ HOWTO (R_RLA, /* type */ 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ 0, /* special_function */ "R_RLA", /* name */ TRUE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ FALSE), /* pcrel_offset */ EMPTY_HOWTO (0xe), @@ -850,23 +879,9 @@ reloc_howto_type xcoff_howto_table[] = EMPTY_HOWTO (0x10), EMPTY_HOWTO (0x11), + EMPTY_HOWTO (0x12), - /* 0x12: TOC relative indirect load. */ - HOWTO (R_TRL, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TRL", /* name */ - TRUE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 0x13: TOC relative load address. */ + /* 0x13: Same as R_TOC. */ HOWTO (R_TRLA, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ @@ -882,7 +897,7 @@ reloc_howto_type xcoff_howto_table[] = FALSE), /* pcrel_offset */ /* 0x14: Modifiable relative branch. */ - HOWTO (R_RRTBI, /* type */ + HOWTO (R_RRTBI, /* type */ 1, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ @@ -897,7 +912,7 @@ reloc_howto_type xcoff_howto_table[] = FALSE), /* pcrel_offset */ /* 0x15: Modifiable absolute branch. */ - HOWTO (R_RRTBA, /* type */ + HOWTO (R_RRTBA, /* type */ 1, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ @@ -1045,12 +1060,50 @@ reloc_howto_type xcoff_howto_table[] = 0xffff, /* src_mask */ 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + EMPTY_HOWTO (0x1f), + + /* 0x20: General-dynamic TLS relocation. */ + EMPTY_HOWTO (R_TLS), + + /* 0x21: Initial-exec TLS relocation. */ + EMPTY_HOWTO (R_TLS_IE), + + /* 0x22: Local-dynamic TLS relocation. */ + EMPTY_HOWTO (R_TLS_LD), + + /* 0x23: Local-exec TLS relocation. */ + EMPTY_HOWTO (R_TLS_LE), + + /* 0x24: TLS relocation. */ + EMPTY_HOWTO(R_TLSM), + + /* 0x25: TLS module relocation. */ + EMPTY_HOWTO(R_TLSML), + + EMPTY_HOWTO(0x26), + EMPTY_HOWTO(0x27), + EMPTY_HOWTO(0x28), + EMPTY_HOWTO(0x29), + EMPTY_HOWTO(0x2a), + EMPTY_HOWTO(0x2b), + EMPTY_HOWTO(0x2c), + EMPTY_HOWTO(0x2d), + EMPTY_HOWTO(0x2e), + EMPTY_HOWTO(0x2f), + + /* 0x30: High-order 16 bit TOC relative relocation. */ + EMPTY_HOWTO (R_TOCU), + + /* 0x31: Low-order 16 bit TOC relative relocation. */ + EMPTY_HOWTO (R_TOCL), + }; void xcoff_rtype2howto (arelent *relent, struct internal_reloc *internal) { - if (internal->r_type > R_RBRC) + if (internal->r_type > R_TOCL) abort (); /* Default howto layout works most of the time */ @@ -3225,11 +3278,14 @@ xcoff_complain_overflow_unsigned_func (bfd *input_bfd, This is currently the only processor which uses XCOFF; I hope that will never change. - I took the relocation type definitions from two documents: + The original version was based on two documents: the PowerPC AIX Version 4 Application Binary Interface, First Edition (April 1992), and the PowerOpen ABI, Big-Endian 32-Bit Hardware Implementation (June 30, 1994). Differences between the documents are noted below. + Now, IBM has released an official documentation about XCOFF + format: + https://www.ibm.com/support/knowledgecenter/ssw_aix_72/filesreference/XCOFF.html Unsupported r_type's @@ -3243,6 +3299,15 @@ xcoff_complain_overflow_unsigned_func (bfd *input_bfd, quite figure out when this is useful. These relocs are not defined by the PowerOpen ABI. + R_TOCU + R_TOCL + R_TLS + R_TLS_IE + R_TLS_LD + R_TLSLE + + Not yet implemented. + Supported r_type's R_POS: @@ -3264,38 +3329,68 @@ xcoff_complain_overflow_unsigned_func (bfd *input_bfd, osym = oTOC + on oinsn = on + o so we must change insn by on - in. + This relocation allows the linker to perform optimizations + by transforming a load instruction into a add-immediate + when possible. The relocation is, then, changed to R_TRLA + in the output file. + TODO: Currently, the optimisation isn't implemented. + + R_TRL: + TOC relative relocation. Same as R_TOC, except that + the optimization isn't allowed + + R_TRLA: + TOC relative relocation. This is a TOC relative load + address instruction which have been changed to an add- + immediate instruction. R_GL: GL linkage relocation. The value of this relocation - is the address of the entry in the TOC section. + is the address of the external symbol in the TOC + section. R_TCL: Local object TOC address. I can't figure out the difference between this and case R_GL. - R_TRL: - TOC relative relocation. A TOC relative load instruction - which may be changed to a load address instruction. - FIXME: We don't currently implement this optimization. + R_RL: + The PowerPC AIX ABI describes this as a load which may be + changed to a load address. The PowerOpen ABI says this + is the same as case R_POS. - R_TRLA: - TOC relative relocation. This is a TOC relative load - address instruction which may be changed to a load - instruction. FIXME: I don't know if this is the correct - implementation. + R_RLA: + The PowerPC AIX ABI describes this as a load address + which may be changed to a load. The PowerOpen ABI says + this is the same as R_POS. + + R_REF: + Not a relocation but a way to prevent the garbage + collector of AIX linker to remove symbols. + This is not needed in our case. R_BA: - Absolute branch. We don't want to mess with the lower - two bits of the instruction. + The PowerOpen ABI says this is the same as R_RBA. + + R_RBA: + Absolute branch which may be modified to become a + relative branch. + + R_BR: + The PowerOpen ABI says this is the same as R_RBR. + + R_RBR: + A relative branch which may be modified to become an + absolute branch. R_CAI: The PowerPC ABI defines this as an absolute call which may be modified to become a relative call. The PowerOpen ABI does not define this relocation type. - R_RBA: - Absolute branch which may be modified to become a - relative branch. + R_CREL: + The PowerPC ABI defines this as a relative call which may + be modified to become an absolute call. The PowerOpen + ABI does not define this relocation type. R_RBAC: The PowerPC ABI defines this as an absolute branch to a @@ -3307,29 +3402,6 @@ xcoff_complain_overflow_unsigned_func (bfd *input_bfd, The PowerPC ABI defines this as an absolute branch to a fixed address which may be modified to a relative branch. The PowerOpen ABI does not define this relocation type. - - R_BR: - Relative branch. We don't want to mess with the lower - two bits of the instruction. - - R_CREL: - The PowerPC ABI defines this as a relative call which may - be modified to become an absolute call. The PowerOpen - ABI does not define this relocation type. - - R_RBR: - A relative branch which may be modified to become an - absolute branch. - - R_RL: - The PowerPC AIX ABI describes this as a load which may be - changed to a load address. The PowerOpen ABI says this - is the same as case R_POS. - - R_RLA: - The PowerPC AIX ABI describes this as a load address - which may be changed to a load. The PowerOpen ABI says - this is the same as R_POS. */ bfd_boolean @@ -3366,21 +3438,34 @@ xcoff_ppc_relocate_section (bfd *output_bfd, if (rel->r_type == R_REF) continue; - /* howto */ - howto.type = rel->r_type; - howto.rightshift = 0; - howto.bitsize = (rel->r_size & 0x1f) + 1; - howto.size = howto.bitsize > 16 ? 2 : 1; - howto.pc_relative = FALSE; - howto.bitpos = 0; + /* Retrieve default value in HOWTO table and fix up according + to r_size field, if it can be different. + This should be made during relocation reading but the algorithms + are expecting constant howtos. */ + memcpy (&howto, &xcoff_howto_table[rel->r_type], sizeof (howto)); + if (howto.bitsize != (rel->r_size & 0x1f) + 1) + { + switch (rel->r_type) + { + case R_POS: + case R_NEG: + howto.bitsize = (rel->r_size & 0x1f) + 1; + howto.size = howto.bitsize > 16 ? 2 : 1; + howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize); + break; + + default: + _bfd_error_handler + (_("%pB: relocatation (%d) at (0x%" BFD_VMA_FMT "x) has wrong" + " r_rsize (0x%x)\n"), + input_bfd, rel->r_type, rel->r_vaddr, rel->r_size); + return FALSE; + } + } + howto.complain_on_overflow = (rel->r_size & 0x80 ? complain_overflow_signed : complain_overflow_bitfield); - howto.special_function = NULL; - howto.name = "internal"; - howto.partial_inplace = TRUE; - howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize); - howto.pcrel_offset = FALSE; /* symbol */ val = 0; diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index 3f74130..0cb7e8b 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -180,34 +180,56 @@ static xcoff_reloc_function xcoff64_reloc_type_br; xcoff_reloc_function *const xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] = { - xcoff_reloc_type_pos, /* R_POS (0x00) */ - xcoff_reloc_type_neg, /* R_NEG (0x01) */ - xcoff_reloc_type_rel, /* R_REL (0x02) */ - xcoff_reloc_type_toc, /* R_TOC (0x03) */ - xcoff_reloc_type_fail, /* R_RTB (0x04) */ - xcoff_reloc_type_toc, /* R_GL (0x05) */ - xcoff_reloc_type_toc, /* R_TCL (0x06) */ - xcoff_reloc_type_fail, /* (0x07) */ - xcoff_reloc_type_ba, /* R_BA (0x08) */ - xcoff_reloc_type_fail, /* (0x09) */ - xcoff64_reloc_type_br, /* R_BR (0x0a) */ - xcoff_reloc_type_fail, /* (0x0b) */ - xcoff_reloc_type_pos, /* R_RL (0x0c) */ - xcoff_reloc_type_pos, /* R_RLA (0x0d) */ - xcoff_reloc_type_fail, /* (0x0e) */ - xcoff_reloc_type_noop, /* R_REF (0x0f) */ - xcoff_reloc_type_fail, /* (0x10) */ - xcoff_reloc_type_fail, /* (0x11) */ - xcoff_reloc_type_toc, /* R_TRL (0x12) */ - xcoff_reloc_type_toc, /* R_TRLA (0x13) */ - xcoff_reloc_type_fail, /* R_RRTBI (0x14) */ - xcoff_reloc_type_fail, /* R_RRTBA (0x15) */ - xcoff_reloc_type_ba, /* R_CAI (0x16) */ - xcoff_reloc_type_crel, /* R_CREL (0x17) */ - xcoff_reloc_type_ba, /* R_RBA (0x18) */ - xcoff_reloc_type_ba, /* R_RBAC (0x19) */ - xcoff64_reloc_type_br, /* R_RBR (0x1a) */ - xcoff_reloc_type_ba, /* R_RBRC (0x1b) */ + xcoff_reloc_type_pos, /* R_POS (0x00) */ + xcoff_reloc_type_neg, /* R_NEG (0x01) */ + xcoff_reloc_type_rel, /* R_REL (0x02) */ + xcoff_reloc_type_toc, /* R_TOC (0x03) */ + xcoff_reloc_type_toc, /* R_TRL (0x04) */ + xcoff_reloc_type_toc, /* R_GL (0x05) */ + xcoff_reloc_type_toc, /* R_TCL (0x06) */ + xcoff_reloc_type_fail, /* (0x07) */ + xcoff_reloc_type_ba, /* R_BA (0x08) */ + xcoff_reloc_type_fail, /* (0x09) */ + xcoff64_reloc_type_br, /* R_BR (0x0a) */ + xcoff_reloc_type_fail, /* (0x0b) */ + xcoff_reloc_type_pos, /* R_RL (0x0c) */ + xcoff_reloc_type_pos, /* R_RLA (0x0d) */ + xcoff_reloc_type_fail, /* (0x0e) */ + xcoff_reloc_type_noop, /* R_REF (0x0f) */ + xcoff_reloc_type_fail, /* (0x10) */ + xcoff_reloc_type_fail, /* (0x11) */ + xcoff_reloc_type_fail, /* (0x12) */ + xcoff_reloc_type_toc, /* R_TRLA (0x13) */ + xcoff_reloc_type_fail, /* R_RRTBI (0x14) */ + xcoff_reloc_type_fail, /* R_RRTBA (0x15) */ + xcoff_reloc_type_ba, /* R_CAI (0x16) */ + xcoff_reloc_type_crel, /* R_CREL (0x17) */ + xcoff_reloc_type_ba, /* R_RBA (0x18) */ + xcoff_reloc_type_ba, /* R_RBAC (0x19) */ + xcoff64_reloc_type_br, /* R_RBR (0x1a) */ + xcoff_reloc_type_ba, /* R_RBRC (0x1b) */ + xcoff_reloc_type_fail, /* (0x1c) */ + xcoff_reloc_type_fail, /* (0x1d) */ + xcoff_reloc_type_fail, /* (0x1e) */ + xcoff_reloc_type_fail, /* (0x1f) */ + xcoff_reloc_type_fail, /* R_TLS (0x20) */ + xcoff_reloc_type_fail, /* R_TLS_IE (0x21) */ + xcoff_reloc_type_fail, /* R_TLS_LD (0x22) */ + xcoff_reloc_type_fail, /* R_TLS_LE (0x23) */ + xcoff_reloc_type_fail, /* R_TLSM (0x24) */ + xcoff_reloc_type_fail, /* R_TLSML (0x25) */ + xcoff_reloc_type_fail, /* (0x26) */ + xcoff_reloc_type_fail, /* (0x27) */ + xcoff_reloc_type_fail, /* (0x28) */ + xcoff_reloc_type_fail, /* (0x29) */ + xcoff_reloc_type_fail, /* (0x2a) */ + xcoff_reloc_type_fail, /* (0x2b) */ + xcoff_reloc_type_fail, /* (0x2c) */ + xcoff_reloc_type_fail, /* (0x2d) */ + xcoff_reloc_type_fail, /* (0x2e) */ + xcoff_reloc_type_fail, /* (0x2f) */ + xcoff_reloc_type_fail, /* R_TOCU (0x30) */ + xcoff_reloc_type_fail, /* R_TOCL (0x31) */ }; /* coffcode.h needs these to be defined. */ @@ -816,11 +838,8 @@ xcoff64_reloc_type_br (bfd *input_bfd, -/* The XCOFF reloc table. Actually, XCOFF relocations specify the - bitsize and whether they are signed or not, along with a - conventional type. This table is for the types, which are used for - different algorithms for putting in the reloc. Many of these - relocs need special_function entries, which I have not written. */ +/* The XCOFF reloc table. + Cf xcoff_howto_table comments. */ reloc_howto_type xcoff64_howto_table[] = { @@ -854,19 +873,19 @@ reloc_howto_type xcoff64_howto_table[] = MINUS_ONE, /* dst_mask */ FALSE), /* pcrel_offset */ - /* 0x02: 32 bit PC relative relocation. */ + /* 0x02: 64 bit PC relative relocation. */ HOWTO (R_REL, /* type */ 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ 0, /* special_function */ "R_REL", /* name */ TRUE, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ FALSE), /* pcrel_offset */ /* 0x03: 16 bit TOC relative relocation. */ @@ -884,19 +903,19 @@ reloc_howto_type xcoff64_howto_table[] = 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* 0x04: I don't really know what this is. */ - HOWTO (R_RTB, /* type */ - 1, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ + /* 0x04: Same as R_TOC. */ + HOWTO (R_TRL, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ 0, /* special_function */ - "R_RTB", /* name */ + "R_TRL", /* name */ TRUE, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ /* 0x05: External TOC relative symbol. */ @@ -931,7 +950,7 @@ reloc_howto_type xcoff64_howto_table[] = EMPTY_HOWTO (7), - /* 0x08: Non modifiable absolute branch. */ + /* 0x08: Same as R_RBA. */ HOWTO (R_BA, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -948,7 +967,7 @@ reloc_howto_type xcoff64_howto_table[] = EMPTY_HOWTO (9), - /* 0x0a: Non modifiable relative branch. */ + /* 0x0a: Same as R_RBR. */ HOWTO (R_BR, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -965,34 +984,34 @@ reloc_howto_type xcoff64_howto_table[] = EMPTY_HOWTO (0xb), - /* 0x0c: Indirect load. */ + /* 0x0c: Same as R_POS. */ HOWTO (R_RL, /* type */ 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ 0, /* special_function */ "R_RL", /* name */ TRUE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ FALSE), /* pcrel_offset */ - /* 0x0d: Load address. */ + /* 0x0d: Same as R_POS. */ HOWTO (R_RLA, /* type */ 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ 0, /* special_function */ "R_RLA", /* name */ TRUE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ FALSE), /* pcrel_offset */ EMPTY_HOWTO (0xe), @@ -1014,23 +1033,9 @@ reloc_howto_type xcoff64_howto_table[] = EMPTY_HOWTO (0x10), EMPTY_HOWTO (0x11), + EMPTY_HOWTO (0x12), - /* 0x12: TOC relative indirect load. */ - HOWTO (R_TRL, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TRL", /* name */ - TRUE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 0x13: TOC relative load address. */ + /* 0x13: Same as R_TOC */ HOWTO (R_TRLA, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ @@ -1075,7 +1080,7 @@ reloc_howto_type xcoff64_howto_table[] = 0xffffffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* 0x16: Modifiable call absolute indirect. */ + /* 0x16: Modifiable call absolute indirect. */ HOWTO (R_CAI, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ @@ -1090,7 +1095,7 @@ reloc_howto_type xcoff64_howto_table[] = 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* 0x17: Modifiable call relative. */ + /* 0x17: Modifiable call relative. */ HOWTO (R_CREL, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ @@ -1225,12 +1230,48 @@ reloc_howto_type xcoff64_howto_table[] = 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* 0x20: General-dynamic TLS relocation. */ + EMPTY_HOWTO (R_TLS), + + /* 0x21: Initial-exec TLS relocation. */ + EMPTY_HOWTO (R_TLS_IE), + + /* 0x22: Local-dynamic TLS relocation. */ + EMPTY_HOWTO (R_TLS_LD), + + /* 0x23: Local-exec TLS relocation. */ + EMPTY_HOWTO (R_TLS_LE), + + /* 0x24: TLS relocation. */ + EMPTY_HOWTO(R_TLSM), + + /* 0x25: TLS module relocation. */ + EMPTY_HOWTO(R_TLSML), + + EMPTY_HOWTO(0x26), + EMPTY_HOWTO(0x27), + EMPTY_HOWTO(0x28), + EMPTY_HOWTO(0x29), + EMPTY_HOWTO(0x2a), + EMPTY_HOWTO(0x2b), + EMPTY_HOWTO(0x2c), + EMPTY_HOWTO(0x2d), + EMPTY_HOWTO(0x2e), + EMPTY_HOWTO(0x2f), + + /* 0x30: High-order 16 bit TOC relative relocation. */ + EMPTY_HOWTO (R_TOCU), + + /* 0x31: Low-order 16 bit TOC relative relocation. */ + EMPTY_HOWTO (R_TOCL), + }; void xcoff64_rtype2howto (arelent *relent, struct internal_reloc *internal) { - if (internal->r_type > R_RBRC) + if (internal->r_type > R_TOCL) abort (); /* Default howto layout works most of the time */ @@ -1345,21 +1386,34 @@ xcoff64_ppc_relocate_section (bfd *output_bfd, if (rel->r_type == R_REF) continue; - /* howto */ - howto.type = rel->r_type; - howto.rightshift = 0; - howto.bitsize = (rel->r_size & 0x3f) + 1; - howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1; - howto.pc_relative = FALSE; - howto.bitpos = 0; + /* Retrieve default value in HOWTO table and fix up according + to r_size field, if it can be different. + This should be made during relocation reading but the algorithms + are expecting constant howtos. */ + memcpy (&howto, &xcoff64_howto_table[rel->r_type], sizeof (howto)); + if (howto.bitsize != (rel->r_size & 0x3f) + 1) + { + switch (rel->r_type) + { + case R_POS: + case R_NEG: + howto.bitsize = (rel->r_size & 0x3f) + 1; + howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1; + howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize); + break; + + default: + _bfd_error_handler + (_("%pB: relocatation (%d) at (0x%" BFD_VMA_FMT "x) has wrong" + " r_rsize (0x%x)\n"), + input_bfd, rel->r_type, rel->r_vaddr, rel->r_size); + return FALSE; + } + } + howto.complain_on_overflow = (rel->r_size & 0x80 ? complain_overflow_signed : complain_overflow_bitfield); - howto.special_function = NULL; - howto.name = "internal"; - howto.partial_inplace = TRUE; - howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize); - howto.pcrel_offset = FALSE; /* symbol */ val = 0; @@ -1394,7 +1448,7 @@ xcoff64_ppc_relocate_section (bfd *output_bfd, { if (info->unresolved_syms_in_objects != RM_IGNORE && (h->flags & XCOFF_WAS_UNDEFINED) != 0) - info->callbacks->undefined_symbol + info->callbacks->undefined_symbol (info, h->root.root.string, input_bfd, input_section, rel->r_vaddr - input_section->vma, info->unresolved_syms_in_objects == RM_DIAGNOSE diff --git a/bfd/libxcoff.h b/bfd/libxcoff.h index e96f532..229e47c 100644 --- a/bfd/libxcoff.h +++ b/bfd/libxcoff.h @@ -202,7 +202,7 @@ struct xcoff_backend_data_rec #define bfd_xcoff_data_align_power(a) ((xcoff_data (a)->data_align_power)) /* xcoff*_ppc_relocate_section macros */ -#define XCOFF_MAX_CALCULATE_RELOCATION (0x1c) +#define XCOFF_MAX_CALCULATE_RELOCATION (0x32) #define XCOFF_MAX_COMPLAIN_OVERFLOW (4) /* N_ONES produces N one bits, without overflowing machine arithmetic. */ #ifdef N_ONES diff --git a/binutils/ChangeLog b/binutils/ChangeLog index b5a9b56..37460e7 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,7 @@ +2021-03-12 Clément Chigot <clement.chigot@atos.net> + + * od-xcoff.c: Replace RTB by TRL entry. + 2021-03-05 Craig Blackmore <craig.blackmore@embecosm.com> Andrew Burgess <andrew.burgess@embecosm.com> diff --git a/binutils/od-xcoff.c b/binutils/od-xcoff.c index ad3235e..f0d566b 100644 --- a/binutils/od-xcoff.c +++ b/binutils/od-xcoff.c @@ -300,7 +300,7 @@ static const struct xlat_table rtype_xlat[] = RTYPE_ENTRY (NEG), RTYPE_ENTRY (REL), RTYPE_ENTRY (TOC), - RTYPE_ENTRY (RTB), + RTYPE_ENTRY (TRL), RTYPE_ENTRY (GL), RTYPE_ENTRY (TCL), RTYPE_ENTRY (BA), @@ -308,7 +308,6 @@ static const struct xlat_table rtype_xlat[] = RTYPE_ENTRY (RL), RTYPE_ENTRY (RLA), RTYPE_ENTRY (REF), - RTYPE_ENTRY (TRL), RTYPE_ENTRY (TRLA), RTYPE_ENTRY (RRTBI), RTYPE_ENTRY (RRTBA), diff --git a/include/ChangeLog b/include/ChangeLog index 0a6e4b6..c736323 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2021-03-12 Clément Chigot <clement.chigot@atos.net> + + * coff/xcoff.h (R_RTB): Remove. + (R_TRL): Fix value. + 2021-03-05 Craig Blackmore <craig.blackmore@embecosm.com> Andrew Burgess <andrew.burgess@embecosm.com> diff --git a/include/coff/xcoff.h b/include/coff/xcoff.h index 50ac0df..36651d4 100644 --- a/include/coff/xcoff.h +++ b/include/coff/xcoff.h @@ -97,36 +97,35 @@ The relocations are described in the function xcoff[64]_ppc_relocate_section in coff64-rs6000.c and coff-rs6000.c */ -#define R_POS (0x00) -#define R_NEG (0x01) -#define R_REL (0x02) -#define R_TOC (0x03) -#define R_RTB (0x04) -#define R_GL (0x05) -#define R_TCL (0x06) -#define R_BA (0x08) -#define R_BR (0x0a) -#define R_RL (0x0c) -#define R_RLA (0x0d) -#define R_REF (0x0f) -#define R_TRL (0x12) -#define R_TRLA (0x13) -#define R_RRTBI (0x14) -#define R_RRTBA (0x15) -#define R_CAI (0x16) -#define R_CREL (0x17) -#define R_RBA (0x18) -#define R_RBAC (0x19) -#define R_RBR (0x1a) -#define R_RBRC (0x1b) -#define R_TLS (0x20) +#define R_POS (0x00) +#define R_NEG (0x01) +#define R_REL (0x02) +#define R_TOC (0x03) +#define R_TRL (0x04) +#define R_GL (0x05) +#define R_TCL (0x06) +#define R_BA (0x08) +#define R_BR (0x0a) +#define R_RL (0x0c) +#define R_RLA (0x0d) +#define R_REF (0x0f) +#define R_TRLA (0x13) +#define R_RRTBI (0x14) +#define R_RRTBA (0x15) +#define R_CAI (0x16) +#define R_CREL (0x17) +#define R_RBA (0x18) +#define R_RBAC (0x19) +#define R_RBR (0x1a) +#define R_RBRC (0x1b) +#define R_TLS (0x20) #define R_TLS_IE (0x21) #define R_TLS_LD (0x22) #define R_TLS_LE (0x23) -#define R_TLSM (0x24) -#define R_TLSML (0x25) -#define R_TOCU (0x30) -#define R_TOCL (0x31) +#define R_TLSM (0x24) +#define R_TLSML (0x25) +#define R_TOCU (0x30) +#define R_TOCL (0x31) /* Storage class #defines, from /usr/include/storclass.h that are not already defined in internal.h */ |