Pass section when available to bfd_octets_per_byte

Message ID 20191125045421.GM31415@bubble.grove.modra.org
State New
Headers show
Series
  • Pass section when available to bfd_octets_per_byte
Related show

Commit Message

Alan Modra Nov. 25, 2019, 4:54 a.m.
and other tidies.  I think it's better to default to passing the
section to bfd_octets_per_byte, even in cases where we know it won't
make a difference.

A number of the coff reloc functions used bfd_octets_per_byte wrongly,
not factoring it into the offset into the data buffer.  As it happens,
the targets using those files always had bfd_octets_per_byte equal to
one, so there wasn't any detectable wrong behaviour.  However, it is
wrong in the source and might cause trouble for anyone creating a new
target.  Besides fixing that, the patch also defines OCTETS_PER_BYTE
as one in target files where that is appropriate.

bfd/
	* archures.c (bfd_octets_per_byte): Tail call
	bfd_arch_mach_octets_per_byte.
	* coff-arm.c (OCTETS_PER_BYTE): Define.
	(coff_arm_reloc): Introduce new "octets" temp.  Use OCTETS_PER_BYTE
	with section.  Correct "addr".  Remove ATTRIBUTE_UNUSED.
	* coff-i386.c (coff_i386_reloc): Similarly.
	* coff-mips.c (mips_reflo_reloc): Similarly.
	* coff-x86_64.c (coff_amd64_reloc): Similarly.
	* elf32-msp430.c (OCTETS_PER_BYTE): Define.
	(rl78_sym_diff_handler): Use OCTETS_PER_BYTE, with section.
	* elf32-nds32.c (nds32_elf_get_relocated_section_contents): Similarly.
	* elf32-ppc.c (ppc_elf_addr16_ha_reloc): Similarly.
	* elf32-pru.c (pru_elf32_do_ldi32_relocate): Similarly.
	* elf32-s12z.c (opru18_reloc): Similarly.
	* elf32-sh.c (sh_elf_reloc): Similarly.
	* elf32-spu.c (spu_elf_rel9): Similarly.
	* elf32-xtensa.c (bfd_elf_xtensa_reloc): Similarly.
	* elf64-ppc.c (ppc64_elf_ha_reloc, ppc64_elf_brtaken_reloc),
	(ppc64_elf_toc64_reloc): Similarly.
	* bfd.c (bfd_get_section_limit): Pass section to bfd_octets_per_byte.
	* cofflink.c (_bfd_coff_link_input_bfd),
	(_bfd_coff_reloc_link_order): Likewise.
	* elf.c (_bfd_elf_section_offset): Likewise.
	* elflink.c (resolve_section, bfd_elf_perform_complex_relocation),
	(elf_link_input_bfd, elf_reloc_link_order, elf_fixup_link_order),
	(bfd_elf_final_link): Likewise.
	* elf.c (_bfd_elf_make_section_from_shdr): Don't strncmp twice
	to set SEC_ELF_OCTETS.
	* reloc.c (bfd_perform_relocation): Tidy SEC_ELF_OCTETS special case.
	(bfd_install_relocation): Likewise.
	(_bfd_final_link_relocate): Don't recalculate octets.
	* syms.c (_bfd_stab_section_find_nearest_line): Introduc new
	"octets" temp.
	* bfd-in2.h: Regenerate.
ld/
	* ldexp.c (fold_name): Pass section to bfd_octets_per_byte.
	* ldlang.c (init_opb): Don't call bfd_arch_mach_octets_per_byte
	unnecessarily.


-- 
Alan Modra
Australia Development Lab, IBM

Patch

diff --git a/bfd/archures.c b/bfd/archures.c
index 1e6611069c..7866c6095b 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -1391,15 +1391,13 @@  DESCRIPTION
 unsigned int
 bfd_octets_per_byte (const bfd *abfd, const asection *sec)
 {
-  unsigned int opb = bfd_arch_mach_octets_per_byte (bfd_get_arch (abfd),
-						    bfd_get_mach (abfd));
-
   if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
       && sec != NULL
       && (sec->flags & SEC_ELF_OCTETS) != 0)
-    opb = 1;
+    return 1;
 
