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@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. */
61typedef
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 */
72typedef
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 */
82typedef
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
98struct _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. */
123static 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
130static 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. */
161typedef  struct { UChar* data; SizeT n_data; }  Frame;
162
163static 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
172static 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
183static 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
192static 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. */
205static 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. */
218static 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. */
236static 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. */
252static 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
264static 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. */
280static 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
335static 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
342static 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
352static 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
366static 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
379static 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
391static 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
404static 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
430static 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
450static DiOffT block_round_down ( DiOffT i )
451{
452   return i & ((DiOffT)~(CACHE_ENTRY_SIZE-1));
453}
454
455/* Is this offset inside this CEnt? */
456static 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 */
482static 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. */
494static 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
514static 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. */
526static 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. */
542static 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))
650static 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. */
805static 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. */
821DiImage* 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. */
872DiImage* 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
979DiOffT 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
1002void 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
1032DiOffT ML_(img_size)(const DiImage* img)
1033{
1034   vg_assert(img != NULL);
1035   return img->size;
1036}
1037
1038DiOffT ML_(img_real_size)(const DiImage* img)
1039{
1040   vg_assert(img != NULL);
1041   return img->real_size;
1042}
1043
1044inline 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))
1052static 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. */
1070static 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
1080void 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
1092SizeT 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
1117SizeT 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
1125HChar* 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
1138Int 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
1152Int 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
1165UChar 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
1171UShort 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
1178UInt 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
1185ULong 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 */
1197UInt 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