hotspot/src/share/tools/hsdis/hsdis.c
author coleenp
Mon, 02 Jul 2012 13:11:28 -0400
changeset 13196 6b399731153b
parent 11782 38cbdb77b3d1
child 13873 7b72e3873785
permissions -rw-r--r--
Merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
347
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
     1
/*
8921
14bfe81f2a9d 7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents: 8496
diff changeset
     2
 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
347
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
     4
 *
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
     7
 * published by the Free Software Foundation.
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
     8
 *
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    13
 * accompanied this code).
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    14
 *
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 3261
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 3261
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 3261
diff changeset
    21
 * questions.
347
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    22
 *
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    23
 */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    24
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    25
/* hsdis.c -- dump a range of addresses as native instructions
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    26
   This implements the plugin protocol required by the
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    27
   HotSpot PrintAssembly option.
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    28
*/
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    29
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    30
#include "hsdis.h"
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    31
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    32
#include <sysdep.h>
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    33
#include <libiberty.h>
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    34
#include <bfd.h>
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    35
#include <dis-asm.h>
2564
85c3ae53ca1c 6684007: PrintAssembly plugin not available for linux or windows
never
parents: 347
diff changeset
    36
#include <inttypes.h>
347
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    37
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    38
#ifndef bool
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    39
#define bool int
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    40
#define true 1
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    41
#define false 0
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    42
#endif /*bool*/
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    43
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    44
/* short names for stuff in hsdis.h */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    45
typedef decode_instructions_event_callback_ftype  event_callback_t;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    46
typedef decode_instructions_printf_callback_ftype printf_callback_t;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    47
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    48
/* disassemble_info.application_data object */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    49
struct hsdis_app_data {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    50
  /* the arguments to decode_instructions */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    51
  uintptr_t start; uintptr_t end;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    52
  event_callback_t  event_callback;  void* event_stream;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    53
  printf_callback_t printf_callback; void* printf_stream;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    54
  bool losing;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    55
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    56
  /* the architecture being disassembled */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    57
  const char* arch_name;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    58
  const bfd_arch_info_type* arch_info;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    59
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    60
  /* the disassembler we are going to use: */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    61
  disassembler_ftype      dfn;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    62
  struct disassemble_info dinfo; /* the actual struct! */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    63
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    64
  char mach_option[64];
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    65
  char insn_options[256];
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    66
};
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    67
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    68
#define DECL_APP_DATA(dinfo) \
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    69
  struct hsdis_app_data* app_data = (struct hsdis_app_data*) (dinfo)->application_data
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    70
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    71
#define DECL_EVENT_CALLBACK(app_data) \
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    72
  event_callback_t  event_callback = (app_data)->event_callback; \
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    73
  void*             event_stream   = (app_data)->event_stream
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    74
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    75
#define DECL_PRINTF_CALLBACK(app_data) \
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    76
  printf_callback_t  printf_callback = (app_data)->printf_callback; \
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    77
  void*              printf_stream   = (app_data)->printf_stream
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    78
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    79
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    80
static void print_help(struct hsdis_app_data* app_data,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    81
                       const char* msg, const char* arg);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    82
static void setup_app_data(struct hsdis_app_data* app_data,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    83
                           const char* options);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    84
