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]

[GOLD] [PATCH 3/3] Introduce and use array_size


This adds a type-safe version of libiberty.h's ARRAY_SIZE, and uses it
throughout.

If something calls array_size with a pointer by mistake instead of an
array, the code doesn't compile, unlike with the (sizeof (array) /
sizeof (array[0])), which is what ARRAY_SIZE does.

Unfortunately, until gold requires C++11, we can't use this with
stack/local arrays (14.3.1/2 "A local type, a type with no linkage, an
unnamed type or a type compounded from any of these types shall not be
used as a template-argument for a template type-parameter.")
Fortunately, the need to use array_size with local arrays is not so
common.  Arrays with local or unnamed type are easily worked around
(just move or name the type).

In mips.cc, this commit moves the definitions of some arrays before
their uses, otherwise at least gcc 4.1 complaints:

  ../../src/gold/mips.cc:2589: error: no matching function for call to 'array_size_require_array(const __uint32_t [])'
  ../../src/gold/mips.cc:2591: error: no matching function for call to 'array_size_require_array(const __uint32_t [])'
  ../../src/gold/mips.cc:2593: error: no matching function for call to 'array_size_require_array(const __uint32_t [])'

Not sure what the standard says here.  In any case, it seems pointless
to me to have multiple instances of the same arrays (one per template
instantiation), so the move actually makes the arrays be static
globals instead of template class statics, while at it.  This reduces
gold's -O2 text size by almost 1k.

gold/ChangeLog:
2017-01-24  Pedro Alves  <palves@redhat.com>

	* arm-reloc-property.cc (struct RAB_table_entry): New, moved from
	...
	(Arm_reloc_property::Arm_reloc_property): ... here.  Use
	array_size.
	* arm.cc (Stub_factory::Stub_factory): Use array_size.
	(Output_data_plt_arm_standard<big_endian>::do_fill_first_plt_entry)
	(Target_arm<big_endian>::aeabi_enum_name)
	(Target_arm<big_endian>::tag_cpu_name_value)
	(Output_data_plt_arm_nacl<big_endian>::do_fill_first_plt_entry):
	Use array_size.
	* defstd.cc (in_section_count, in_segment_count): Use array_size.
	* dynobj.cc (Dynobj::compute_bucket_count): Likewise.
	* gold.h (array_size_require_array, array_size): New.
	* layout.cc (Layout::special_ordering_of_input_section): Use
	array_size.
	(Layout::section_name_mapping_count): Use array_size.
	* mips.cc (Mips_output_data_plt) <plt0_entry_o32, plt0_entry_n32,
	plt0_entry_n64, plt0_entry_micromips_o32,
	plt0_entry_micromips32_o32, plt_entry, plt_entry_r6,
	plt_entry_mips16_o32, plt_entry_micromips_o32,
	plt_entry_micromips32_o32): Moved outsize the template class and
	made static const globals.
	(Mips_output_data_plt<size, big_endian>::get_plt_header_size)
	(Mips_output_data_plt<size, big_endian>::standard_plt_entry_size)
	(Mips_output_data_plt<size, big_endian>::do_write): Use
	array_size.
	* powerpc.cc (Target_powerpc<size, big_endian>::do_relax): Use
	array_size.
	* script.cc (script_keywords, version_script_keywords)
	(dynamic_list_keywords): Use array_size.
	(phdr_type_name): Give anonymous struct a name.
	(script_phdr_string_to_type): Use array_size.
---
 gold/arm-reloc-property.cc |  14 +-
 gold/arm.cc                |  16 +--
 gold/defstd.cc             |   4 +-
 gold/dynobj.cc             |   2 +-
 gold/gold.h                |  17 +++
 gold/layout.cc             |   7 +-
 gold/mips.cc               | 313 ++++++++++++++++++++-------------------------
 gold/powerpc.cc            |   4 +-
 gold/script.cc             |  15 +--
 9 files changed, 178 insertions(+), 214 deletions(-)

diff --git a/gold/arm-reloc-property.cc b/gold/arm-reloc-property.cc
index 7b17b57..8d83c0d 100644
--- a/gold/arm-reloc-property.cc
+++ b/gold/arm-reloc-property.cc
@@ -85,6 +85,12 @@ Arm_reloc_property::Tree_node::make_tree(const std::string& s)
   return node_stack[0];
 }
 
