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
50 /* These values (1024 entries of 8192 bytes each) gives a cache
52 #define CACHE_ENTRY_SIZE_BITS (12+1)
53 #define CACHE_N_ENTRIES 1024
55 #define CACHE_ENTRY_SIZE (1 << CACHE_ENTRY_SIZE_BITS)
57 #define COMPRESSED_SLICE_ARRAY_GROW_SIZE 64
59 #define ELFCOMPRESS_ZLIB 1
60 #define ELFCOMPRESS_ZSTD 2
62 /* An entry in the cache. */
65 Bool fromC
; // True === contains decompressed data
66 DiOffT off
; // file offset for data[0]
67 SizeT size
; // sizeof(data)
68 SizeT used
; // 1 .. sizeof(data), or 0 to denote not-in-use
73 /* Compressed slice */
76 DiOffT offD
; // offset of decompressed data
77 SizeT szD
; // size of decompressed data
78 DiOffT offC
; // offset of compressed data
79 SizeT szC
; // size of compressed data
80 UChar typeC
; // type of compressed data
84 /* Source for files */
87 // True: img is of local file. False: img is from a server.
89 // The fd for the local file, or sd for a remote server.
91 // The name. In ML_(dinfo_zalloc)'d space. Used only for printing
92 // error messages; hence it doesn't really matter what this contains.
94 // The rest of these fields are only valid when using remote files
95 // (that is, using a debuginfo server; hence when is_local==False)
96 // Session ID allocated to us by the server. Cannot be zero.
102 // The source -- how to get hold of the file we are reading
104 // Virtual size of the image = real size + size of uncompressed data
106 // Real size of image
108 // The number of entries used. 0 .. CACHE_N_ENTRIES
110 // Pointers to the entries. ces[0 .. ces_used-1] are non-NULL.
111 // ces[ces_used .. CACHE_N_ENTRIES-1] are NULL.
112 // The non-NULL entries may be arranged arbitrarily. We expect to use
113 // a pseudo-LRU scheme though.
114 CEnt
* ces
[CACHE_N_ENTRIES
];
116 // Array of compressed slices
118 // Number of compressed slices used
120 // Size of cslc array
125 /* Sanity check code for CEnts. */
126 static void pp_CEnt(const HChar
* msg
, CEnt
* ce
)
128 VG_(printf
)("%s: fromC %s, used %llu, size %llu, offset %llu\n",
129 msg
, ce
->fromC
? "True" : "False",
130 (ULong
)ce
->used
, (ULong
)ce
->size
, (ULong
)ce
->off
);
133 static Bool
is_sane_CEnt ( const HChar
* who
, const DiImage
* img
, UInt i
)
136 vg_assert(i
<= CACHE_N_ENTRIES
);
138 CEnt
* ce
= img
->ces
[i
];
139 if (!(ce
->used
<= ce
->size
)) goto fail
;
141 // ce->size can be anything, but ce->used must be either the
142 // same or zero, in the case that it hasn't been set yet.
143 // Similarly, ce->off must either be above the real_size
144 // threshold, or zero if it hasn't been set yet.
145 if (!(ce
->off
>= img
->real_size
|| ce
->off
== 0)) goto fail
;
146 if (!(ce
->off
+ ce
->used
<= img
->size
)) goto fail
;
147 if (!(ce
->used
== ce
->size
|| ce
->used
== 0)) goto fail
;
149 if (!(ce
->size
== CACHE_ENTRY_SIZE
)) goto fail
;
150 if (!(ce
->off
+ ce
->used
<= img
->real_size
)) goto fail
;
155 VG_(printf
)("is_sane_CEnt[%u]: fail: %s\n", i
, who
);
156 pp_CEnt("failing CEnt", ce
);
161 /* A frame. The first 4 bytes of |data| give the kind of the frame,
162 and the rest of it is kind-specific data. */
163 typedef struct { UChar
* data
; SizeT n_data
; } Frame
;
165 static void write_UInt_le ( /*OUT*/UChar
* dst
, UInt n
)
168 for (i
= 0; i
<= 3; i
++) {
169 dst
[i
] = (UChar
)(n
& 0xFF);
174 static UInt
read_UInt_le ( const UChar
* src
)
178 for (i
= 3; i
>= 0; i
--) {
185 static void write_ULong_le ( /*OUT*/UChar
* dst
, ULong n
)
188 for (i
= 0; i
<= 7; i
++) {
189 dst
[i
] = (UChar
)(n
& 0xFF);
194 static ULong
read_ULong_le ( const UChar
* src
)
198 for (i
= 7; i
>= 0; i
--) {
206 /* Set |sd| to be blocking. Returns True on success. */
207 static Bool
set_blocking ( int sd
)
210 res
= VG_(fcntl
)(sd
, VKI_F_GETFL
, 0/*ignored*/);
212 res
= VG_(fcntl
)(sd
, VKI_F_SETFL
, res
& ~VKI_O_NONBLOCK
);
216 /* Tries to read 'len' bytes from fd, blocking if necessary. Assumes
217 fd has been set in blocking mode. If it returns with the number of
218 bytes read < len, it means that either fd was closed, or there was
220 static Int
my_read ( Int fd
, UChar
* buf
, Int len
)
224 if (nRead
== len
) return nRead
;
225 vg_assert(nRead
< len
);
226 Int nNeeded
= len
- nRead
;
227 vg_assert(nNeeded
> 0);
228 Int n
= VG_(read
)(fd
, &buf
[nRead
], nNeeded
);
229 if (n
<= 0) return nRead
; /* error or EOF */
234 /* Tries to write 'len' bytes to fd, blocking if necessary. Assumes
235 fd has been set in blocking mode. If it returns with the number of
236 bytes written < len, it means that either fd was closed, or there was
238 static Int
my_write ( Int fd
, const UChar
* buf
, Int len
)
242 if (nWritten
== len
) return nWritten
;
243 vg_assert(nWritten
< len
);
244 Int nStillToDo
= len
- nWritten
;
245 vg_assert(nStillToDo
> 0);
246 Int n
= VG_(write_socket
)(fd
, &buf
[nWritten
], nStillToDo
);
247 if (n
< 0) return nWritten
; /* error or EOF */
252 /* If we lost communication with the remote server, just give up.
253 Recovering is too difficult. */
254 static void give_up__comms_lost(void)
258 "Valgrind: debuginfo reader: Lost communication with the remote\n");
260 "Valgrind: debuginfo server. I can't recover. Giving up. Sorry.\n");
266 static void give_up__image_overrun(void)
270 "Valgrind: debuginfo reader: Possibly corrupted debuginfo file.\n");
272 "Valgrind: I can't recover. Giving up. Sorry.\n");
278 /* "Do" a transaction: that is, send the given frame to the server and
279 return the frame it sends back. Caller owns the resulting frame
280 and must free it. A NULL return means the transaction failed for
282 static Frame
* do_transaction ( Int sd
, const Frame
* req
)
284 if (0) VG_(printf
)("CLIENT: send %c%c%c%c\n",
285 req
->data
[0], req
->data
[1], req
->data
[2], req
->data
[3]);
287 /* What goes on the wire is:
288 adler(le32) n_data(le32) data[0 .. n_data-1]
289 where the checksum covers n_data as well as data[].
291 /* The initial Adler-32 value */
292 UInt adler
= VG_(adler32
)(0, NULL
, 0);
294 /* Fold in the length field, encoded as le32. */
296 write_UInt_le(&wr_first8
[4], req
->n_data
);
297 adler
= VG_(adler32
)(adler
, &wr_first8
[4], 4);
298 /* Fold in the data values */
299 adler
= VG_(adler32
)(adler
, req
->data
, req
->n_data
);
300 write_UInt_le(&wr_first8
[0], adler
);
302 Int r
= my_write(sd
, &wr_first8
[0], 8);
303 if (r
!= 8) return NULL
;
304 vg_assert(req
->n_data
>= 4); // else ill formed -- no KIND field
305 r
= my_write(sd
, req
->data
, req
->n_data
);
306 if (r
!= req
->n_data
) return NULL
;
308 /* So, the request is sent. Now get a request of the same format
309 out of the channel. */
310 UChar rd_first8
[8]; // adler32; length32
311 r
= my_read(sd
, &rd_first8
[0], 8);
312 if (r
!= 8) return NULL
;
313 UInt rd_adler
= read_UInt_le(&rd_first8
[0]);
314 UInt rd_len
= read_UInt_le(&rd_first8
[4]);
315 /* Allocate a Frame to hold the result data, and read into it. */
316 // Reject obviously-insane length fields.
317 if (rd_len
< 4 || rd_len
> 4*1024*1024) return NULL
;
318 Frame
* res
= ML_(dinfo_zalloc
)("di.do_transaction.1", sizeof(Frame
));
319 res
->n_data
= rd_len
;
320 res
->data
= ML_(dinfo_zalloc
)("di.do_transaction.2", rd_len
);
321 r
= my_read(sd
, res
->data
, res
->n_data
);
322 if (r
!= rd_len
) return NULL
;
324 if (0) VG_(printf
)("CLIENT: recv %c%c%c%c\n",
325 res
->data
[0], res
->data
[1], res
->data
[2], res
->data
[3]);
327 /* Compute the checksum for the received data, and check it. */
328 adler
= VG_(adler32
)(0, NULL
, 0); // initial value
329 adler
= VG_(adler32
)(adler
, &rd_first8
[4], 4);
331 adler
= VG_(adler32
)(adler
, res
->data
, res
->n_data
);
333 if (adler
/*computed*/ != rd_adler
/*expected*/) return NULL
;
337 static void free_Frame ( Frame
* fr
)
339 vg_assert(fr
&& fr
->data
);
340 ML_(dinfo_free
)(fr
->data
);
344 static Frame
* mk_Frame_noargs ( const HChar
* tag
)
346 vg_assert(VG_(strlen
)(tag
) == 4);
347 Frame
* f
= ML_(dinfo_zalloc
)("di.mFn.1", sizeof(Frame
));
349 f
->data
= ML_(dinfo_zalloc
)("di.mFn.2", f
->n_data
);
350 VG_(memcpy
)(&f
->data
[0], tag
, 4);
354 static Frame
* mk_Frame_le64_le64_le64 ( const HChar
* tag
,
355 ULong n1
, ULong n2
, ULong n3
)
357 vg_assert(VG_(strlen
)(tag
) == 4);
358 Frame
* f
= ML_(dinfo_zalloc
)("di.mFlll.1", sizeof(Frame
));
360 f
->data
= ML_(dinfo_zalloc
)("di.mFlll.2", f
->n_data
);
361 VG_(memcpy
)(&f
->data
[0], tag
, 4);
362 write_ULong_le(&f
->data
[4 + 0*8], n1
);
363 write_ULong_le(&f
->data
[4 + 1*8], n2
);
364 write_ULong_le(&f
->data
[4 + 2*8], n3
);
368 static Frame
* mk_Frame_asciiz ( const HChar
* tag
, const HChar
* str
)
370 vg_assert(VG_(strlen
)(tag
) == 4);
371 Frame
* f
= ML_(dinfo_zalloc
)("di.mFa.1", sizeof(Frame
));
372 SizeT n_str
= VG_(strlen
)(str
);
373 f
->n_data
= 4 + n_str
+ 1;
374 f
->data
= ML_(dinfo_zalloc
)("di.mFa.2", f
->n_data
);
375 VG_(memcpy
)(&f
->data
[0], tag
, 4);
376 VG_(memcpy
)(&f
->data
[4], str
, n_str
);
377 vg_assert(f
->data
[4 + n_str
] == 0);
381 static Bool
parse_Frame_le64 ( const Frame
* fr
, const HChar
* tag
,
384 vg_assert(VG_(strlen
)(tag
) == 4);
385 if (!fr
|| !fr
->data
) return False
;
386 if (fr
->n_data
< 4) return False
;
387 if (VG_(memcmp
)(&fr
->data
[0], tag
, 4) != 0) return False
;
388 if (fr
->n_data
!= 4 + 1*8) return False
;
389 *n1
= read_ULong_le(&fr
->data
[4 + 0*8]);
393 static Bool
parse_Frame_le64_le64 ( const Frame
* fr
, const HChar
* tag
,
394 /*OUT*/ULong
* n1
, /*OUT*/ULong
* n2
)
396 vg_assert(VG_(strlen
)(tag
) == 4);
397 if (!fr
|| !fr
->data
) return False
;
398 if (fr
->n_data
< 4) return False
;
399 if (VG_(memcmp
)(&fr
->data
[0], tag
, 4) != 0) return False
;
400 if (fr
->n_data
!= 4 + 2*8) return False
;
401 *n1
= read_ULong_le(&fr
->data
[4 + 0*8]);
402 *n2
= read_ULong_le(&fr
->data
[4 + 1*8]);
406 static Bool
parse_Frame_asciiz ( const Frame
* fr
, const HChar
* tag
,
409 vg_assert(VG_(strlen
)(tag
) == 4);
410 if (!fr
|| !fr
->data
) return False
;
411 if (fr
->n_data
< 4) return False
;
412 if (VG_(memcmp
)(&fr
->data
[0], tag
, 4) != 0) return False
;
413 if (fr
->n_data
< 5) return False
; // else there isn't even enough
414 // space for the terminating zero
415 /* Find the terminating zero and ensure it's right at the end
416 of the data. If not, the frame is malformed. */
419 if (i
>= fr
->n_data
) break;
420 if (fr
->data
[i
] == 0) break;
423 vg_assert(i
<= fr
->n_data
);
424 if (i
== fr
->n_data
-1 && fr
->data
[i
] == 0) {
432 static Bool
parse_Frame_le64_le64_le64_bytes (
433 const Frame
* fr
, const HChar
* tag
,
434 /*OUT*/ULong
* n1
, /*OUT*/ULong
* n2
, /*OUT*/ULong
* n3
,
435 /*OUT*/UChar
** data
, /*OUT*/ULong
* n_data
438 vg_assert(VG_(strlen
)(tag
) == 4);
439 if (!fr
|| !fr
->data
) return False
;
440 if (fr
->n_data
< 4) return False
;
441 if (VG_(memcmp
)(&fr
->data
[0], tag
, 4) != 0) return False
;
442 if (fr
->n_data
< 4 + 3*8) return False
;
443 *n1
= read_ULong_le(&fr
->data
[4 + 0*8]);
444 *n2
= read_ULong_le(&fr
->data
[4 + 1*8]);
445 *n3
= read_ULong_le(&fr
->data
[4 + 2*8]);
446 *data
= &fr
->data
[4 + 3*8];
447 *n_data
= fr
->n_data
- (4 + 3*8);
448 vg_assert(fr
->n_data
>= 4 + 3*8);
452 static DiOffT
block_round_down ( DiOffT i
)
454 return i
& ((DiOffT
)~(CACHE_ENTRY_SIZE
-1));
457 /* Is this offset inside this CEnt? */
458 static inline Bool
is_in_CEnt ( const CEnt
* cent
, DiOffT off
)
460 /* This assertion is checked by set_CEnt, so checking it here has
461 no benefit, whereas skipping it does remove it from the hottest
463 /* vg_assert(cent->used > 0 && cent->used <= cent->size); */
464 /* What we want to return is:
465 cent->off <= off && off < cent->off + cent->used;
466 This is however a very hot path, so here's alternative that uses
467 only one conditional branch, using the following transformation,
468 where all quantities are unsigned:
470 --> x-LO >= 0 && x-LO < LO+N-LO
471 --> x-LO >= 0 && x-LO < N
473 This is however only valid when the original bounds, that is, LO
474 .. LO+N-1, do not wrap around the end of the address space. That
475 is, we require that LO <= LO+N-1. But that's OK .. we don't
476 expect wraparounds in CEnts or for that matter any object
477 allocated from C-land. See Hacker's Delight, Chapter 4.1,
478 "Checking Bounds of Integers", for more details.
480 return off
- cent
->off
< cent
->used
;
483 /* Returns pointer to CSlc or NULL */
484 static inline CSlc
* find_cslc ( DiImage
* img
, DiOffT off
)
486 for (UInt i
= 0; i
< img
->cslc_used
; i
++) {
487 if ( (img
->cslc
[i
].offD
<= off
)
488 && (img
->cslc
[i
].offD
+ img
->cslc
[i
].szD
> off
)
490 return &img
->cslc
[i
];
495 /* Allocate a new CEnt, connect it to |img|, and return its index. */
496 static UInt
alloc_CEnt ( DiImage
* img
, SizeT szB
, Bool fromC
)
498 vg_assert(img
!= NULL
);
499 vg_assert(img
->ces_used
< CACHE_N_ENTRIES
);
501 // szB can be arbitrary
503 vg_assert(szB
== CACHE_ENTRY_SIZE
);
505 UInt entNo
= img
->ces_used
;
507 vg_assert(img
->ces
[entNo
] == NULL
);
508 img
->ces
[entNo
] = ML_(dinfo_zalloc
)("di.alloc_CEnt.1",
509 offsetof(CEnt
, data
) + szB
);
510 img
->ces
[entNo
]->size
= szB
;
511 img
->ces
[entNo
]->fromC
= fromC
;
512 vg_assert(is_sane_CEnt("alloc_CEnt", img
, entNo
));
516 static void realloc_CEnt ( DiImage
* img
, UInt entNo
, SizeT szB
, Bool fromC
)
518 vg_assert(img
!= NULL
);
519 vg_assert(fromC
|| szB
>= CACHE_ENTRY_SIZE
);
520 vg_assert(is_sane_CEnt("realloc_CEnt-pre", img
, entNo
));
521 img
->ces
[entNo
] = ML_(dinfo_realloc
)("di.realloc_CEnt.1",
523 offsetof(CEnt
, data
) + szB
);
526 /* Move the given entry to the top and slide those above it down by 1,
528 static void move_CEnt_to_top ( DiImage
* img
, UInt entNo
)
530 vg_assert(entNo
< img
->ces_used
);
531 if (LIKELY(entNo
== 1)) {
532 CEnt
* tmp
= img
->ces
[1];
533 img
->ces
[entNo
] = img
->ces
[0];
536 vg_assert(entNo
> 1); // a.k.a. >= 2
537 CEnt
* tmp
= img
->ces
[entNo
];
538 img
->ces
[entNo
] = img
->ces
[entNo
-1];
540 img
->ces
[entNo
] = img
->ces
[entNo
-1];
543 img
->ces
[entNo
] = img
->ces
[entNo
-1];
550 /* Set the given entry so that it has a chunk of the file containing
551 the given offset. It is this function that brings data into the
552 cache, either by reading the local file or pulling it from the
554 static void set_CEnt ( const DiImage
* img
, UInt entNo
, DiOffT off
)
557 DiOffT off_orig
= off
;
558 vg_assert(img
!= NULL
);
559 vg_assert(img
->ces_used
<= CACHE_N_ENTRIES
);
560 vg_assert(entNo
< img
->ces_used
);
561 vg_assert(off
< img
->real_size
);
562 CEnt
* ce
= img
->ces
[entNo
];
563 vg_assert(ce
!= NULL
);
564 /* Compute [off, +len) as the slice we are going to read. */
565 off
= block_round_down(off
);
566 len
= img
->real_size
- off
;
569 /* It is conceivable that the 'len > 0' bit could fail if we make
570 an image with a zero sized file. But then no 'get' request on
571 that image would be valid. */
572 vg_assert(len
> 0 && len
<= ce
->size
);
573 vg_assert(off
+ len
<= img
->real_size
);
574 vg_assert(off
<= off_orig
&& off_orig
< off
+len
);
575 /* So, read off .. off+len-1 into the entry. */
578 static UInt t_last
= 0;
579 static ULong nread
= 0;
580 UInt now
= VG_(read_millisecond_timer
)();
581 UInt delay
= now
- t_last
;
584 VG_(printf
)("XXXXXXXX (tot %'llu) read %'lu offset %'llu delay %'u\n",
585 nread
, len
, off
, delay
);
588 if (img
->source
.is_local
) {
589 // Simple: just read it
591 // PJF not quite so simple - see
592 // https://bugs.kde.org/show_bug.cgi?id=480405
593 // if img->source.fd was opened with O_DIRECT the memory needs
594 // to be aligned and also the length
595 // that's a lot of hassle just to take a quick peek to see if
596 // is an ELF binary so just twiddle the flag before and after
598 // This doesn't seem to be a problem on FreeBSD. I haven't tested
599 // on macOS or Solaris, hence the conditional compilation
600 #if defined(VKI_O_DIRECT)
601 Int flags
= VG_(fcntl
)(img
->source
.fd
, VKI_F_GETFL
, 0);
602 if (flags
& VKI_O_DIRECT
) {
603 VG_(fcntl
)(img
->source
.fd
, VKI_F_SETFL
, flags
& ~VKI_O_DIRECT
);
606 SysRes sr
= VG_(pread
)(img
->source
.fd
, &ce
->data
[0], (Int
)len
, off
);
607 #if defined(VKI_O_DIRECT)
608 if (flags
& VKI_O_DIRECT
) {
609 VG_(fcntl
)(img
->source
.fd
, VKI_F_SETFL
, flags
);
612 vg_assert(!sr_isError(sr
));
614 // Not so simple: poke the server
615 vg_assert(img
->source
.session_id
> 0);
617 = mk_Frame_le64_le64_le64("READ", img
->source
.session_id
, off
, len
);
618 Frame
* res
= do_transaction(img
->source
.fd
, req
);
619 free_Frame(req
); req
= NULL
;
620 if (!res
) goto server_fail
;
621 ULong rx_session_id
= 0, rx_off
= 0, rx_len
= 0, rx_zdata_len
= 0;
622 UChar
* rx_data
= NULL
;
623 /* Pretty confusing. rx_sessionid, rx_off and rx_len are copies
624 of the values that we requested in the READ frame just above,
625 so we can be sure that the server is responding to the right
626 request. It just copies them from the request into the
627 response. rx_data is the actual data, and rx_zdata_len is
628 its compressed length. Hence rx_len must equal len, but
629 rx_zdata_len can be different -- smaller, hopefully.. */
630 if (!parse_Frame_le64_le64_le64_bytes
631 (res
, "RDOK", &rx_session_id
, &rx_off
,
632 &rx_len
, &rx_data
, &rx_zdata_len
))
634 if (rx_session_id
!= img
->source
.session_id
635 || rx_off
!= off
|| rx_len
!= len
|| rx_data
== NULL
)
638 //VG_(memcpy)(&ce->data[0], rx_data, len);
639 // Decompress into the destination buffer
640 // Tell the lib the max number of output bytes it can write.
641 // After the call, this holds the number of bytes actually written,
642 // and it's an error if it is different.
643 lzo_uint out_len
= len
;
644 Int lzo_rc
= lzo1x_decompress_safe(rx_data
, rx_zdata_len
,
645 &ce
->data
[0], &out_len
,
647 Bool ok
= lzo_rc
== LZO_E_OK
&& out_len
== len
;
648 if (!ok
) goto server_fail
;
650 free_Frame(res
); res
= NULL
;
651 goto end_of_else_clause
;
653 /* The server screwed up somehow. Now what? */
655 UChar
* reason
= NULL
;
656 if (parse_Frame_asciiz(res
, "FAIL", &reason
)) {
657 VG_(umsg
)("set_CEnt (reading data from DI server): fail: "
660 VG_(umsg
)("set_CEnt (reading data from DI server): fail: "
663 free_Frame(res
); res
= NULL
;
665 VG_(umsg
)("set_CEnt (reading data from DI server): fail: "
666 "server unexpectedly closed the connection\n");
668 give_up__comms_lost();
678 vg_assert(ce
== img
->ces
[entNo
]);
679 vg_assert(is_sane_CEnt("set_CEnt", img
, entNo
));
682 __attribute__((noinline
))
683 static UChar
get_slowcase ( DiImage
* img
, DiOffT off
)
686 vg_assert(off
< img
->size
);
687 vg_assert(img
->ces_used
<= CACHE_N_ENTRIES
);
689 /* Start the search at entry 1, since the fast-case function
690 checked slot zero already. */
691 for (i
= 1; i
< img
->ces_used
; i
++) {
692 vg_assert(img
->ces
[i
]);
693 if (is_in_CEnt(img
->ces
[i
], off
))
698 if (LIKELY(i
< img
->ces_used
)) {
699 // Found it. Move to the top and stop.
700 move_CEnt_to_top(img
, i
);
701 vg_assert(is_in_CEnt(img
->ces
[0], off
));
702 return img
->ces
[0]->data
[ off
- img
->ces
[0]->off
];
705 vg_assert(i
<= img
->ces_used
);
707 // It's not in any entry. Either allocate a new one or recycle the LRU
708 // one. This is where the presence of compressed sections makes things
709 // tricky. There are 4 cases to consider:
711 // (1) not from a compressed slice, we can allocate a new entry
712 // (2) not from a compressed slice, we have to recycle the LRU entry
713 // (3) from a compressed slice, we can allocate a new entry
714 // (4) from a compressed slice, we have to recycle the LRU entry
716 // Cases (3) and (4) are complex because we will have to call
717 // ML_(img_get_some) to get the compressed data. But this function is
718 // reachable from ML_(img_get_some), so we may re-enter get_slowcase a
719 // second time as a result. Given that the compressed data will be cause
720 // only cases (1) and (2) to happen, this guarantees no infinite recursion.
721 // It does however mean that we can't carry (in this function invokation)
722 // any local copies of the overall cache state across the ML_(img_get_some)
723 // call, since it may become invalidated by the recursive call to
726 // First of all, see if it is in a compressed slice, and if so, pull the
727 // compressed data into an intermediate buffer. Given the preceding
728 // comment, this is a safe place to do it, since we are not carrying any
729 // cache state here apart from the knowledge that the requested offset is
730 // not in the cache at all, and the recursive call won't change that fact.
732 CSlc
* cslc
= find_cslc(img
, off
);
736 cbuf
= ML_(dinfo_zalloc
)("di.image.get_slowcase.cbuf-1", cslc
->szC
);
737 // get compressed data
738 while (len
< cslc
->szC
)
739 len
+= ML_(img_get_some
)(cbuf
+ len
, img
, cslc
->offC
+ len
,
743 // Now we can do what we like.
744 vg_assert((cslc
== NULL
&& cbuf
== NULL
) || (cslc
!= NULL
&& cbuf
!= NULL
));
746 // Note, we can't capture this earlier, for exactly the reasons detailed
748 UInt ces_used_at_entry
= img
->ces_used
;
750 // This is the size of the CEnt that we want to have after allocation or
752 SizeT size
= (cslc
== NULL
) ? CACHE_ENTRY_SIZE
: cslc
->szD
;
755 if (img
->ces_used
< CACHE_N_ENTRIES
) {
756 /* Allocate a new cache entry, and fill it in. */
757 i
= alloc_CEnt(img
, size
, /*fromC?*/cslc
!= NULL
);
759 set_CEnt(img
, i
, off
);
760 img
->ces
[i
]->fromC
= False
;
761 vg_assert(is_sane_CEnt("get_slowcase-case-1", img
, i
));
762 vg_assert(img
->ces_used
== ces_used_at_entry
+ 1);
765 if(cslc
->typeC
== ELFCOMPRESS_ZLIB
) {
766 len
= tinfl_decompress_mem_to_mem(
767 img
->ces
[i
]->data
, cslc
->szD
,
769 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
770 | TINFL_FLAG_PARSE_ZLIB_HEADER
);
773 len
= ZSTD_decompress(
774 img
->ces
[i
]->data
, cslc
->szD
,
778 vg_assert(len
== cslc
->szD
); // sanity check on data, FIXME
779 vg_assert(cslc
->szD
== size
);
780 img
->ces
[i
]->used
= cslc
->szD
;
781 img
->ces
[i
]->off
= cslc
->offD
;
782 img
->ces
[i
]->fromC
= True
;
783 vg_assert(is_sane_CEnt("get_slowcase-case-3", img
, i
));
784 vg_assert(img
->ces_used
== ces_used_at_entry
+ 1);
786 vg_assert(img
->ces_used
== ces_used_at_entry
+ 1);
788 move_CEnt_to_top(img
, i
);
791 vg_assert(is_in_CEnt(img
->ces
[i
], off
));
793 ML_(dinfo_free
)(cbuf
);
795 return img
->ces
[i
]->data
[ off
- img
->ces
[i
]->off
];
799 /* All entries in use. Recycle the (ostensibly) LRU one. But try to find
800 a non-fromC entry to recycle, though, since discarding and reloading
801 fromC entries is very expensive. The result is that -- unless all
802 CACHE_N_ENTRIES wind up being used by decompressed slices, which is
803 highly unlikely -- we'll wind up keeping all the decompressed data in
804 the cache for its entire remaining life. We could probably do better
805 but it would make the cache management even more complex. */
806 vg_assert(img
->ces_used
== CACHE_N_ENTRIES
);
808 // Select entry to recycle.
809 for (i
= CACHE_N_ENTRIES
-1; i
> 0; i
--) {
810 if (!img
->ces
[i
]->fromC
)
813 vg_assert(i
< CACHE_N_ENTRIES
);
815 realloc_CEnt(img
, i
, size
, /*fromC?*/cslc
!= NULL
);
816 img
->ces
[i
]->size
= size
;
817 img
->ces
[i
]->used
= 0;
819 set_CEnt(img
, i
, off
);
820 img
->ces
[i
]->fromC
= False
;
821 vg_assert(is_sane_CEnt("get_slowcase-case-2", img
, i
));
824 if(cslc
->typeC
== ELFCOMPRESS_ZLIB
) {
825 len
= tinfl_decompress_mem_to_mem(
826 img
->ces
[i
]->data
, cslc
->szD
,
828 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
829 | TINFL_FLAG_PARSE_ZLIB_HEADER
);
832 len
= ZSTD_decompress(
833 img
->ces
[i
]->data
, cslc
->szD
,
836 vg_assert(len
== size
);
837 img
->ces
[i
]->used
= size
;
838 img
->ces
[i
]->off
= cslc
->offD
;
839 img
->ces
[i
]->fromC
= True
;
840 vg_assert(is_sane_CEnt("get_slowcase-case-4", img
, i
));
842 vg_assert(img
->ces_used
== ces_used_at_entry
);
844 move_CEnt_to_top(img
, i
);
847 vg_assert(is_in_CEnt(img
->ces
[i
], off
));
849 ML_(dinfo_free
)(cbuf
);
851 return img
->ces
[i
]->data
[ off
- img
->ces
[i
]->off
];
854 // This is called a lot, so do the usual fast/slow split stuff on it. */
855 static inline UChar
get ( DiImage
* img
, DiOffT off
)
857 /* Most likely case is, it's in the ces[0] position. */
858 /* ML_(img_from_local_file) requests a read for ces[0] when
859 creating the image. Hence slot zero is always non-NULL, so we
860 can skip this test. */
861 if (LIKELY(/* img->ces[0] != NULL && */
862 is_in_CEnt(img
->ces
[0], off
))) {
863 return img
->ces
[0]->data
[ off
- img
->ces
[0]->off
];
865 /* Else we'll have to fish around for it. */
866 return get_slowcase(img
, off
);
869 /* Create an image from a file in the local filesystem. This is
870 relatively straightforward. */
871 DiImage
* ML_(img_from_local_file
)(const HChar
* fullpath
)
874 struct vg_stat stat_buf
;
877 fd
= VG_(open
)(fullpath
, VKI_O_RDONLY
, 0);
881 if (VG_(fstat
)(sr_Res(fd
), &stat_buf
) != 0) {
882 VG_(close
)(sr_Res(fd
));
886 size
= stat_buf
.size
;
887 if (size
== 0 || size
== DiOffT_INVALID
888 || /* size is unrepresentable as a SizeT */
889 size
!= (DiOffT
)(SizeT
)(size
)) {
890 VG_(close
)(sr_Res(fd
));
894 DiImage
* img
= ML_(dinfo_zalloc
)("di.image.ML_iflf.1", sizeof(DiImage
));
895 img
->source
.is_local
= True
;
896 img
->source
.fd
= sr_Res(fd
);
898 img
->real_size
= size
;
900 img
->source
.name
= ML_(dinfo_strdup
)("di.image.ML_iflf.2", fullpath
);
904 /* img->ces is already zeroed out */
905 vg_assert(img
->source
.fd
>= 0);
907 /* Force the zeroth entry to be the first chunk of the file.
908 That's likely to be the first part that's requested anyway, and
909 loading it at this point forcing img->cent[0] to always be
910 non-empty, thereby saving us an is-it-empty check on the fast
912 UInt entNo
= alloc_CEnt(img
, CACHE_ENTRY_SIZE
, False
/*!fromC*/);
913 vg_assert(entNo
== 0);
919 /* As above, but uses fd rather than filename */
920 DiImage
* ML_(img_from_fd
)(Int fd
, const HChar
* fullpath
)
922 struct vg_stat stat_buf
;
925 if (VG_(fstat
)(fd
, &stat_buf
) != 0) {
929 size
= stat_buf
.size
;
930 if (size
== 0 || size
== DiOffT_INVALID
931 || /* size is unrepresentable as a SizeT */
932 size
!= (DiOffT
)(SizeT
)(size
)) {
936 DiImage
* img
= ML_(dinfo_zalloc
)("di.image.ML_iflf.1", sizeof(DiImage
));
937 img
->source
.is_local
= True
;
940 img
->real_size
= size
;
942 img
->source
.name
= ML_(dinfo_strdup
)("di.image.ML_iflf.2", fullpath
);
946 /* img->ces is already zeroed out */
947 vg_assert(img
->source
.fd
>= 0);
949 /* Force the zeroth entry to be the first chunk of the file.
950 That's likely to be the first part that's requested anyway, and
951 loading it at this point forcing img->cent[0] to always be
952 non-empty, thereby saving us an is-it-empty check on the fast
954 UInt entNo
= alloc_CEnt(img
, CACHE_ENTRY_SIZE
, False
/*!fromC*/);
955 vg_assert(entNo
== 0);
963 /* Create an image from a file on a remote debuginfo server. This is
964 more complex. There are lots of ways in which it can fail. */
965 DiImage
* ML_(img_from_di_server
)(const HChar
* filename
,
966 const HChar
* serverAddr
)
968 if (filename
== NULL
|| serverAddr
== NULL
)
971 /* The filename must be a plain filename -- no slashes at all. */
972 if (VG_(strchr
)(filename
, '/') != NULL
)
975 /* Try to connect to the server. A side effect of this is to parse
976 and reject, if syntactically invalid, |serverAddr|. Reasons why
978 - serverAddr is not of the form d.d.d.d:d or d.d.d.d
979 - attempt to connect to that address:port failed
981 Int sd
= VG_(connect_via_socket
)(serverAddr
);
984 if (!set_blocking(sd
))
987 Int sr
= VG_(setsockopt
)(sd
, VKI_IPPROTO_TCP
, VKI_TCP_NODELAY
,
991 /* Ok, we got a connection. Ask it for version string, so as to be
992 reasonably sure we're talking to an instance of
993 auxprogs/valgrind-di-server and not to some other random program
994 that happens to be listening on that port. */
995 Frame
* req
= mk_Frame_noargs("VERS");
996 Frame
* res
= do_transaction(sd
, req
);
998 goto fail
; // do_transaction failed?!
1000 if (!parse_Frame_asciiz(res
, "VEOK", &vstr
))
1001 goto fail
; // unexpected response kind, or invalid ID string
1003 if (VG_(strcmp
)("Valgrind Debuginfo Server, Version 1",
1004 (const HChar
*)vstr
) != 0)
1005 goto fail
; // wrong version string
1011 /* Server seems plausible. Present it with the name of the file we
1012 want and see if it'll give us back a session ID for it. */
1013 req
= mk_Frame_asciiz("OPEN", filename
);
1014 res
= do_transaction(sd
, req
);
1017 ULong session_id
= 0, size
= 0;
1018 if (!parse_Frame_le64_le64(res
, "OPOK", &session_id
, &size
))
1025 /* We have a session ID. We're ready to roll. */
1026 DiImage
* img
= ML_(dinfo_zalloc
)("di.image.ML_ifds.1", sizeof(DiImage
));
1027 img
->source
.is_local
= False
;
1028 img
->source
.fd
= sd
;
1029 img
->source
.session_id
= session_id
;
1031 img
->real_size
= size
;
1033 img
->source
.name
= ML_(dinfo_zalloc
)("di.image.ML_ifds.2",
1034 20 + VG_(strlen
)(filename
)
1035 + VG_(strlen
)(serverAddr
));
1036 VG_(sprintf
)(img
->source
.name
, "%s at %s", filename
, serverAddr
);
1041 /* img->ces is already zeroed out */
1042 vg_assert(img
->source
.fd
>= 0);
1044 /* See comment on equivalent bit in ML_(img_from_local_file) for
1046 UInt entNo
= alloc_CEnt(img
, CACHE_ENTRY_SIZE
, False
/*!fromC*/);
1047 vg_assert(entNo
== 0);
1048 set_CEnt(img
, 0, 0);
1055 UChar
* reason
= NULL
;
1056 if (parse_Frame_asciiz(res
, "FAIL", &reason
)) {
1057 // HACK: if it's just telling us that the file can't
1058 // be opened, don't print it, else we'll get flooded with
1059 // such complaints, one for each main object for which there
1060 // isn't a debuginfo file on the server.
1061 if (0 != VG_(strcmp
)((const HChar
*)reason
, "OPEN: cannot open file"))
1062 VG_(umsg
)("ML_(img_from_di_server): fail: %s\n", reason
);
1064 VG_(umsg
)("ML_(img_from_di_server): fail: unknown reason\n");
1072 DiOffT
ML_(img_mark_compressed_part
)(DiImage
* img
, DiOffT offset
, SizeT szC
,
1073 SizeT szD
, UChar typeC
)
1076 vg_assert(img
!= NULL
);
1077 vg_assert(offset
+ szC
<= img
->size
);
1079 if (img
->cslc_used
== img
->cslc_size
) {
1080 img
->cslc_size
+= COMPRESSED_SLICE_ARRAY_GROW_SIZE
;
1081 img
->cslc
= ML_(dinfo_realloc
)("di.image.ML_img_mark_compressed_part.1",
1082 img
->cslc
, img
->cslc_size
* sizeof(CSlc
));
1086 img
->cslc
[img
->cslc_used
].offC
= offset
;
1087 img
->cslc
[img
->cslc_used
].szC
= szC
;
1088 img
->cslc
[img
->cslc_used
].offD
= img
->size
;
1089 img
->cslc
[img
->cslc_used
].szD
= szD
;
1090 img
->cslc
[img
->cslc_used
].typeC
= typeC
;
1096 void ML_(img_free
)(DiImage
* img
)
1098 vg_assert(img
!= NULL
);
1100 /* Free up the cache entries, ultimately |img| itself. */
1102 vg_assert(img
->ces_used
<= CACHE_N_ENTRIES
);
1103 for (i
= 0; i
< img
->ces_used
; i
++) {
1104 ML_(dinfo_free
)(img
->ces
[i
]);
1106 /* Take the opportunity to sanity check the rest. */
1107 for (i
= i
; i
< img
->ces_used
; i
++) {
1108 vg_assert(img
->ces
[i
] == NULL
);
1110 ML_(dinfo_free
)(img
->source
.name
);
1111 ML_(dinfo_free
)(img
->cslc
);
1112 ML_(dinfo_free
)(img
);
1115 void ML_(img_done
)(DiImage
* img
)
1117 vg_assert(img
!= NULL
);
1118 if (img
->source
.is_local
) {
1119 /* Close the file; nothing else to do. */
1120 vg_assert(img
->source
.session_id
== 0);
1121 VG_(close
)(img
->source
.fd
);
1123 /* Close the socket. The server can detect this and will scrub
1124 the connection when it happens, so there's no need to tell it
1125 explicitly by sending it a "CLOSE" message, or any such. */
1126 vg_assert(img
->source
.session_id
!= 0);
1127 VG_(close
)(img
->source
.fd
);
1135 DiOffT
ML_(img_size
)(const DiImage
* img
)
1137 vg_assert(img
!= NULL
);
1141 DiOffT
ML_(img_real_size
)(const DiImage
* img
)
1143 vg_assert(img
!= NULL
);
1144 return img
->real_size
;
1147 inline Bool
ML_(img_valid
)(const DiImage
* img
, DiOffT offset
, SizeT size
)
1149 vg_assert(img
!= NULL
);
1150 vg_assert(offset
!= DiOffT_INVALID
);
1151 return img
->size
> 0 && offset
+ size
<= (DiOffT
)img
->size
;
1154 __attribute__((noinline
))
1155 static void ensure_valid_failed (const DiImage
* img
, DiOffT offset
, SizeT size
,
1156 const HChar
* caller
)
1158 VG_(umsg
)("Valgrind: debuginfo reader: ensure_valid failed:\n");
1159 VG_(umsg
)("Valgrind: during call to %s\n", caller
);
1160 VG_(umsg
)("Valgrind: request for range [%llu, +%lu) exceeds\n",
1162 VG_(umsg
)("Valgrind: valid image size of %lu for image:\n",
1164 VG_(umsg
)("Valgrind: \"%s\"\n", img
->source
.name
);
1165 give_up__image_overrun();
1168 /* Check the given range is valid, and if not, shut down the system.
1169 An invalid range would imply that we're trying to read outside the
1170 image, which normally means the image is corrupted somehow, or the
1171 caller is buggy. Recovering is too complex, and we have
1172 probably-corrupt debuginfo, so just give up. */
1173 static void ensure_valid(const DiImage
* img
, DiOffT offset
, SizeT size
,
1174 const HChar
* caller
)
1176 if (LIKELY(ML_(img_valid
)(img
, offset
, size
)))
1179 ensure_valid_failed(img
, offset
, size
, caller
);
1183 void ML_(img_get
)(/*OUT*/void* dst
,
1184 DiImage
* img
, DiOffT offset
, SizeT size
)
1186 vg_assert(img
!= NULL
);
1187 vg_assert(size
> 0);
1188 ensure_valid(img
, offset
, size
, "ML_(img_get)");
1190 for (i
= 0; i
< size
; i
++) {
1191 ((UChar
*)dst
)[i
] = get(img
, offset
+ i
);
1195 SizeT
ML_(img_get_some
)(/*OUT*/void* dst
,
1196 DiImage
* img
, DiOffT offset
, SizeT size
)
1198 vg_assert(img
!= NULL
);
1199 vg_assert(size
> 0);
1200 ensure_valid(img
, offset
, size
, "ML_(img_get_some)");
1201 UChar
* dstU
= (UChar
*)dst
;
1202 /* Use |get| in the normal way to get the first byte of the range.
1203 This guarantees to put the cache entry containing |offset| in
1205 dstU
[0] = get(img
, offset
);
1206 /* Now just read as many bytes as we can (or need) directly out of
1207 entry zero, without bothering to call |get| each time. */
1208 const CEnt
* ce
= img
->ces
[0];
1209 vg_assert(ce
&& ce
->used
>= 1);
1210 vg_assert(is_in_CEnt(ce
, offset
));
1211 SizeT nToCopy
= size
- 1;
1212 SizeT nAvail
= (SizeT
)(ce
->used
- (offset
+ 1 - ce
->off
));
1213 vg_assert(nAvail
<= ce
->used
-1);
1214 if (nAvail
< nToCopy
) nToCopy
= nAvail
;
1215 VG_(memcpy
)(&dstU
[1], &ce
->data
[offset
+ 1 - ce
->off
], nToCopy
);
1220 SizeT
ML_(img_strlen
)(DiImage
* img
, DiOffT off
)
1222 ensure_valid(img
, off
, 1, "ML_(img_strlen)");
1224 while (get(img
, off
+ i
) != 0) i
++;
1228 HChar
* ML_(img_strdup
)(DiImage
* img
, const HChar
* cc
, DiOffT offset
)
1230 ensure_valid(img
, offset
, 1, "ML_(img_strdup)");
1231 SizeT len
= ML_(img_strlen
)(img
, offset
);
1232 HChar
* res
= ML_(dinfo_zalloc
)(cc
, len
+1);
1234 for (i
= 0; i
< len
; i
++) {
1235 res
[i
] = get(img
, offset
+i
);
1237 vg_assert(res
[len
] == 0);
1241 Int
ML_(img_strcmp
)(DiImage
* img
, DiOffT off1
, DiOffT off2
)
1243 ensure_valid(img
, off1
, 1, "ML_(img_strcmp)(first arg)");
1244 ensure_valid(img
, off2
, 1, "ML_(img_strcmp)(second arg)");
1246 UChar c1
= get(img
, off1
);
1247 UChar c2
= get(img
, off2
);
1248 if (c1
< c2
) return -1;
1249 if (c1
> c2
) return 1;
1250 if (c1
== 0) return 0;
1255 Int
ML_(img_strcmp_c
)(DiImage
* img
, DiOffT off1
, const HChar
* str2
)
1257 ensure_valid(img
, off1
, 1, "ML_(img_strcmp_c)");
1259 UChar c1
= get(img
, off1
);
1260 UChar c2
= *(const UChar
*)str2
;
1261 if (c1
< c2
) return -1;
1262 if (c1
> c2
) return 1;
1263 if (c1
== 0) return 0;
1268 Int
ML_(img_strcmp_n
)(DiImage
* img
, DiOffT off1
, const HChar
* str2
, Word n
)
1270 ensure_valid(img
, off1
, 1, "ML_(img_strcmp_c)");
1272 UChar c1
= get(img
, off1
);
1273 UChar c2
= *(const UChar
*)str2
;
1274 if (c1
< c2
) return -1;
1275 if (c1
> c2
) return 1;
1276 if (c1
== 0) return 0;
1277 off1
++; str2
++; --n
;
1282 UChar
ML_(img_get_UChar
)(DiImage
* img
, DiOffT offset
)
1284 ensure_valid(img
, offset
, 1, "ML_(img_get_UChar)");
1285 return get(img
, offset
);
1288 UShort
ML_(img_get_UShort
)(DiImage
* img
, DiOffT offset
)
1291 ML_(img_get
)(&r
, img
, offset
, sizeof(r
));
1295 UInt
ML_(img_get_UInt
)(DiImage
* img
, DiOffT offset
)
1298 ML_(img_get
)(&r
, img
, offset
, sizeof(r
));
1302 ULong
ML_(img_get_ULong
)(DiImage
* img
, DiOffT offset
)
1305 ML_(img_get
)(&r
, img
, offset
, sizeof(r
));
1311 * This routine for calculating the CRC for a separate debug file
1312 * is GPLed code borrowed from GNU binutils.
1314 UInt
ML_(img_calc_gnu_debuglink_crc32
)(DiImage
* img
)
1316 static const UInt crc32_table
[256] =
1318 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
1319 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
1320 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
1321 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
1322 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
1323 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
1324 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
1325 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
1326 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
1327 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
1328 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
1329 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
1330 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
1331 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
1332 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
1333 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
1334 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
1335 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
1336 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
1337 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
1338 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
1339 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
1340 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
1341 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
1342 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
1343 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
1344 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
1345 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
1346 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
1347 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
1348 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
1349 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
1350 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
1351 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
1352 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
1353 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
1354 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
1355 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
1356 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
1357 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
1358 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
1359 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
1360 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
1361 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
1362 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
1363 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
1364 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
1365 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
1366 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
1367 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
1368 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
1372 vg_assert(img
!= NULL
);
1374 /* If the image is local, calculate the CRC here directly. If it's
1375 remote, forward the request to the server. */
1376 if (img
->source
.is_local
) {
1377 /* Work through the image in 1 KB chunks. */
1378 UInt crc
= 0xFFFFFFFF;
1379 DiOffT img_szB
= ML_(img_size
)(img
);
1380 DiOffT curr_off
= 0;
1382 vg_assert(curr_off
<= img_szB
);
1383 if (curr_off
== img_szB
) break;
1384 DiOffT avail
= img_szB
- curr_off
;
1385 vg_assert(avail
> 0 && avail
<= img_szB
);
1386 if (avail
> 1024) avail
= 1024;
1388 SizeT nGot
= ML_(img_get_some
)(buf
, img
, curr_off
, avail
);
1389 vg_assert(nGot
>= 1 && nGot
<= avail
);
1391 for (i
= 0; i
< (UInt
)nGot
; i
++)
1392 crc
= crc32_table
[(crc
^ buf
[i
]) & 0xff] ^ (crc
>> 8);
1395 return ~crc
& 0xFFFFFFFF;
1397 Frame
* req
= mk_Frame_noargs("CRC3");
1398 Frame
* res
= do_transaction(img
->source
.fd
, req
);
1399 if (!res
) goto remote_crc_fail
;
1401 if (!parse_Frame_le64(res
, "CROK", &crc32
)) goto remote_crc_fail
;
1402 if ((crc32
& ~0xFFFFFFFFULL
) != 0) goto remote_crc_fail
;
1408 // XXXX common this up with the READ diagnostic cases
1410 UChar
* reason
= NULL
;
1411 if (parse_Frame_asciiz(res
, "FAIL", &reason
)) {
1412 VG_(umsg
)("img_calc_gnu_debuglink_crc32: fail: "
1415 VG_(umsg
)("img_calc_gnu_debuglink_crc32: fail: "
1416 "unknown reason\n");
1419 VG_(umsg
)("img_calc_gnu_debuglink_crc32: fail: "
1420 "server unexpectedly closed the connection\n");
1423 if (req
) free_Frame(req
);
1424 if (res
) free_Frame(res
);
1426 give_up__comms_lost();
1434 ////////////////////////////////////////////////////
1435 #include "minilzo-inl.c"
1437 /*--------------------------------------------------------------------*/
1438 /*--- end image.c ---*/
1439 /*--------------------------------------------------------------------*/