aix: correct HOWTO table and add missing relocations
authorClément Chigot <clement.chigot@atos.net>
Thu, 11 Mar 2021 10:08:18 +0000 (11:08 +0100)
committerAlan Modra <amodra@gmail.com>
Fri, 12 Mar 2021 11:38:20 +0000 (22:08 +1030)
Since the last time AIX HOWTO table was modified, IBM has now
released an official documentation about XCOFF relocations.
This commit corrects the wrong ones and add some missing.
For now, the "custom" relocations made for xcoff_rtype2howto have
been kept.
The new relocations are still set as EMPTY_HOWTO because they will
be implemented in later commits.

In xcoff[64]_ppc_relocate_section, instead of recreating howto
from scratch, it's better to use the existing howto from the
table and fixing it according to r_size field.

bfd/
* 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.
binutils/
* od-xcoff.c: Replace RTB by TRL entry.
include/
* coff/xcoff.h (R_RTB): Remove.
(R_TRL): Fix value.

bfd/ChangeLog
bfd/coff-rs6000.c
bfd/coff64-rs6000.c
bfd/libxcoff.h
binutils/ChangeLog
binutils/od-xcoff.c
include/ChangeLog
include/coff/xcoff.h

index 9c301d0f19f4ac2bf1733eceb1b81177fa5ba20c..6c359ac1a8825a8383863d8d7f6145d1eff3ae5c 100644 (file)
@@ -1,3 +1,18 @@
+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.
index 54fbf58e3ae993bc56df1d34e424832f407f86c9..2cae299539d1642ca5f7ab67bc9baa101562405a 100644 (file)
@@ -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);
 }
 \f
-/* 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;
index 3f74130da0ddd03a1323fc3936c078d372a5f93c..0cb7e8b12780eb85891094818c147f31b5f6fc72 100644 (file)
@@ -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,
 
 
 \f
-/* 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
index e96f53260ef7147252444cd5f11e777f56af7465..229e47c2ae14b219da32d2baf70fa39a0a803d48 100644 (file)
@@ -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
index b5a9b56954cd59da49e9e6495c44c47182b6483e..37460e7bcde0948c23c8df52d4ff46aafe6153be 100644 (file)
@@ -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>
 
index ad3235e64365b59d80f47fa0d83c08bcf95e6fa6..f0d566b190213c393af2494b5547d5373661d643 100644 (file)
@@ -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),
index 0a6e4b6f535277cd4cca0298814962a876130f60..c736323b63918912384b1d994b2558b2a35b537e 100644 (file)
@@ -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>
 
index 50ac0df20d6b5f9fd24cd2defbd52d26b8155d07..36651d4375dab3ca440721e28a29a4c72609dd31 100644 (file)
    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 */