static const char* format_insn_close(const char* close,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    85
                                     disassemble_info* dinfo,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    86
                                     char* buf, size_t bufsize);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    87
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    88
void*
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    89
#ifdef DLL_ENTRY
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    90
  DLL_ENTRY
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    91
#endif
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    92
decode_instructions(void* start_pv, void* end_pv,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    93
                    event_callback_t  event_callback_arg,  void* event_stream_arg,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    94
                    printf_callback_t printf_callback_arg, void* printf_stream_arg,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    95
                    const char* options) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    96
  struct hsdis_app_data app_data;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    97
  memset(&app_data, 0, sizeof(app_data));
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    98
  app_data.start = (uintptr_t) start_pv;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
    99
  app_data.end   = (uintptr_t) end_pv;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   100
  app_data.event_callback  = event_callback_arg;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   101
  app_data.event_stream    = event_stream_arg;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   102
  app_data.printf_callback = printf_callback_arg;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   103
  app_data.printf_stream   = printf_stream_arg;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   104
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   105
  setup_app_data(&app_data, options);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   106
  char buf[128];
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   107
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   108
  {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   109
    /* now reload everything from app_data: */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   110
    DECL_EVENT_CALLBACK(&app_data);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   111
    DECL_PRINTF_CALLBACK(&app_data);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   112
    uintptr_t start = app_data.start;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   113
    uintptr_t end   = app_data.end;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   114
    uintptr_t p     = start;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   115
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   116
    (*event_callback)(event_stream, "insns", (void*)start);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   117
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   118
    (*event_callback)(event_stream, "mach name='%s'",
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   119
                      (void*) app_data.arch_info->printable_name);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   120
    if (app_data.dinfo.bytes_per_line != 0) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   121
      (*event_callback)(event_stream, "format bytes-per-line='%p'/",
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   122
                        (void*)(intptr_t) app_data.dinfo.bytes_per_line);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   123
    }
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   124
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   125
    while (p < end && !app_data.losing) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   126
      (*event_callback)(event_stream, "insn", (void*) p);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   127
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   128
      /* reset certain state, so we can read it with confidence */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   129
      app_data.dinfo.insn_info_valid    = 0;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   130
      app_data.dinfo.branch_delay_insns = 0;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   131
      app_data.dinfo.data_size          = 0;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   132
      app_data.dinfo.insn_type          = 0;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   133
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   134
      int size = (*app_data.dfn)((bfd_vma) p, &app_data.dinfo);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   135
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   136
      if (size > 0)  p += size;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   137
      else           app_data.losing = true;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   138
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   139
      const char* insn_close = format_insn_close("/insn", &app_data.dinfo,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   140
                                                 buf, sizeof(buf));
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   141
      (*event_callback)(event_stream, insn_close, (void*) p);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   142
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   143
      /* follow each complete insn by a nice newline */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   144
      (*printf_callback)(printf_stream, "\n");
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   145
    }
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   146
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   147
    (*event_callback)(event_stream, "/insns", (void*) p);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   148
    return (void*) p;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   149
  }
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   150
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   151
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   152
/* take the address of the function, for luck, and also test the typedef: */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   153
const decode_instructions_ftype decode_instructions_address = &decode_instructions;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   154
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   155
static const char* format_insn_close(const char* close,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   156
                                     disassemble_info* dinfo,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   157
                                     char* buf, size_t bufsize) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   158
  if (!dinfo->insn_info_valid)
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   159
    return close;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   160
  enum dis_insn_type itype = dinfo->insn_type;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   161
  int dsize = dinfo->data_size, delays = dinfo->branch_delay_insns;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   162
  if ((itype == dis_nonbranch && (dsize | delays) == 0)
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   163
      || (strlen(close) + 3*20 > bufsize))
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   164
    return close;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   165
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   166
  const char* type = "unknown";
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   167
  switch (itype) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   168
  case dis_nonbranch:   type = NULL;         break;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   169
  case dis_branch:      type = "branch";     break;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   170
  case dis_condbranch:  type = "condbranch"; break;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   171
  case dis_jsr:         type = "jsr";        break;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   172
  case dis_condjsr:     type = "condjsr";    break;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   173
  case dis_dref:        type = "dref";       break;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   174
  case dis_dref2:       type = "dref2";      break;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   175
  }
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   176
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   177
  strcpy(buf, close);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   178
  char* p = buf;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   179
  if (type)    sprintf(p += strlen(p), " type='%s'", type);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   180
  if (dsize)   sprintf(p += strlen(p), " dsize='%d'", dsize);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   181
  if (delays)  sprintf(p += strlen(p), " delay='%d'", delays);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   182
  return buf;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   183
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   184
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   185
/* handler functions */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   186
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   187
static int
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   188
hsdis_read_memory_func(bfd_vma memaddr,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   189
                       bfd_byte* myaddr,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   190
                       unsigned int length,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   191
                       struct disassemble_info* dinfo) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   192
  uintptr_t memaddr_p = (uintptr_t) memaddr;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   193
  DECL_APP_DATA(dinfo);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   194
  if (memaddr_p + length > app_data->end) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   195
    /* read is out of bounds */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   196
    return EIO;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   197
  } else {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   198
    memcpy(myaddr, (bfd_byte*) memaddr_p, length);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   199
    return 0;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   200
  }
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   201
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   202
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   203
static void
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   204
hsdis_print_address_func(bfd_vma vma, struct disassemble_info* dinfo) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   205
  /* the actual value to print: */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   206
  void* addr_value = (void*) (uintptr_t) vma;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   207
  DECL_APP_DATA(dinfo);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   208
  DECL_EVENT_CALLBACK(app_data);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   209
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   210
  /* issue the event: */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   211
  void* result =
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   212
    (*event_callback)(event_stream, "addr/", addr_value);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   213
  if (result == NULL) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   214
    /* event declined */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   215
    generic_print_address(vma, dinfo);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   216
  }
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   217
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   218
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   219
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   220
/* configuration */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   221
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   222
static void set_optional_callbacks(struct hsdis_app_data* app_data);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   223
static void parse_caller_options(struct hsdis_app_data* app_data,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   224
                                 const char* caller_options);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   225
