summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--elfcpp/ChangeLog4
-rw-r--r--elfcpp/elfcpp_swap.h67
-rw-r--r--gold/ChangeLog5
-rw-r--r--gold/gdb-index.cc5
4 files changed, 78 insertions, 3 deletions
diff --git a/elfcpp/ChangeLog b/elfcpp/ChangeLog
index 25502dfb3b..6e31367a99 100644
--- a/elfcpp/ChangeLog
+++ b/elfcpp/ChangeLog
@@ -1,3 +1,7 @@
+2012-04-23 Cary Coutant <ccoutant@google.com>
+
+ * elfcpp_swap.h (struct Swap_aligned32): New template.
+
2012-04-16 David S. Miller <davem@davemloft.net>
* sparc.h (R_SPARC_JMP_IREL): New relocation.
diff --git a/elfcpp/elfcpp_swap.h b/elfcpp/elfcpp_swap.h
index 0685276158..833da5da5f 100644
--- a/elfcpp/elfcpp_swap.h
+++ b/elfcpp/elfcpp_swap.h
@@ -1,6 +1,6 @@
// elfcpp_swap.h -- Handle swapping for elfcpp -*- C++ -*-
-// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2012 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of elfcpp.
@@ -430,6 +430,71 @@ struct Swap_unaligned<64, true>
}
};
+// Swap_aligned32 is a template based on size and on whether the
+// target is big endian. It defines the type Valtype and the
+// functions readval and writeval. The functions read and write
+// values of the appropriate size out of buffers which may not be
+// 64-bit aligned, but are 32-bit aligned.
+
+template<int size, bool big_endian>
+struct Swap_aligned32
+{
+ typedef typename Valtype_base<size>::Valtype Valtype;
+
+ static inline Valtype
+ readval(const unsigned char* wv)
+ { return Swap<size, big_endian>::readval(
+ reinterpret_cast<const Valtype*>(wv)); }
+
+ static inline void
+ writeval(unsigned char* wv, Valtype v)
+ { Swap<size, big_endian>::writeval(reinterpret_cast<Valtype*>(wv), v); }
+};
+
+template<>
+struct Swap_aligned32<64, true>
+{
+ typedef Valtype_base<64>::Valtype Valtype;
+
+ static inline Valtype
+ readval(const unsigned char* wv)
+ {
+ return ((static_cast<Valtype>(Swap<32, true>::readval(wv)) << 32)
+ | static_cast<Valtype>(Swap<32, true>::readval(wv + 4)));
+ }
+
+ static inline void
+ writeval(unsigned char* wv, Valtype v)
+ {
+ typedef Valtype_base<32>::Valtype Valtype32;
+
+ Swap<32, true>::writeval(wv, static_cast<Valtype32>(v >> 32));
+ Swap<32, true>::writeval(wv + 4, static_cast<Valtype32>(v));
+ }
+};
+
+template<>
+struct Swap_aligned32<64, false>
+{
+ typedef Valtype_base<64>::Valtype Valtype;
+
+ static inline Valtype
+ readval(const unsigned char* wv)
+ {
+ return ((static_cast<Valtype>(Swap<32, false>::readval(wv + 4)) << 32)
+ | static_cast<Valtype>(Swap<32, false>::readval(wv)));
+ }
+
+ static inline void
+ writeval(unsigned char* wv, Valtype v)
+ {
+ typedef Valtype_base<32>::Valtype Valtype32;
+
+ Swap<32, false>::writeval(wv + 4, static_cast<Valtype32>(v >> 32));
+ Swap<32, false>::writeval(wv, static_cast<Valtype32>(v));
+ }
+};
+
} // End namespace elfcpp.
#endif // !defined(ELFCPP_SWAP_H)
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 7706aa4e30..b3e6f7ca2b 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,8 @@
+2012-04-23 Cary Coutant <ccoutant@google.com>
+
+ * gdb-index.cc (Gdb_index::do_write): Use Swap_aligned32 for writing
+ CU range table of gdb index.
+
2012-04-20 David S. Miller <davem@davemloft.net>
* target.cc (Sized_target::do_adjust_elf_header): Use big_endian
diff --git a/gold/gdb-index.cc b/gold/gdb-index.cc
index 07ba2ab542..a6db505fa8 100644
--- a/gold/gdb-index.cc
+++ b/gold/gdb-index.cc
@@ -1166,8 +1166,9 @@ Gdb_index::do_write(Output_file* of)
base = (os->address()
+ object->output_section_offset(range.shndx));
}
- elfcpp::Swap_unaligned<64, false>::writeval(pov, base + range.start);
- elfcpp::Swap_unaligned<64, false>::writeval(pov + 8, base + range.end);
+ elfcpp::Swap_aligned32<64, false>::writeval(pov, base + range.start);
+ elfcpp::Swap_aligned32<64, false>::writeval(pov + 8,
+ base + range.end);
elfcpp::Swap<32, false>::writeval(pov + 16, cu_index);
pov += 20;
}