1
2/*--------------------------------------------------------------------*/
3/*--- Misc simple stuff lacking a better home.              misc.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2008-2013 OpenWorks LLP
11      info@open-works.co.uk
12
13   This program is free software; you can redistribute it and/or
14   modify it under the terms of the GNU General Public License as
15   published by the Free Software Foundation; either version 2 of the
16   License, or (at your option) any later version.
17
18   This program is distributed in the hope that it will be useful, but
19   WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21   General Public License for more details.
22
23   You should have received a copy of the GNU General Public License
24   along with this program; if not, write to the Free Software
25   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26   02111-1307, USA.
27
28   The GNU General Public License is contained in the file COPYING.
29
30   Neither the names of the U.S. Department of Energy nor the
31   University of California nor the names of its contributors may be
32   used to endorse or promote products derived from this software
33   without prior written permission.
34*/
35
36#include "pub_core_basics.h"
37#include "pub_core_libcbase.h"
38#include "pub_core_libcassert.h"
39#include "pub_core_mallocfree.h"
40#include "pub_core_xarray.h"
41
42#include "priv_misc.h"            /* self */
43
44
45void* ML_(dinfo_zalloc) ( const HChar* cc, SizeT szB ) {
46   void* v;
47   vg_assert(szB > 0);
48   v = VG_(arena_malloc)( VG_AR_DINFO, cc, szB );
49   vg_assert(v);
50   VG_(memset)(v, 0, szB);
51   return v;
52}
53
54void ML_(dinfo_free) ( void* v ) {
55   VG_(arena_free)( VG_AR_DINFO, v );
56}
57
58HChar* ML_(dinfo_strdup) ( const HChar* cc, const HChar* str ) {
59   return VG_(arena_strdup)( VG_AR_DINFO, cc, str );
60}
61
62void* ML_(dinfo_memdup) ( const HChar* cc, void* str, SizeT nStr ) {
63   void* dst = VG_(arena_malloc)( VG_AR_DINFO, cc, nStr );
64   tl_assert(dst);
65   VG_(memcpy)(dst, str, nStr);
66   return dst;
67}
68
69static inline Bool host_is_little_endian ( void ) {
70   UInt x = 0x76543210;
71   UChar* p = (UChar*)(&x);
72   return toBool(*p == 0x10);
73}
74
75Short ML_(read_Short)( UChar* data ) {
76   Short r = 0;
77   if (host_is_little_endian()) {
78      r = data[0]
79          | ( ((UInt)data[1]) << 8 );
80   } else {
81      r = data[1]
82          | ( ((UInt)data[0]) << 8 );
83   }
84   return r;
85}
86
87Int ML_(read_Int) ( UChar* data ) {
88   Int r = 0;
89   if (host_is_little_endian()) {
90      r = data[0]
91          | ( ((UInt)data[1]) << 8 )
92          | ( ((UInt)data[2]) << 16 )
93          | ( ((UInt)data[3]) << 24 );
94   } else {
95      r = data[3]
96          | ( ((UInt)data[2]) << 8 )
97          | ( ((UInt)data[1]) << 16 )
98          | ( ((UInt)data[0]) << 24 );
99   }
100   return r;
101}
102
103Long ML_(read_Long) ( UChar* data ) {
104   Long r = 0;
105   if (host_is_little_endian()) {
106      r = data[0]
107          | ( ((ULong)data[1]) << 8 )
108          | ( ((ULong)data[2]) << 16 )
109          | ( ((ULong)data[3]) << 24 )
110          | ( ((ULong)data[4]) << 32 )
111          | ( ((ULong)data[5]) << 40 )
112          | ( ((ULong)data[6]) << 48 )
113          | ( ((ULong)data[7]) << 56 );
114   } else {
115      r = data[7]
116          | ( ((ULong)data[6]) << 8 )
117          | ( ((ULong)data[5]) << 16 )
118          | ( ((ULong)data[4]) << 24 )
119          | ( ((ULong)data[3]) << 32 )
120          | ( ((ULong)data[2]) << 40 )
121          | ( ((ULong)data[1]) << 48 )
122          | ( ((ULong)data[0]) << 56 );
123   }
124   return r;
125}
126
127UShort ML_(read_UShort) ( UChar* data ) {
128   UInt r = 0;
129   if (host_is_little_endian()) {
130      r = data[0]
131          | ( ((UInt)data[1]) << 8 );
132   } else {
133      r = data[1]
134          | ( ((UInt)data[0]) << 8 );
135   }
136   return r;
137}
138
139UChar *ML_(write_UShort) ( UChar* ptr, UShort val ) {
140   if (host_is_little_endian()) {
141      ptr[0] = val & 0xff;
142      ptr[1] = ( val >> 8 ) & 0xff;
143   } else {
144      ptr[0] = ( val >> 8 ) & 0xff;
145      ptr[1] = val & 0xff;
146   }
147   return ptr + sizeof(UShort);
148}
149
150UWord ML_(read_UWord) ( UChar* data ) {
151   if (sizeof(UWord) == sizeof(UInt)) {
152      return ML_(read_UInt)(data);
153   } else if  (sizeof(UWord) == sizeof(ULong)) {
154      return ML_(read_ULong)(data);
155   } else {
156      vg_assert(0);
157   }
158}
159
160UInt ML_(read_UInt) ( UChar* data ) {
161   UInt r = 0;
162   if (host_is_little_endian()) {
163      r = data[0]
164          | ( ((UInt)data[1]) << 8 )
165          | ( ((UInt)data[2]) << 16 )
166          | ( ((UInt)data[3]) << 24 );
167   } else {
168      r = data[3]
169          | ( ((UInt)data[2]) << 8 )
170          | ( ((UInt)data[1]) << 16 )
171          | ( ((UInt)data[0]) << 24 );
172   }
173   return r;
174}
175
176UChar* ML_(write_UInt) ( UChar* ptr, UInt val ) {
177   if (host_is_little_endian()) {
178      ptr[0] = val & 0xff;
179      ptr[1] = ( val >> 8 ) & 0xff;
180      ptr[2] = ( val >> 16 ) & 0xff;
181      ptr[3] = ( val >> 24 ) & 0xff;
182   } else {
183      ptr[0] = ( val >> 24 ) & 0xff;
184      ptr[1] = ( val >> 16 ) & 0xff;
185      ptr[2] = ( val >> 8 ) & 0xff;
186      ptr[3] = val & 0xff;
187   }
188   return ptr + sizeof(UInt);
189}
190
191ULong ML_(read_ULong) ( UChar* data ) {
192   ULong r = 0;
193   if (host_is_little_endian()) {
194      r = data[0]
195       | ( ((ULong)data[1]) << 8 )
196       | ( ((ULong)data[2]) << 16 )
197       | ( ((ULong)data[3]) << 24 )
198       | ( ((ULong)data[4]) << 32 )
199       | ( ((ULong)data[5]) << 40 )
200       | ( ((ULong)data[6]) << 48 )
201       | ( ((ULong)data[7]) << 56 );
202   } else {
203      r = data[7]
204       | ( ((ULong)data[6]) << 8 )
205       | ( ((ULong)data[5]) << 16 )
206       | ( ((ULong)data[4]) << 24 )
207       | ( ((ULong)data[3]) << 32 )
208       | ( ((ULong)data[2]) << 40 )
209       | ( ((ULong)data[1]) << 48 )
210       | ( ((ULong)data[0]) << 56 );
211   }
212   return r;
213}
214
215UChar* ML_(write_ULong) ( UChar* ptr, ULong val ) {
216   if (host_is_little_endian()) {
217      ptr[0] = val & 0xff;
218      ptr[1] = ( val >> 8 ) & 0xff;
219      ptr[2] = ( val >> 16 ) & 0xff;
220      ptr[3] = ( val >> 24 ) & 0xff;
221      ptr[4] = ( val >> 32 ) & 0xff;
222      ptr[5] = ( val >> 40 ) & 0xff;
223      ptr[6] = ( val >> 48 ) & 0xff;
224      ptr[7] = ( val >> 56 ) & 0xff;
225   } else {
226      ptr[0] = ( val >> 56 ) & 0xff;
227      ptr[1] = ( val >> 48 ) & 0xff;
228      ptr[2] = ( val >> 40 ) & 0xff;
229      ptr[3] = ( val >> 32 ) & 0xff;
230      ptr[4] = ( val >> 24 ) & 0xff;
231      ptr[5] = ( val >> 16 ) & 0xff;
232      ptr[6] = ( val >> 8 ) & 0xff;
233      ptr[7] = val & 0xff;
234   }
235   return ptr + sizeof(ULong);
236}
237
238UChar ML_(read_UChar) ( UChar* data ) {
239   return data[0];
240}
241
242UChar* ML_(write_UChar) ( UChar* ptr, UChar val ) {
243   ptr[0] = val;
244   return ptr + sizeof(UChar);
245}
246
247Addr ML_(read_Addr) ( UChar* data ) {
248   if (sizeof(Addr) == sizeof(UInt)) {
249      return ML_(read_UInt)(data);
250   } else if  (sizeof(Addr) == sizeof(ULong)) {
251      return ML_(read_ULong)(data);
252   } else {
253      vg_assert(0);
254   }
255}
256
257UChar* ML_(write_Addr) ( UChar* ptr, Addr val ) {
258   if (sizeof(Addr) == sizeof(UInt)) {
259      return ML_(write_UInt)(ptr, val);
260   } else if  (sizeof(Addr) == sizeof(ULong)) {
261      return ML_(write_ULong)(ptr, val);
262   } else {
263      vg_assert(0);
264   }
265}
266
267
268/*--------------------------------------------------------------------*/
269/*--- end                                                   misc.c ---*/
270/*--------------------------------------------------------------------*/
271