static const char* native_arch_name();
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   226
static enum bfd_endian native_endian();
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   227
static const bfd_arch_info_type* find_arch_info(const char* arch_nane);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   228
static bfd* get_native_bfd(const bfd_arch_info_type* arch_info,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   229
                           /* to avoid malloc: */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   230
                           bfd* empty_bfd, bfd_target* empty_xvec);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   231
static void init_disassemble_info_from_bfd(struct disassemble_info* dinfo,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   232
                                           void *stream,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   233
                                           fprintf_ftype fprintf_func,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   234
                                           bfd* bfd,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   235
                                           char* disassembler_options);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   236
static void parse_fake_insn(disassembler_ftype dfn,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   237
                            struct disassemble_info* dinfo);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   238
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   239
static void setup_app_data(struct hsdis_app_data* app_data,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   240
                           const char* caller_options) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   241
  /* Make reasonable defaults for null callbacks.
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   242
     A non-null stream for a null callback is assumed to be a FILE* for output.
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   243
     Events are rendered as XML.
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   244
  */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   245
  set_optional_callbacks(app_data);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   246
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   247
  /* Look into caller_options for anything interesting. */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   248
  if (caller_options != NULL)
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   249
    parse_caller_options(app_data, caller_options);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   250
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   251
  /* Discover which architecture we are going to disassemble. */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   252
  app_data->arch_name = &app_data->mach_option[0];
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   253
  if (app_data->arch_name[0] == '\0')
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   254
    app_data->arch_name = native_arch_name();
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   255
  app_data->arch_info = find_arch_info(app_data->arch_name);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   256
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   257
  /* Make a fake bfd to hold the arch. and byteorder info. */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   258
  struct {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   259
    bfd_target empty_xvec;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   260
    bfd        empty_bfd;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   261
  } buf;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   262
  bfd* native_bfd = get_native_bfd(app_data->arch_info,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   263
                                   /* to avoid malloc: */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   264
                                   &buf.empty_bfd, &buf.empty_xvec);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   265
  init_disassemble_info_from_bfd(&app_data->dinfo,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   266
                                 app_data->printf_stream,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   267
                                 app_data->printf_callback,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   268
                                 native_bfd,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   269
                                 app_data->insn_options);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   270
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   271
  /* Finish linking together the various callback blocks. */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   272
  app_data->dinfo.application_data = (void*) app_data;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   273
  app_data->dfn = disassembler(native_bfd);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   274
  app_data->dinfo.print_address_func = hsdis_print_address_func;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   275
  app_data->dinfo.read_memory_func = hsdis_read_memory_func;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   276
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   277
  if (app_data->dfn == NULL) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   278
    const char* bad = app_data->arch_name;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   279
    static bool complained;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   280
    if (bad == &app_data->mach_option[0])
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   281
      print_help(app_data, "bad mach=%s", bad);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   282
    else if (!complained)
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   283
      print_help(app_data, "bad native mach=%s; please port hsdis to this platform", bad);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   284
    complained = true;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   285
    /* must bail out */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   286
    app_data->losing = true;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   287
    return;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   288
  }
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   289
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   290
  parse_fake_insn(app_data->dfn, &app_data->dinfo);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   291
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   292
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   293
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   294
/* ignore all events, return a null */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   295
static void* null_event_callback(void* ignore_stream, const char* ignore_event, void* arg) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   296
  return NULL;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   297
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   298
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   299
/* print all events as XML markup */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   300
static void* xml_event_callback(void* stream, const char* event, void* arg) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   301
  FILE* fp = (FILE*) stream;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   302
