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]

Pack reloc_howto_struct


This patch uses bitfields in reloc_howto_struct, reducing its size
from 80 to 40 bytes on 64-bit hosts and from 52 to 32 bytes on 32-bit
hosts (with a 32-bit bfd_vma).  I've also added a new "negate" field
rather than making the encoded "size" field do double duty as both
a size and a flag.

There was just one use of an encoded size of 8, which according to
bfd_get_reloc_size meant 16 bytes, in vms-alpha.c ALPHA_R_LINKAGE.
See git commit c3d8e071bf adding ALPHA_R_LINKAGE and git commit
8612a388f7 decoding size 8 in bfd_get_reloc_size.  Since no other part
of BFD handles 16 byte relocs, I've removed that encoding and special
cased the ALPHA_R_LINKAGE size in vms-alpha.c.

Tristan, you might like to check whether 16 bytes is correct.  The old
bitsize of 256 (which is unused) seems to disagree.

	* reloc.c (reloc_howto_type): Typedef.
	(bfd_symbol): Delete forward declaration.
	(struct reloc_howto_struct): Add "negate" field.  Make "size",
	"bitsize", "rightshift", "bitpos", "complain_on_overflow",
	"pc_relative", "partial_inplace", and "pcrel_offset" bitfields.
	Rearrange for better packing.  Revise comments.
	(HOWTO): Map to rearranged reloc_howto_struct.
	(bfd_get_reloc_size): Delete now unused cases.
	(read_reloc, write_reloc): Likewise.
	(apply_reloc, _bfd_relocate_contents): Test howto->negate
	rather than howto->size < 0 for negated relocation values.
	* coff-rs6000.c (xcoff_complain_overflow_bitfield_func): Avoid
	signed/unsigned warning.
	(xcoff_ppc_relocate_section): Delete "condition is always false"
	code.
	* coff64-rs6000.c (xcoff64_ppc_relocate_section): Likewise.
	* cpu-ns32k.c (do_ns32k_reloc): Adjust to suit reloc_howto_struct
	changes.
	* vms-alpha.c (_bfd_vms_write_etir, alpha_vms_slurp_relocs): Use
	size 16 for ALPHA_R_LINKAGE.
	(alpha_howto_table <ALPHA_R_LINKAGE>): Set encoded size and
	bitsize to zero.
	* bfd-in.h (reloc_howto_type): Delete.
	* bfd-in2.h: Regenerate.

diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index f00625d832..47b60bcfbf 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -234,9 +234,6 @@ bfd_format;
 /* A count of carsyms (canonical archive symbols).  */
 typedef unsigned long symindex;
 
-/* How to perform a relocation.  */
-typedef const struct reloc_howto_struct reloc_howto_type;
-
 #define BFD_NO_MORE_SYMBOLS ((symindex) ~0)
 
 /* General purpose part of a symbol X;
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index ab282dfef0..edff50daaa 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -3090,7 +3090,7 @@ xcoff_complain_overflow_bitfield_func (bfd *input_bfd,
      relies on it, and it is the only way to write assembler
      code which can run when loaded at a location 0x80000000
      away from the location at which it is linked.  */
