15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @file parse_dump.c
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * parse a jit dump file
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @remark Copyright 2007 OProfile authors
658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * @remark Read the file COPYING
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @author Jens Wilke
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @Modifications Maynard Johnson
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @Modifications Philippe Elie
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @Modifications Daniel Hansel
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Copyright IBM Corporation 2007
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "opjitconv.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "jitdump.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "opd_printf.h"
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "op_libiberty.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* parse a code load record and add the entry to the jitentry list */
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static int parse_code_load(void const * ptr_arg, int size,
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			   unsigned long long end_time)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	struct jitentry * entry;
30c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch	int rc = OP_JIT_CONV_OK;
31c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch	char const * ptr = ptr_arg;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct jr_code_load const * rec = ptr_arg;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	char const * end;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	size_t padding_count, rec_totalsize;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	end = rec->code_addr ? ptr + size : NULL;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	entry = xcalloc(1, sizeof(struct jitentry));
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	// jitentry constructor
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	entry->next = NULL;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ptr += sizeof(*rec);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* symbol_name can be malloced so we cast away the constness. */
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	entry->symbol_name = (char *)ptr;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	entry->sym_name_malloced = 0;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ptr += strlen(ptr) + 1;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	entry->code = rec->code_addr ? ptr : NULL;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	entry->vma = rec->vma;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	entry->code_size = rec->code_size;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	entry->section = NULL;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	entry->life_start = rec->timestamp;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	// if nothing else is known the symbol lives till the end of the
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	// sampling run, this value may be overwritten by an unload record1
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	// later
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	entry->life_end = end_time;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	// build list
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	entry->next = jitentry_list;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	jitentry_list = entry;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* padding bytes are calculated over the complete record
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	 * (i.e. header + symbol name + code)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rec_totalsize = sizeof(*rec) + strlen(entry->symbol_name) + 1 + entry->code_size;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	padding_count = PADDING_8ALIGNED(rec_totalsize);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	verbprintf(debug, "record0: name=%s, vma=%llx, code_size=%i, "
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		   "padding_count=%llu, life_start=%lli, life_end=%lli\n", entry->symbol_name,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   entry->vma, entry->code_size, (unsigned long long)padding_count, entry->life_start,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   entry->life_end);
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	/* If end == NULL, the dump does not include code, and this sanity
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * check is skipped.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	if (end && (ptr + entry->code_size + padding_count != end)) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		verbprintf(debug, "record total size mismatch\n");
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rc = OP_JIT_CONV_FAIL;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rc;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * parse a code unload record. Search for existing record with this code
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * address and fill life_end field with the timestamp. linear search not very
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * efficient. FIXME: inefficient
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void parse_code_unload(void const * ptr, unsigned long long end_time)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct jr_code_unload const * rec = ptr;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct jitentry * entry;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	verbprintf(debug,"record1: vma=%llx, life_end=%lli\n",
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		   rec->vma, rec->timestamp);
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	/**
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	 * Normally we won't get a jr_code_unload with a zero time stamp or
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * a zero code address. The code address is directly provided by the JVMTI.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * The documentation of JVMTI does not say anything about the address value if
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * it could be zero or not. Therefore it is only a sanity check at the moment.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rec->timestamp > 0 && rec->vma != 0) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		for (entry = jitentry_list; entry; entry = entry->next) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (entry->vma == rec->vma &&
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    entry->life_end == end_time) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)				entry->life_end = rec->timestamp;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				verbprintf(debug,"matching record found\n");
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				break;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/*
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * There is no real parsing here, we just record a pointer to the data,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we will interpret on the fly the record when building the bfd file.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void parse_code_debug_info(void const * ptr, void const * end,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  unsigned long long end_time)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct jr_code_debug_info const * rec = ptr;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct jitentry_debug_line * debug_line =
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmalloc(sizeof(struct jitentry_debug_line));
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	debug_line->data = rec;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	debug_line->end = end;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	debug_line->life_start = rec->timestamp;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	debug_line->life_end = end_time;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	debug_line->next = jitentry_debug_line_list;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	jitentry_debug_line_list = debug_line;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* parse all entries in the jit dump file and build jitentry_list.
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the code needs to check always whether there is enough
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to read remaining. this is because the file may be written to
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * concurrently. */
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int parse_entries(void const * ptr, void const * end,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 unsigned long long end_time)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	int rc = OP_JIT_CONV_OK;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	struct jr_prefix const * rec = ptr;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while ((void *)rec + sizeof(struct jr_prefix) < end) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (((void *) rec + rec->total_size) > end) {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			verbprintf(debug, "record past end of file\n");
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			rc = OP_JIT_CONV_FAIL;
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			break;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		switch (rec->id) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case JIT_CODE_LOAD:
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (parse_code_load(rec, rec->total_size, end_time)) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				rc = OP_JIT_CONV_FAIL;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)				break;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			break;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		case JIT_CODE_UNLOAD:
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			parse_code_unload(rec, end_time);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		// end of VM live time, no action
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		case JIT_CODE_CLOSE:
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case JIT_CODE_DEBUG_INFO:
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (rec->total_size == 0) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				/* op_write_debug_line_info() ensures to write records with
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 * totalsize > 0.
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)				 */
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)				rc = OP_JIT_CONV_FAIL;
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)				break;
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			}
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			parse_code_debug_info(rec, end, end_time);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			break;
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		default:
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			verbprintf(debug, "unknown record type\n");
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			rc = OP_JIT_CONV_FAIL;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		/* advance to next record (incl. possible padding bytes) */
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		rec = (void *)rec + rec->total_size;
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	}
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rc;
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* parse the jit dump header information
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The ptr arg is the address of the pointer to the mmapped
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * file, which we modify below.
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static int parse_header(char const ** ptr, char const * end)
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	int rc = OP_JIT_CONV_OK;
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	struct jitheader const * header;
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	if (*ptr + sizeof(struct jitheader) >= end) {
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		verbprintf(debug,
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			   "opjitconv: EOF in jitdump file, no header\n");
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		rc = OP_JIT_CONV_FAIL;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		goto out;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	header = (struct jitheader *)*ptr;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (header->magic != JITHEADER_MAGIC) {
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		verbprintf(debug, "opjitconv: Wrong jitdump file magic\n");
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rc = OP_JIT_CONV_FAIL;
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		goto out;
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	}
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	if (header->version != JITHEADER_VERSION) {
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		verbprintf(debug, "opjitconv: Wrong jitdump file version\n");
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rc = OP_JIT_CONV_FAIL;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto out;
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	}
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	if (*ptr + header->totalsize > end) {
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		verbprintf(debug, "opjitconv: EOF in jitdump file, not enough "
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			   "data for header\n");
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rc = OP_JIT_CONV_FAIL;
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch		goto out;
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch	}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	dump_bfd_arch = header->bfd_arch;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	dump_bfd_mach = header->bfd_mach;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	dump_bfd_target_name = header->bfd_target;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	verbprintf(debug, "header: bfd-arch=%i, bfd-mach=%i,"
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		   " bfd_target_name=%s\n", dump_bfd_arch, dump_bfd_mach,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   dump_bfd_target_name);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	*ptr = *ptr + header->totalsize;
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)out:
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	return rc;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
234c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
235c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Read in the memory mapped jitdump file.
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Build up jitentry structure and set global variables.
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)*/
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int parse_all(void const * start, void const * end,
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	      unsigned long long end_time)
241c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch{
242c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch	char const * ptr = start;
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	if (!parse_header(&ptr, end))
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		return parse_entries(ptr, end, end_time);
2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch	else
2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch		return OP_JIT_CONV_FAIL;
2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)