#define NS_PFX "dis:"
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   303
  if (event[0] != '/') {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   304
    /* issue the tag, with or without a formatted argument */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   305
    fprintf(fp, "<"NS_PFX);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   306
    fprintf(fp, event, arg);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   307
    fprintf(fp, ">");
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   308
  } else {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   309
    ++event;                    /* skip slash */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   310
    const char* argp = strchr(event, ' ');
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   311
    if (argp == NULL) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   312
      /* no arguments; just issue the closing tag */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   313
      fprintf(fp, "</"NS_PFX"%s>", event);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   314
    } else {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   315
      /* split out the closing attributes as <dis:foo_done attr='val'/> */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   316
      int event_prefix = (argp - event);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   317
      fprintf(fp, "<"NS_PFX"%.*s_done", event_prefix, event);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   318
      fprintf(fp, argp, arg);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   319
      fprintf(fp, "/></"NS_PFX"%.*s>", event_prefix, event);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   320
    }
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   321
  }
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   322
  return NULL;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   323
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   324
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   325
static void set_optional_callbacks(struct hsdis_app_data* app_data) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   326
  if (app_data->printf_callback == NULL) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   327
    int (*fprintf_callback)(FILE*, const char*, ...) = &fprintf;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   328
    FILE* fprintf_stream = stdout;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   329
    app_data->printf_callback = (printf_callback_t) fprintf_callback;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   330
    if (app_data->printf_stream == NULL)
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   331
      app_data->printf_stream   = (void*)           fprintf_stream;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   332
  }
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   333
  if (app_data->event_callback == NULL) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   334
    if (app_data->event_stream == NULL)
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   335
      app_data->event_callback = &null_event_callback;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   336
    else
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   337
      app_data->event_callback = &xml_event_callback;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   338
  }
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   339
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   340
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   341
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   342
static void parse_caller_options(struct hsdis_app_data* app_data, const char* caller_options) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   343
  char* iop_base = app_data->insn_options;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   344
  char* iop_limit = iop_base + sizeof(app_data->insn_options) - 1;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   345
  char* iop = iop_base;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   346
  const char* p;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   347
  for (p = caller_options; p != NULL; ) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   348
    const char* q = strchr(p, ',');
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   349
    size_t plen = (q == NULL) ? strlen(p) : ((q++) - p);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   350
    if (plen == 4 && strncmp(p, "help", plen) == 0) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   351
      print_help(app_data, NULL, NULL);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   352
    } else if (plen >= 5 && strncmp(p, "mach=", 5) == 0) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   353
      char*  mach_option = app_data->mach_option;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   354
      size_t mach_size   = sizeof(app_data->mach_option);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   355
      mach_size -= 1;           /*leave room for the null*/
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   356
      if (plen > mach_size)  plen = mach_size;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   357
      strncpy(mach_option, p, plen);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   358
      mach_option[plen] = '\0';