-  if (howto->bitsize + howto->rightshift
+  if ((unsigned) howto->bitsize + howto->rightshift
       == bfd_arch_bits_per_address (input_bfd))
     return FALSE;
 
@@ -3458,10 +3458,6 @@ xcoff_ppc_relocate_section (bfd *output_bfd,
 	 operation, which would be tedious, or we must do the computations
 	 in a type larger than bfd_vma, which would be inefficient.  */
 
-      if ((unsigned int) howto.complain_on_overflow
-	  >= XCOFF_MAX_COMPLAIN_OVERFLOW)
-	abort ();
-
       if (((*xcoff_complain_overflow[howto.complain_on_overflow])
 	   (input_bfd, value_to_relocate, relocation, &howto)))
 	{
diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c
index 2135001f19..928a23d4f8 100644
--- a/bfd/coff64-rs6000.c
+++ b/bfd/coff64-rs6000.c
@@ -1306,10 +1306,6 @@ xcoff64_ppc_relocate_section (bfd *output_bfd,
 	 operation, which would be tedious, or we must do the computations
 	 in a type larger than bfd_vma, which would be inefficient.  */
 
-      if ((unsigned int) howto.complain_on_overflow
-	  >= XCOFF_MAX_COMPLAIN_OVERFLOW)
-	abort ();
-
       if (((*xcoff_complain_overflow[howto.complain_on_overflow])
 	   (input_bfd, value_to_relocate, relocation, &howto)))
 	{
diff --git a/bfd/cpu-ns32k.c b/bfd/cpu-ns32k.c
index 2eef0ba7bb..436cba4c41 100644
--- a/bfd/cpu-ns32k.c
+++ b/bfd/cpu-ns32k.c
@@ -501,6 +501,9 @@ do_ns32k_reloc (bfd *      abfd,
      -----------------------
      R R R R R R R R R R	put into bfd_put<size>.  */
 
+  if (howto->negate)
+    relocation = -relocation;
+
 #define DOIT(x) \
   x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) +  relocation) & howto->dst_mask))
 
@@ -531,14 +534,6 @@ do_ns32k_reloc (bfd *      abfd,
 	  put_data ((bfd_vma) x, location, 4);
 	}
       break;
-    case -2:
-      {
-	bfd_vma x = get_data (location, 4);
-	relocation = -relocation;
-	DOIT(x);
-	put_data ((bfd_vma) x, location, 4);
-      }
-      break;
 
     case 3:
       /* Do nothing.  */
diff --git a/bfd/reloc.c b/bfd/reloc.c
index ec58a7e4af..0dcf2be9a0 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -94,6 +94,7 @@ CODE_FRAGMENT
 . }
 . bfd_reloc_status_type;
 .
+.typedef const struct reloc_howto_struct reloc_howto_type;
 .
 .typedef struct reloc_cache_entry
 .{
@@ -279,51 +280,39 @@ SUBSUBSECTION
 	information that libbfd needs to know to tie up a back end's data.
 
 CODE_FRAGMENT
-.struct bfd_symbol;		{* Forward declaration.  *}
-.
 .struct reloc_howto_struct
 .{
-.  {*  The type field has mainly a documentary use - the back end can
-.      do what it wants with it, though normally the back end's
-.      external idea of what a reloc number is stored
-.      in this field.  For example, a PC relative word relocation
-.      in a coff environment has the type 023 - because that's
-.      what the outside world calls a R_PCRWORD reloc.  *}
+.  {* The type field has mainly a documentary use - the back end can
+.     do what it wants with it, though normally the back end's idea of
+.     an external reloc number is stored in this field.  *}
 .  unsigned int type;
 .
-.  {*  The value the final relocation is shifted right by.  This drops
-.      unwanted data from the relocation.  *}
-.  unsigned int rightshift;
-.
-.  {*  The size of the item to be relocated.  This is *not* a
-.      power-of-two measure.  To get the number of bytes operated
-.      on by a type of relocation, use bfd_get_reloc_size.  *}
-.  int size;
+.  {* The encoded size of the item to be relocated.  This is *not* a
+.     power-of-two measure.  Use bfd_get_reloc_size to find the size
+.     of the item in bytes.  *}
+.  unsigned int size:3;
 .
-.  {*  The number of bits in the item to be relocated.  This is used
-.      when doing overflow checking.  *}
-.  unsigned int bitsize;
+.  {* The number of bits in the field to be relocated.  This is used
+.     when doing overflow checking.  *}
+.  unsigned int bitsize:7;
 .
-.  {*  The relocation is relative to the field being relocated.  *}
-.  bfd_boolean pc_relative;
+.  {* The value the final relocation is shifted right by.  This drops
+.     unwanted data from the relocation.  *}
+.  unsigned int rightshift:6;
 .
-.  {*  The bit position of the reloc value in the destination.
-.      The relocated value is left shifted by this amount.  *}
-.  unsigned int bitpos;
+.  {* The bit position of the reloc value in the destination.
+.     The relocated value is left shifted by this amount.  *}
+.  unsigned int bitpos:6;
 .
 .  {* What type of overflow error should be checked for when
 .     relocating.  *}
-.  enum complain_overflow complain_on_overflow;
+.  ENUM_BITFIELD (complain_overflow) complain_on_overflow:2;
 .
-.  {* If this field is non null, then the supplied function is
-.     called rather than the normal function.  This allows really
-.     strange relocation methods to be accommodated.  *}
-.  bfd_reloc_status_type (*special_function)
-.    (bfd *, arelent *, struct bfd_symbol *, void *, asection *,
-.     bfd *, char **);
+.  {* The relocation value should be negated before applying.  *}
+.  unsigned int negate:1;
 .
-.  {* The textual name of the relocation type.  *}
-.  char *name;
+.  {* The relocation is relative to the item being relocated.  *}
+.  unsigned int pc_relative:1;
 .
 .  {* Some formats record a relocation addend in the section contents
 .     rather than with the relocation.  For ELF formats this is the
@@ -340,29 +329,39 @@ CODE_FRAGMENT
 .     USE_REL targets set this field to TRUE.  Why this is so is peculiar
 .     to each particular target.  For relocs that aren't used in partial
 .     links (e.g. GOT stuff) it doesn't matter what this is set to.  *}
-.  bfd_boolean partial_inplace;
+.  unsigned int partial_inplace:1;
+.
+.  {* When some formats create PC relative instructions, they leave
+.     the value of the pc of the place being relocated in the offset
+.     slot of the instruction, so that a PC relative relocation can
+.     be made just by adding in an ordinary offset (e.g., sun3 a.out).
+.     Some formats leave the displacement part of an instruction
+.     empty (e.g., ELF); this flag signals the fact.  *}
+.  unsigned int pcrel_offset:1;
 .
 .  {* src_mask selects the part of the instruction (or data) to be used
 .     in the relocation sum.  If the target relocations don't have an
 .     addend in the reloc, eg. ELF USE_REL, src_mask will normally equal
 .     dst_mask to extract the addend from the section contents.  If
 .     relocations do have an addend in the reloc, eg. ELF USE_RELA, this
-.     field should be zero.  Non-zero values for ELF USE_RELA targets are
-.     bogus as in those cases the value in the dst_mask part of the
-.     section contents should be treated as garbage.  *}
+.     field should normally be zero.  Non-zero values for ELF USE_RELA
+.     targets should be viewed with suspicion as normally the value in
+.     the dst_mask part of the section contents should be ignored.  *}
 .  bfd_vma src_mask;
 .
 .  {* dst_mask selects which parts of the instruction (or data) are
 .     replaced with a relocated value.  *}
 .  bfd_vma dst_mask;
 .
-.  {* When some formats create PC relative instructions, they leave
-.     the value of the pc of the place being relocated in the offset
-.     slot of the instruction, so that a PC relative relocation can
-.     be made just by adding in an ordinary offset (e.g., sun3 a.out).
-.     Some formats leave the displacement part of an instruction
-.     empty (e.g., ELF); this flag signals the fact.  *}
-.  bfd_boolean pcrel_offset;
+.  {* If this field is non null, then the supplied function is
+.     called rather than the normal function.  This allows really
+.     strange relocation methods to be accommodated.  *}
+.  bfd_reloc_status_type (*special_function)
+.    (bfd *, arelent *, struct bfd_symbol *, void *, asection *,
+.     bfd *, char **);
+.
+.  {* The textual name of the relocation type.  *}
+.  char *name;
 .};
 .
 */
@@ -375,8 +374,10 @@ DESCRIPTION
 	The HOWTO macro fills in a reloc_howto_type (a typedef for
 	const struct reloc_howto_struct).
 
-.#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
-.  { (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC }
+.#define HOWTO(type, right, size, bits, pcrel, left, ovf, func, name,	\
+.              inplace, src_mask, dst_mask, pcrel_off)			\
+.  { (unsigned) type, size < 0 ? -size : size, bits, right, left, ovf,	\
+.    size < 0, pcrel, inplace, pcrel_off, src_mask, dst_mask, func, name }
 
 DESCRIPTION
 	This is used to fill in an empty howto entry in an array.
@@ -405,14 +406,11 @@ bfd_get_reloc_size (reloc_howto_type *howto)
   switch (howto->size)
     {
     case 0: return 1;
-    case 1:
-    case -1: return 2;
-    case 2:
-    case -2: return 4;
+    case 1: return 2;
+    case 2: return 4;
     case 3: return 0;
     case 4: return 8;
     case 5: return 3;
-    case 8: return 16;
     default: abort ();
     }
 }
@@ -559,11 +557,9 @@ read_reloc (bfd *abfd, bfd_byte *data, reloc_howto_type *howto)
       return bfd_get_8 (abfd, data);
 
     case 1:
-    case -1:
       return bfd_get_16 (abfd, data);
 
     case 2:
-    case -2:
       return bfd_get_32 (abfd, data);
 
     case 3:
@@ -596,12 +592,10 @@ write_reloc (bfd *abfd, bfd_vma val, bfd_byte *data, reloc_howto_type *howto)
       break;
 
     case 1:
-    case -1:
       bfd_put_16 (abfd, val, data);
       break;
 
     case 2:
-    case -2:
       bfd_put_32 (abfd, val, data);
       break;
 
@@ -632,7 +626,7 @@ apply_reloc (bfd *abfd, bfd_byte *data, reloc_howto_type *howto,
 {
   bfd_vma val = read_reloc (abfd, data, howto);
 
-  if (howto->size < 0)
+  if (howto->negate)
     relocation = -relocation;
 
   val = ((val & ~howto->dst_mask)
@@ -1391,9 +1385,7 @@ _bfd_relocate_contents (reloc_howto_type *howto,
   unsigned int rightshift = howto->rightshift;
   unsigned int bitpos = howto->bitpos;
 
-  /* If the size is negative, negate RELOCATION.  This isn't very
-     general.  */
-  if (howto->size < 0)
+  if (howto->negate)
     relocation = -relocation;
 
   /* Get the value we are going to relocate.  */
diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c
index fc45260e49..8f22a31ae5 100644
--- a/bfd/vms-alpha.c
+++ b/bfd/vms-alpha.c
@@ -4001,6 +4001,7 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 		  break;
 
 		case ALPHA_R_LINKAGE:
+		  size = 16;
 		  etir_output_check (abfd, section, curr_addr, 64);
 		  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LP_PSB);
 		  _bfd_vms_output_long
@@ -5157,6 +5158,7 @@ alpha_vms_slurp_relocs (bfd *abfd)
 	    asection *sec;
 	    struct vms_section_data_struct *vms_sec;
 	    arelent *reloc;
+	    bfd_size_type size;
 
 	    /* Get section to which the relocation applies.  */
 	    if (cur_psect < 0 || cur_psect > (int)PRIV (section_count))
@@ -5237,7 +5239,11 @@ alpha_vms_slurp_relocs (bfd *abfd)
 	    reloc->address = cur_address;
 	    reloc->addend = cur_addend;
 
-	    vaddr += bfd_get_reloc_size (reloc->howto);
+	    if (reloc_code == ALPHA_R_LINKAGE)
+	      size = 16;
+	    else
+	      size = bfd_get_reloc_size (reloc->howto);
+	    vaddr += size;
 	  }
 
 	  cur_addend = 0;
@@ -5496,8 +5502,8 @@ static reloc_howto_type alpha_howto_table[] =
   /* Hack. Linkage is done by linker.  */
   HOWTO (ALPHA_R_LINKAGE,	/* Type.  */
 	 0,			/* Rightshift.  */
-	 8,			/* Size (0 = byte, 1 = short, 2 = long).  */
-	 256,			/* Bitsize.  */
+	 0,			/* Size (0 = byte, 1 = short, 2 = long).  */
+	 0,			/* Bitsize.  */
 	 FALSE,			/* PC relative.  */
 	 0,			/* Bitpos.  */
 	 complain_overflow_dont,/* Complain_on_overflow.  */

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]