15d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
25d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*--------------------------------------------------------------------*/
35d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*--- An abstraction that provides a file-reading mechanism.       ---*/
45d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*---                                                 priv_image.h ---*/
55d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*--------------------------------------------------------------------*/
65d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
75d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*
85d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   This file is part of Valgrind, a dynamic binary instrumentation
95d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   framework.
105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   Copyright (C) 2013-2013 Mozilla Foundation
125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   This program is free software; you can redistribute it and/or
145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   modify it under the terms of the GNU General Public License as
155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   published by the Free Software Foundation; either version 2 of the
165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   License, or (at your option) any later version.
175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   This program is distributed in the hope that it will be useful, but
195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   General Public License for more details.
225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   You should have received a copy of the GNU General Public License
245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   along with this program; if not, write to the Free Software
255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   02111-1307, USA.
275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   The GNU General Public License is contained in the file COPYING.
295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj*/
305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Contributed by Julian Seward <jseward@acm.org> */
325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
33535fb1b49a80f2e880f755ee618381de3e222ddfflorian#ifndef __PRIV_IMAGE_H
34535fb1b49a80f2e880f755ee618381de3e222ddfflorian#define __PRIV_IMAGE_H
35535fb1b49a80f2e880f755ee618381de3e222ddfflorian
36535fb1b49a80f2e880f755ee618381de3e222ddfflorian#include "pub_core_basics.h"    // ULong
37535fb1b49a80f2e880f755ee618381de3e222ddfflorian#include "priv_misc.h"          // ML_(dinfo_zalloc)
385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*------------------------------------------------------------*/
405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*--- DiImage -- abstract images                           ---*/
415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*------------------------------------------------------------*/
425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* The basic type, containing an abstractified memory area that can be
445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   read from.  This is an abstract type since there can be more than
455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   one implementation of it. */
465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* abstract */
485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjtypedef  struct _DiImage  DiImage;
495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
505d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* an offset in the image */
515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjtypedef  ULong  DiOffT;
525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* This denotes an invalid DiOffT value.  Except where otherwise
545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   noted, you must never pass this to any of the ML_(image_*)
555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   functions -- they will assert.  That does mean though that they can
565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   be used for signalling other conditions, for example that some
575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   expected part of the image is missing. */
585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj#define DiOffT_INVALID ((DiOffT)(0xFFFFFFFFFFFFFFFFULL))
595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Create an image from a file in the local filesysem.  Returns NULL
615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if it fails, for whatever reason. */
625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjDiImage* ML_(img_from_local_file)(const HChar* fullpath);
635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Create an image by connecting to a Valgrind debuginfo server
655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   (auxprogs/valgrind-di-server.c).  |filename| contains the object
665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   name to ask for; it must be a plain filename, not absolute, not a
675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   path.  |serverAddr| must be of the form either "d.d.d.d" or
685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   "d.d.d.d:d" where d is one or more digits.  These specify the IPv4
695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   address and (in the second case) port number for the server.  In
705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   the first case, port 1500 is assumed. */
715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjDiImage* ML_(img_from_di_server)(const HChar* filename,
725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                 const HChar* serverAddr);
735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Destroy an existing image. */
755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjvoid ML_(img_done)(DiImage*);
765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* How big is the image? */
78518850bf0da07ed3e2244e307268ae0fd80e93a8florianDiOffT ML_(img_size)(const DiImage* img);
795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Does the section [offset, +size) exist in the image? */
81518850bf0da07ed3e2244e307268ae0fd80e93a8florianBool ML_(img_valid)(const DiImage* img, DiOffT offset, SizeT size);
825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Get info out of an image.  If any part of the section denoted by
845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   [offset, +size) is invalid, does not return. */
855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjvoid ML_(img_get)(/*OUT*/void* dst,
865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  DiImage* img, DiOffT offset, SizeT size);
875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* A version of ML_(img_get) that is significantly cheaper when
895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   fetching a lot of data, at the cost of being more difficult to use.
905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   Fetches between 1 and |size| bytes from |img| at |offset| and
915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   places them in |dst|.  |size| must be at least 1.  The number of
925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   bytes read is returned, and the caller must be able to deal with
935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   any number between 1 and |size|.  |offset| must be a valid offset
945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   in the image; if not the function will not return.  This function
955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   will not read off the end of the image. */
965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjSizeT ML_(img_get_some)(/*OUT*/void* dst,
975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                        DiImage* img, DiOffT offset, SizeT size);
985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Copy a C string out of the image, into ML_(dinfo_zalloc)'d space.
1005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   The caller owns the string and must free it with ML_(dinfo_free).
1015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   |offset| may be DiOffT_INVALID, in which case this returns NULL. */
1025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjHChar* ML_(img_strdup)(DiImage* img, const HChar* cc, DiOffT offset);
1035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Do strcmp on two C strings in the image.  Chars are cast to HChar
1055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   before comparison. */
1065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjInt ML_(img_strcmp)(DiImage* img, DiOffT off1, DiOffT off2);
1075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Do strcmp of a C string in the image vs a normal one.  Chars are
1095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   cast to HChar before comparison. */
1105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjInt ML_(img_strcmp_c)(DiImage* img, DiOffT off1, const HChar* str2);
1115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Do strlen of a C string in the image. */
1135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjSizeT ML_(img_strlen)(DiImage* img, DiOffT off);
1145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Fetch various sized primitive types from the image.  These operate
1165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   at the endianness and word size of the host. */
1175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjUChar  ML_(img_get_UChar) (DiImage* img, DiOffT offset);
1185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjUShort ML_(img_get_UShort)(DiImage* img, DiOffT offset);
1195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjUInt   ML_(img_get_UInt)  (DiImage* img, DiOffT offset);
1205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjULong  ML_(img_get_ULong) (DiImage* img, DiOffT offset);
1215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Calculate the "GNU Debuglink CRC" for the image.  This
1235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   unfortunately has to be done as part of the DiImage implementation
1245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   because it involves reading the entire image, and is therefore
1255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   something that needs to be handed off to the remote server -- since
1265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   to do it otherwise would imply pulling the entire image across the
1275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   connection, making the client/server split pointless. */
1285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjUInt ML_(img_calc_gnu_debuglink_crc32)(DiImage* img);
1295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*------------------------------------------------------------*/
1325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*--- DiCursor -- cursors for reading images               ---*/
1335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*------------------------------------------------------------*/
1345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* A type built on DiImage.  It contains a DiImage and a 'current
1365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   offset' in the image, and is useful for building low level readers
1375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   of images.  In the functions section below, "read" means "read data
1385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   at the cursor without moving it along", and "step" means "read data
1395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   at the cursor and move it along by the size of the item read". */
1405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjtypedef
1415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   struct { DiImage* img; DiOffT ioff; }
1425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor;
1435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* An invalid cursor.  You can't use it for anything. */
1455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj#define DiCursor_INVALID ((DiCursor){NULL,DiOffT_INVALID})
1465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline DiCursor mk_DiCursor ( DiImage* img, DiOffT ioff ) {
1485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return (DiCursor){img, ioff};
1495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
1505d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline Bool ML_(cur_is_valid)(DiCursor c) {
1525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return c.img != NULL;
1535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
1545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*------------------------------------------------------------*/
1575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*--- DiSlice -- subranges within DiImages                 ---*/
1585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*------------------------------------------------------------*/
1595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Another type built on top of DiImage.  It denotes a subrange of an
1615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   image and is useful for representing (eg) exactly the part of an
1625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   image that is a specific ELF section. */
1635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjtypedef
1645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   struct { DiImage* img; DiOffT ioff; DiOffT szB; }
1655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice;
1665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* A DiSlice can also be INVALID, meaning it does not refer to any
1685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   part of any image. */
1695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj#define DiSlice_INVALID ((DiSlice){NULL,DiOffT_INVALID,0})
1705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline DiSlice mk_DiSlice ( DiImage* img, DiOffT ioff, DiOffT szB ) {
1725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return (DiSlice){img, ioff, szB};
1735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
1745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline Bool ML_(sli_is_valid)( DiSlice sli ) {
1765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return sli.img != NULL;
1775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
1785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Create a slice from a combination of a cursor and a length.  The
1805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   maximum implied offset must not exceed the size of the underlying
1815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   image; this is asserted for. */
1825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline DiSlice ML_(sli_from_cur)( DiCursor cur, DiOffT size ) {
1835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (ML_(cur_is_valid)(cur)) {
1845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      vg_assert(size != DiOffT_INVALID);
1855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      vg_assert(cur.ioff + size <= ML_(img_size)(cur.img));
1865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return mk_DiSlice(cur.img, cur.ioff, size);
1875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   } else {
1885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return DiSlice_INVALID;
1895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   }
1905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
1915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Create a slice which exactly covers the given image. */
1935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline DiSlice ML_(sli_from_img)( DiImage* img ) {
1945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (img) {
1955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return mk_DiSlice(img, 0, ML_(img_size)(img));
1965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   } else {
1975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return DiSlice_INVALID;
1985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   }
1995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*------------------------------------------------------------*/
2035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*--- Functions that operate on DiCursors                  ---*/
2045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*------------------------------------------------------------*/
2055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Create a cursor from a slice, referring to the first byte of the
2075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   slice. */
2085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline DiCursor ML_(cur_from_sli)( DiSlice sl ) {
2095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (ML_(sli_is_valid)(sl)) {
2105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiCursor c;
2115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      c.img  = sl.img;
2125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      c.ioff = sl.ioff;
2135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return c;
2145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   } else {
2155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return DiCursor_INVALID;
2165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   }
2175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline Bool ML_(cur_cmpLT)( DiCursor c1, DiCursor c2 ) {
2205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   vg_assert(c1.img == c2.img);
2215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return c1.ioff < c2.ioff;
2225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline Bool ML_(cur_cmpEQ)( DiCursor c1, DiCursor c2 ) {
2245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   vg_assert(c1.img == c2.img);
2255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return c1.ioff == c2.ioff;
2265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline Bool ML_(cur_cmpGT)( DiCursor c1, DiCursor c2 ) {
2285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   vg_assert(c1.img == c2.img);
2295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return c1.ioff > c2.ioff;
2305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline DiCursor ML_(cur_plus)( DiCursor c, Long n ) {
2335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c.ioff += (DiOffT)n;
2345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return c;
2355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Asserts that c1 and c2 refer to the same image.  Returns the difference
2385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   in offsets (c1.ioff - c2.ioff). */
2395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline Long ML_(cur_minus)( DiCursor c1, DiCursor c2 ) {
2405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   vg_assert(c1.img == c2.img);
2415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return (Long)(c1.ioff) - (Long)(c2.ioff);
2425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline SizeT ML_(cur_strlen)( DiCursor c ) {
2455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return ML_(img_strlen)( c.img, c.ioff );
2465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// strdup from the given cursor.  Caller must ML_(dinfo_free) the
2495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// resulting string.
2505d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline HChar* ML_(cur_read_strdup)( DiCursor c, const HChar* cc ) {
2515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   vg_assert(c.ioff != DiOffT_INVALID);
2525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   HChar* res = ML_(img_strdup)(c.img, cc, c.ioff);
2535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return res;
2545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// strdup from the given cursor and advance it.  Caller must
2565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// ML_(dinfo_free) the resulting string.
2575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline HChar* ML_(cur_step_strdup)( DiCursor* c, const HChar* cc ) {
2585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   vg_assert(c->ioff != DiOffT_INVALID);
2595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   HChar* res = ML_(img_strdup)(c->img, cc, c->ioff);
2605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->ioff += VG_(strlen)(res) + 1;
2615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return res;
2625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// Fetch an arbitrary number of bytes from the cursor.
2655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline void ML_(cur_read_get) ( /*OUT*/void* dst,
2665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       DiCursor c, SizeT size) {
2675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ML_(img_get)(dst, c.img, c.ioff, size);
2685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// Fetch an arbitrary number of bytes from the cursor, and advance it.
2715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline void ML_(cur_step_get) ( /*OUT*/void* dst,
2725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       DiCursor* c, SizeT size) {
2735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ML_(img_get)(dst, c->img, c->ioff, size);
2745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->ioff += size;
2755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// memdup from the given cursor.  Caller must ML_(dinfo_free) the
2785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// resulting block.
2795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline UChar* ML_(cur_read_memdup)( DiCursor c, SizeT size,
2805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                           const HChar* cc )
2815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj{
2825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar* dst = ML_(dinfo_zalloc)(cc, size);
2835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (size > 0)
2845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      ML_(cur_read_get)(dst, c, size);
2855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return dst;
2865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline UChar ML_(cur_read_UChar) ( DiCursor c ) {
2895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar r = ML_(img_get_UChar)( c.img, c.ioff );
2905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return r;
2915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline UChar ML_(cur_step_UChar)( DiCursor* c ) {
2935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar r = ML_(img_get_UChar)( c->img, c->ioff );
2945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->ioff += sizeof(UChar);
2955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return r;
2965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline UShort ML_(cur_read_UShort) ( DiCursor c ) {
2995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UShort r = ML_(img_get_UShort)( c.img, c.ioff );
3005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return r;
3015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
3025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline UShort ML_(cur_step_UShort) ( DiCursor* c ) {
3035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UShort r = ML_(img_get_UShort)( c->img, c->ioff );
3045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->ioff += sizeof(UShort);
3055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return r;
3065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
3075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline Short ML_(cur_step_Short) ( DiCursor* c ) {
3085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return (Short)ML_(cur_step_UShort)( c );
3095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
3105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
3115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline UInt ML_(cur_read_UInt) ( DiCursor c ) {
3125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UInt r = ML_(img_get_UInt)( c.img, c.ioff );
3135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return r;
3145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
3155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline UInt ML_(cur_step_UInt) ( DiCursor* c ) {
3165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UInt r = ML_(img_get_UInt)( c->img, c->ioff );
3175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->ioff += sizeof(UInt);
3185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return r;
3195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
3205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline Int ML_(cur_step_Int) ( DiCursor* c ) {
3215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return (Int)ML_(cur_step_UInt)( c );
3225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
3235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
3245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline ULong ML_(cur_read_ULong) ( DiCursor c ) {
3255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ULong r = ML_(img_get_ULong)( c.img, c.ioff );
3265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return r;
3275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
3285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline ULong ML_(cur_step_ULong) ( DiCursor* c ) {
3295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ULong r = ML_(img_get_ULong)( c->img, c->ioff );
3305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->ioff += sizeof(ULong);
3315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return r;
3325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
3335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline Long ML_(cur_step_Long) ( DiCursor* c ) {
3345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return (Long)ML_(cur_step_ULong)( c );
3355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
3365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
3375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline Addr ML_(cur_step_Addr) ( DiCursor* c ) {
3385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (sizeof(Addr) == sizeof(UInt)) {
3395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return ML_(cur_step_UInt)(c);
3405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   } else if  (sizeof(Addr) == sizeof(ULong)) {
3415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return ML_(cur_step_ULong)(c);
3425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   } else {
3435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      vg_assert(0);
3445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   }
3455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
3465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
347535fb1b49a80f2e880f755ee618381de3e222ddfflorian#endif /* ndef __PRIV_IMAGE_H */
3485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
3495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*--------------------------------------------------------------------*/
3505d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*--- end                                             priv_image.h ---*/
3515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/*--------------------------------------------------------------------*/
352