11782
38cbdb77b3d1 7140985: HSDIS does not handle caller options correctly
kvn
parents: 8921
diff changeset
   359
    } else if (plen > 6 && strncmp(p, "hsdis-", 6) == 0) {
347
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   360
      // do not pass these to the next level
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   361
    } else {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   362
      /* just copy it; {i386,sparc}-dis.c might like to see it  */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   363
      if (iop > iop_base && iop < iop_limit)  (*iop++) = ',';
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   364
      if (iop + plen > iop_limit)
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   365
        plen = iop_limit - iop;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   366
      strncpy(iop, p, plen);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   367
      iop += plen;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   368
    }
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   369
    p = q;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   370
  }
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   371
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   372
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   373
static void print_help(struct hsdis_app_data* app_data,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   374
                       const char* msg, const char* arg) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   375
  DECL_PRINTF_CALLBACK(app_data);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   376
  if (msg != NULL) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   377
    (*printf_callback)(printf_stream, "hsdis: ");
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   378
    (*printf_callback)(printf_stream, msg, arg);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   379
    (*printf_callback)(printf_stream, "\n");
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   380
  }
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   381
  (*printf_callback)(printf_stream, "hsdis output options:\n");
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   382
  if (printf_callback == (printf_callback_t) &fprintf)
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   383
    disassembler_usage((FILE*) printf_stream);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   384
  else
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   385
    disassembler_usage(stderr); /* better than nothing */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   386
  (*printf_callback)(printf_stream, "  mach=<arch>   select disassembly mode\n");
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   387
#if defined(LIBARCH_i386) || defined(LIBARCH_amd64)
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   388
  (*printf_callback)(printf_stream, "  mach=i386     select 32-bit mode\n");
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   389
  (*printf_callback)(printf_stream, "  mach=x86-64   select 64-bit mode\n");
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   390
  (*printf_callback)(printf_stream, "  suffix        always print instruction suffix\n");
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   391
#endif
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   392
  (*printf_callback)(printf_stream, "  help          print this message\n");
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   393
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   394
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   395
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   396
/* low-level bfd and arch stuff that binutils doesn't do for us */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   397
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   398
static const bfd_arch_info_type* find_arch_info(const char* arch_name) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   399
  const bfd_arch_info_type* arch_info = bfd_scan_arch(arch_name);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   400
  if (arch_info == NULL) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   401
    extern const bfd_arch_info_type bfd_default_arch_struct;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   402
    arch_info = &bfd_default_arch_struct;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   403
  }
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   404
  return arch_info;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   405
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   406
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   407
static const char* native_arch_name() {
2564
85c3ae53ca1c 6684007: PrintAssembly plugin not available for linux or windows
never
parents: 347
diff changeset
   408
  const char* res = NULL;
85c3ae53ca1c 6684007: PrintAssembly plugin not available for linux or windows
never
parents: 347
diff changeset
   409
#ifdef LIBARCH_i386
85c3ae53ca1c 6684007: PrintAssembly plugin not available for linux or windows
never
parents: 347
diff changeset
   410
    res = "i386";
85c3ae53ca1c 6684007: PrintAssembly plugin not available for linux or windows
never
parents: 347
diff changeset
   411
#endif
347
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   412
#ifdef LIBARCH_amd64
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   413
    res = "i386:x86-64";
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   414
#endif
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   415
#ifdef LIBARCH_sparc
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   416
    res = "sparc:v8plusb";
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   417
#endif
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   418
#ifdef LIBARCH_sparcv9
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   419
    res = "sparc:v9b";
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   420
#endif
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   421
  if (res == NULL)
2564
85c3ae53ca1c 6684007: PrintAssembly plugin not available for linux or windows
never
parents: 347
diff changeset
   422
    res = "architecture not set in Makefile!";
347
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   423
  return res;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   424
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   425
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   426
static enum bfd_endian native_endian() {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   427
  int32_t endian_test = 'x';
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   428
  if (*(const char*) &endian_test == 'x')
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   429
    return BFD_ENDIAN_LITTLE;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   430
  else
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   431
    return BFD_ENDIAN_BIG;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   432
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   433
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   434
static bfd* get_native_bfd(const bfd_arch_info_type* arch_info,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   435
                           bfd* empty_bfd, bfd_target* empty_xvec) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   436
  memset(empty_bfd,  0, sizeof(*empty_bfd));
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   437
  memset(empty_xvec, 0, sizeof(*empty_xvec));
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   438
  empty_xvec->flavour = bfd_target_unknown_flavour;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   439
  empty_xvec->byteorder = native_endian();
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   440
  empty_bfd->xvec = empty_xvec;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   441
  empty_bfd->arch_info = arch_info;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   442
  return empty_bfd;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   443
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   444
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   445
static int read_zero_data_only(bfd_vma ignore_p,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   446
                               bfd_byte* myaddr, unsigned int length,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   447
                               struct disassemble_info *ignore_info) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   448
  memset(myaddr, 0, length);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   449
  return 0;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   450
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   451
static int print_to_dev_null(void* ignore_stream, const char* ignore_format, ...) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   452
  return 0;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   453
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   454
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   455
/* Prime the pump by running the selected disassembler on a null input.
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   456
   This forces the machine-specific disassembler to divulge invariant
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   457
   information like bytes_per_line.
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   458
 */
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   459
static void parse_fake_insn(disassembler_ftype dfn,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   460
                            struct disassemble_info* dinfo) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   461
  typedef int (*read_memory_ftype)
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   462
    (bfd_vma memaddr, bfd_byte *myaddr, unsigned int length,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   463
     struct disassemble_info *info);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   464
  read_memory_ftype read_memory_func = dinfo->read_memory_func;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   465
  fprintf_ftype     fprintf_func     = dinfo->fprintf_func;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   466
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   467
  dinfo->read_memory_func = &read_zero_data_only;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   468
  dinfo->fprintf_func     = &print_to_dev_null;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   469
  (*dfn)(0, dinfo);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   470
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   471
  // put it back:
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   472
  dinfo->read_memory_func = read_memory_func;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   473
  dinfo->fprintf_func     = fprintf_func;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   474
}
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   475
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   476
static void init_disassemble_info_from_bfd(struct disassemble_info* dinfo,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   477
                                           void *stream,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   478
                                           fprintf_ftype fprintf_func,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   479
                                           bfd* abfd,
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   480
                                           char* disassembler_options) {
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   481
  init_disassemble_info(dinfo, stream, fprintf_func);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   482
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   483
  dinfo->flavour = bfd_get_flavour(abfd);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   484
  dinfo->arch = bfd_get_arch(abfd);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   485
  dinfo->mach = bfd_get_mach(abfd);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   486
  dinfo->disassembler_options = disassembler_options;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   487
  dinfo->octets_per_byte = bfd_octets_per_byte (abfd);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   488
  dinfo->skip_zeroes = sizeof(void*) * 2;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   489
  dinfo->skip_zeroes_at_end = sizeof(void*)-1;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   490
  dinfo->disassembler_needs_relocs = FALSE;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   491
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   492
  if (bfd_big_endian(abfd))
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   493
    dinfo->display_endian = dinfo->endian = BFD_ENDIAN_BIG;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   494
  else if (bfd_little_endian(abfd))
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   495
    dinfo->display_endian = dinfo->endian = BFD_ENDIAN_LITTLE;
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   496
  else
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   497
    dinfo->endian = native_endian();
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   498
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   499
  disassemble_init_for_target(dinfo);
df859fcca515 6667042: PrintAssembly option does not work without special plugin
jrose
parents:
diff changeset
   500
}