-  return opb;
+  return bfd_arch_mach_octets_per_byte (bfd_get_arch (abfd),
+					bfd_get_mach (abfd));
 }
 
 /*
diff --git a/bfd/bfd.c b/bfd/bfd.c
index c1f3fcadd6..a3c522cbf8 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -493,7 +493,7 @@  CODE_FRAGMENT
 .bfd_get_section_limit (const bfd *abfd, const asection *sec)
 .{
 .  return (bfd_get_section_limit_octets (abfd, sec)
-.	   / bfd_octets_per_byte (abfd, NULL));
+.	   / bfd_octets_per_byte (abfd, sec));
 .}
 .
 .{* Functions to handle insertion and deletion of a bfd's sections.  These
diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c
index e297df27e8..242c90bf87 100644
--- a/bfd/coff-arm.c
+++ b/bfd/coff-arm.c
@@ -33,6 +33,9 @@ 
 
 #include "libcoff.h"
 
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
 /* Macros for manipulation the bits in the flags field of the coff data
    structure.  */
 #define APCS_26_FLAG(abfd) \
@@ -96,7 +99,7 @@  coff_arm_reloc (bfd *abfd,
 		arelent *reloc_entry,
 		asymbol *symbol ATTRIBUTE_UNUSED,
 		void * data,
-		asection *input_section ATTRIBUTE_UNUSED,
+		asection *input_section,
 		bfd *output_bfd,
 		char **error_message ATTRIBUTE_UNUSED)
 {
@@ -114,11 +117,11 @@  coff_arm_reloc (bfd *abfd,
   if (diff != 0)
     {
       reloc_howto_type *howto = reloc_entry->howto;
-      unsigned char *addr = (unsigned char *) data + reloc_entry->address;
+      bfd_size_type octets = (reloc_entry->address
+			      * OCTETS_PER_BYTE (abfd, input_section));
+      unsigned char *addr = (unsigned char *) data + octets;
 
-      if (! bfd_reloc_offset_in_range (howto, abfd, input_section,
-				       reloc_entry->address
-				       * bfd_octets_per_byte (abfd, NULL)))
+      if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets))
 	return bfd_reloc_outofrange;
 
       switch (howto->size)
diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c
index f28eb8af0c..99f6079863 100644
--- a/bfd/coff-i386.c
+++ b/bfd/coff-i386.c
@@ -41,6 +41,9 @@ 
 
 #include "libcoff.h"
 
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
 static reloc_howto_type *coff_i386_rtype_to_howto
   (bfd *, asection *, struct internal_reloc *,
    struct coff_link_hash_entry *, struct internal_syment *,
@@ -67,7 +70,7 @@  coff_i386_reloc (bfd *abfd,
 		 arelent *reloc_entry,
 		 asymbol *symbol,
 		 void * data,
-		 asection *input_section ATTRIBUTE_UNUSED,
+		 asection *input_section,
 		 bfd *output_bfd,
 		 char **error_message ATTRIBUTE_UNUSED)
 {
@@ -142,11 +145,11 @@  coff_i386_reloc (bfd *abfd,
   if (diff != 0)
     {
       reloc_howto_type *howto = reloc_entry->howto;
-      unsigned char *addr = (unsigned char *) data + reloc_entry->address;
+      bfd_size_type octets = (reloc_entry->address
+			      * OCTETS_PER_BYTE (abfd, input_section));
+      unsigned char *addr = (unsigned char *) data + octets;
 
-      if (! bfd_reloc_offset_in_range (howto, abfd, input_section,
-				       reloc_entry->address
-				       * bfd_octets_per_byte (abfd, NULL)))
+      if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets))
 	return bfd_reloc_outofrange;
 
       switch (howto->size)
diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c
index c9c7fc66ba..76de32009a 100644
--- a/bfd/coff-mips.c
+++ b/bfd/coff-mips.c
@@ -31,6 +31,9 @@ 
 #include "coff/mips.h"
 #include "libcoff.h"
 #include "libecoff.h"
+
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
 
 /* Prototypes for static functions.  */
 static bfd_reloc_status_type
@@ -484,13 +487,13 @@  mips_refhi_reloc (bfd *abfd ATTRIBUTE_UNUSED,
    relocation described above.  */
 
 static bfd_reloc_status_type
-mips_reflo_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+mips_reflo_reloc (bfd *abfd,
 		  arelent *reloc_entry,
 		  asymbol *symbol,
 		  void * data,
 		  asection *input_section,
 		  bfd *output_bfd,
-		  char **error_message ATTRIBUTE_UNUSED)
+		  char **error_message)
 {
   if (mips_refhi_list != NULL)
     {
@@ -503,11 +506,12 @@  mips_reflo_reloc (bfd *abfd ATTRIBUTE_UNUSED,
 	  unsigned long val;
 	  unsigned long vallo;
 	  struct mips_hi *next;
+	  bfd_size_type octets = (reloc_entry->address
+				  * OCTETS_PER_BYTE (abfd, input_section));
+	  bfd_byte *loc = (bfd_byte *) data + octets;
 
-	  if (! bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
-					   input_section,
-					   reloc_entry->address
-					   * bfd_octets_per_byte (abfd, NULL)))
+	  if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
+					  input_section, octets))
 	    return bfd_reloc_outofrange;
 
 	  /* Do the REFHI relocation.  Note that we actually don't
@@ -515,8 +519,7 @@  mips_reflo_reloc (bfd *abfd ATTRIBUTE_UNUSED,
 	     where to find the low 16 bits of the addend needed by the
 	     REFHI.  */
 	  insn = bfd_get_32 (abfd, l->addr);
-	  vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
-		   & 0xffff);
+	  vallo = bfd_get_32 (abfd, loc) & 0xffff;
 	  val = ((insn & 0xffff) << 16) + vallo;
 	  val += l->addend;
 
@@ -544,7 +547,7 @@  mips_reflo_reloc (bfd *abfd ATTRIBUTE_UNUSED,
 
   /* Now do the REFLO reloc in the usual way.  */
   return mips_generic_reloc (abfd, reloc_entry, symbol, data,
-			      input_section, output_bfd, error_message);
+			     input_section, output_bfd, error_message);
 }
 
 /* Do a GPREL relocation.  This is a 16 bit value which must become
diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
index 94fd7ac3e4..4edbd23609 100644
--- a/bfd/coff-x86_64.c
+++ b/bfd/coff-x86_64.c
@@ -52,6 +52,9 @@ 
 
 #define COFF_PAGE_SIZE 0x1000
 
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
 /* For some reason when using AMD COFF the value stored in the .text
    section for a reference to a common symbol is the value itself plus
    any desired offset.  Ian Taylor, Cygnus Support.  */
@@ -141,11 +144,11 @@  coff_amd64_reloc (bfd *abfd,
   if (diff != 0)
     {
       reloc_howto_type *howto = reloc_entry->howto;
-      unsigned char *addr = (unsigned char *) data + reloc_entry->address;
+      bfd_size_type octets = (reloc_entry->address
+			      * OCTETS_PER_BYTE (abfd, input_section));
+      unsigned char *addr = (unsigned char *) data + octets;
 
-      if (! bfd_reloc_offset_in_range (howto, abfd, input_section,
-				       reloc_entry->address
-				       * bfd_octets_per_byte (abfd, NULL)))
+      if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets))
 	return bfd_reloc_outofrange;
 
       switch (howto->size)
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
index 23a8e6b226..0ca8649dff 100644
--- a/bfd/cofflink.c
+++ b/bfd/cofflink.c
@@ -2542,7 +2542,7 @@  _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
       if (secdata == NULL || secdata->stab_info == NULL)
 	{
 	  file_ptr loc = (o->output_offset
-			  * bfd_octets_per_byte (output_bfd, NULL));
+			  * bfd_octets_per_byte (output_bfd, o));
 	  if (! bfd_set_section_contents (output_bfd, o->output_section,
 					  contents, loc, o->size))
 	    return FALSE;
@@ -2834,7 +2834,7 @@  _bfd_coff_reloc_link_order (bfd *output_bfd,
 	return FALSE;
 
       rstat = _bfd_relocate_contents (howto, output_bfd,
-				      (bfd_vma) link_order->u.reloc.p->addend,\
+				      (bfd_vma) link_order->u.reloc.p->addend,
 				      buf);
       switch (rstat)
 	{
@@ -2853,7 +2853,8 @@  _bfd_coff_reloc_link_order (bfd *output_bfd,
 	     (bfd *) NULL, (asection *) NULL, (bfd_vma) 0);
 	  break;
 	}
-      loc = link_order->offset * bfd_octets_per_byte (output_bfd, NULL);
+      loc = link_order->offset * bfd_octets_per_byte (output_bfd,
+						      output_section);
       ok = bfd_set_section_contents (output_bfd, output_section, buf,
 				     loc, size);
       free (buf);
diff --git a/bfd/elf.c b/bfd/elf.c
index 43ef632fa7..a4f26dac71 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1102,33 +1102,17 @@  _bfd_elf_make_section_from_shdr (bfd *abfd,
 	 not any sort of flag.  Their SEC_ALLOC bits are cleared.  */
       if (name [0] == '.')
 	{
-	  const char *p;
-	  int n;
-	  if (name[1] == 'd')
-	    p = ".debug", n = 6;
-	  else if (name[1] == 'g' && name[2] == 'n')
-	    p = ".gnu.linkonce.wi.", n = 17;
-	  else if (name[1] == 'g' && name[2] == 'd')
-	    p = ".gdb_index", n = 11; /* yes we really do mean 11.  */
-	  else if (name[1] == 'l')
-	    p = ".line", n = 5;
-	  else if (name[1] == 's')
-	    p = ".stab", n = 5;
-	  else if (name[1] == 'z')
-	    p = ".zdebug", n = 7;
-	  else
-	    p = NULL, n = 0;
-	  if (p != NULL && strncmp (name, p, n) == 0)
+	  if (strncmp (name, ".debug", 6) == 0
+	      || strncmp (name, ".gnu.linkonce.wi.", 17) == 0
+	      || strncmp (name, ".zdebug", 7) == 0)
+	    flags |= SEC_DEBUGGING | SEC_ELF_OCTETS;
+	  else if (strncmp (name, GNU_BUILD_ATTRS_SECTION_NAME, 21) == 0
+		   || strncmp (name, ".note.gnu", 9) == 0)
+	    flags |= SEC_ELF_OCTETS;
+	  else if (strncmp (name, ".line", 5) == 0
+		   || strncmp (name, ".stab", 5) == 0
+		   || strcmp (name, ".gdb_index") == 0)
 	    flags |= SEC_DEBUGGING;
-
-	  /* DWARF debug sections and ELF notes are organized in octets. */
-	  if (strncmp (name, ".debug", 6) == 0 ||
-	      strncmp (name, ".zdebug", 7) == 0 ||
-	      strncmp (name, GNU_BUILD_ATTRS_SECTION_NAME, 21) == 0 ||
-	      strncmp (name, ".note.gnu", 9) == 0)
-	    {
-	      flags |= SEC_ELF_OCTETS;
-	    }
 	}
     }
 
@@ -12064,7 +12048,7 @@  _bfd_elf_section_offset (bfd *abfd,
 	  /* address_size and sec->size are in octets.  Convert
 	     to bytes before subtracting the original offset.  */
 	  offset = ((sec->size - address_size)
-		    / bfd_octets_per_byte (abfd, NULL) - offset);
+		    / bfd_octets_per_byte (abfd, sec) - offset);
 	}
       return offset;
     }