+struct RAB_table_entry
+{
+  Arm_reloc_property::Relative_address_base rab;
+  const char* name;
+};
+
 // Arm_reloc_property methods.
 
 // Constructor.
@@ -169,12 +175,6 @@ Arm_reloc_property::Arm_reloc_property(
       && node->child(0)->is_leaf()
       && node->child(0)->name() == "-")
     {
-      struct RAB_table_entry
-      {
-	Relative_address_base rab;
-	const char* name;
-      };
-
       static const RAB_table_entry rab_table[] =
       {
 	{ RAB_B_S, "( B S )" },
@@ -186,7 +186,7 @@ Arm_reloc_property::Arm_reloc_property(
       	{ RAB_tp, "tp" }
       };
 
-      static size_t rab_table_size = sizeof(rab_table) / sizeof(rab_table[0]);
+      static size_t rab_table_size = array_size(rab_table);
       const std::string rhs(node->child(2)->s_expression());
       for (size_t i = 0; i < rab_table_size; ++i)
 	if (rhs == rab_table[i].name)
diff --git a/gold/arm.cc b/gold/arm.cc
index ff472ea..dd3d629 100644
--- a/gold/arm.cc
+++ b/gold/arm.cc
@@ -4984,11 +4984,10 @@ Stub_factory::Stub_factory()
 #define DEF_STUB(x)	\
   do \
     { \
-      size_t array_size \
-	= sizeof(elf32_arm_stub_##x) / sizeof(elf32_arm_stub_##x[0]); \
       Stub_type type = arm_stub_##x; \
       this->stub_templates_[type] = \
-	new Stub_template(type, elf32_arm_stub_##x, array_size); \
+	new Stub_template(type, elf32_arm_stub_##x, \
+			  array_size (elf32_arm_stub_##x)); \
     } \
   while (0);
 
@@ -7888,8 +7887,7 @@ Output_data_plt_arm_standard<big_endian>::do_fill_first_plt_entry(
     Arm_address plt_address)
 {
   // Write first PLT entry.  All but the last word are constants.
-  const size_t num_first_plt_words = (sizeof(first_plt_entry)
-				      / sizeof(first_plt_entry[0]));
+  const size_t num_first_plt_words = array_size (first_plt_entry);
   for (size_t i = 0; i < num_first_plt_words - 1; i++)
     {
       if (parameters->options().be8())
@@ -11152,8 +11150,7 @@ Target_arm<big_endian>::aeabi_enum_name(unsigned int value)
 {
   static const char* aeabi_enum_names[] =
     { "", "variable-size", "32-bit", "" };
-  const size_t aeabi_enum_names_size =
-    sizeof(aeabi_enum_names) / sizeof(aeabi_enum_names[0]);
+  const size_t aeabi_enum_names_size = array_size(aeabi_enum_names);
 
   if (value < aeabi_enum_names_size)
     return std::string(aeabi_enum_names[value]);
@@ -11190,7 +11187,7 @@ Target_arm<big_endian>::tag_cpu_name_value(unsigned int value)
    "ARM v7E-M",
    "ARM v8"
  };
- const size_t name_table_size = sizeof(name_table) / sizeof(name_table[0]);
+ const size_t name_table_size = array_size(name_table);
 
   if (value < name_table_size)
     return std::string(name_table[value]);
@@ -13127,8 +13124,7 @@ Output_data_plt_arm_nacl<big_endian>::do_fill_first_plt_entry(
     Arm_address plt_address)
 {
   // Write first PLT entry.  All but first two words are constants.
-  const size_t num_first_plt_words = (sizeof(first_plt_entry)
-				      / sizeof(first_plt_entry[0]));
+  const size_t num_first_plt_words = array_size(first_plt_entry);
 
   int32_t got_displacement = got_address + 8 - (plt_address + 16);
 
diff --git a/gold/defstd.cc b/gold/defstd.cc
index a7fdd93..75ad7e5 100644
--- a/gold/defstd.cc
+++ b/gold/defstd.cc
@@ -122,7 +122,7 @@ const Define_symbol_in_section in_section[] =
   },
 };
 
-const int in_section_count = sizeof in_section / sizeof in_section[0];
+const int in_section_count = array_size (in_section);
 
 const Define_symbol_in_segment in_segment[] =
 {
@@ -268,7 +268,7 @@ const Define_symbol_in_segment in_segment[] =
   }
 };
 
-const int in_segment_count = sizeof in_segment / sizeof in_segment[0];
+const int in_segment_count = array_size (in_segment);
 
 } // End anonymous namespace.
 
diff --git a/gold/dynobj.cc b/gold/dynobj.cc
index 0d38418..9da502d 100644
--- a/gold/dynobj.cc
+++ b/gold/dynobj.cc
@@ -870,7 +870,7 @@ Dynobj::compute_bucket_count(const std::vector<uint32_t>& hashcodes,
     1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209,
     16411, 32771, 65537, 131101, 262147
   };
-  const int buckets_count = sizeof buckets / sizeof buckets[0];
+  const int buckets_count = array_size (buckets);
 
   unsigned int symcount = hashcodes.size();
   unsigned int ret = 1;
diff --git a/gold/gold.h b/gold/gold.h
index ae36e2f..4f62c10 100644
--- a/gold/gold.h
+++ b/gold/gold.h
@@ -175,6 +175,23 @@ extern void do_gold_unreachable(const char*, int, const char*)
 
 #define gold_assert(expr) ((void)(!(expr) ? gold_unreachable(), 0 : 0))
 
+// Type-safe version of libiberty.h's ARRAY_SIZE.  If you pass in a
+// pointer by mistake instead of an array, you get a compile-time
+// error.
+//
+// Until we require C++11, we can't use this with non-static local
+// arrays (C++03 14.3.1/2 "A local type, a type with no linkage, an
+// unnamed type or a type compounded from any of these types shall not
+// be used as a template-argument for a template type-parameter.")
+// Fortunately, the need for computing sizes of local arrays is not
+// that common.  Once we require C++11, we can make this a constexpr
+// function instead (just like C++17's non-member std::size).
+
+template <typename T, std::size_t N>
+char (&array_size_require_array(T(&)[N]))[N];
+
+#define array_size(array) sizeof(array_size_require_array(array))
+
 // Print version information.
 extern void
 print_version(bool print_short);
diff --git a/gold/layout.cc b/gold/layout.cc
index 07a3590..5dda3b3 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -1130,9 +1130,7 @@ Layout::special_ordering_of_input_section(const char* name)
     ".text.hot"
   };
 
-  for (size_t i = 0;
-       i < sizeof(text_section_sort) / sizeof(text_section_sort[0]);
-       i++)
+  for (size_t i = 0; i < array_size (text_section_sort); i++)
     if (is_prefix_of(text_section_sort[i], name))
       return i;
 
@@ -5091,8 +5089,7 @@ const Layout::Section_name_mapping Layout::section_name_mapping[] =
 #undef MAPPING_INIT_EXACT
 
 const int Layout::section_name_mapping_count =
-  (sizeof(Layout::section_name_mapping)
-   / sizeof(Layout::section_name_mapping[0]));
+  array_size (Layout::section_name_mapping);
 
 // Choose the output section name to use given an input section name.
 // Set *PLEN to the length of the name.  *PLEN is initialized to the
diff --git a/gold/mips.cc b/gold/mips.cc
index 56af570..56480de 100644
--- a/gold/mips.cc
+++ b/gold/mips.cc
@@ -2445,6 +2445,132 @@ class Mips_output_data_reloc : public Output_data_reloc<sh_type, dynamic,
   }
 };
 
+// The format of the first PLT entry in an O32 executable.
+static const uint32_t plt0_entry_o32[] =
+{
+  0x3c1c0000,         // lui $28, %hi(&GOTPLT[0])
+  0x8f990000,         // lw $25, %lo(&GOTPLT[0])($28)
+  0x279c0000,         // addiu $28, $28, %lo(&GOTPLT[0])
+  0x031cc023,         // subu $24, $24, $28
+  0x03e07825,         // or $15, $31, zero
+  0x0018c082,         // srl $24, $24, 2
+  0x0320f809,         // jalr $25
+  0x2718fffe          // subu $24, $24, 2
+};
+
+// The format of the first PLT entry in an N32 executable.  Different
+// because gp ($28) is not available; we use t2 ($14) instead.
+static const uint32_t plt0_entry_n32[] =
+{
+  0x3c0e0000,         // lui $14, %hi(&GOTPLT[0])
+  0x8dd90000,         // lw $25, %lo(&GOTPLT[0])($14)
+  0x25ce0000,         // addiu $14, $14, %lo(&GOTPLT[0])
+  0x030ec023,         // subu $24, $24, $14
+  0x03e07825,         // or $15, $31, zero
+  0x0018c082,         // srl $24, $24, 2
+  0x0320f809,         // jalr $25
+  0x2718fffe          // subu $24, $24, 2
+};
+
+// The format of the first PLT entry in an N64 executable.  Different
+// from N32 because of the increased size of GOT entries.
+static const uint32_t plt0_entry_n64[] =
+{
+  0x3c0e0000,         // lui $14, %hi(&GOTPLT[0])
+  0xddd90000,         // ld $25, %lo(&GOTPLT[0])($14)
+  0x25ce0000,         // addiu $14, $14, %lo(&GOTPLT[0])
+  0x030ec023,         // subu $24, $24, $14
+  0x03e07825,         // or $15, $31, zero
+  0x0018c0c2,         // srl $24, $24, 3
+  0x0320f809,         // jalr $25
+  0x2718fffe          // subu $24, $24, 2
+};
+
+// The format of the microMIPS first PLT entry in an O32 executable.
+// We rely on v0 ($2) rather than t8 ($24) to contain the address
+// of the GOTPLT entry handled, so this stub may only be used when
+// all the subsequent PLT entries are microMIPS code too.
+//
+// The trailing NOP is for alignment and correct disassembly only.
+static const uint32_t plt0_entry_micromips_o32[] =
+{
+  0x7980, 0x0000,      // addiupc $3, (&GOTPLT[0]) - .
+  0xff23, 0x0000,      // lw $25, 0($3)
+  0x0535,              // subu $2, $2, $3
+  0x2525,              // srl $2, $2, 2
+  0x3302, 0xfffe,      // subu $24, $2, 2
+  0x0dff,              // move $15, $31
+  0x45f9,              // jalrs $25
+  0x0f83,              // move $28, $3
+  0x0c00               // nop
+};
+
+// The format of the microMIPS first PLT entry in an O32 executable
+// in the insn32 mode.
+static const uint32_t plt0_entry_micromips32_o32[] =
+{
+  0x41bc, 0x0000,      // lui $28, %hi(&GOTPLT[0])
+  0xff3c, 0x0000,      // lw $25, %lo(&GOTPLT[0])($28)
+  0x339c, 0x0000,      // addiu $28, $28, %lo(&GOTPLT[0])
+  0x0398, 0xc1d0,      // subu $24, $24, $28
+  0x001f, 0x7a90,      // or $15, $31, zero
+  0x0318, 0x1040,      // srl $24, $24, 2
+  0x03f9, 0x0f3c,      // jalr $25
+  0x3318, 0xfffe       // subu $24, $24, 2
+};
+
+// The format of subsequent standard entries in the PLT.
+static const uint32_t plt_entry[] =
+{
+  0x3c0f0000,           // lui $15, %hi(.got.plt entry)
+  0x01f90000,           // l[wd] $25, %lo(.got.plt entry)($15)
+  0x03200008,           // jr $25
+  0x25f80000            // addiu $24, $15, %lo(.got.plt entry)
+};
+
+// The format of subsequent R6 PLT entries.
+static const uint32_t plt_entry_r6[] =
+{
+  0x3c0f0000,           // lui $15, %hi(.got.plt entry)
+  0x01f90000,           // l[wd] $25, %lo(.got.plt entry)($15)
+  0x03200009,           // jr $25
+  0x25f80000            // addiu $24, $15, %lo(.got.plt entry)
+};
+
+// The format of subsequent MIPS16 o32 PLT entries.  We use v1 ($3) as a
+// temporary because t8 ($24) and t9 ($25) are not directly addressable.
+// Note that this differs from the GNU ld which uses both v0 ($2) and v1 ($3).
+// We cannot use v0 because MIPS16 call stubs from the CS toolchain expect
+// target function address in register v0.
+static const uint32_t plt_entry_mips16_o32[] =
+{
+  0xb303,              // lw $3, 12($pc)
+  0x651b,              // move $24, $3
+  0x9b60,              // lw $3, 0($3)
+  0xeb00,              // jr $3
+  0x653b,              // move $25, $3
+  0x6500,              // nop
+  0x0000, 0x0000       // .word (.got.plt entry)
+};
+
+// The format of subsequent microMIPS o32 PLT entries.  We use v0 ($2)
+// as a temporary because t8 ($24) is not addressable with ADDIUPC.
+const uint32_t plt_entry_micromips_o32[] =
+{
+  0x7900, 0x0000,      // addiupc $2, (.got.plt entry) - .
+  0xff22, 0x0000,      // lw $25, 0($2)
+  0x4599,              // jr $25
+  0x0f02               // move $24, $2
+};
+
+// The format of subsequent microMIPS o32 PLT entries in the insn32 mode.
+static const uint32_t plt_entry_micromips32_o32[] =
+{
+  0x41af, 0x0000,      // lui $15, %hi(.got.plt entry)
+  0xff2f, 0x0000,      // lw $25, %lo(.got.plt entry)($15)
+  0x0019, 0x0f3c,      // jr $25
+  0x330f, 0x0000       // addiu $24, $15, %lo(.got.plt entry)
+};
 
 // A class to handle the PLT data.
 
@@ -2543,19 +2669,6 @@ class Mips_output_data_plt : public Output_section_data
   { mapfile->print_output_data(this, _(".plt")); }
 
  private:
-  // Template for the first PLT entry.
-  static const uint32_t plt0_entry_o32[];
-  static const uint32_t plt0_entry_n32[];
-  static const uint32_t plt0_entry_n64[];
-  static const uint32_t plt0_entry_micromips_o32[];
-  static const uint32_t plt0_entry_micromips32_o32[];
-
-  // Template for subsequent PLT entries.
-  static const uint32_t plt_entry[];
-  static const uint32_t plt_entry_r6[];
-  static const uint32_t plt_entry_mips16_o32[];
-  static const uint32_t plt_entry_micromips_o32[];
-  static const uint32_t plt_entry_micromips32_o32[];
 
   // Set the final size.
   void
@@ -2586,17 +2699,15 @@ class Mips_output_data_plt : public Output_section_data
   get_plt_header_size() const
   {
     if (this->target_->is_output_n64())
-      return 4 * sizeof(plt0_entry_n64) / sizeof(plt0_entry_n64[0]);
+      return 4 * array_size(plt0_entry_n64);
     else if (this->target_->is_output_n32())
-      return 4 * sizeof(plt0_entry_n32) / sizeof(plt0_entry_n32[0]);
+      return 4 * array_size(plt0_entry_n32);
     else if (!this->is_plt_header_compressed())
-      return 4 * sizeof(plt0_entry_o32) / sizeof(plt0_entry_o32[0]);
+      return 4 * array_size(plt0_entry_o32);
     else if (this->target_->use_32bit_micromips_instructions())
-      return (2 * sizeof(plt0_entry_micromips32_o32)
-              / sizeof(plt0_entry_micromips32_o32[0]));
+      return 2 * array_size(plt0_entry_micromips32_o32);
     else
-      return (2 * sizeof(plt0_entry_micromips_o32)
-              / sizeof(plt0_entry_micromips_o32[0]));
+      return 2 * array_size(plt0_entry_micromips_o32);
   }
 
   // Return the PLT header entry.
@@ -2618,7 +2729,7 @@ class Mips_output_data_plt : public Output_section_data
   // Return the size of the standard PLT entry.
   unsigned int
   standard_plt_entry_size() const
-  { return 4 * sizeof(plt_entry) / sizeof(plt_entry[0]); }
+  { return 4 * array_size(plt_entry); }
 
   // Return the size of the compressed PLT entry.
   unsigned int
@@ -2627,14 +2738,11 @@ class Mips_output_data_plt : public Output_section_data
     gold_assert(!this->target_->is_output_newabi());
 
     if (!this->target_->is_output_micromips())
-      return (2 * sizeof(plt_entry_mips16_o32)
-              / sizeof(plt_entry_mips16_o32[0]));
+      return 2 * array_size(plt_entry_mips16_o32);
     else if (this->target_->use_32bit_micromips_instructions())
-      return (2 * sizeof(plt_entry_micromips32_o32)
-              / sizeof(plt_entry_micromips32_o32[0]));
+      return 2 * array_size(plt_entry_micromips32_o32);
     else
-      return (2 * sizeof(plt_entry_micromips_o32)
-              / sizeof(plt_entry_micromips_o32[0]));
+      return 2 * array_size(plt_entry_micromips_o32);
   }
 
   // The reloc section.
@@ -7161,147 +7269,6 @@ Mips_output_data_la25_stub<size, big_endian>::do_write(Output_file* of)
 
 // Mips_output_data_plt methods.
 
-// The format of the first PLT entry in an O32 executable.
-template<int size, bool big_endian>
-const uint32_t Mips_output_data_plt<size, big_endian>::plt0_entry_o32[] =
-{
-  0x3c1c0000,         // lui $28, %hi(&GOTPLT[0])
-  0x8f990000,         // lw $25, %lo(&GOTPLT[0])($28)
-  0x279c0000,         // addiu $28, $28, %lo(&GOTPLT[0])
-  0x031cc023,         // subu $24, $24, $28
-  0x03e07825,         // or $15, $31, zero
-  0x0018c082,         // srl $24, $24, 2
-  0x0320f809,         // jalr $25
-  0x2718fffe          // subu $24, $24, 2
-};
-
-// The format of the first PLT entry in an N32 executable.  Different
-// because gp ($28) is not available; we use t2 ($14) instead.
-template<int size, bool big_endian>
-const uint32_t Mips_output_data_plt<size, big_endian>::plt0_entry_n32[] =
-{
-  0x3c0e0000,         // lui $14, %hi(&GOTPLT[0])
-  0x8dd90000,         // lw $25, %lo(&GOTPLT[0])($14)
-  0x25ce0000,         // addiu $14, $14, %lo(&GOTPLT[0])
-  0x030ec023,         // subu $24, $24, $14
-  0x03e07825,         // or $15, $31, zero
-  0x0018c082,         // srl $24, $24, 2
-  0x0320f809,         // jalr $25
-  0x2718fffe          // subu $24, $24, 2
-};
-
-// The format of the first PLT entry in an N64 executable.  Different
-// from N32 because of the increased size of GOT entries.
-template<int size, bool big_endian>
-const uint32_t Mips_output_data_plt<size, big_endian>::plt0_entry_n64[] =
-{
-  0x3c0e0000,         // lui $14, %hi(&GOTPLT[0])
-  0xddd90000,         // ld $25, %lo(&GOTPLT[0])($14)
-  0x25ce0000,         // addiu $14, $14, %lo(&GOTPLT[0])
-  0x030ec023,         // subu $24, $24, $14
-  0x03e07825,         // or $15, $31, zero
-  0x0018c0c2,         // srl $24, $24, 3
-  0x0320f809,         // jalr $25
-  0x2718fffe          // subu $24, $24, 2
-};
-
-// The format of the microMIPS first PLT entry in an O32 executable.
-// We rely on v0 ($2) rather than t8 ($24) to contain the address
-// of the GOTPLT entry handled, so this stub may only be used when
-// all the subsequent PLT entries are microMIPS code too.
-//
-// The trailing NOP is for alignment and correct disassembly only.
-template<int size, bool big_endian>
-const uint32_t Mips_output_data_plt<size, big_endian>::
-plt0_entry_micromips_o32[] =
-{
-  0x7980, 0x0000,      // addiupc $3, (&GOTPLT[0]) - .
-  0xff23, 0x0000,      // lw $25, 0($3)
-  0x0535,              // subu $2, $2, $3
-  0x2525,              // srl $2, $2, 2
-  0x3302, 0xfffe,      // subu $24, $2, 2
-  0x0dff,              // move $15, $31
-  0x45f9,              // jalrs $25
-  0x0f83,              // move $28, $3
-  0x0c00               // nop
-};
-
-// The format of the microMIPS first PLT entry in an O32 executable
-// in the insn32 mode.
-template<int size, bool big_endian>
-const uint32_t Mips_output_data_plt<size, big_endian>::
-plt0_entry_micromips32_o32[] =
-{
-  0x41bc, 0x0000,      // lui $28, %hi(&GOTPLT[0])
-  0xff3c, 0x0000,      // lw $25, %lo(&GOTPLT[0])($28)
-  0x339c, 0x0000,      // addiu $28, $28, %lo(&GOTPLT[0])
-  0x0398, 0xc1d0,      // subu $24, $24, $28
-  0x001f, 0x7a90,      // or $15, $31, zero
-  0x0318, 0x1040,      // srl $24, $24, 2
-  0x03f9, 0x0f3c,      // jalr $25
-  0x3318, 0xfffe       // subu $24, $24, 2
-};
-
-// The format of subsequent standard entries in the PLT.
-template<int size, bool big_endian>
-const uint32_t Mips_output_data_plt<size, big_endian>::plt_entry[] =
-{
-  0x3c0f0000,           // lui $15, %hi(.got.plt entry)
-  0x01f90000,           // l[wd] $25, %lo(.got.plt entry)($15)
-  0x03200008,           // jr $25
-  0x25f80000            // addiu $24, $15, %lo(.got.plt entry)
-};
-
-// The format of subsequent R6 PLT entries.
-template<int size, bool big_endian>
-const uint32_t Mips_output_data_plt<size, big_endian>::plt_entry_r6[] =
-{
-  0x3c0f0000,           // lui $15, %hi(.got.plt entry)
-  0x01f90000,           // l[wd] $25, %lo(.got.plt entry)($15)
-  0x03200009,           // jr $25
-  0x25f80000            // addiu $24, $15, %lo(.got.plt entry)
-};
-
-// The format of subsequent MIPS16 o32 PLT entries.  We use v1 ($3) as a
-// temporary because t8 ($24) and t9 ($25) are not directly addressable.
-// Note that this differs from the GNU ld which uses both v0 ($2) and v1 ($3).
-// We cannot use v0 because MIPS16 call stubs from the CS toolchain expect
-// target function address in register v0.
-template<int size, bool big_endian>
-const uint32_t Mips_output_data_plt<size, big_endian>::plt_entry_mips16_o32[] =
-{
-  0xb303,              // lw $3, 12($pc)
-  0x651b,              // move $24, $3
-  0x9b60,              // lw $3, 0($3)
-  0xeb00,              // jr $3
-  0x653b,              // move $25, $3
-  0x6500,              // nop
-  0x0000, 0x0000       // .word (.got.plt entry)
-};
-
-// The format of subsequent microMIPS o32 PLT entries.  We use v0 ($2)
-// as a temporary because t8 ($24) is not addressable with ADDIUPC.
-template<int size, bool big_endian>
-const uint32_t Mips_output_data_plt<size, big_endian>::
-plt_entry_micromips_o32[] =
-{
-  0x7900, 0x0000,      // addiupc $2, (.got.plt entry) - .
-  0xff22, 0x0000,      // lw $25, 0($2)
-  0x4599,              // jr $25
-  0x0f02               // move $24, $2
-};
-
-// The format of subsequent microMIPS o32 PLT entries in the insn32 mode.
-template<int size, bool big_endian>
-const uint32_t Mips_output_data_plt<size, big_endian>::
-plt_entry_micromips32_o32[] =
-{
-  0x41af, 0x0000,      // lui $15, %hi(.got.plt entry)
-  0xff2f, 0x0000,      // lw $25, %lo(.got.plt entry)($15)
-  0x0019, 0x0f3c,      // jr $25
-  0x330f, 0x0000       // addiu $24, $15, %lo(.got.plt entry)
-};
-
 // Add an entry to the PLT for a symbol referenced by r_type relocation.
 
 template<int size, bool big_endian>
@@ -7455,10 +7422,7 @@ Mips_output_data_plt<size, big_endian>::do_write(Output_file* of)
       elfcpp::Swap<16, big_endian>::writeval(pov + 2,
                                              (gotpc_offset >> 2) & 0xffff);
       pov += 4;
-      for (unsigned int i = 2;
-           i < (sizeof(plt0_entry_micromips_o32)
-                / sizeof(plt0_entry_micromips_o32[0]));
-           i++)
+      for (unsigned int i = 2; i < array_size(plt0_entry_micromips_o32); i++)
         {
           elfcpp::Swap<16, big_endian>::writeval(pov, plt0_entry[i]);
           pov += 2;
@@ -7474,10 +7438,7 @@ Mips_output_data_plt<size, big_endian>::do_write(Output_file* of)
       elfcpp::Swap<16, big_endian>::writeval(pov + 8, plt0_entry[4]);
       elfcpp::Swap<16, big_endian>::writeval(pov + 10, gotplt_addr_low);
       pov += 12;
-      for (unsigned int i = 6;
-           i < (sizeof(plt0_entry_micromips32_o32)
-                / sizeof(plt0_entry_micromips32_o32[0]));
-           i++)
+      for (unsigned int i = 6; i < array_size(plt0_entry_micromips32_o32); i++)
         {
           elfcpp::Swap<16, big_endian>::writeval(pov, plt0_entry[i]);
           pov += 2;
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index a67c336..37bc7ce 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -3060,9 +3060,7 @@ Target_powerpc<size, big_endian>::do_relax(int pass,
 	    thread_safe = true;
 	  else
 	    {
-	      for (unsigned int i = 0;
-		   i < sizeof(thread_starter) / sizeof(thread_starter[0]);
-		   i++)
+	      for (unsigned int i = 0; i < array_size(thread_starter); i++)
 		{
 		  Symbol* sym = symtab->lookup(thread_starter[i], NULL);
 		  thread_safe = (sym != NULL
diff --git a/gold/script.cc b/gold/script.cc
index 67540a5..dfe6469 100644
--- a/gold/script.cc
+++ b/gold/script.cc
@@ -1821,8 +1821,7 @@ script_keyword_parsecodes[] =
 
 static const Keyword_to_parsecode
 script_keywords(&script_keyword_parsecodes[0],
-                (sizeof(script_keyword_parsecodes)
-                 / sizeof(script_keyword_parsecodes[0])));
+		array_size(script_keyword_parsecodes));
 
 static const Keyword_to_parsecode::Keyword_parsecode
 version_script_keyword_parsecodes[] =
@@ -1834,8 +1833,7 @@ version_script_keyword_parsecodes[] =
 
 static const Keyword_to_parsecode
 version_script_keywords(&version_script_keyword_parsecodes[0],
-                        (sizeof(version_script_keyword_parsecodes)
-                         / sizeof(version_script_keyword_parsecodes[0])));
+                        array_size(version_script_keyword_parsecodes));
 
 static const Keyword_to_parsecode::Keyword_parsecode
 dynamic_list_keyword_parsecodes[] =
@@ -1845,8 +1843,7 @@ dynamic_list_keyword_parsecodes[] =
 
 static const Keyword_to_parsecode
 dynamic_list_keywords(&dynamic_list_keyword_parsecodes[0],
-                      (sizeof(dynamic_list_keyword_parsecodes)
-                       / sizeof(dynamic_list_keyword_parsecodes[0])));
+                      array_size(dynamic_list_keyword_parsecodes));
 
 
 
@@ -3262,7 +3259,7 @@ script_add_phdr(void* closurev, const char* name, size_t namelen,
 
 #define PHDR_TYPE(NAME) { #NAME, sizeof(#NAME) - 1, elfcpp::NAME }
 
-static struct
+static struct phdr_type_name
 {
   const char* name;
   size_t namelen;
@@ -3285,9 +3282,7 @@ static struct
 extern "C" unsigned int
 script_phdr_string_to_type(void* closurev, const char* name, size_t namelen)
 {
-  for (unsigned int i = 0;
-       i < sizeof(phdr_type_names) / sizeof(phdr_type_names[0]);
-       ++i)
+  for (unsigned int i = 0; i < array_size(phdr_type_names); ++i)
     if (namelen == phdr_type_names[i].namelen
 	&& strncmp(name, phdr_type_names[i].name, namelen) == 0)
       return phdr_type_names[i].val;
-- 
2.5.5



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