Home | History | Annotate | Download | only in m_debuginfo
      1 /* -*- mode: C; c-basic-offset: 3; -*- */
      2 
      3 /*--------------------------------------------------------------------*/
      4 /*--- An abstraction that provides a file-reading mechanism.       ---*/
      5 /*---                                                      image.c ---*/
      6 /*--------------------------------------------------------------------*/
      7 
      8 /*
      9    This file is part of Valgrind, a dynamic binary instrumentation
     10    framework.
     11 
     12    Copyright (C) 2013-2017 Mozilla Foundation
     13 
     14    This program is free software; you can redistribute it and/or
     15    modify it under the terms of the GNU General Public License as
     16    published by the Free Software Foundation; either version 2 of the
     17    License, or (at your option) any later version.
     18 
     19    This program is distributed in the hope that it will be useful, but
     20    WITHOUT ANY WARRANTY; without even the implied warranty of
     21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     22    General Public License for more details.
     23 
     24    You should have received a copy of the GNU General Public License
     25    along with this program; if not, write to the Free Software
     26    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     27    02111-1307, USA.
     28 
     29    The GNU General Public License is contained in the file COPYING.
     30 */
     31 
     32 /* Contributed by Julian Seward <jseward (at) acm.org> */
     33 
     34 /* See the corresponding auxprogs/valgrind-di-server.c for a list of
     35    cleanups for this file and itself. */
     36 
     37 #include "pub_core_basics.h"
     38 #include "pub_core_vki.h"
     39 #include "pub_core_libcbase.h"
     40 #include "pub_core_libcassert.h"
     41 #include "pub_core_libcprint.h"
     42 #include "pub_core_libcproc.h"     /* VG_(read_millisecond_timer) */
     43 #include "pub_core_libcfile.h"
     44 #include "priv_misc.h"             /* dinfo_zalloc/free/strdup */
     45 #include "priv_image.h"            /* self */
     46 
     47 #include "minilzo.h"
     48 #define TINFL_HEADER_FILE_ONLY
     49 #include "tinfl.c"
     50 
     51 /* These values (1024 entries of 8192 bytes each) gives a cache
     52    size of 8MB. */
     53 #define CACHE_ENTRY_SIZE_BITS (12+1)
     54 #define CACHE_N_ENTRIES       1024
     55 
     56 #define CACHE_ENTRY_SIZE      (1 << CACHE_ENTRY_SIZE_BITS)
     57 
     58 #define COMPRESSED_SLICE_ARRAY_GROW_SIZE 64
     59 
     60 /* An entry in the cache. */
     61 typedef
     62    struct {
     63       Bool   fromC;  // True === contains decompressed data
     64       DiOffT off;    // file offset for data[0]
     65       SizeT  size;   // sizeof(data)
     66       SizeT  used;   // 1 .. sizeof(data), or 0 to denote not-in-use
     67       UChar  data[];
     68    }
     69    CEnt;
     70 
     71 /* Compressed slice */
     72 typedef
     73    struct {
     74       DiOffT offD;  // offset of decompressed data
     75       SizeT  szD;   // size of decompressed data
     76       DiOffT offC;  // offset of compressed data
     77       SizeT  szC;   // size of compressed data
     78    }
     79    CSlc;
     80 
     81 /* Source for files */
     82 typedef
     83    struct {
     84       // True: img is of local file.  False: img is from a server.
     85       Bool  is_local;
     86       // The fd for the local file, or sd for a remote server.
     87       Int   fd;
     88       // The name.  In ML_(dinfo_zalloc)'d space.  Used only for printing
     89       // error messages; hence it doesn't really matter what this contains.
     90       HChar* name;
     91       // The rest of these fields are only valid when using remote files
     92       // (that is, using a debuginfo server; hence when is_local==False)
     93       // Session ID allocated to us by the server.  Cannot be zero.
     94       ULong session_id;
     95    }
     96    Source;
     97 
     98 struct _DiImage {
     99    // The source -- how to get hold of the file we are reading
    100    Source source;
    101    // Virtual size of the image = real size + size of uncompressed data
    102    SizeT size;
    103    // Real size of image
    104    SizeT real_size;
    105    // The number of entries used.  0 .. CACHE_N_ENTRIES
    106    UInt  ces_used;
    107    // Pointers to the entries.  ces[0 .. ces_used-1] are non-NULL.
    108    // ces[ces_used .. CACHE_N_ENTRIES-1] are NULL.
    109    // The non-NULL entries may be arranged arbitrarily.  We expect to use
    110    // a pseudo-LRU scheme though.
    111    CEnt* ces[CACHE_N_ENTRIES];
    112 
    113    // Array of compressed slices
    114    CSlc* cslc;
    115    // Number of compressed slices used
    116    UInt  cslc_used;
    117    // Size of cslc array
    118    UInt  cslc_size;
    119 };
    120 
    121 
    122 /* Sanity check code for CEnts. */
    123 static void pp_CEnt(const HChar* msg, CEnt* ce)
    124 {
    125    VG_(printf)("%s: fromC %s, used %llu, size %llu, offset %llu\n",
    126                msg, ce->fromC ? "True" : "False",
    127                (ULong)ce->used, (ULong)ce->size, (ULong)ce->off);
    128 }
    129 
    130 static Bool is_sane_CEnt ( const HChar* who, const DiImage* img, UInt i )
    131 {
    132    vg_assert(img);
    133    vg_assert(i <= CACHE_N_ENTRIES);
    134 
    135    CEnt* ce = img->ces[i];
    136    if (!(ce->used <= ce->size)) goto fail;
    137    if (ce->fromC) {
    138       // ce->size can be anything, but ce->used must be either the
    139       // same or zero, in the case that it hasn't been set yet.
    140       // Similarly, ce->off must either be above the real_size
    141       // threshold, or zero if it hasn't been set yet.
    142       if (!(ce->off >= img->real_size || ce->off == 0)) goto fail;
    143       if (!(ce->off + ce->used <= img->size)) goto fail;
    144       if (!(ce->used == ce->size || ce->used == 0)) goto fail;
    145    } else {
    146       if (!(ce->size == CACHE_ENTRY_SIZE)) goto fail;
    147       if (!(ce->off >= 0)) goto fail;
    148       if (!(ce->off + ce->used <= img->real_size)) goto fail;
    149    }
    150    return True;
    151 
    152  fail:
    153    VG_(printf)("is_sane_CEnt[%u]: fail: %s\n", i, who);
    154    pp_CEnt("failing CEnt", ce);
    155    return False;
    156 }
    157 
    158 
    159 /* A frame.  The first 4 bytes of |data| give the kind of the frame,
    160    and the rest of it is kind-specific data. */
    161 typedef  struct { UChar* data; SizeT n_data; }  Frame;
    162 
    163 static void write_UInt_le ( /*OUT*/UChar* dst, UInt n )
    164 {
    165    Int i;
    166    for (i = 0; i <= 3; i++) {
    167       dst[i] = (UChar)(n & 0xFF);
    168       n >>= 8;
    169    }
    170 }
    171 
    172 static UInt read_UInt_le ( const UChar* src )
    173 {
    174    UInt r = 0;
    175    Int i;
    176    for (i = 3; i >= 0; i--) {
    177       r <<= 8;
    178       r += (UInt)src[i];
    179    }
    180    return r;
    181 }
    182 
    183 static void write_ULong_le ( /*OUT*/UChar* dst, ULong n )
    184 {
    185    Int i;
    186    for (i = 0; i <= 7; i++) {
    187       dst[i] = (UChar)(n & 0xFF);
    188       n >>= 8;
    189    }
    190 }
    191 
    192 static ULong read_ULong_le ( const UChar* src )
    193 {
    194    ULong r = 0;
    195    Int i;
    196    for (i = 7; i >= 0; i--) {
    197       r <<= 8;
    198       r += (ULong)src[i];
    199    }
    200    return r;
    201 }
    202 
    203 
    204 /* Set |sd| to be blocking.  Returns True on success. */
    205 static Bool set_blocking ( int sd )
    206 {
    207    Int res;
    208    res = VG_(fcntl)(sd, VKI_F_GETFL, 0/*ignored*/);
    209    if (res != -1)
    210       res = VG_(fcntl)(sd, VKI_F_SETFL, res & ~VKI_O_NONBLOCK);
    211    return (res != -1);
    212 }
    213 
    214 /* Tries to read 'len' bytes from fd, blocking if necessary.  Assumes
    215    fd has been set in blocking mode.  If it returns with the number of
    216    bytes read < len, it means that either fd was closed, or there was
    217    an error on it. */
    218 static Int my_read ( Int fd, UChar* buf, Int len )
    219 {
    220    Int nRead = 0;
    221    while (1) {
    222       if (nRead == len) return nRead;
    223       vg_assert(nRead < len);
    224       Int nNeeded = len - nRead;
    225       vg_assert(nNeeded > 0);
    226       Int n = VG_(read)(fd, &buf[nRead], nNeeded);
    227       if (n <= 0) return nRead; /* error or EOF */
    228       nRead += n;
    229    }
    230 }
    231 
    232 /* Tries to write 'len' bytes to fd, blocking if necessary.  Assumes
    233    fd has been set in blocking mode.  If it returns with the number of
    234    bytes written < len, it means that either fd was closed, or there was
    235    an error on it. */
    236 static Int my_write ( Int fd, const UChar* buf, Int len )
    237 {
    238    Int nWritten = 0;
    239    while (1) {
    240       if (nWritten == len) return nWritten;
    241       vg_assert(nWritten < len);
    242       Int nStillToDo = len - nWritten;
    243       vg_assert(nStillToDo > 0);
    244       Int n = VG_(write_socket)(fd, &buf[nWritten], nStillToDo);
    245       if (n < 0) return nWritten; /* error or EOF */
    246       nWritten += n;
    247    }
    248 }
    249 
    250 /* If we lost communication with the remote server, just give up.
    251    Recovering is too difficult. */
    252 static void give_up__comms_lost(void)
    253 {
    254    VG_(umsg)("\n");
    255    VG_(umsg)(
    256       "Valgrind: debuginfo reader: Lost communication with the remote\n");
    257    VG_(umsg)(
    258       "Valgrind: debuginfo server.  I can't recover.  Giving up.  Sorry.\n");
    259    VG_(umsg)("\n");
    260    VG_(exit)(1);
    261    /*NOTREACHED*/
    262 }
    263 
    264 static void give_up__image_overrun(void)
    265 {
    266    VG_(umsg)("\n");
    267    VG_(umsg)(
    268       "Valgrind: debuginfo reader: Possibly corrupted debuginfo file.\n");
    269    VG_(umsg)(
    270       "Valgrind: I can't recover.  Giving up.  Sorry.\n");
    271    VG_(umsg)("\n");
    272    VG_(exit)(1);
    273    /*NOTREACHED*/
    274 }
    275 
    276 /* "Do" a transaction: that is, send the given frame to the server and
    277    return the frame it sends back.  Caller owns the resulting frame
    278    and must free it.  A NULL return means the transaction failed for
    279    some reason. */
    280 static Frame* do_transaction ( Int sd, const Frame* req )
    281 {
    282    if (0) VG_(printf)("CLIENT: send %c%c%c%c\n",
    283                       req->data[0], req->data[1], req->data[2], req->data[3]);
    284 
    285    /* What goes on the wire is:
    286          adler(le32) n_data(le32) data[0 .. n_data-1]
    287       where the checksum covers n_data as well as data[].
    288    */
    289    /* The initial Adler-32 value */
    290    UInt adler = VG_(adler32)(0, NULL, 0);
    291 
    292    /* Fold in the length field, encoded as le32. */
    293    UChar wr_first8[8];
    294    write_UInt_le(&wr_first8[4], req->n_data);
    295    adler = VG_(adler32)(adler, &wr_first8[4], 4);
    296    /* Fold in the data values */
    297    adler = VG_(adler32)(adler, req->data, req->n_data);
    298    write_UInt_le(&wr_first8[0], adler);
    299 
    300    Int r = my_write(sd, &wr_first8[0], 8);
    301    if (r != 8) return NULL;
    302    vg_assert(req->n_data >= 4); // else ill formed -- no KIND field
    303    r = my_write(sd, req->data, req->n_data);
    304    if (r != req->n_data) return NULL;
    305 
    306    /* So, the request is sent.  Now get a request of the same format
    307       out of the channel. */
    308    UChar rd_first8[8];  // adler32; length32
    309    r = my_read(sd, &rd_first8[0], 8);
    310    if (r != 8) return NULL;
    311    UInt rd_adler = read_UInt_le(&rd_first8[0]);
    312    UInt rd_len   = read_UInt_le(&rd_first8[4]);
    313    /* Allocate a Frame to hold the result data, and read into it. */
    314    // Reject obviously-insane length fields.
    315    if (rd_len < 4 || rd_len > 4*1024*1024) return NULL;
    316    Frame* res = ML_(dinfo_zalloc)("di.do_transaction.1", sizeof(Frame));
    317    res->n_data = rd_len;
    318    res->data = ML_(dinfo_zalloc)("di.do_transaction.2", rd_len);
    319    r = my_read(sd, res->data, res->n_data);
    320    if (r != rd_len) return NULL;
    321 
    322    if (0) VG_(printf)("CLIENT: recv %c%c%c%c\n",
    323                       res->data[0], res->data[1], res->data[2], res->data[3]);
    324 
    325    /* Compute the checksum for the received data, and check it. */
    326    adler = VG_(adler32)(0, NULL, 0); // initial value
    327    adler = VG_(adler32)(adler, &rd_first8[4], 4);
    328    if (res->n_data > 0)
    329       adler = VG_(adler32)(adler, res->data, res->n_data);
    330 
    331    if (adler/*computed*/ != rd_adler/*expected*/) return NULL;
    332    return res;
    333 }
    334 
    335 static void free_Frame ( Frame* fr )
    336 {
    337    vg_assert(fr && fr->data);
    338    ML_(dinfo_free)(fr->data);
    339    ML_(dinfo_free)(fr);
    340 }
    341 
    342 static Frame* mk_Frame_noargs ( const HChar* tag )
    343 {
    344    vg_assert(VG_(strlen)(tag) == 4);
    345    Frame* f = ML_(dinfo_zalloc)("di.mFn.1", sizeof(Frame));
    346    f->n_data = 4;
    347    f->data = ML_(dinfo_zalloc)("di.mFn.2", f->n_data);
    348    VG_(memcpy)(&f->data[0], tag, 4);
    349    return f;
    350 }
    351 
    352 static Frame* mk_Frame_le64_le64_le64 ( const HChar* tag,
    353                                         ULong n1, ULong n2, ULong n3 )
    354 {
    355    vg_assert(VG_(strlen)(tag) == 4);
    356    Frame* f = ML_(dinfo_zalloc)("di.mFlll.1", sizeof(Frame));
    357    f->n_data = 4 + 3*8;
    358    f->data = ML_(dinfo_zalloc)("di.mFlll.2", f->n_data);
    359    VG_(memcpy)(&f->data[0], tag, 4);
    360    write_ULong_le(&f->data[4 + 0*8], n1);
    361    write_ULong_le(&f->data[4 + 1*8], n2);
    362    write_ULong_le(&f->data[4 + 2*8], n3);
    363    return f;
    364 }
    365 
    366 static Frame* mk_Frame_asciiz ( const HChar* tag, const HChar* str )
    367 {
    368    vg_assert(VG_(strlen)(tag) == 4);
    369    Frame* f = ML_(dinfo_zalloc)("di.mFa.1", sizeof(Frame));
    370    SizeT n_str = VG_(strlen)(str);
    371    f->n_data = 4 + n_str + 1;
    372    f->data = ML_(dinfo_zalloc)("di.mFa.2", f->n_data);
    373    VG_(memcpy)(&f->data[0], tag, 4);
    374    VG_(memcpy)(&f->data[4], str, n_str);
    375    vg_assert(f->data[4 + n_str] == 0);
    376    return f;
    377 }
    378 
    379 static Bool parse_Frame_le64 ( const Frame* fr, const HChar* tag,
    380                                /*OUT*/ULong* n1 )
    381 {
    382    vg_assert(VG_(strlen)(tag) == 4);
    383    if (!fr || !fr->data) return False;
    384    if (fr->n_data < 4) return False;
    385    if (VG_(memcmp)(&fr->data[0], tag, 4) != 0) return False;
    386    if (fr->n_data != 4 + 1*8) return False;
    387    *n1 = read_ULong_le(&fr->data[4 + 0*8]);
    388    return True;
    389 }
    390 
    391 static Bool parse_Frame_le64_le64 ( const Frame* fr, const HChar* tag,
    392                                     /*OUT*/ULong* n1, /*OUT*/ULong* n2 )
    393 {
    394    vg_assert(VG_(strlen)(tag) == 4);
    395    if (!fr || !fr->data) return False;
    396    if (fr->n_data < 4) return False;
    397    if (VG_(memcmp)(&fr->data[0], tag, 4) != 0) return False;
    398    if (fr->n_data != 4 + 2*8) return False;
    399    *n1 = read_ULong_le(&fr->data[4 + 0*8]);
    400    *n2 = read_ULong_le(&fr->data[4 + 1*8]);
    401    return True;
    402 }
    403 
    404 static Bool parse_Frame_asciiz ( const Frame* fr, const HChar* tag,
    405                                  /*OUT*/UChar** str )
    406 {
    407    vg_assert(VG_(strlen)(tag) == 4);
    408    if (!fr || !fr->data) return False;
    409    if (fr->n_data < 4) return False;
    410    if (VG_(memcmp)(&fr->data[0], tag, 4) != 0) return False;
    411    if (fr->n_data < 5) return False; // else there isn't even enough
    412                                      // space for the terminating zero
    413    /* Find the terminating zero and ensure it's right at the end
    414       of the data.  If not, the frame is malformed. */
    415    SizeT i = 4;
    416    while (True) {
    417       if (i >= fr->n_data) break;
    418       if (fr->data[i] == 0) break;
    419       i++;
    420    }
    421    vg_assert(i <= fr->n_data);
    422    if (i == fr->n_data-1 && fr->data[i] == 0) {
    423       *str = &fr->data[4];
    424       return True;
    425    } else {
    426       return False;
    427    }
    428 }
    429 
    430 static Bool parse_Frame_le64_le64_le64_bytes (
    431                const Frame* fr, const HChar* tag,
    432                /*OUT*/ULong* n1, /*OUT*/ULong* n2, /*OUT*/ULong* n3,
    433                /*OUT*/UChar** data, /*OUT*/ULong* n_data
    434             )
    435 {
    436    vg_assert(VG_(strlen)(tag) == 4);
    437    if (!fr || !fr->data) return False;
    438    if (fr->n_data < 4) return False;
    439    if (VG_(memcmp)(&fr->data[0], tag, 4) != 0) return False;
    440    if (fr->n_data < 4 + 3*8) return False;
    441    *n1 = read_ULong_le(&fr->data[4 + 0*8]);
    442    *n2 = read_ULong_le(&fr->data[4 + 1*8]);
    443    *n3 = read_ULong_le(&fr->data[4 + 2*8]);
    444    *data   = &fr->data[4 + 3*8];
    445    *n_data = fr->n_data - (4 + 3*8);
    446    vg_assert(fr->n_data >= 4 + 3*8);
    447    return True;
    448 }
    449 
    450 static DiOffT block_round_down ( DiOffT i )
    451 {
    452    return i & ((DiOffT)~(CACHE_ENTRY_SIZE-1));
    453 }
    454 
    455 /* Is this offset inside this CEnt? */
    456 static inline Bool is_in_CEnt ( const CEnt* cent, DiOffT off )
    457 {
    458    /* This assertion is checked by set_CEnt, so checking it here has
    459       no benefit, whereas skipping it does remove it from the hottest
    460       path. */
    461    /* vg_assert(cent->used > 0 && cent->used <= cent->size); */
    462    /* What we want to return is:
    463         cent->off <= off && off < cent->off + cent->used;
    464       This is however a very hot path, so here's alternative that uses
    465       only one conditional branch, using the following transformation,
    466       where all quantities are unsigned:
    467               x >= LO && x < LO+N
    468          -->  x-LO >= 0 && x-LO < LO+N-LO
    469          -->  x-LO >= 0 && x-LO < N
    470          -->  x-LO < N
    471       This is however only valid when the original bounds, that is, LO
    472       .. LO+N-1, do not wrap around the end of the address space.  That
    473       is, we require that LO <= LO+N-1.  But that's OK .. we don't
    474       expect wraparounds in CEnts or for that matter any object
    475       allocated from C-land.  See Hacker's Delight, Chapter 4.1,
    476       "Checking Bounds of Integers", for more details.
    477    */
    478    return off - cent->off < cent->used;
    479 }
    480 
    481 /* Returns pointer to CSlc or NULL */
    482 static inline CSlc* find_cslc ( DiImage* img, DiOffT off )
    483 {
    484    for (UInt i = 0; i < img->cslc_used; i++) {
    485       if ( (img->cslc[i].offD <= off)
    486            && (img->cslc[i].offD + img->cslc[i].szD > off)
    487          )
    488          return &img->cslc[i];
    489    }
    490    return NULL;
    491 }
    492 
    493 /* Allocate a new CEnt, connect it to |img|, and return its index. */
    494 static UInt alloc_CEnt ( DiImage* img, SizeT szB, Bool fromC )
    495 {
    496    vg_assert(img != NULL);
    497    vg_assert(img->ces_used < CACHE_N_ENTRIES);
    498    if (fromC) {
    499       // szB can be arbitrary
    500    } else {
    501       vg_assert(szB == CACHE_ENTRY_SIZE);
    502    }
    503    UInt entNo = img->ces_used;
    504    img->ces_used++;
    505    vg_assert(img->ces[entNo] == NULL);
    506    img->ces[entNo] = ML_(dinfo_zalloc)("di.alloc_CEnt.1",
    507                                        offsetof(CEnt, data) + szB);
    508    img->ces[entNo]->size = szB;
    509    img->ces[entNo]->fromC = fromC;
    510    vg_assert(is_sane_CEnt("alloc_CEnt", img, entNo));
    511    return entNo;
    512 }
    513 
    514 static void realloc_CEnt ( DiImage* img, UInt entNo, SizeT szB )
    515 {
    516    vg_assert(img != NULL);
    517    vg_assert(szB >= CACHE_ENTRY_SIZE);
    518    vg_assert(is_sane_CEnt("realloc_CEnt-pre", img, entNo));
    519    img->ces[entNo] = ML_(dinfo_realloc)("di.realloc_CEnt.1",
    520                                         img->ces[entNo],
    521                                         offsetof(CEnt, data) + szB);
    522 }
    523 
    524 /* Move the given entry to the top and slide those above it down by 1,
    525    to make space. */
    526 static void move_CEnt_to_top ( DiImage* img, UInt entNo )
    527 {
    528    vg_assert(img->ces_used <= CACHE_N_ENTRIES);
    529    vg_assert(entNo > 0 && entNo < img->ces_used);
    530    CEnt* tmp = img->ces[entNo];
    531    while (entNo > 0) {
    532       img->ces[entNo] = img->ces[entNo-1];
    533       entNo--;
    534    }
    535    img->ces[0] = tmp;
    536 }
    537 
    538 /* Set the given entry so that it has a chunk of the file containing
    539    the given offset.  It is this function that brings data into the
    540    cache, either by reading the local file or pulling it from the
    541    remote server. */
    542 static void set_CEnt ( const DiImage* img, UInt entNo, DiOffT off )
    543 {
    544    SizeT len;
    545    DiOffT off_orig = off;
    546    vg_assert(img != NULL);
    547    vg_assert(img->ces_used <= CACHE_N_ENTRIES);
    548    vg_assert(entNo >= 0 && entNo < img->ces_used);
    549    vg_assert(off < img->real_size);
    550    CEnt* ce = img->ces[entNo];
    551    vg_assert(ce != NULL);
    552    /* Compute [off, +len) as the slice we are going to read. */
    553    off = block_round_down(off);
    554    len = img->real_size - off;
    555    if (len > ce->size)
    556       len = ce->size;
    557    /* It is conceivable that the 'len > 0' bit could fail if we make
    558       an image with a zero sized file.  But then no 'get' request on
    559       that image would be valid. */
    560    vg_assert(len > 0 && len <= ce->size);
    561    vg_assert(off + len <= img->real_size);
    562    vg_assert(off <= off_orig && off_orig < off+len);
    563    /* So, read  off .. off+len-1  into the entry. */
    564 
    565    if (0) {
    566       static UInt t_last = 0;
    567       static ULong nread = 0;
    568       UInt now = VG_(read_millisecond_timer)();
    569       UInt delay = now - t_last;
    570       t_last = now;
    571       nread += len;
    572       VG_(printf)("XXXXXXXX (tot %'llu)  read %'lu  offset %'llu  delay %'u\n",
    573                   nread, len, off, delay);
    574    }
    575 
    576    if (img->source.is_local) {
    577       // Simple: just read it
    578       SysRes sr = VG_(pread)(img->source.fd, &ce->data[0], (Int)len, off);
    579       vg_assert(!sr_isError(sr));
    580    } else {
    581       // Not so simple: poke the server
    582       vg_assert(img->source.session_id > 0);
    583       Frame* req
    584          = mk_Frame_le64_le64_le64("READ", img->source.session_id, off, len);
    585       Frame* res = do_transaction(img->source.fd, req);
    586       free_Frame(req); req = NULL;
    587       if (!res) goto server_fail;
    588       ULong  rx_session_id = 0, rx_off = 0, rx_len = 0, rx_zdata_len = 0;
    589       UChar* rx_data = NULL;
    590       /* Pretty confusing.  rx_sessionid, rx_off and rx_len are copies
    591          of the values that we requested in the READ frame just above,
    592          so we can be sure that the server is responding to the right
    593          request.  It just copies them from the request into the
    594          response.  rx_data is the actual data, and rx_zdata_len is
    595          its compressed length.  Hence rx_len must equal len, but
    596          rx_zdata_len can be different -- smaller, hopefully.. */
    597       if (!parse_Frame_le64_le64_le64_bytes
    598           (res, "RDOK", &rx_session_id, &rx_off,
    599                         &rx_len, &rx_data, &rx_zdata_len))
    600          goto server_fail;
    601       if (rx_session_id != img->source.session_id
    602           || rx_off != off || rx_len != len || rx_data == NULL)
    603          goto server_fail;
    604 
    605       //VG_(memcpy)(&ce->data[0], rx_data, len);
    606       // Decompress into the destination buffer
    607       // Tell the lib the max number of output bytes it can write.
    608       // After the call, this holds the number of bytes actually written,
    609       // and it's an error if it is different.
    610       lzo_uint out_len = len;
    611       Int lzo_rc = lzo1x_decompress_safe(rx_data, rx_zdata_len,
    612                                          &ce->data[0], &out_len,
    613                                          NULL);
    614       Bool ok = lzo_rc == LZO_E_OK && out_len == len;
    615       if (!ok) goto server_fail;
    616 
    617       free_Frame(res); res = NULL;
    618       goto end_of_else_clause;
    619      server_fail:
    620       /* The server screwed up somehow.  Now what? */
    621       if (res) {
    622          UChar* reason = NULL;
    623          if (parse_Frame_asciiz(res, "FAIL", &reason)) {
    624             VG_(umsg)("set_CEnt (reading data from DI server): fail: "
    625                       "%s\n", reason);
    626          } else {
    627             VG_(umsg)("set_CEnt (reading data from DI server): fail: "
    628                       "unknown reason\n");
    629          }
    630          free_Frame(res); res = NULL;
    631       } else {
    632          VG_(umsg)("set_CEnt (reading data from DI server): fail: "
    633                    "server unexpectedly closed the connection\n");
    634       }
    635       give_up__comms_lost();
    636       /* NOTREACHED */
    637       vg_assert(0);
    638      end_of_else_clause:
    639       {}
    640    }
    641 
    642    ce->off  = off;
    643    ce->used = len;
    644    ce->fromC = False;
    645    vg_assert(ce == img->ces[entNo]);
    646    vg_assert(is_sane_CEnt("set_CEnt", img, entNo));
    647 }
    648 
    649 __attribute__((noinline))
    650 static UChar get_slowcase ( DiImage* img, DiOffT off )
    651 {
    652    /* Stay sane .. */
    653    vg_assert(off < img->size);
    654    vg_assert(img->ces_used <= CACHE_N_ENTRIES);
    655    UInt i;
    656    /* Start the search at entry 1, since the fast-case function
    657       checked slot zero already. */
    658    for (i = 1; i < img->ces_used; i++) {
    659       vg_assert(img->ces[i]);
    660       if (is_in_CEnt(img->ces[i], off))
    661          break;
    662    }
    663    vg_assert(i >= 1);
    664 
    665    if (LIKELY(i < img->ces_used)) {
    666       // Found it.  Move to the top and stop.
    667       move_CEnt_to_top(img, i);
    668       vg_assert(is_in_CEnt(img->ces[0], off));
    669       return img->ces[0]->data[ off - img->ces[0]->off ];
    670    }
    671 
    672    vg_assert(i <= img->ces_used);
    673 
    674    // It's not in any entry.  Either allocate a new one or recycle the LRU
    675    // one.  This is where the presence of compressed sections makes things
    676    // tricky.  There are 4 cases to consider:
    677    //
    678    // (1) not from a compressed slice, we can allocate a new entry
    679    // (2) not from a compressed slice, we have to recycle the LRU entry
    680    // (3) from a compressed slice, we can allocate a new entry
    681    // (4) from a compressed slice, we have to recycle the LRU entry
    682    //
    683    // Cases (3) and (4) are complex because we will have to call
    684    // ML_(img_get_some) to get the compressed data.  But this function is
    685    // reachable from ML_(img_get_some), so we may re-enter get_slowcase a
    686    // second time as a result.  Given that the compressed data will be cause
    687    // only cases (1) and (2) to happen, this guarantees no infinite recursion.
    688    // It does however mean that we can't carry (in this function invokation)
    689    // any local copies of the overall cache state across the ML_(img_get_some)
    690    // call, since it may become invalidated by the recursive call to
    691    // get_slowcase.
    692 
    693    // First of all, see if it is in a compressed slice, and if so, pull the
    694    // compressed data into an intermediate buffer.  Given the preceding
    695    // comment, this is a safe place to do it, since we are not carrying any
    696    // cache state here apart from the knowledge that the requested offset is
    697    // not in the cache at all, and the recursive call won't change that fact.
    698 
    699    CSlc* cslc = find_cslc(img, off);
    700    UChar* cbuf = NULL;
    701    if (cslc != NULL) {
    702       SizeT len = 0;
    703       cbuf = ML_(dinfo_zalloc)("di.image.get_slowcase.cbuf-1", cslc->szC);
    704       // get compressed data
    705       while (len < cslc->szC)
    706          len += ML_(img_get_some)(cbuf + len, img, cslc->offC + len,
    707                                   cslc->szC - len);
    708    }
    709 
    710    // Now we can do what we like.
    711    vg_assert((cslc == NULL && cbuf == NULL) || (cslc != NULL && cbuf != NULL));
    712 
    713    // Note, we can't capture this earlier, for exactly the reasons detailed
    714    // above.
    715    UInt ces_used_at_entry = img->ces_used;
    716 
    717    // This is the size of the CEnt that we want to have after allocation or
    718    // recycling.
    719    SizeT size = (cslc == NULL) ? CACHE_ENTRY_SIZE : cslc->szD;
    720 
    721    // Cases (1) and (3)
    722    if (img->ces_used < CACHE_N_ENTRIES) {
    723       /* Allocate a new cache entry, and fill it in. */
    724       i = alloc_CEnt(img, size, /*fromC?*/cslc != NULL);
    725       if (cslc == NULL) {
    726          set_CEnt(img, i, off);
    727          img->ces[i]->fromC = False;
    728          vg_assert(is_sane_CEnt("get_slowcase-case-1", img, i));
    729          vg_assert(img->ces_used == ces_used_at_entry + 1);
    730       } else {
    731          SizeT len = tinfl_decompress_mem_to_mem(
    732                         img->ces[i]->data, cslc->szD,
    733                         cbuf, cslc->szC,
    734                         TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
    735                         | TINFL_FLAG_PARSE_ZLIB_HEADER);
    736          vg_assert(len == cslc->szD); // sanity check on data, FIXME
    737          vg_assert(cslc->szD == size);
    738          img->ces[i]->used = cslc->szD;
    739          img->ces[i]->off = cslc->offD;
    740          img->ces[i]->fromC = True;
    741          vg_assert(is_sane_CEnt("get_slowcase-case-3", img, i));
    742          vg_assert(img->ces_used == ces_used_at_entry + 1);
    743       }
    744       vg_assert(img->ces_used == ces_used_at_entry + 1);
    745       if (i > 0) {
    746          move_CEnt_to_top(img, i);
    747          i = 0;
    748       }
    749       vg_assert(is_in_CEnt(img->ces[i], off));
    750       if (cbuf != NULL) {
    751          ML_(dinfo_free)(cbuf);
    752       }
    753       return img->ces[i]->data[ off - img->ces[i]->off ];
    754    }
    755 
    756    // Cases (2) and (4)
    757    /* All entries in use.  Recycle the (ostensibly) LRU one.  But try to find
    758       a non-fromC entry to recycle, though, since discarding and reloading
    759       fromC entries is very expensive.  The result is that -- unless all
    760       CACHE_N_ENTRIES wind up being used by decompressed slices, which is
    761       highly unlikely -- we'll wind up keeping all the decompressed data in
    762       the cache for its entire remaining life.  We could probably do better
    763       but it would make the cache management even more complex. */
    764    vg_assert(img->ces_used == CACHE_N_ENTRIES);
    765 
    766    // Select entry to recycle.
    767    for (i = CACHE_N_ENTRIES-1; i > 0; i--) {
    768       if (!img->ces[i]->fromC)
    769          break;
    770    }
    771    vg_assert(i >= 0 && i < CACHE_N_ENTRIES);
    772 
    773    realloc_CEnt(img, i, size);
    774    img->ces[i]->size = size;
    775    img->ces[i]->used = 0;
    776    if (cslc == NULL) {
    777       set_CEnt(img, i, off);
    778       img->ces[i]->fromC = False;
    779       vg_assert(is_sane_CEnt("get_slowcase-case-2", img, i));
    780    } else {
    781       SizeT len = tinfl_decompress_mem_to_mem(
    782                      img->ces[i]->data, cslc->szD,
    783                      cbuf, cslc->szC,
    784                      TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
    785                      | TINFL_FLAG_PARSE_ZLIB_HEADER);
    786       vg_assert(len == size);
    787       img->ces[i]->used = size;
    788       img->ces[i]->off = cslc->offD;
    789       img->ces[i]->fromC = True;
    790       vg_assert(is_sane_CEnt("get_slowcase-case-4", img, i));
    791    }
    792    vg_assert(img->ces_used == ces_used_at_entry);
    793    if (i > 0) {
    794       move_CEnt_to_top(img, i);
    795       i = 0;
    796    }
    797    vg_assert(is_in_CEnt(img->ces[i], off));
    798    if (cbuf != NULL) {
    799       ML_(dinfo_free)(cbuf);
    800    }
    801    return img->ces[i]->data[ off - img->ces[i]->off ];
    802 }
    803 
    804 // This is called a lot, so do the usual fast/slow split stuff on it. */
    805 static inline UChar get ( DiImage* img, DiOffT off )
    806 {
    807    /* Most likely case is, it's in the ces[0] position. */
    808    /* ML_(img_from_local_file) requests a read for ces[0] when
    809       creating the image.  Hence slot zero is always non-NULL, so we
    810       can skip this test. */
    811    if (LIKELY(/* img->ces[0] != NULL && */
    812               is_in_CEnt(img->ces[0], off))) {
    813       return img->ces[0]->data[ off - img->ces[0]->off ];
    814    }
    815    /* Else we'll have to fish around for it. */
    816    return get_slowcase(img, off);
    817 }
    818 
    819 /* Create an image from a file in the local filesystem.  This is
    820    relatively straightforward. */
    821 DiImage* ML_(img_from_local_file)(const HChar* fullpath)
    822 {
    823    SysRes         fd;
    824    struct vg_stat stat_buf;
    825    DiOffT         size;
    826 
    827    fd = VG_(open)(fullpath, VKI_O_RDONLY, 0);
    828    if (sr_isError(fd))
    829       return NULL;
    830 
    831    if (VG_(fstat)(sr_Res(fd), &stat_buf) != 0) {
    832       VG_(close)(sr_Res(fd));
    833       return NULL;
    834    }
    835 
    836    size = stat_buf.size;
    837    if (size == 0 || size == DiOffT_INVALID
    838        || /* size is unrepresentable as a SizeT */
    839           size != (DiOffT)(SizeT)(size)) {
    840       VG_(close)(sr_Res(fd));
    841       return NULL;
    842    }
    843 
    844    DiImage* img = ML_(dinfo_zalloc)("di.image.ML_iflf.1", sizeof(DiImage));
    845    img->source.is_local = True;
    846    img->source.fd       = sr_Res(fd);
    847    img->size            = size;
    848    img->real_size       = size;
    849    img->ces_used        = 0;
    850    img->source.name     = ML_(dinfo_strdup)("di.image.ML_iflf.2", fullpath);
    851    img->cslc            = NULL;
    852    img->cslc_size       = 0;
    853    img->cslc_used       = 0;
    854    /* img->ces is already zeroed out */
    855    vg_assert(img->source.fd >= 0);
    856 
    857    /* Force the zeroth entry to be the first chunk of the file.
    858       That's likely to be the first part that's requested anyway, and
    859       loading it at this point forcing img->cent[0] to always be
    860       non-empty, thereby saving us an is-it-empty check on the fast
    861       path in get(). */
    862    UInt entNo = alloc_CEnt(img, CACHE_ENTRY_SIZE, False/*!fromC*/);
    863    vg_assert(entNo == 0);
    864    set_CEnt(img, 0, 0);
    865 
    866    return img;
    867 }
    868 
    869 
    870 /* Create an image from a file on a remote debuginfo server.  This is
    871    more complex.  There are lots of ways in which it can fail. */
    872 DiImage* ML_(img_from_di_server)(const HChar* filename,
    873                                  const HChar* serverAddr)
    874 {
    875    if (filename == NULL || serverAddr == NULL)
    876       return NULL;
    877 
    878    /* The filename must be a plain filename -- no slashes at all. */
    879    if (VG_(strchr)(filename, '/') != NULL)
    880       return NULL;
    881 
    882    /* Try to connect to the server.  A side effect of this is to parse
    883       and reject, if syntactically invalid, |serverAddr|.  Reasons why
    884       this could fail:
    885       - serverAddr is not of the form d.d.d.d:d or d.d.d.d
    886       - attempt to connect to that address:port failed
    887    */
    888    Int sd = VG_(connect_via_socket)(serverAddr);
    889    if (sd < 0)
    890       return NULL;
    891    if (!set_blocking(sd))
    892       return NULL;
    893    Int one = 1;
    894    Int sr = VG_(setsockopt)(sd, VKI_IPPROTO_TCP, VKI_TCP_NODELAY,
    895                             &one, sizeof(one));
    896    vg_assert(sr == 0);
    897 
    898    /* Ok, we got a connection.  Ask it for version string, so as to be
    899       reasonably sure we're talking to an instance of
    900       auxprogs/valgrind-di-server and not to some other random program
    901       that happens to be listening on that port. */
    902    Frame* req = mk_Frame_noargs("VERS");
    903    Frame* res = do_transaction(sd, req);
    904    if (res == NULL)
    905       goto fail; // do_transaction failed?!
    906    UChar* vstr = NULL;
    907    if (!parse_Frame_asciiz(res, "VEOK", &vstr))
    908       goto fail; // unexpected response kind, or invalid ID string
    909    vg_assert(vstr);
    910    if (VG_(strcmp)("Valgrind Debuginfo Server, Version 1",
    911                    (const HChar*)vstr) != 0)
    912       goto fail; // wrong version string
    913    free_Frame(req);
    914    free_Frame(res);
    915    req = NULL;
    916    res = NULL;
    917 
    918    /* Server seems plausible.  Present it with the name of the file we
    919       want and see if it'll give us back a session ID for it. */
    920    req = mk_Frame_asciiz("OPEN", filename);
    921    res = do_transaction(sd, req);
    922    if (res == NULL)
    923       goto fail;
    924    ULong session_id = 0, size = 0;
    925    if (!parse_Frame_le64_le64(res, "OPOK", &session_id, &size))
    926       goto fail;
    927    free_Frame(req);
    928    free_Frame(res);
    929    req = NULL;
    930    res = NULL;
    931 
    932    /* We have a session ID.  We're ready to roll. */
    933    DiImage* img = ML_(dinfo_zalloc)("di.image.ML_ifds.1", sizeof(DiImage));
    934    img->source.is_local   = False;
    935    img->source.fd         = sd;
    936    img->source.session_id = session_id;
    937    img->size              = size;
    938    img->real_size         = size;
    939    img->ces_used          = 0;
    940    img->source.name       = ML_(dinfo_zalloc)("di.image.ML_ifds.2",
    941                                               20 + VG_(strlen)(filename)
    942                                                  + VG_(strlen)(serverAddr));
    943    VG_(sprintf)(img->source.name, "%s at %s", filename, serverAddr);
    944    img->cslc            = NULL;
    945    img->cslc_size       = 0;
    946    img->cslc_used       = 0;
    947 
    948    /* img->ces is already zeroed out */
    949    vg_assert(img->source.fd >= 0);
    950 
    951    /* See comment on equivalent bit in ML_(img_from_local_file) for
    952       rationale. */
    953    UInt entNo = alloc_CEnt(img, CACHE_ENTRY_SIZE, False/*!fromC*/);
    954    vg_assert(entNo == 0);
    955    set_CEnt(img, 0, 0);
    956 
    957    return img;
    958 
    959   fail:
    960    free_Frame(req);
    961    if (res) {
    962       UChar* reason = NULL;
    963       if (parse_Frame_asciiz(res, "FAIL", &reason)) {
    964          // HACK: if it's just telling us that the file can't
    965          // be opened, don't print it, else we'll get flooded with
    966          // such complaints, one for each main object for which there
    967          // isn't a debuginfo file on the server.
    968          if (0 != VG_(strcmp)((const HChar*)reason, "OPEN: cannot open file"))
    969             VG_(umsg)("ML_(img_from_di_server): fail: %s\n", reason);
    970       } else {
    971          VG_(umsg)("ML_(img_from_di_server): fail: unknown reason\n");
    972       }
    973       free_Frame(res);
    974    }
    975    VG_(close)(sd);
    976    return NULL;
    977 }
    978 
    979 DiOffT ML_(img_mark_compressed_part)(DiImage* img, DiOffT offset, SizeT szC,
    980                                      SizeT szD)
    981 {
    982    DiOffT ret;
    983    vg_assert(img != NULL);
    984    vg_assert(offset + szC <= img->size);
    985 
    986    if (img->cslc_used == img->cslc_size) {
    987       img->cslc_size += COMPRESSED_SLICE_ARRAY_GROW_SIZE;
    988       img->cslc = ML_(dinfo_realloc)("di.image.ML_img_mark_compressed_part.1",
    989                                      img->cslc, img->cslc_size * sizeof(CSlc));
    990    }
    991 
    992    ret = img->size;
    993    img->cslc[img->cslc_used].offC = offset;
    994    img->cslc[img->cslc_used].szC = szC;
    995    img->cslc[img->cslc_used].offD = img->size;
    996    img->cslc[img->cslc_used].szD = szD;
    997    img->size += szD;
    998    img->cslc_used++;
    999    return ret;
   1000 }
   1001 
   1002 void ML_(img_done)(DiImage* img)
   1003 {
   1004    vg_assert(img != NULL);
   1005    if (img->source.is_local) {
   1006       /* Close the file; nothing else to do. */
   1007       vg_assert(img->source.session_id == 0);
   1008       VG_(close)(img->source.fd);
   1009    } else {
   1010       /* Close the socket.  The server can detect this and will scrub
   1011          the connection when it happens, so there's no need to tell it
   1012          explicitly by sending it a "CLOSE" message, or any such. */
   1013       vg_assert(img->source.session_id != 0);
   1014       VG_(close)(img->source.fd);
   1015    }
   1016 
   1017    /* Free up the cache entries, ultimately |img| itself. */
   1018    UInt i;
   1019    vg_assert(img->ces_used <= CACHE_N_ENTRIES);
   1020    for (i = 0; i < img->ces_used; i++) {
   1021       ML_(dinfo_free)(img->ces[i]);
   1022    }
   1023    /* Take the opportunity to sanity check the rest. */
   1024    for (i = i; i < img->ces_used; i++) {
   1025       vg_assert(img->ces[i] == NULL);
   1026    }
   1027    ML_(dinfo_free)(img->source.name);
   1028    ML_(dinfo_free)(img->cslc);
   1029    ML_(dinfo_free)(img);
   1030 }
   1031 
   1032 DiOffT ML_(img_size)(const DiImage* img)
   1033 {
   1034    vg_assert(img != NULL);
   1035    return img->size;
   1036 }
   1037 
   1038 DiOffT ML_(img_real_size)(const DiImage* img)
   1039 {
   1040    vg_assert(img != NULL);
   1041    return img->real_size;
   1042 }
   1043 
   1044 inline Bool ML_(img_valid)(const DiImage* img, DiOffT offset, SizeT size)
   1045 {
   1046    vg_assert(img != NULL);
   1047    vg_assert(offset != DiOffT_INVALID);
   1048    return img->size > 0 && offset + size <= (DiOffT)img->size;
   1049 }
   1050 
   1051 __attribute__((noinline))
   1052 static void ensure_valid_failed (const DiImage* img, DiOffT offset, SizeT size,
   1053                                  const HChar* caller)
   1054 {
   1055    VG_(umsg)("Valgrind: debuginfo reader: ensure_valid failed:\n");
   1056    VG_(umsg)("Valgrind:   during call to %s\n", caller);
   1057    VG_(umsg)("Valgrind:   request for range [%llu, +%lu) exceeds\n",
   1058              offset, size);
   1059    VG_(umsg)("Valgrind:   valid image size of %lu for image:\n",
   1060              img->size);
   1061    VG_(umsg)("Valgrind:   \"%s\"\n", img->source.name);
   1062    give_up__image_overrun();
   1063 }
   1064 
   1065 /* Check the given range is valid, and if not, shut down the system.
   1066    An invalid range would imply that we're trying to read outside the
   1067    image, which normally means the image is corrupted somehow, or the
   1068    caller is buggy.  Recovering is too complex, and we have
   1069    probably-corrupt debuginfo, so just give up. */
   1070 static void ensure_valid(const DiImage* img, DiOffT offset, SizeT size,
   1071                          const HChar* caller)
   1072 {
   1073    if (LIKELY(ML_(img_valid)(img, offset, size)))
   1074       return;
   1075    else
   1076       ensure_valid_failed(img, offset, size, caller);
   1077 }
   1078 
   1079 
   1080 void ML_(img_get)(/*OUT*/void* dst,
   1081                   DiImage* img, DiOffT offset, SizeT size)
   1082 {
   1083    vg_assert(img != NULL);
   1084    vg_assert(size > 0);
   1085    ensure_valid(img, offset, size, "ML_(img_get)");
   1086    SizeT i;
   1087    for (i = 0; i < size; i++) {
   1088       ((UChar*)dst)[i] = get(img, offset + i);
   1089    }
   1090 }
   1091 
   1092 SizeT ML_(img_get_some)(/*OUT*/void* dst,
   1093                         DiImage* img, DiOffT offset, SizeT size)
   1094 {
   1095    vg_assert(img != NULL);
   1096    vg_assert(size > 0);
   1097    ensure_valid(img, offset, size, "ML_(img_get_some)");
   1098    UChar* dstU = (UChar*)dst;
   1099    /* Use |get| in the normal way to get the first byte of the range.
   1100       This guarantees to put the cache entry containing |offset| in
   1101       position zero. */
   1102    dstU[0] = get(img, offset);
   1103    /* Now just read as many bytes as we can (or need) directly out of
   1104       entry zero, without bothering to call |get| each time. */
   1105    const CEnt* ce = img->ces[0];
   1106    vg_assert(ce && ce->used >= 1);
   1107    vg_assert(is_in_CEnt(ce, offset));
   1108    SizeT nToCopy = size - 1;
   1109    SizeT nAvail  = (SizeT)(ce->used - (offset + 1 - ce->off));
   1110    vg_assert(nAvail >= 0 && nAvail <= ce->used-1);
   1111    if (nAvail < nToCopy) nToCopy = nAvail;
   1112    VG_(memcpy)(&dstU[1], &ce->data[offset + 1 - ce->off], nToCopy);
   1113    return nToCopy + 1;
   1114 }
   1115 
   1116 
   1117 SizeT ML_(img_strlen)(DiImage* img, DiOffT off)
   1118 {
   1119    ensure_valid(img, off, 1, "ML_(img_strlen)");
   1120    SizeT i = 0;
   1121    while (get(img, off + i) != 0) i++;
   1122    return i;
   1123 }
   1124 
   1125 HChar* ML_(img_strdup)(DiImage* img, const HChar* cc, DiOffT offset)
   1126 {
   1127    ensure_valid(img, offset, 1, "ML_(img_strdup)");
   1128    SizeT  len = ML_(img_strlen)(img, offset);
   1129    HChar* res = ML_(dinfo_zalloc)(cc, len+1);
   1130    SizeT  i;
   1131    for (i = 0; i < len; i++) {
   1132       res[i] = get(img, offset+i);
   1133    }
   1134    vg_assert(res[len] == 0);
   1135    return res;
   1136 }
   1137 
   1138 Int ML_(img_strcmp)(DiImage* img, DiOffT off1, DiOffT off2)
   1139 {
   1140    ensure_valid(img, off1, 1, "ML_(img_strcmp)(first arg)");
   1141    ensure_valid(img, off2, 1, "ML_(img_strcmp)(second arg)");
   1142    while (True) {
   1143       UChar c1 = get(img, off1);
   1144       UChar c2 = get(img, off2);
   1145       if (c1 < c2) return -1;
   1146       if (c1 > c2) return 1;
   1147       if (c1 == 0) return 0;
   1148       off1++; off2++;
   1149    }
   1150 }
   1151 
   1152 Int ML_(img_strcmp_c)(DiImage* img, DiOffT off1, const HChar* str2)
   1153 {
   1154    ensure_valid(img, off1, 1, "ML_(img_strcmp_c)");
   1155    while (True) {
   1156       UChar c1 = get(img, off1);
   1157       UChar c2 = *(const UChar*)str2;
   1158       if (c1 < c2) return -1;
   1159       if (c1 > c2) return 1;
   1160       if (c1 == 0) return 0;
   1161       off1++; str2++;
   1162    }
   1163 }
   1164 
   1165 UChar ML_(img_get_UChar)(DiImage* img, DiOffT offset)
   1166 {
   1167    ensure_valid(img, offset, 1, "ML_(img_get_UChar)");
   1168    return get(img, offset);
   1169 }
   1170 
   1171 UShort ML_(img_get_UShort)(DiImage* img, DiOffT offset)
   1172 {
   1173    UShort r;
   1174    ML_(img_get)(&r, img, offset, sizeof(r));
   1175    return r;
   1176 }
   1177 
   1178 UInt ML_(img_get_UInt)(DiImage* img, DiOffT offset)
   1179 {
   1180    UInt r;
   1181    ML_(img_get)(&r, img, offset, sizeof(r));
   1182    return r;
   1183 }
   1184 
   1185 ULong ML_(img_get_ULong)(DiImage* img, DiOffT offset)
   1186 {
   1187    ULong r;
   1188    ML_(img_get)(&r, img, offset, sizeof(r));
   1189    return r;
   1190 }
   1191 
   1192 
   1193 /*
   1194  * This routine for calculating the CRC for a separate debug file
   1195  * is GPLed code borrowed from GNU binutils.
   1196  */
   1197 UInt ML_(img_calc_gnu_debuglink_crc32)(DiImage* img)
   1198 {
   1199   static const UInt crc32_table[256] =
   1200     {
   1201       0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
   1202       0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
   1203       0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
   1204       0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
   1205       0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
   1206       0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
   1207       0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
   1208       0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
   1209       0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
   1210       0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
   1211       0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
   1212       0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
   1213       0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
   1214       0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
   1215       0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
   1216       0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
   1217       0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
   1218       0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
   1219       0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
   1220       0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
   1221       0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
   1222       0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
   1223       0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
   1224       0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
   1225       0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
   1226       0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
   1227       0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
   1228       0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
   1229       0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
   1230       0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
   1231       0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
   1232       0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
   1233       0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
   1234       0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
   1235       0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
   1236       0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
   1237       0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
   1238       0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
   1239       0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
   1240       0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
   1241       0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
   1242       0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
   1243       0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
   1244       0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
   1245       0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
   1246       0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
   1247       0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
   1248       0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
   1249       0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
   1250       0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
   1251       0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
   1252       0x2d02ef8d
   1253     };
   1254 
   1255    vg_assert(img != NULL);
   1256 
   1257    /* If the image is local, calculate the CRC here directly.  If it's
   1258       remote, forward the request to the server. */
   1259    if (img->source.is_local) {
   1260       /* Work through the image in 1 KB chunks. */
   1261       UInt   crc      = 0xFFFFFFFF;
   1262       DiOffT img_szB  = ML_(img_size)(img);
   1263       DiOffT curr_off = 0;
   1264       while (1) {
   1265          vg_assert(curr_off >= 0 && curr_off <= img_szB);
   1266          if (curr_off == img_szB) break;
   1267          DiOffT avail = img_szB - curr_off;
   1268          vg_assert(avail > 0 && avail <= img_szB);
   1269          if (avail > 1024) avail = 1024;
   1270          UChar buf[1024];
   1271          SizeT nGot = ML_(img_get_some)(buf, img, curr_off, avail);
   1272          vg_assert(nGot >= 1 && nGot <= avail);
   1273          UInt i;
   1274          for (i = 0; i < (UInt)nGot; i++)
   1275             crc = crc32_table[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
   1276          curr_off += nGot;
   1277       }
   1278       return ~crc & 0xFFFFFFFF;
   1279    } else {
   1280       Frame* req = mk_Frame_noargs("CRC3");
   1281       Frame* res = do_transaction(img->source.fd, req);
   1282       if (!res) goto remote_crc_fail;
   1283       ULong crc32 = 0;
   1284       if (!parse_Frame_le64(res, "CROK", &crc32)) goto remote_crc_fail;
   1285       if ((crc32 & ~0xFFFFFFFFULL) != 0) goto remote_crc_fail;
   1286       free_Frame(req);
   1287       free_Frame(res);
   1288       return (UInt)crc32;
   1289      remote_crc_fail:
   1290 
   1291       // XXXX common this up with the READ diagnostic cases
   1292       if (res) {
   1293          UChar* reason = NULL;
   1294          if (parse_Frame_asciiz(res, "FAIL", &reason)) {
   1295             VG_(umsg)("img_calc_gnu_debuglink_crc32: fail: "
   1296                       "%s\n", reason);
   1297          } else {
   1298             VG_(umsg)("img_calc_gnu_debuglink_crc32: fail: "
   1299                       "unknown reason\n");
   1300          }
   1301       } else {
   1302          VG_(umsg)("img_calc_gnu_debuglink_crc32: fail: "
   1303                    "server unexpectedly closed the connection\n");
   1304       }
   1305 
   1306       if (req) free_Frame(req);
   1307       if (res) free_Frame(res);
   1308       // FIXME: now what?
   1309       give_up__comms_lost();
   1310       /* NOTREACHED */
   1311       vg_assert(0);
   1312    }
   1313    /*NOTREACHED*/
   1314    vg_assert(0);
   1315 }
   1316 
   1317 ////////////////////////////////////////////////////
   1318 #include "minilzo-inl.c"
   1319 
   1320 /*--------------------------------------------------------------------*/
   1321 /*--- end                                                  image.c ---*/
   1322 /*--------------------------------------------------------------------*/
   1323