1 /* -*- mode: C; c-basic-offset: 3; -*- */
3 /*--------------------------------------------------------------------*/
4 /*--- An abstraction that provides a file-reading mechanism. ---*/
6 /*--------------------------------------------------------------------*/
9 This file is part of Valgrind, a dynamic binary instrumentation
12 Copyright (C) 2013-2017 Mozilla Foundation
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.
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.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, see <http://www.gnu.org/licenses/>.
27 The GNU General Public License is contained in the file COPYING.
30 /* Contributed by Julian Seward <jseward@acm.org> */
32 /* See the corresponding auxprogs/valgrind-di-server.c for a list of
33 cleanups for this file and itself. */
35 #include "pub_core_basics.h"
36 #include "pub_core_vki.h"
37 #include "pub_core_libcbase.h"
38 #include "pub_core_libcassert.h"
39 #include "pub_core_libcprint.h"
40 #include "pub_core_libcproc.h" /* VG_(read_millisecond_timer) */
41 #include "pub_core_libcfile.h"
42 #include "priv_misc.h" /* dinfo_zalloc/free/strdup */
43 #include "priv_image.h" /* self */
46 #define TINFL_HEADER_FILE_ONLY
49 /* These values (1024 entries of 8192 bytes each) gives a cache
51 #define CACHE_ENTRY_SIZE_BITS (12+1)
52 #define CACHE_N_ENTRIES 1024
54 #define CACHE_ENTRY_SIZE (1 << CACHE_ENTRY_SIZE_BITS)
56 #define COMPRESSED_SLICE_ARRAY_GROW_SIZE 64
58 /* An entry in the cache. */
61 Bool fromC
; // True === contains decompressed data
62 DiOffT off
; // file offset for data[0]
63 SizeT size
; // sizeof(data)
64 SizeT used
; // 1 .. sizeof(data), or 0 to denote not-in-use
69 /* Compressed slice */
72 DiOffT offD
; // offset of decompressed data
73 SizeT szD
; // size of decompressed data
74 DiOffT offC
; // offset of compressed data
75 SizeT szC
; // size of compressed data
79 /* Source for files */
82 // True: img is of local file. False: img is from a server.
84 // The fd for the local file, or sd for a remote server.
86 // The name. In ML_(dinfo_zalloc)'d space. Used only for printing
87 // error messages; hence it doesn't really matter what this contains.
89 // The rest of these fields are only valid when using remote files
90 // (that is, using a debuginfo server; hence when is_local==False)
91 // Session ID allocated to us by the server. Cannot be zero.
97 // The source -- how to get hold of the file we are reading
99 // Virtual size of the image = real size + size of uncompressed data
101 // Real size of image
103 // The number of entries used. 0 .. CACHE_N_ENTRIES
105 // Pointers to the entries. ces[0 .. ces_used-1] are non-NULL.
106 // ces[ces_used .. CACHE_N_ENTRIES-1] are NULL.
107 // The non-NULL entries may be arranged arbitrarily. We expect to use
108 // a pseudo-LRU scheme though.
109 CEnt
* ces
[CACHE_N_ENTRIES
];
111 // Array of compressed slices
113 // Number of compressed slices used
115 // Size of cslc array
120 /* Sanity check code for CEnts. */
121 static void pp_CEnt(const HChar
* msg
, CEnt
* ce
)
123 VG_(printf
)("%s: fromC %s, used %llu, size %llu, offset %llu\n",
124 msg
, ce
->fromC
? "True" : "False",
125 (ULong
)ce
->used
, (ULong
)ce
->size
, (ULong
)ce
->off
);
128 static Bool
is_sane_CEnt ( const HChar
* who
, const DiImage
* img
, UInt i
)
131 vg_assert(i
<= CACHE_N_ENTRIES
);
133 CEnt
* ce
= img
->ces
[i
];
134 if (!(ce
->used
<= ce
->size
)) goto fail
;
136 // ce->size can be anything, but ce->used must be either the
137 // same or zero, in the case that it hasn't been set yet.
138 // Similarly, ce->off must either be above the real_size
139 // threshold, or zero if it hasn't been set yet.
140 if (!(ce
->off
>= img
->real_size
|| ce
->off
== 0)) goto fail
;
141 if (!(ce
->off
+ ce
->used
<= img
->size
)) goto fail
;
142 if (!(ce
->used
== ce
->size
|| ce
->used
== 0)) goto fail
;
144 if (!(ce
->size
== CACHE_ENTRY_SIZE
)) goto fail
;
145 if (!(ce
->off
+ ce
->used
<= img
->real_size
)) goto fail
;
150 VG_(printf
)("is_sane_CEnt[%u]: fail: %s\n", i
, who
);
151 pp_CEnt("failing CEnt", ce
);
156 /* A frame. The first 4 bytes of |data| give the kind of the frame,
157 and the rest of it is kind-specific data. */
158 typedef struct { UChar
* data
; SizeT n_data
; } Frame
;
160 static void write_UInt_le ( /*OUT*/UChar
* dst
, UInt n
)
163 for (i
= 0; i
<= 3; i
++) {
164 dst
[i
] = (UChar
)(n
& 0xFF);
169 static UInt
read_UInt_le ( const UChar
* src
)
173 for (i
= 3; i
>= 0; i
--) {
180 static void write_ULong_le ( /*OUT*/UChar
* dst
, ULong n
)
183 for (i
= 0; i
<= 7; i
++) {
184 dst
[i
] = (UChar
)(n
& 0xFF);
189 static ULong
read_ULong_le ( const UChar
* src
)
193 for (i
= 7; i
>= 0; i
--) {
201 /* Set |sd| to be blocking. Returns True on success. */
202 static Bool
set_blocking ( int sd
)
205 res
= VG_(fcntl
)(sd
, VKI_F_GETFL
, 0/*ignored*/);
207 res
= VG_(fcntl
)(sd
, VKI_F_SETFL
, res
& ~VKI_O_NONBLOCK
);
211 /* Tries to read 'len' bytes from fd, blocking if necessary. Assumes
212 fd has been set in blocking mode. If it returns with the number of
213 bytes read < len, it means that either fd was closed, or there was
215 static Int
my_read ( Int fd
, UChar
* buf
, Int len
)
219 if (nRead
== len
) return nRead
;
220 vg_assert(nRead
< len
);
221 Int nNeeded
= len
- nRead
;
222 vg_assert(nNeeded
> 0);
223 Int n
= VG_(read
)(fd
, &buf
[nRead
], nNeeded
);
224 if (n
<= 0) return nRead
; /* error or EOF */
229 /* Tries to write 'len' bytes to fd, blocking if necessary. Assumes
230 fd has been set in blocking mode. If it returns with the number of
231 bytes written < len, it means that either fd was closed, or there was
233 static Int
my_write ( Int fd
, const UChar
* buf
, Int len
)
237 if (nWritten
== len
) return nWritten
;
238 vg_assert(nWritten
< len
);
239 Int nStillToDo
= len
- nWritten
;
240 vg_assert(nStillToDo
> 0);
241 Int n
= VG_(write_socket
)(fd
, &buf
[nWritten
], nStillToDo
);
242 if (n
< 0) return nWritten
; /* error or EOF */
247 /* If we lost communication with the remote server, just give up.
248 Recovering is too difficult. */
249 static void give_up__comms_lost(void)
253 "Valgrind: debuginfo reader: Lost communication with the remote\n");
255 "Valgrind: debuginfo server. I can't recover. Giving up. Sorry.\n");
261 static void give_up__image_overrun(void)
265 "Valgrind: debuginfo reader: Possibly corrupted debuginfo file.\n");
267 "Valgrind: I can't recover. Giving up. Sorry.\n");
273 /* "Do" a transaction: that is, send the given frame to the server and
274 return the frame it sends back. Caller owns the resulting frame
275 and must free it. A NULL return means the transaction failed for
277 static Frame
* do_transaction ( Int sd
, const Frame
* req
)
279 if (0) VG_(printf
)("CLIENT: send %c%c%c%c\n",
280 req
->data
[0], req
->data
[1], req
->data
[2], req
->data
[3]);
282 /* What goes on the wire is:
283 adler(le32) n_data(le32) data[0 .. n_data-1]
284 where the checksum covers n_data as well as data[].
286 /* The initial Adler-32 value */
287 UInt adler
= VG_(adler32
)(0, NULL
, 0);
289 /* Fold in the length field, encoded as le32. */
291 write_UInt_le(&wr_first8
[4], req
->n_data
);
292 adler
= VG_(adler32
)(adler
, &wr_first8
[4], 4);
293 /* Fold in the data values */
294 adler
= VG_(adler32
)(adler
, req
->data
, req
->n_data
);
295 write_UInt_le(&wr_first8
[0], adler
);
297 Int r
= my_write(sd
, &wr_first8
[0], 8);
298 if (r
!= 8) return NULL
;
299 vg_assert(req
->n_data
>= 4); // else ill formed -- no KIND field
300 r
= my_write(sd
, req
->data
, req
->n_data
);
301 if (r
!= req
->n_data
) return NULL
;
303 /* So, the request is sent. Now get a request of the same format
304 out of the channel. */
305 UChar rd_first8
[8]; // adler32; length32
306 r
= my_read(sd
, &rd_first8
[0], 8);
307 if (r
!= 8) return NULL
;
308 UInt rd_adler
= read_UInt_le(&rd_first8
[0]);
309 UInt rd_len
= read_UInt_le(&rd_first8
[4]);
310 /* Allocate a Frame to hold the result data, and read into it. */
311 // Reject obviously-insane length fields.
312 if (rd_len
< 4 || rd_len
> 4*1024*1024) return NULL
;
313 Frame
* res
= ML_(dinfo_zalloc
)("di.do_transaction.1", sizeof(Frame
));
314 res
->n_data
= rd_len
;
315 res
->data
= ML_(dinfo_zalloc
)("di.do_transaction.2", rd_len
);
316 r
= my_read(sd
, res
->data
, res
->n_data
);
317 if (r
!= rd_len
) return NULL
;
319 if (0) VG_(printf
)("CLIENT: recv %c%c%c%c\n",
320 res
->data
[0], res
->data
[1], res
->data
[2], res
->data
[3]);
322 /* Compute the checksum for the received data, and check it. */
323 adler
= VG_(adler32
)(0, NULL
, 0); // initial value
324 adler
= VG_(adler32
)(adler
, &rd_first8
[4], 4);
326 adler
= VG_(adler32
)(adler
, res
->data
, res
->n_data
);
328 if (adler
/*computed*/ != rd_adler
/*expected*/) return NULL
;
332 static void free_Frame ( Frame
* fr
)
334 vg_assert(fr
&& fr
->data
);
335 ML_(dinfo_free
)(fr
->data
);
339 static Frame
* mk_Frame_noargs ( const HChar
* tag
)
341 vg_assert(VG_(strlen
)(tag
) == 4);
342 Frame
* f
= ML_(dinfo_zalloc
)("di.mFn.1", sizeof(Frame
));
344 f
->data
= ML_(dinfo_zalloc
)("di.mFn.2", f
->n_data
);
345 VG_(memcpy
)(&f
->data
[0], tag
, 4);
349 static Frame
* mk_Frame_le64_le64_le64 ( const HChar
* tag
,
350 ULong n1
, ULong n2
, ULong n3
)
352 vg_assert(VG_(strlen
)(tag
) == 4);
353 Frame
* f
= ML_(dinfo_zalloc
)("di.mFlll.1", sizeof(Frame
));
355 f
->data
= ML_(dinfo_zalloc
)("di.mFlll.2", f
->n_data
);
356 VG_(memcpy
)(&f
->data
[0], tag
, 4);
357 write_ULong_le(&f
->data
[4 + 0*8], n1
);
358 write_ULong_le(&f
->data
[4 + 1*8], n2
);
359 write_ULong_le(&f
->data
[4 + 2*8], n3
);
363 static Frame
* mk_Frame_asciiz ( const HChar
* tag
, const HChar
* str
)
365 vg_assert(VG_(strlen
)(tag
) == 4);
366 Frame
* f
= ML_(dinfo_zalloc
)("di.mFa.1", sizeof(Frame
));
367 SizeT n_str
= VG_(strlen
)(str
);
368 f
->n_data
= 4 + n_str
+ 1;
369 f
->data
= ML_(dinfo_zalloc
)("di.mFa.2", f
->n_data
);
370 VG_(memcpy
)(&f
->data
[0], tag
, 4);
371 VG_(memcpy
)(&f
->data
[4], str
, n_str
);
372 vg_assert(f
->data
[4 + n_str
] == 0);
376 static Bool
parse_Frame_le64 ( const Frame
* fr
, const HChar
* tag
,
379 vg_assert(VG_(strlen
)(tag
) == 4);
380 if (!fr
|| !fr
->data
) return False
;
381 if (fr
->n_data
< 4) return False
;
382 if (VG_(memcmp
)(&fr
->data
[0], tag
, 4) != 0) return False
;
383 if (fr
->n_data
!= 4 + 1*8) return False
;
384 *n1
= read_ULong_le(&fr
->data
[4 + 0*8]);
388 static Bool
parse_Frame_le64_le64 ( const Frame
* fr
, const HChar
* tag
,
389 /*OUT*/ULong
* n1
, /*OUT*/ULong
* n2
)
391 vg_assert(VG_(strlen
)(tag
) == 4);
392 if (!fr
|| !fr
->data
) return False
;
393 if (fr
->n_data
< 4) return False
;
394 if (VG_(memcmp
)(&fr
->data
[0], tag
, 4) != 0) return False
;
395 if (fr
->n_data
!= 4 + 2*8) return False
;
396 *n1
= read_ULong_le(&fr
->data
[4 + 0*8]);
397 *n2
= read_ULong_le(&fr
->data
[4 + 1*8]);
401 static Bool
parse_Frame_asciiz ( const Frame
* fr
, const HChar
* tag
,
404 vg_assert(VG_(strlen
)(tag
) == 4);
405 if (!fr
|| !fr
->data
) return False
;
406 if (fr
->n_data
< 4) return False
;
407 if (VG_(memcmp
)(&fr
->data
[0], tag
, 4) != 0) return False
;
408 if (fr
->n_data
< 5) return False
; // else there isn't even enough
409 // space for the terminating zero
410 /* Find the terminating zero and ensure it's right at the end
411 of the data. If not, the frame is malformed. */
414 if (i
>= fr
->n_data
) break;
415 if (fr
->data
[i
] == 0) break;
418 vg_assert(i
<= fr
->n_data
);
419 if (i
== fr
->n_data
-1 && fr
->data
[i
] == 0) {
427 static Bool
parse_Frame_le64_le64_le64_bytes (
428 const Frame
* fr
, const HChar
* tag
,
429 /*OUT*/ULong
* n1
, /*OUT*/ULong
* n2
, /*OUT*/ULong
* n3
,
430 /*OUT*/UChar
** data
, /*OUT*/ULong
* n_data
433 vg_assert(VG_(strlen
)(tag
) == 4);
434 if (!fr
|| !fr
->data
) return False
;
435 if (fr
->n_data
< 4) return False
;
436 if (VG_(memcmp
)(&fr
->data
[0], tag
, 4) != 0) return False
;
437 if (fr
->n_data
< 4 + 3*8) return False
;
438 *n1
= read_ULong_le(&fr
->data
[4 + 0*8]);
439 *n2
= read_ULong_le(&fr
->data
[4 + 1*8]);
440 *n3
= read_ULong_le(&fr
->data
[4 + 2*8]);
441 *data
= &fr
->data
[4 + 3*8];
442 *n_data
= fr
->n_data
- (4 + 3*8);
443 vg_assert(fr
->n_data
>= 4 + 3*8);
447 static DiOffT
block_round_down ( DiOffT i
)
449 return i
& ((DiOffT
)~(CACHE_ENTRY_SIZE
-1));
452 /* Is this offset inside this CEnt? */
453 static inline Bool
is_in_CEnt ( const CEnt
* cent
, DiOffT off
)
455 /* This assertion is checked by set_CEnt, so checking it here has
456 no benefit, whereas skipping it does remove it from the hottest
458 /* vg_assert(cent->used > 0 && cent->used <= cent->size); */
459 /* What we want to return is:
460 cent->off <= off && off < cent->off + cent->used;
461 This is however a very hot path, so here's alternative that uses
462 only one conditional branch, using the following transformation,
463 where all quantities are unsigned:
465 --> x-LO >= 0 && x-LO < LO+N-LO
466 --> x-LO >= 0 && x-LO < N
468 This is however only valid when the original bounds, that is, LO
469 .. LO+N-1, do not wrap around the end of the address space. That
470 is, we require that LO <= LO+N-1. But that's OK .. we don't
471 expect wraparounds in CEnts or for that matter any object
472 allocated from C-land. See Hacker's Delight, Chapter 4.1,
473 "Checking Bounds of Integers", for more details.
475 return off
- cent
->off
< cent
->used
;
478 /* Returns pointer to CSlc or NULL */
479 static inline CSlc
* find_cslc ( DiImage
* img
, DiOffT off
)
481 for (UInt i
= 0; i
< img
->cslc_used
; i
++) {
482 if ( (img
->cslc
[i
].offD
<= off
)
483 && (img
->cslc
[i
].offD
+ img
->cslc
[i
].szD
> off
)
485 return &img
->cslc
[i
];
490 /* Allocate a new CEnt, connect it to |img|, and return its index. */
491 static UInt
alloc_CEnt ( DiImage
* img
, SizeT szB
, Bool fromC
)
493 vg_assert(img
!= NULL
);
494 vg_assert(img
->ces_used
< CACHE_N_ENTRIES
);
496 // szB can be arbitrary
498 vg_assert(szB
== CACHE_ENTRY_SIZE
);
500 UInt entNo
= img
->ces_used
;
502 vg_assert(img
->ces
[entNo
] == NULL
);
503 img
->ces
[entNo
] = ML_(dinfo_zalloc
)("di.alloc_CEnt.1",
504 offsetof(CEnt
, data
) + szB
);
505 img
->ces
[entNo
]->size
= szB
;
506 img
->ces
[entNo
]->fromC
= fromC
;
507 vg_assert(is_sane_CEnt("alloc_CEnt", img
, entNo
));
511 static void realloc_CEnt ( DiImage
* img
, UInt entNo
, SizeT szB
, Bool fromC
)
513 vg_assert(img
!= NULL
);
514 vg_assert(fromC
|| szB
>= CACHE_ENTRY_SIZE
);
515 vg_assert(is_sane_CEnt("realloc_CEnt-pre", img
, entNo
));
516 img
->ces
[entNo
] = ML_(dinfo_realloc
)("di.realloc_CEnt.1",
518 offsetof(CEnt
, data
) + szB
);
521 /* Move the given entry to the top and slide those above it down by 1,
523 static void move_CEnt_to_top ( DiImage
* img
, UInt entNo
)
525 vg_assert(entNo
< img
->ces_used
);
526 if (LIKELY(entNo
== 1)) {
527 CEnt
* tmp
= img
->ces
[1];
528 img
->ces
[entNo
] = img
->ces
[0];
531 vg_assert(entNo
> 1); // a.k.a. >= 2
532 CEnt
* tmp
= img
->ces
[entNo
];
533 img
->ces
[entNo
] = img
->ces
[entNo
-1];
535 img
->ces
[entNo
] = img
->ces
[entNo
-1];
538 img
->ces
[entNo
] = img
->ces
[entNo
-1];
545 /* Set the given entry so that it has a chunk of the file containing
546 the given offset. It is this function that brings data into the
547 cache, either by reading the local file or pulling it from the
549 static void set_CEnt ( const DiImage
* img
, UInt entNo
, DiOffT off
)
552 DiOffT off_orig
= off
;
553 vg_assert(img
!= NULL
);
554 vg_assert(img
->ces_used
<= CACHE_N_ENTRIES
);
555 vg_assert(entNo
< img
->ces_used
);
556 vg_assert(off
< img
->real_size
);
557 CEnt
* ce
= img
->ces
[entNo
];
558 vg_assert(ce
!= NULL
);
559 /* Compute [off, +len) as the slice we are going to read. */
560 off
= block_round_down(off
);
561 len
= img
->real_size
- off
;
564 /* It is conceivable that the 'len > 0' bit could fail if we make
565 an image with a zero sized file. But then no 'get' request on
566 that image would be valid. */
567 vg_assert(len
> 0 && len
<= ce
->size
);
568 vg_assert(off
+ len
<= img
->real_size
);
569 vg_assert(off
<= off_orig
&& off_orig
< off
+len
);
570 /* So, read off .. off+len-1 into the entry. */
573 static UInt t_last
= 0;
574 static ULong nread
= 0;
575 UInt now
= VG_(read_millisecond_timer
)();
576 UInt delay
= now
- t_last
;
579 VG_(printf
)("XXXXXXXX (tot %'llu) read %'lu offset %'llu delay %'u\n",
580 nread
, len
, off
, delay
);
583 if (img
->source
.is_local
) {
584 // Simple: just read it
586 // PJF not quite so simple - see
587 // https://bugs.kde.org/show_bug.cgi?id=480405
588 // if img->source.fd was opened with O_DIRECT the memory needs
589 // to be aligned and also the length
590 // that's a lot of hassle just to take a quick peek to see if
591 // is an ELF binary so just twiddle the flag before and after
593 // This doesn't seem to be a problem on FreeBSD. I haven't tested
594 // on macOS or Solaris, hence the conditional compilation
595 #if defined(VKI_O_DIRECT)
596 Int flags
= VG_(fcntl
)(img
->source
.fd
, VKI_F_GETFL
, 0);
597 if (flags
& VKI_O_DIRECT
) {
598 VG_(fcntl
)(img
->source
.fd
, VKI_F_SETFL
, flags
& ~VKI_O_DIRECT
);
601 SysRes sr
= VG_(pread
)(img
->source
.fd
, &ce
->data
[0], (Int
)len
, off
);
602 #if defined(VKI_O_DIRECT)
603 if (flags
& VKI_O_DIRECT
) {
604 VG_(fcntl
)(img
->source
.fd
, VKI_F_SETFL
, flags
);
607 vg_assert(!sr_isError(sr
));
609 // Not so simple: poke the server
610 vg_assert(img
->source
.session_id
> 0);
612 = mk_Frame_le64_le64_le64("READ", img
->source
.session_id
, off
, len
);
613 Frame
* res
= do_transaction(img
->source
.fd
, req
);
614 free_Frame(req
); req
= NULL
;
615 if (!res
) goto server_fail
;
616 ULong rx_session_id
= 0, rx_off
= 0, rx_len
= 0, rx_zdata_len
= 0;
617 UChar
* rx_data
= NULL
;
618 /* Pretty confusing. rx_sessionid, rx_off and rx_len are copies
619 of the values that we requested in the READ frame just above,
620 so we can be sure that the server is responding to the right
621 request. It just copies them from the request into the
622 response. rx_data is the actual data, and rx_zdata_len is
623 its compressed length. Hence rx_len must equal len, but
624 rx_zdata_len can be different -- smaller, hopefully.. */
625 if (!parse_Frame_le64_le64_le64_bytes
626 (res
, "RDOK", &rx_session_id
, &rx_off
,
627 &rx_len
, &rx_data
, &rx_zdata_len
))
629 if (rx_session_id
!= img
->source
.session_id
630 || rx_off
!= off
|| rx_len
!= len
|| rx_data
== NULL
)
633 //VG_(memcpy)(&ce->data[0], rx_data, len);
634 // Decompress into the destination buffer
635 // Tell the lib the max number of output bytes it can write.
636 // After the call, this holds the number of bytes actually written,
637 // and it's an error if it is different.
638 lzo_uint out_len
= len
;
639 Int lzo_rc
= lzo1x_decompress_safe(rx_data
, rx_zdata_len
,
640 &ce
->data
[0], &out_len
,
642 Bool ok
= lzo_rc
== LZO_E_OK
&& out_len
== len
;
643 if (!ok
) goto server_fail
;
645 free_Frame(res
); res
= NULL
;
646 goto end_of_else_clause
;
648 /* The server screwed up somehow. Now what? */
650 UChar
* reason
= NULL
;
651 if (parse_Frame_asciiz(res
, "FAIL", &reason
)) {
652 VG_(umsg
)("set_CEnt (reading data from DI server): fail: "
655 VG_(umsg
)("set_CEnt (reading data from DI server): fail: "
658 free_Frame(res
); res
= NULL
;
660 VG_(umsg
)("set_CEnt (reading data from DI server): fail: "
661 "server unexpectedly closed the connection\n");
663 give_up__comms_lost();
673 vg_assert(ce
== img
->ces
[entNo
]);
674 vg_assert(is_sane_CEnt("set_CEnt", img
, entNo
));
677 __attribute__((noinline
))
678 static UChar
get_slowcase ( DiImage
* img
, DiOffT off
)
681 vg_assert(off
< img
->size
);
682 vg_assert(img
->ces_used
<= CACHE_N_ENTRIES
);
684 /* Start the search at entry 1, since the fast-case function
685 checked slot zero already. */
686 for (i
= 1; i
< img
->ces_used
; i
++) {
687 vg_assert(img
->ces
[i
]);
688 if (is_in_CEnt(img
->ces
[i
], off
))
693 if (LIKELY(i
< img
->ces_used
)) {
694 // Found it. Move to the top and stop.
695 move_CEnt_to_top(img
, i
);
696 vg_assert(is_in_CEnt(img
->ces
[0], off
));
697 return img
->ces
[0]->data
[ off
- img
->ces
[0]->off
];
700 vg_assert(i
<= img
->ces_used
);
702 // It's not in any entry. Either allocate a new one or recycle the LRU
703 // one. This is where the presence of compressed sections makes things
704 // tricky. There are 4 cases to consider:
706 // (1) not from a compressed slice, we can allocate a new entry
707 // (2) not from a compressed slice, we have to recycle the LRU entry
708 // (3) from a compressed slice, we can allocate a new entry
709 // (4) from a compressed slice, we have to recycle the LRU entry
711 // Cases (3) and (4) are complex because we will have to call
712 // ML_(img_get_some) to get the compressed data. But this function is
713 // reachable from ML_(img_get_some), so we may re-enter get_slowcase a
714 // second time as a result. Given that the compressed data will be cause
715 // only cases (1) and (2) to happen, this guarantees no infinite recursion.
716 // It does however mean that we can't carry (in this function invokation)
717 // any local copies of the overall cache state across the ML_(img_get_some)
718 // call, since it may become invalidated by the recursive call to
721 // First of all, see if it is in a compressed slice, and if so, pull the
722 // compressed data into an intermediate buffer. Given the preceding
723 // comment, this is a safe place to do it, since we are not carrying any
724 // cache state here apart from the knowledge that the requested offset is
725 // not in the cache at all, and the recursive call won't change that fact.
727 CSlc
* cslc
= find_cslc(img
, off
);
731 cbuf
= ML_(dinfo_zalloc
)("di.image.get_slowcase.cbuf-1", cslc
->szC
);
732 // get compressed data
733 while (len
< cslc
->szC
)
734 len
+= ML_(img_get_some
)(cbuf
+ len
, img
, cslc
->offC
+ len
,
738 // Now we can do what we like.
739 vg_assert((cslc
== NULL
&& cbuf
== NULL
) || (cslc
!= NULL
&& cbuf
!= NULL
));
741 // Note, we can't capture this earlier, for exactly the reasons detailed
743 UInt ces_used_at_entry
= img
->ces_used
;
745 // This is the size of the CEnt that we want to have after allocation or
747 SizeT size
= (cslc
== NULL
) ? CACHE_ENTRY_SIZE
: cslc
->szD
;
750 if (img
->ces_used
< CACHE_N_ENTRIES
) {
751 /* Allocate a new cache entry, and fill it in. */
752 i
= alloc_CEnt(img
, size
, /*fromC?*/cslc
!= NULL
);
754 set_CEnt(img
, i
, off
);
755 img
->ces
[i
]->fromC
= False
;
756 vg_assert(is_sane_CEnt("get_slowcase-case-1", img
, i
));
757 vg_assert(img
->ces_used
== ces_used_at_entry
+ 1);
759 SizeT len
= tinfl_decompress_mem_to_mem(
760 img
->ces
[i
]->data
, cslc
->szD
,
762 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
763 | TINFL_FLAG_PARSE_ZLIB_HEADER
);
764 vg_assert(len
== cslc
->szD
); // sanity check on data, FIXME
765 vg_assert(cslc
->szD
== size
);
766 img
->ces
[i
]->used
= cslc
->szD
;
767 img
->ces
[i
]->off
= cslc
->offD
;
768 img
->ces
[i
]->fromC
= True
;
769 vg_assert(is_sane_CEnt("get_slowcase-case-3", img
, i
));
770 vg_assert(img
->ces_used
== ces_used_at_entry
+ 1);
772 vg_assert(img
->ces_used
== ces_used_at_entry
+ 1);
774 move_CEnt_to_top(img
, i
);
777 vg_assert(is_in_CEnt(img
->ces
[i
], off
));
779 ML_(dinfo_free
)(cbuf
);
781 return img
->ces
[i
]->data
[ off
- img
->ces
[i
]->off
];
785 /* All entries in use. Recycle the (ostensibly) LRU one. But try to find
786 a non-fromC entry to recycle, though, since discarding and reloading
787 fromC entries is very expensive. The result is that -- unless all
788 CACHE_N_ENTRIES wind up being used by decompressed slices, which is
789 highly unlikely -- we'll wind up keeping all the decompressed data in
790 the cache for its entire remaining life. We could probably do better
791 but it would make the cache management even more complex. */
792 vg_assert(img
->ces_used
== CACHE_N_ENTRIES
);
794 // Select entry to recycle.
795 for (i
= CACHE_N_ENTRIES
-1; i
> 0; i
--) {
796 if (!img
->ces
[i
]->fromC
)
799 vg_assert(i
< CACHE_N_ENTRIES
);
801 realloc_CEnt(img
, i
, size
, /*fromC?*/cslc
!= NULL
);
802 img
->ces
[i
]->size
= size
;
803 img
->ces
[i
]->used
= 0;
805 set_CEnt(img
, i
, off
);
806 img
->ces
[i
]->fromC
= False
;
807 vg_assert(is_sane_CEnt("get_slowcase-case-2", img
, i
));
809 SizeT len
= tinfl_decompress_mem_to_mem(
810 img
->ces
[i
]->data
, cslc
->szD
,
812 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
813 | TINFL_FLAG_PARSE_ZLIB_HEADER
);
814 vg_assert(len
== size
);
815 img
->ces
[i
]->used
= size
;
816 img
->ces
[i
]->off
= cslc
->offD
;
817 img
->ces
[i
]->fromC
= True
;
818 vg_assert(is_sane_CEnt("get_slowcase-case-4", img
, i
));
820 vg_assert(img
->ces_used
== ces_used_at_entry
);
822 move_CEnt_to_top(img
, i
);
825 vg_assert(is_in_CEnt(img
->ces
[i
], off
));
827 ML_(dinfo_free
)(cbuf
);
829 return img
->ces
[i
]->data
[ off
- img
->ces
[i
]->off
];
832 // This is called a lot, so do the usual fast/slow split stuff on it. */
833 static inline UChar
get ( DiImage
* img
, DiOffT off
)
835 /* Most likely case is, it's in the ces[0] position. */
836 /* ML_(img_from_local_file) requests a read for ces[0] when
837 creating the image. Hence slot zero is always non-NULL, so we
838 can skip this test. */
839 if (LIKELY(/* img->ces[0] != NULL && */
840 is_in_CEnt(img
->ces
[0], off
))) {
841 return img
->ces
[0]->data
[ off
- img
->ces
[0]->off
];
843 /* Else we'll have to fish around for it. */
844 return get_slowcase(img
, off
);
847 /* Create an image from a file in the local filesystem. This is
848 relatively straightforward. */
849 DiImage
* ML_(img_from_local_file
)(const HChar
* fullpath
)
852 struct vg_stat stat_buf
;
855 fd
= VG_(open
)(fullpath
, VKI_O_RDONLY
, 0);
859 if (VG_(fstat
)(sr_Res(fd
), &stat_buf
) != 0) {
860 VG_(close
)(sr_Res(fd
));
864 size
= stat_buf
.size
;
865 if (size
== 0 || size
== DiOffT_INVALID
866 || /* size is unrepresentable as a SizeT */
867 size
!= (DiOffT
)(SizeT
)(size
)) {
868 VG_(close
)(sr_Res(fd
));
872 DiImage
* img
= ML_(dinfo_zalloc
)("di.image.ML_iflf.1", sizeof(DiImage
));
873 img
->source
.is_local
= True
;
874 img
->source
.fd
= sr_Res(fd
);
876 img
->real_size
= size
;
878 img
->source
.name
= ML_(dinfo_strdup
)("di.image.ML_iflf.2", fullpath
);
882 /* img->ces is already zeroed out */
883 vg_assert(img
->source
.fd
>= 0);
885 /* Force the zeroth entry to be the first chunk of the file.
886 That's likely to be the first part that's requested anyway, and
887 loading it at this point forcing img->cent[0] to always be
888 non-empty, thereby saving us an is-it-empty check on the fast
890 UInt entNo
= alloc_CEnt(img
, CACHE_ENTRY_SIZE
, False
/*!fromC*/);
891 vg_assert(entNo
== 0);
897 /* As above, but uses fd rather than filename */
898 DiImage
* ML_(img_from_fd
)(Int fd
, const HChar
* fullpath
)
900 struct vg_stat stat_buf
;
903 if (VG_(fstat
)(fd
, &stat_buf
) != 0) {
907 size
= stat_buf
.size
;
908 if (size
== 0 || size
== DiOffT_INVALID
909 || /* size is unrepresentable as a SizeT */
910 size
!= (DiOffT
)(SizeT
)(size
)) {
914 DiImage
* img
= ML_(dinfo_zalloc
)("di.image.ML_iflf.1", sizeof(DiImage
));
915 img
->source
.is_local
= True
;
918 img
->real_size
= size
;
920 img
->source
.name
= ML_(dinfo_strdup
)("di.image.ML_iflf.2", fullpath
);
924 /* img->ces is already zeroed out */
925 vg_assert(img
->source
.fd
>= 0);
927 /* Force the zeroth entry to be the first chunk of the file.
928 That's likely to be the first part that's requested anyway, and
929 loading it at this point forcing img->cent[0] to always be
930 non-empty, thereby saving us an is-it-empty check on the fast
932 UInt entNo
= alloc_CEnt(img
, CACHE_ENTRY_SIZE
, False
/*!fromC*/);
933 vg_assert(entNo
== 0);
941 /* Create an image from a file on a remote debuginfo server. This is
942 more complex. There are lots of ways in which it can fail. */
943 DiImage
* ML_(img_from_di_server
)(const HChar
* filename
,
944 const HChar
* serverAddr
)
946 if (filename
== NULL
|| serverAddr
== NULL
)
949 /* The filename must be a plain filename -- no slashes at all. */
950 if (VG_(strchr
)(filename
, '/') != NULL
)
953 /* Try to connect to the server. A side effect of this is to parse
954 and reject, if syntactically invalid, |serverAddr|. Reasons why
956 - serverAddr is not of the form d.d.d.d:d or d.d.d.d
957 - attempt to connect to that address:port failed
959 Int sd
= VG_(connect_via_socket
)(serverAddr
);
962 if (!set_blocking(sd
))
965 Int sr
= VG_(setsockopt
)(sd
, VKI_IPPROTO_TCP
, VKI_TCP_NODELAY
,
969 /* Ok, we got a connection. Ask it for version string, so as to be
970 reasonably sure we're talking to an instance of
971 auxprogs/valgrind-di-server and not to some other random program
972 that happens to be listening on that port. */
973 Frame
* req
= mk_Frame_noargs("VERS");
974 Frame
* res
= do_transaction(sd
, req
);
976 goto fail
; // do_transaction failed?!
978 if (!parse_Frame_asciiz(res
, "VEOK", &vstr
))
979 goto fail
; // unexpected response kind, or invalid ID string
981 if (VG_(strcmp
)("Valgrind Debuginfo Server, Version 1",
982 (const HChar
*)vstr
) != 0)
983 goto fail
; // wrong version string
989 /* Server seems plausible. Present it with the name of the file we
990 want and see if it'll give us back a session ID for it. */
991 req
= mk_Frame_asciiz("OPEN", filename
);
992 res
= do_transaction(sd
, req
);
995 ULong session_id
= 0, size
= 0;
996 if (!parse_Frame_le64_le64(res
, "OPOK", &session_id
, &size
))
1003 /* We have a session ID. We're ready to roll. */
1004 DiImage
* img
= ML_(dinfo_zalloc
)("di.image.ML_ifds.1", sizeof(DiImage
));
1005 img
->source
.is_local
= False
;
1006 img
->source
.fd
= sd
;
1007 img
->source
.session_id
= session_id
;
1009 img
->real_size
= size
;
1011 img
->source
.name
= ML_(dinfo_zalloc
)("di.image.ML_ifds.2",
1012 20 + VG_(strlen
)(filename
)
1013 + VG_(strlen
)(serverAddr
));
1014 VG_(sprintf
)(img
->source
.name
, "%s at %s", filename
, serverAddr
);
1019 /* img->ces is already zeroed out */
1020 vg_assert(img
->source
.fd
>= 0);
1022 /* See comment on equivalent bit in ML_(img_from_local_file) for
1024 UInt entNo
= alloc_CEnt(img
, CACHE_ENTRY_SIZE
, False
/*!fromC*/);
1025 vg_assert(entNo
== 0);
1026 set_CEnt(img
, 0, 0);
1033 UChar
* reason
= NULL
;
1034 if (parse_Frame_asciiz(res
, "FAIL", &reason
)) {
1035 // HACK: if it's just telling us that the file can't
1036 // be opened, don't print it, else we'll get flooded with
1037 // such complaints, one for each main object for which there
1038 // isn't a debuginfo file on the server.
1039 if (0 != VG_(strcmp
)((const HChar
*)reason
, "OPEN: cannot open file"))
1040 VG_(umsg
)("ML_(img_from_di_server): fail: %s\n", reason
);
1042 VG_(umsg
)("ML_(img_from_di_server): fail: unknown reason\n");
1050 DiOffT
ML_(img_mark_compressed_part
)(DiImage
* img
, DiOffT offset
, SizeT szC
,
1054 vg_assert(img
!= NULL
);
1055 vg_assert(offset
+ szC
<= img
->size
);
1057 if (img
->cslc_used
== img
->cslc_size
) {
1058 img
->cslc_size
+= COMPRESSED_SLICE_ARRAY_GROW_SIZE
;
1059 img
->cslc
= ML_(dinfo_realloc
)("di.image.ML_img_mark_compressed_part.1",
1060 img
->cslc
, img
->cslc_size
* sizeof(CSlc
));
1064 img
->cslc
[img
->cslc_used
].offC
= offset
;
1065 img
->cslc
[img
->cslc_used
].szC
= szC
;
1066 img
->cslc
[img
->cslc_used
].offD
= img
->size
;
1067 img
->cslc
[img
->cslc_used
].szD
= szD
;
1073 void ML_(img_free
)(DiImage
* img
)
1075 vg_assert(img
!= NULL
);
1077 /* Free up the cache entries, ultimately |img| itself. */
1079 vg_assert(img
->ces_used
<= CACHE_N_ENTRIES
);
1080 for (i
= 0; i
< img
->ces_used
; i
++) {
1081 ML_(dinfo_free
)(img
->ces
[i
]);
1083 /* Take the opportunity to sanity check the rest. */
1084 for (i
= i
; i
< img
->ces_used
; i
++) {
1085 vg_assert(img
->ces
[i
] == NULL
);
1087 ML_(dinfo_free
)(img
->source
.name
);
1088 ML_(dinfo_free
)(img
->cslc
);
1089 ML_(dinfo_free
)(img
);
1092 void ML_(img_done
)(DiImage
* img
)
1094 vg_assert(img
!= NULL
);
1095 if (img
->source
.is_local
) {
1096 /* Close the file; nothing else to do. */
1097 vg_assert(img
->source
.session_id
== 0);
1098 VG_(close
)(img
->source
.fd
);
1100 /* Close the socket. The server can detect this and will scrub
1101 the connection when it happens, so there's no need to tell it
1102 explicitly by sending it a "CLOSE" message, or any such. */
1103 vg_assert(img
->source
.session_id
!= 0);
1104 VG_(close
)(img
->source
.fd
);
1112 DiOffT
ML_(img_size
)(const DiImage
* img
)
1114 vg_assert(img
!= NULL
);
1118 DiOffT
ML_(img_real_size
)(const DiImage
* img
)
1120 vg_assert(img
!= NULL
);
1121 return img
->real_size
;
1124 inline Bool
ML_(img_valid
)(const DiImage
* img
, DiOffT offset
, SizeT size
)
1126 vg_assert(img
!= NULL
);
1127 vg_assert(offset
!= DiOffT_INVALID
);
1128 return img
->size
> 0 && offset
+ size
<= (DiOffT
)img
->size
;
1131 __attribute__((noinline
))
1132 static void ensure_valid_failed (const DiImage
* img
, DiOffT offset
, SizeT size
,
1133 const HChar
* caller
)
1135 VG_(umsg
)("Valgrind: debuginfo reader: ensure_valid failed:\n");
1136 VG_(umsg
)("Valgrind: during call to %s\n", caller
);
1137 VG_(umsg
)("Valgrind: request for range [%llu, +%lu) exceeds\n",
1139 VG_(umsg
)("Valgrind: valid image size of %lu for image:\n",
1141 VG_(umsg
)("Valgrind: \"%s\"\n", img
->source
.name
);
1142 give_up__image_overrun();
1145 /* Check the given range is valid, and if not, shut down the system.
1146 An invalid range would imply that we're trying to read outside the
1147 image, which normally means the image is corrupted somehow, or the
1148 caller is buggy. Recovering is too complex, and we have
1149 probably-corrupt debuginfo, so just give up. */
1150 static void ensure_valid(const DiImage
* img
, DiOffT offset
, SizeT size
,
1151 const HChar
* caller
)
1153 if (LIKELY(ML_(img_valid
)(img
, offset
, size
)))
1156 ensure_valid_failed(img
, offset
, size
, caller
);
1160 void ML_(img_get
)(/*OUT*/void* dst
,
1161 DiImage
* img
, DiOffT offset
, SizeT size
)
1163 vg_assert(img
!= NULL
);
1164 vg_assert(size
> 0);
1165 ensure_valid(img
, offset
, size
, "ML_(img_get)");
1167 for (i
= 0; i
< size
; i
++) {
1168 ((UChar
*)dst
)[i
] = get(img
, offset
+ i
);
1172 SizeT
ML_(img_get_some
)(/*OUT*/void* dst
,
1173 DiImage
* img
, DiOffT offset
, SizeT size
)
1175 vg_assert(img
!= NULL
);
1176 vg_assert(size
> 0);
1177 ensure_valid(img
, offset
, size
, "ML_(img_get_some)");
1178 UChar
* dstU
= (UChar
*)dst
;
1179 /* Use |get| in the normal way to get the first byte of the range.
1180 This guarantees to put the cache entry containing |offset| in
1182 dstU
[0] = get(img
, offset
);
1183 /* Now just read as many bytes as we can (or need) directly out of
1184 entry zero, without bothering to call |get| each time. */
1185 const CEnt
* ce
= img
->ces
[0];
1186 vg_assert(ce
&& ce
->used
>= 1);
1187 vg_assert(is_in_CEnt(ce
, offset
));
1188 SizeT nToCopy
= size
- 1;
1189 SizeT nAvail
= (SizeT
)(ce
->used
- (offset
+ 1 - ce
->off
));
1190 vg_assert(nAvail
<= ce
->used
-1);
1191 if (nAvail
< nToCopy
) nToCopy
= nAvail
;
1192 VG_(memcpy
)(&dstU
[1], &ce
->data
[offset
+ 1 - ce
->off
], nToCopy
);
1197 SizeT
ML_(img_strlen
)(DiImage
* img
, DiOffT off
)
1199 ensure_valid(img
, off
, 1, "ML_(img_strlen)");
1201 while (get(img
, off
+ i
) != 0) i
++;
1205 HChar
* ML_(img_strdup
)(DiImage
* img
, const HChar
* cc
, DiOffT offset
)
1207 ensure_valid(img
, offset
, 1, "ML_(img_strdup)");
1208 SizeT len
= ML_(img_strlen
)(img
, offset
);
1209 HChar
* res
= ML_(dinfo_zalloc
)(cc
, len
+1);
1211 for (i
= 0; i
< len
; i
++) {
1212 res
[i
] = get(img
, offset
+i
);
1214 vg_assert(res
[len
] == 0);
1218 Int
ML_(img_strcmp
)(DiImage
* img
, DiOffT off1
, DiOffT off2
)
1220 ensure_valid(img
, off1
, 1, "ML_(img_strcmp)(first arg)");
1221 ensure_valid(img
, off2
, 1, "ML_(img_strcmp)(second arg)");
1223 UChar c1
= get(img
, off1
);
1224 UChar c2
= get(img
, off2
);
1225 if (c1
< c2
) return -1;
1226 if (c1
> c2
) return 1;
1227 if (c1
== 0) return 0;
1232 Int
ML_(img_strcmp_c
)(DiImage
* img
, DiOffT off1
, const HChar
* str2
)
1234 ensure_valid(img
, off1
, 1, "ML_(img_strcmp_c)");
1236 UChar c1
= get(img
, off1
);
1237 UChar c2
= *(const UChar
*)str2
;
1238 if (c1
< c2
) return -1;
1239 if (c1
> c2
) return 1;
1240 if (c1
== 0) return 0;
1245 Int
ML_(img_strcmp_n
)(DiImage
* img
, DiOffT off1
, const HChar
* str2
, Word n
)
1247 ensure_valid(img
, off1
, 1, "ML_(img_strcmp_c)");
1249 UChar c1
= get(img
, off1
);
1250 UChar c2
= *(const UChar
*)str2
;
1251 if (c1
< c2
) return -1;
1252 if (c1
> c2
) return 1;
1253 if (c1
== 0) return 0;
1254 off1
++; str2
++; --n
;
1259 UChar
ML_(img_get_UChar
)(DiImage
* img
, DiOffT offset
)
1261 ensure_valid(img
, offset
, 1, "ML_(img_get_UChar)");
1262 return get(img
, offset
);
1265 UShort
ML_(img_get_UShort
)(DiImage
* img
, DiOffT offset
)
1268 ML_(img_get
)(&r
, img
, offset
, sizeof(r
));
1272 UInt
ML_(img_get_UInt
)(DiImage
* img
, DiOffT offset
)
1275 ML_(img_get
)(&r
, img
, offset
, sizeof(r
));
1279 ULong
ML_(img_get_ULong
)(DiImage
* img
, DiOffT offset
)
1282 ML_(img_get
)(&r
, img
, offset
, sizeof(r
));
1288 * This routine for calculating the CRC for a separate debug file
1289 * is GPLed code borrowed from GNU binutils.
1291 UInt
ML_(img_calc_gnu_debuglink_crc32
)(DiImage
* img
)
1293 static const UInt crc32_table
[256] =
1295 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
1296 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
1297 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
1298 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
1299 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
1300 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
1301 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
1302 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
1303 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
1304 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
1305 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
1306 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
1307 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
1308 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
1309 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
1310 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
1311 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
1312 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
1313 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
1314 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
1315 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
1316 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
1317 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
1318 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
1319 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
1320 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
1321 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
1322 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
1323 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
1324 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
1325 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
1326 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
1327 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
1328 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
1329 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
1330 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
1331 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
1332 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
1333 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
1334 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
1335 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
1336 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
1337 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
1338 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
1339 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
1340 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
1341 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
1342 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
1343 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
1344 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
1345 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
1349 vg_assert(img
!= NULL
);
1351 /* If the image is local, calculate the CRC here directly. If it's
1352 remote, forward the request to the server. */
1353 if (img
->source
.is_local
) {
1354 /* Work through the image in 1 KB chunks. */
1355 UInt crc
= 0xFFFFFFFF;
1356 DiOffT img_szB
= ML_(img_size
)(img
);
1357 DiOffT curr_off
= 0;
1359 vg_assert(curr_off
<= img_szB
);
1360 if (curr_off
== img_szB
) break;
1361 DiOffT avail
= img_szB
- curr_off
;
1362 vg_assert(avail
> 0 && avail
<= img_szB
);
1363 if (avail
> 1024) avail
= 1024;
1365 SizeT nGot
= ML_(img_get_some
)(buf
, img
, curr_off
, avail
);
1366 vg_assert(nGot
>= 1 && nGot
<= avail
);
1368 for (i
= 0; i
< (UInt
)nGot
; i
++)
1369 crc
= crc32_table
[(crc
^ buf
[i
]) & 0xff] ^ (crc
>> 8);
1372 return ~crc
& 0xFFFFFFFF;
1374 Frame
* req
= mk_Frame_noargs("CRC3");
1375 Frame
* res
= do_transaction(img
->source
.fd
, req
);
1376 if (!res
) goto remote_crc_fail
;
1378 if (!parse_Frame_le64(res
, "CROK", &crc32
)) goto remote_crc_fail
;
1379 if ((crc32
& ~0xFFFFFFFFULL
) != 0) goto remote_crc_fail
;
1385 // XXXX common this up with the READ diagnostic cases
1387 UChar
* reason
= NULL
;
1388 if (parse_Frame_asciiz(res
, "FAIL", &reason
)) {
1389 VG_(umsg
)("img_calc_gnu_debuglink_crc32: fail: "
1392 VG_(umsg
)("img_calc_gnu_debuglink_crc32: fail: "
1393 "unknown reason\n");
1396 VG_(umsg
)("img_calc_gnu_debuglink_crc32: fail: "
1397 "server unexpectedly closed the connection\n");
1400 if (req
) free_Frame(req
);
1401 if (res
) free_Frame(res
);
1403 give_up__comms_lost();
1411 ////////////////////////////////////////////////////
1412 #include "minilzo-inl.c"
1414 /*--------------------------------------------------------------------*/
1415 /*--- end image.c ---*/
1416 /*--------------------------------------------------------------------*/