diff --git a/bfd/elf32-msp430.c b/bfd/elf32-msp430.c
index 7f675fcc34..eeed0c6fc0 100644
--- a/bfd/elf32-msp430.c
+++ b/bfd/elf32-msp430.c
@@ -26,6 +26,9 @@ 
 #include "elf-bfd.h"
 #include "elf/msp430.h"
 
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
 static bfd_reloc_status_type
 rl78_sym_diff_handler (bfd * abfd,
 		       arelent * reloc,
@@ -36,7 +39,7 @@  rl78_sym_diff_handler (bfd * abfd,
 		       char ** error_message ATTRIBUTE_UNUSED)
 {
   bfd_size_type octets;
-  octets = reloc->address * bfd_octets_per_byte (abfd, NULL);
+  octets = reloc->address * OCTETS_PER_BYTE (abfd, input_sec);
 
   /* Catch the case where bfd_install_relocation would return
      bfd_reloc_outofrange because the SYM_DIFF reloc is being used in a very
diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c
index a47d98e270..cb8f7755dc 100644
--- a/bfd/elf32-nds32.c
+++ b/bfd/elf32-nds32.c
@@ -32,6 +32,9 @@ 
 #include "opcode/cgen.h"
 #include "../opcodes/nds32-opc.h"
 
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
 /* Relocation HOWTO functions.  */
 static bfd_reloc_status_type nds32_elf_ignore_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
@@ -13220,7 +13223,8 @@  nds32_elf_get_relocated_section_contents (bfd *abfd,
 		= HOWTO (0, 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL,
 			 "unused", FALSE, 0, 0, FALSE);
 
-	      off = (*parent)->address * bfd_octets_per_byte (input_bfd, NULL);
+	      off = (*parent)->address * OCTETS_PER_BYTE (input_bfd,
+							  input_section);
 	      _bfd_clear_contents ((*parent)->howto, input_bfd,
 				   input_section, data, off);
 	      (*parent)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 0e6a3476d2..162367afd5 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -37,6 +37,9 @@ 
 #include "dwarf2.h"
 #include "opcode/ppc.h"
 
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
 typedef enum split16_format_type
 {
   split16a_type = 0,
@@ -956,7 +959,7 @@  ppc_elf_addr16_ha_reloc (bfd *abfd,
 	    + input_section->output_section->vma);
   value >>= 16;
 
-  octets = reloc_entry->address * bfd_octets_per_byte (abfd, NULL);
+  octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section);
   insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
   insn &= ~0x1fffc1;
   insn |= (value & 0xffc1) | ((value & 0x3e) << 15);
diff --git a/bfd/elf32-pru.c b/bfd/elf32-pru.c
index 98b2018621..dcf4adfa86 100644
--- a/bfd/elf32-pru.c
+++ b/bfd/elf32-pru.c
@@ -32,6 +32,9 @@ 
 #include "opcode/pru.h"
 #include "libiberty.h"
 
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
 #define SWAP_VALS(A,B)		      \
   do {				      \
       (A) ^= (B);		      \
@@ -537,7 +540,7 @@  pru_elf32_do_ldi32_relocate (bfd *abfd, reloc_howto_type *howto,
 			     bfd_vma symbol_value, bfd_vma addend)
 {
   bfd_signed_vma relocation;
-  bfd_size_type octets = offset * bfd_octets_per_byte (abfd, NULL);
+  bfd_size_type octets = offset * OCTETS_PER_BYTE (abfd, input_section);
   bfd_byte *location;
   unsigned long in1, in2;
 
@@ -557,7 +560,7 @@  pru_elf32_do_ldi32_relocate (bfd *abfd, reloc_howto_type *howto,
   BFD_ASSERT (!howto->pc_relative);
 
   /* A hacked-up version of _bfd_relocate_contents() follows.  */
-  location = data + offset * bfd_octets_per_byte (abfd, NULL);
+  location = data + octets;
 
   BFD_ASSERT (!howto->pc_relative);
 
diff --git a/bfd/elf32-s12z.c b/bfd/elf32-s12z.c
index 8b3099c26e..f8f46ba34b 100644
--- a/bfd/elf32-s12z.c
+++ b/bfd/elf32-s12z.c
@@ -27,6 +27,9 @@ 
 
 #include "elf/s12z.h"
 
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
 /* Relocation functions.  */
 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
   (bfd *, bfd_reloc_code_real_type);
@@ -44,7 +47,7 @@  opru18_reloc (bfd *abfd, arelent *reloc_entry, struct bfd_symbol *symbol,
      Appendix A.4 of the S12Z reference manual.  */
 
   bfd_size_type octets = (reloc_entry->address
-			  * bfd_octets_per_byte (abfd, NULL));
+			  * OCTETS_PER_BYTE (abfd, input_section));
   bfd_vma result = bfd_get_24 (abfd, (unsigned char *) data + octets);
   bfd_vma val = bfd_asymbol_value (symbol);
 
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
index 3dc25eefe5..8aa49b099c 100644
--- a/bfd/elf32-sh.c
+++ b/bfd/elf32-sh.c
@@ -30,6 +30,9 @@ 
 #include "libiberty.h"
 #include "../opcodes/sh-opc.h"
 
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
 static bfd_reloc_status_type sh_elf_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type sh_elf_ignore_reloc
@@ -233,7 +236,8 @@  sh_elf_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol_in,
   bfd_vma sym_value;
   enum elf_sh_reloc_type r_type;
   bfd_vma addr = reloc_entry->address;
-  bfd_byte *hit_data = addr + (bfd_byte *) data;
+  bfd_size_type octets = addr * OCTETS_PER_BYTE (abfd, input_section);
+  bfd_byte *hit_data = (bfd_byte *) data + octets;
 
   r_type = (enum elf_sh_reloc_type) reloc_entry->howto->type;
 
@@ -254,8 +258,7 @@  sh_elf_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol_in,
     return bfd_reloc_undefined;
 
   /* PR 17512: file: 9891ca98.  */
-  if ((addr * bfd_octets_per_byte (abfd, NULL)
-       + bfd_get_reloc_size (reloc_entry->howto))
+  if (octets + bfd_get_reloc_size (reloc_entry->howto)
       > bfd_get_section_limit_octets (abfd, input_section))
     return bfd_reloc_outofrange;
 
diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c
index 6f8b32ab58..823628898f 100644
--- a/bfd/elf32-spu.c
+++ b/bfd/elf32-spu.c
@@ -27,6 +27,9 @@ 
 #include "elf/spu.h"
 #include "elf32-spu.h"
 
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
 /* We use RELA style relocs.  Don't define USE_REL.  */
 
 static bfd_reloc_status_type spu_elf_rel9 (bfd *, arelent *, asymbol *,
@@ -212,7 +215,7 @@  spu_elf_rel9 (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
 
   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
     return bfd_reloc_outofrange;
-  octets = reloc_entry->address * bfd_octets_per_byte (abfd, NULL);
+  octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section);
 
   /* Get symbol value.  */
   val = 0;
diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c
index 31e9530256..c42e95ab57 100644
--- a/bfd/elf32-xtensa.c
+++ b/bfd/elf32-xtensa.c
@@ -32,6 +32,9 @@ 
 #include "xtensa-isa.h"
 #include "xtensa-config.h"
 
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
 #define XTENSA_NO_NOP_REMOVAL 0
 
 /* Local helper functions.  */
@@ -2104,7 +2107,7 @@  bfd_elf_xtensa_reloc (bfd *abfd,
   bfd_vma relocation;
   bfd_reloc_status_type flag;
   bfd_size_type octets = (reloc_entry->address
-			  * bfd_octets_per_byte (abfd, NULL));
+			  * OCTETS_PER_BYTE (abfd, input_section));
   bfd_vma output_base = 0;
   reloc_howto_type *howto = reloc_entry->howto;
   asection *reloc_target_output_section;
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 5c7f32315f..9a9374fab1 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -35,6 +35,9 @@ 
 #include "elf64-ppc.h"
 #include "dwarf2.h"
 
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
 static bfd_reloc_status_type ppc64_elf_ha_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type ppc64_elf_branch_reloc
@@ -1405,7 +1408,7 @@  ppc64_elf_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
 	    + input_section->output_section->vma);
   value = (bfd_signed_vma) value >> 16;
 
-  octets = reloc_entry->address * bfd_octets_per_byte (abfd, NULL);
+  octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section);
   insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
   insn &= ~0x1fffc1;
   insn |= (value & 0xffc1) | ((value & 0x3e) << 15);
@@ -1480,7 +1483,7 @@  ppc64_elf_brtaken_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
     return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
 				  input_section, output_bfd, error_message);
 
-  octets = reloc_entry->address * bfd_octets_per_byte (abfd, NULL);
+  octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section);
   insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
   insn &= ~(0x01 << 21);
   r_type = reloc_entry->howto->type;
@@ -1630,7 +1633,7 @@  ppc64_elf_toc64_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
   if (TOCstart == 0)
     TOCstart = ppc64_elf_set_toc (NULL, input_section->output_section->owner);
 
-  octets = reloc_entry->address * bfd_octets_per_byte (abfd, NULL);
+  octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section);
   bfd_put_64 (abfd, TOCstart + TOC_BASE_OFF, (bfd_byte *) data + octets);
   return bfd_reloc_ok;
 }
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 824669a536..554936124c 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -8457,7 +8457,7 @@  resolve_section (const char *name,
 	  if (strncmp (".end", name + len, 4) == 0)
 	    {
 	      *result = (curr->vma
-			 + curr->size / bfd_octets_per_byte (abfd, NULL));
+			 + curr->size / bfd_octets_per_byte (abfd, curr));
 	      return TRUE;
 	    }
 
@@ -8752,7 +8752,7 @@  decode_complex_addend (unsigned long *start,   /* in bits */
 
 bfd_reloc_status_type
 bfd_elf_perform_complex_relocation (bfd *input_bfd,
-				    asection *input_section ATTRIBUTE_UNUSED,
+				    asection *input_section,
 				    bfd_byte *contents,
 				    Elf_Internal_Rela *rel,
 				    bfd_vma relocation)
@@ -8760,6 +8760,7 @@  bfd_elf_perform_complex_relocation (bfd *input_bfd,
   bfd_vma shift, x, mask;
   unsigned long start, oplen, len, wordsz, chunksz, lsb0_p, signed_p, trunc_p;
   bfd_reloc_status_type r;
+  bfd_size_type octets;
 
   /*  Perform this reloc, since it is complex.
       (this is not to say that it necessarily refers to a complex
@@ -8778,9 +8779,8 @@  bfd_elf_perform_complex_relocation (bfd *input_bfd,
   else
     shift = (8 * wordsz) - (start + len);
 
-  x = get_value (wordsz, chunksz, input_bfd,
-		 contents
-		 + rel->r_offset * bfd_octets_per_byte (input_bfd, NULL));
+  octets = rel->r_offset * bfd_octets_per_byte (input_bfd, input_section);
+  x = get_value (wordsz, chunksz, input_bfd, contents + octets);
 
 #ifdef DEBUG
   printf ("Doing complex reloc: "
@@ -8812,8 +8812,7 @@  bfd_elf_perform_complex_relocation (bfd *input_bfd,
 	  (unsigned long) relocation, (unsigned long) (mask << shift),
 	  (unsigned long) ((relocation & mask) << shift), (unsigned long) x);
 #endif
-  put_value (wordsz, chunksz, input_bfd, x,
-	     contents + rel->r_offset * bfd_octets_per_byte (input_bfd, NULL));
+  put_value (wordsz, chunksz, input_bfd, x, contents + octets);
   return r;
 }
 
@@ -11305,7 +11304,7 @@  elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
 		file_ptr offset = (file_ptr) o->output_offset;
 		bfd_size_type todo = o->size;
 
-		offset *= bfd_octets_per_byte (output_bfd, NULL);
+		offset *= bfd_octets_per_byte (output_bfd, o);
 
 		if ((o->flags & SEC_ELF_REVERSE_COPY))
 		  {
@@ -11439,6 +11438,7 @@  elf_reloc_link_order (bfd *output_bfd,
       bfd_byte *buf;
       bfd_boolean ok;
       const char *sym_name;
+      bfd_size_type octets;
 
       size = (bfd_size_type) bfd_get_reloc_size (howto);
       buf = (bfd_byte *) bfd_zmalloc (size);
@@ -11465,10 +11465,10 @@  elf_reloc_link_order (bfd *output_bfd,
 	  break;
 	}
 
+      octets = link_order->offset * bfd_octets_per_byte (output_bfd,
+							 output_section);
       ok = bfd_set_section_contents (output_bfd, output_section, buf,
-				     link_order->offset
-				     * bfd_octets_per_byte (output_bfd, NULL),
-				     size);
+				     octets, size);
       free (buf);
       if (! ok)
 	return FALSE;
@@ -11635,7 +11635,7 @@  elf_fixup_link_order (bfd *abfd, asection *o)
       s = sections[n]->u.indirect.section;
       mask = ~(bfd_vma) 0 << s->alignment_power;
       offset = (offset + ~mask) & mask;
-      s->output_offset = offset / bfd_octets_per_byte (abfd, NULL);
+      s->output_offset = offset / bfd_octets_per_byte (abfd, s);
       sections[n]->offset = offset;
       offset += sections[n]->size;
     }
@@ -12856,12 +12856,10 @@  bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 	    continue;
 	  if (strcmp (o->name, ".dynstr") != 0)
 	    {
-	      if (! bfd_set_section_contents (abfd, o->output_section,
-					      o->contents,
-					      (file_ptr) o->output_offset
-					      * bfd_octets_per_byte (abfd,
-								     NULL),
-					      o->size))
+	      bfd_size_type octets = ((file_ptr) o->output_offset
+				      * bfd_octets_per_byte (abfd, o));
+	      if (!bfd_set_section_contents (abfd, o->output_section,
+					     o->contents, octets, o->size))
 		goto error_return;
 	    }
 	  else
diff --git a/bfd/reloc.c b/bfd/reloc.c
index e01cb5182e..b00b79f319 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -744,14 +744,14 @@  bfd_perform_relocation (bfd *abfd,
   else
     output_base = reloc_target_output_section->vma;
 
-  /* For sections where relocations are in octets, output_base and
-     output_offset must also be converted to octets.  */
+  output_base += symbol->section->output_offset;
+
+  /* If symbol addresses are in octets, convert to bytes.  */
   if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
       && (symbol->section->flags & SEC_ELF_OCTETS))
-    relocation += ((output_base + symbol->section->output_offset)
-		   * bfd_octets_per_byte (abfd, NULL));
-  else
-    relocation += output_base + symbol->section->output_offset;
+    output_base *= bfd_octets_per_byte (abfd, input_section);
+
+  relocation += output_base;
 
   /* Add in supplied addend.  */
   relocation += reloc_entry->addend;
@@ -1080,14 +1080,14 @@  bfd_install_relocation (bfd *abfd,
   else
     output_base = reloc_target_output_section->vma;
 
-  /* For sections where relocations are in octets, output_base and
-     output_offset must also be converted to octets.  */
+  output_base += symbol->section->output_offset;
+
+  /* If symbol addresses are in octets, convert to bytes.  */
   if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
       && (symbol->section->flags & SEC_ELF_OCTETS))
-    relocation += ((output_base + symbol->section->output_offset)
-		   * bfd_octets_per_byte (abfd, NULL));
-  else
-    relocation += output_base + symbol->section->output_offset;
+    output_base *= bfd_octets_per_byte (abfd, input_section);
+
+  relocation += output_base;
 
   /* Add in supplied addend.  */
   relocation += reloc_entry->addend;
@@ -1383,10 +1383,7 @@  _bfd_final_link_relocate (reloc_howto_type *howto,
     }
 
   return _bfd_relocate_contents (howto, input_bfd, relocation,
-				 contents
-				 + address
-				 * bfd_octets_per_byte (input_bfd,
-							input_section));
+				 contents + octets);
 }
 
 /* Relocate a given location using a given value and howto.  */
diff --git a/bfd/syms.c b/bfd/syms.c
index ec7d2c8dba..f02cae9fc7 100644
--- a/bfd/syms.c
+++ b/bfd/syms.c
@@ -1078,20 +1078,21 @@  _bfd_stab_section_find_nearest_line (bfd *abfd,
 	      arelent *r;
 	      unsigned long val;
 	      asymbol *sym;
+	      bfd_size_type octets;
 
 	      r = *pr;
 	      /* Ignore R_*_NONE relocs.  */
 	      if (r->howto->dst_mask == 0)
 		continue;
 
+	      octets = r->address * bfd_octets_per_byte (abfd, NULL);
 	      if (r->howto->rightshift != 0
 		  || r->howto->size != 2
 		  || r->howto->bitsize != 32
 		  || r->howto->pc_relative
 		  || r->howto->bitpos != 0
 		  || r->howto->dst_mask != 0xffffffff
-		  || (r->address * bfd_octets_per_byte (abfd, NULL) + 4
-		      > stabsize))
+		  || octets + 4 > stabsize)
 		{
 		  _bfd_error_handler
 		    (_("unsupported .stab relocation"));
@@ -1101,14 +1102,11 @@  _bfd_stab_section_find_nearest_line (bfd *abfd,
 		  return FALSE;
 		}
 
-	      val = bfd_get_32 (abfd, info->stabs
-				+ (r->address
-				   * bfd_octets_per_byte (abfd, NULL)));
+	      val = bfd_get_32 (abfd, info->stabs + octets);
 	      val &= r->howto->src_mask;
 	      sym = *r->sym_ptr_ptr;
 	      val += sym->value + sym->section->vma + r->addend;
-	      bfd_put_32 (abfd, (bfd_vma) val, info->stabs
-			  + r->address * bfd_octets_per_byte (abfd, NULL));
+	      bfd_put_32 (abfd, (bfd_vma) val, info->stabs + octets);
 	    }
 	}
 
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 8327a3f2bc..b287022f5a 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -852,7 +852,8 @@  fold_name (etree_type *tree)
 
 	      if (tree->type.node_code == SIZEOF)
 		val = (os->bfd_section->size
-		       / bfd_octets_per_byte (link_info.output_bfd, NULL));
+		       / bfd_octets_per_byte (link_info.output_bfd,
+					      os->bfd_section));
 	      else
 		val = (bfd_vma)1 << os->bfd_section->alignment_power;
 
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 3bcab7a876..191d8f1c61 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -3442,16 +3442,16 @@  ldlang_open_output (lang_statement_union_type *statement)
 static void
 init_opb (asection *s)
 {
-  unsigned x = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
-					      ldfile_output_machine);
-  if (s != NULL)
-    {
-      if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
-	  && (s->flags & SEC_ELF_OCTETS))
-	x = 1;
-    }
+  unsigned int x;
 
   opb_shift = 0;
+  if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
+      && s != NULL
+      && (s->flags & SEC_ELF_OCTETS) != 0)
+    return;
+
+  x = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
+				     ldfile_output_machine);
   if (x > 1)
     while ((x & 1) == 0)
       {