2012-04-23 Cary Coutant elfcpp/ * elfcpp_swap.h (struct Swap_aligned32): New template. gold/ * gdb-index.cc (Gdb_index::do_write): Use Swap_aligned32 for writing CU range table of gdb index. commit 20f450f1aa8b7bcceaff1c2475ee993e9fd21fd2 Author: Cary Coutant Date: Mon Apr 23 15:31:45 2012 -0700 Add Swap_aligned32 template for writing gdb index. diff --git a/elfcpp/elfcpp_swap.h b/elfcpp/elfcpp_swap.h index 0685276..2e2ef7c 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 . // 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 +struct Swap_aligned32 +{ + typedef typename Valtype_base::Valtype Valtype; + + static inline Valtype + readval(const unsigned char* wv) + { return Swap::readval( + reinterpret_cast(wv)); } + + static inline void + writeval(unsigned char* wv, Valtype v) + { Swap::writeval(reinterpret_cast(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(Swap<32, true>::readval(wv)) << 32) + | static_cast(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(v >> 32)); + Swap<32, true>::writeval(wv+4, static_cast(v)); + } +}; + +template<> +struct Swap_aligned32<64, false> +{ + typedef Valtype_base<64>::Valtype Valtype; + + static inline Valtype + readval(const unsigned char* wv) + { + return ((static_cast(Swap<32, false>::readval(wv+4)) << 32) + | static_cast(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(v >> 32)); + Swap<32, false>::writeval(wv, static_cast(v)); + } +}; + } // End namespace elfcpp. #endif // !defined(ELFCPP_SWAP_H) diff --git a/gold/gdb-index.cc b/gold/gdb-index.cc index 07ba2ab..a6db505 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; }