]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Merge fido bits:
authorKazu Hirata <kazu@codesourcery.com>
Mon, 30 Oct 2006 19:46:10 +0000 (19:46 +0000)
committerKazu Hirata <kazu@codesourcery.com>
Mon, 30 Oct 2006 19:46:10 +0000 (19:46 +0000)
2006-10-25  Kazu Hirata  <kazu@codesourcery.com>

gprof/
* hist.c, hist.h: Fix formatting.

gprof/
* Makefile.in (corefile.o): Depend on hist.h.
* corefile.c: Include hist.h.

2006-10-06  Vladimir Prus  <vladimir@codesourcery.com>

* hist.h (struct histogram)
(histograms, num_histograms): New.
* hist.c (find_histogram, find_histogram_for_pc)
(read_histogram_header): New.
(s_lowpc, s_highpc, lowpc, highpc, hist_num_bins)
(hist_sample): Remove.
(hist_read_rec): Use the above, and handle multiple
histogram records with disjoint address ranges.
(hist_write_hist): Support several histogram records.
(scale_and_align_entries): Adjust for multiple histograms.
(hist_assign_samples_1): New.
(hist_assign_samples): Use the above.
(hist_clip_symbol_address): New.
* hist.h (hist_check_address)
(hist_clip_symbol_address): Declare.
* gmon_io.c (gmon_out_read, gmon_out_write): Adjust handling
of legacy format for multiple histogram changes.
* corefile.c (find_call): Check for core_text_space and
clip symbol address range here.
* vax.c (vax_find_call): Don't check for
core_text_space, or clip the symbol's address range here.
Use hist_check_address to check call's target address.
* sparc.c: Likewise.
* tahoe.c: Likewise.
* i386.c: Likewise.
* mips.c: Likewise. Also use core_text_sect->vma as the base
address for code accesses, just like other machine-specific
routines do.

2006-08-03  Kazu Hirata  <kazu@codesourcery.com>

* gas/config/tc-m68k.c (archs): Add -mfido as an alias for
-mfido_a.

2006-06-23  Kazu Hirata  <kazu@codesourcery.com>

* gas/config/tc-m68k.c (cpu_of_arch): Replace fido with
fido_a.
(archs): Likewise.
(m68k_ip): Likewise.
(select_control_regs): Likewise.
(md_show_usage): Replace -mfido with -mfidoa.
* include/opcode/m68k.h (fido): Rename to fido_a.
* opcodes/m68k-opc.c (m68k_opcodes): Replace fido with fido_a.

2006-06-22  Kazu Hirata  <kazu@codesourcery.com>

* config.sub: Replace fido with fido.
* bfd/config.bfd: Likewise
* gas/configure.tgt: Likewise.
* gas/config/m68k-parse.h: Likewise.
* gas/config/tc-m68k.c: Likewise.
* gas/testsuite/gas/m68k/all.exp: Likewise.
* gas/testsuite/gas/m68k/fido.d: Rename to fido.d.
* gas/testsuite/gas/m68k/fido.s: Rename to fido.s.
* include/opcode/m68k.h: Replace fido with fido.
* ld/configure.tgt: Likewise.
* opcodes/m68k-dis.c: Likewise.
* opcodes/m68k-opc.c: Likewise.

2005-08-01  Kazu Hirata  <kazu@codesourcery.com>

* gas/config/m68k-parse.h (m68k_register): Add CAC and MBB.
* gas/config/tc-m68k.c (fido_control_regs): New.
(cpu_of_arch): Add fido.
(archs): Add an entry for fido.
(m68k_ip): Add warnings for uses of tbl[su]{n,}[bwl] on
fido.  Recognize CAC and MBB.
(init_tabl): Add CAC and MBB.
(select_control_regs): Choose fido as the current chip
when the current architecture is fido or when -mfido
is given explicitly.
* gas/testsuite/gas/m68k/all.exp: Disable operands, cas, and
bitfield on fido-*-*.  Run fido on fido-*-*.
* gas/testsuite/gas/m68k/fido.d: New.
* gas/testsuite/gas/m68k/fido.s: Likewise.
* include/opcode/m68k.h: Document new control registers CAC
and MBB.
* opcodes/m68k-dis.c (print_insn_arg): Add cac and mbb.
* opcodes/m68k-opc.c (m68k_opcodes): Add sleep and trapx.

2005-07-22  Kazu Hirata  <kazu@codesourcery.com>

* gas/config/tc-m68k.c (archs): Add fido as an OR of
cpu32 and fido.
(md_show_usage): Add -mfido.
* include/opcode/m68k.h (fido): New.

2005-07-11  Kazu Hirata  <kazu@codesourcery.com>

* config.sub: Recognize fido and fido-*.
* bfd/config.bfd: Likewise.
* gas/configure.tgt: Likewise.
* ld/configure.tgt: Likewise.

23 files changed:
ChangeLog.csl
bfd/config.bfd
config.sub
gas/config/m68k-parse.h
gas/config/tc-m68k.c
gas/configure.tgt
gas/testsuite/gas/m68k/all.exp
gas/testsuite/gas/m68k/fido.d [new file with mode: 0644]
gas/testsuite/gas/m68k/fido.s [new file with mode: 0644]
gprof/alpha.c
gprof/corefile.c
gprof/gmon_io.c
gprof/hist.c
gprof/hist.h
gprof/i386.c
gprof/mips.c
gprof/sparc.c
gprof/tahoe.c
gprof/vax.c
include/opcode/m68k.h
ld/configure.tgt
opcodes/m68k-dis.c
opcodes/m68k-opc.c

index dbe5cc8d22064d5a28c17f19794b90e9a189b208..0a14213f2c69792ce1aafaa988af63dc74096f42 100644 (file)
@@ -1,3 +1,112 @@
+2006-10-30  Kazu Hirata  <kazu@codesourcery.com>
+
+       Merge fido bits:
+       2006-10-25  Kazu Hirata  <kazu@codesourcery.com>
+
+       gprof/
+       * hist.c, hist.h: Fix formatting.
+
+       gprof/
+       * Makefile.in (corefile.o): Depend on hist.h.
+       * corefile.c: Include hist.h.
+
+       2006-10-06  Vladimir Prus  <vladimir@codesourcery.com>
+
+       * hist.h (struct histogram)
+       (histograms, num_histograms): New.
+       * hist.c (find_histogram, find_histogram_for_pc)
+       (read_histogram_header): New.
+       (s_lowpc, s_highpc, lowpc, highpc, hist_num_bins)
+       (hist_sample): Remove.
+       (hist_read_rec): Use the above, and handle multiple
+       histogram records with disjoint address ranges.
+       (hist_write_hist): Support several histogram records.
+       (scale_and_align_entries): Adjust for multiple histograms.
+       (hist_assign_samples_1): New.
+       (hist_assign_samples): Use the above.
+       (hist_clip_symbol_address): New.
+       * hist.h (hist_check_address)
+       (hist_clip_symbol_address): Declare.
+       * gmon_io.c (gmon_out_read, gmon_out_write): Adjust handling
+       of legacy format for multiple histogram changes.
+       * corefile.c (find_call): Check for core_text_space and
+       clip symbol address range here.
+       * vax.c (vax_find_call): Don't check for
+       core_text_space, or clip the symbol's address range here.
+       Use hist_check_address to check call's target address.  
+       * sparc.c: Likewise.
+       * tahoe.c: Likewise.
+       * i386.c: Likewise.
+       * mips.c: Likewise. Also use core_text_sect->vma as the base
+       address for code accesses, just like other machine-specific
+       routines do.
+
+       2006-08-03  Kazu Hirata  <kazu@codesourcery.com>
+
+       * gas/config/tc-m68k.c (archs): Add -mfido as an alias for
+       -mfido_a.
+
+       2006-06-23  Kazu Hirata  <kazu@codesourcery.com>
+
+       * gas/config/tc-m68k.c (cpu_of_arch): Replace fido with
+       fido_a.
+       (archs): Likewise.
+       (m68k_ip): Likewise.
+       (select_control_regs): Likewise.
+       (md_show_usage): Replace -mfido with -mfidoa.
+       * include/opcode/m68k.h (fido): Rename to fido_a.
+       * opcodes/m68k-opc.c (m68k_opcodes): Replace fido with fido_a.
+
+       2006-06-22  Kazu Hirata  <kazu@codesourcery.com>
+
+       * config.sub: Replace fido with fido.
+       * bfd/config.bfd: Likewise
+       * gas/configure.tgt: Likewise.
+       * gas/config/m68k-parse.h: Likewise.
+       * gas/config/tc-m68k.c: Likewise.
+       * gas/testsuite/gas/m68k/all.exp: Likewise.
+       * gas/testsuite/gas/m68k/fido.d: Rename to fido.d.
+       * gas/testsuite/gas/m68k/fido.s: Rename to fido.s.
+       * include/opcode/m68k.h: Replace fido with fido.
+       * ld/configure.tgt: Likewise.
+       * opcodes/m68k-dis.c: Likewise.
+       * opcodes/m68k-opc.c: Likewise.
+
+       2005-08-01  Kazu Hirata  <kazu@codesourcery.com>
+
+       * gas/config/m68k-parse.h (m68k_register): Add CAC and MBB.
+       * gas/config/tc-m68k.c (fido_control_regs): New.
+       (cpu_of_arch): Add fido.
+       (archs): Add an entry for fido.
+       (m68k_ip): Add warnings for uses of tbl[su]{n,}[bwl] on
+       fido.  Recognize CAC and MBB.
+       (init_tabl): Add CAC and MBB.
+       (select_control_regs): Choose fido as the current chip
+       when the current architecture is fido or when -mfido
+       is given explicitly.
+       * gas/testsuite/gas/m68k/all.exp: Disable operands, cas, and
+       bitfield on fido-*-*.  Run fido on fido-*-*.
+       * gas/testsuite/gas/m68k/fido.d: New.
+       * gas/testsuite/gas/m68k/fido.s: Likewise.
+       * include/opcode/m68k.h: Document new control registers CAC
+       and MBB.
+       * opcodes/m68k-dis.c (print_insn_arg): Add cac and mbb.
+       * opcodes/m68k-opc.c (m68k_opcodes): Add sleep and trapx.
+
+       2005-07-22  Kazu Hirata  <kazu@codesourcery.com>
+
+       * gas/config/tc-m68k.c (archs): Add fido as an OR of
+       cpu32 and fido.
+       (md_show_usage): Add -mfido.
+       * include/opcode/m68k.h (fido): New.
+
+       2005-07-11  Kazu Hirata  <kazu@codesourcery.com>
+
+       * config.sub: Recognize fido and fido-*.
+       * bfd/config.bfd: Likewise.
+       * gas/configure.tgt: Likewise.
+       * ld/configure.tgt: Likewise.
+
 2006-10-28  Paul Brook  <paul@codesourcery.com>
        Julian Brown  <julian@codesourcery.com>
 
index a07d77f378e2ddfaef0412fd993764827396b157..a2f8cf11bdd126377f1075159b8df05870bc47fa 100644 (file)
@@ -78,6 +78,7 @@ c54x*)                 targ_archs=bfd_tic54x_arch ;;
 crisv32)        targ_archs=bfd_cris_arch ;;
 crx*)           targ_archs=bfd_crx_arch ;;
 dlx*)           targ_archs=bfd_dlx_arch ;;
+fido*)          targ_archs=bfd_m68k_arch ;;
 hppa*)          targ_archs=bfd_hppa_arch ;;
 i[3-7]86)       targ_archs=bfd_i386_arch ;;
 i370)           targ_archs=bfd_i370_arch ;;
@@ -365,6 +366,11 @@ case "${targ}" in
     targ_defvec=bfd_elf32_d30v_vec
     ;;
 
+  fido-*-elf* )
+    targ_defvec=bfd_elf32_m68k_vec
+    targ_selvecs="m68kcoff_vec ieee_vec"
+    ;;
+
   fr30-*-elf)
     targ_defvec=bfd_elf32_fr30_vec
     ;;
index a4e8a94a335109a3cf7adeca65617cfab1514b35..b2dea75f0e908647e65fbb0ff49c6f6070e4bfff 100755 (executable)
@@ -244,7 +244,7 @@ case $basic_machine in
        | bfin \
        | c4x | clipper \
        | d10v | d30v | dlx | dsp16xx \
-       | fr30 | frv \
+       | fido | fr30 | frv \
        | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
        | i370 | i860 | i960 | ia64 \
        | ip2k | iq2000 \
@@ -323,7 +323,7 @@ case $basic_machine in
        | clipper-* | craynv-* | cydra-* \
        | d10v-* | d30v-* | dlx-* \
        | elxsi-* \
-       | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+       | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
        | h8300-* | h8500-* \
        | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
        | i*86-* | i860-* | i960-* | ia64-* \
index e7af8536a805176c2dd7d42e8f73da5e7a5aab28..272075dc43db71f9ba02bb8d8b6afc60ccc62220 100644 (file)
@@ -126,7 +126,9 @@ enum m68k_register
   FLASHBAR, RAMBAR,            /* mcf528x added these.  */
   MBAR2,                       /* mcf5249 added this.  */
   MBAR,
-#define last_movec_reg MBAR
+  CAC,                         /* fido added this.  */
+  MBB,
+#define last_movec_reg MBB
   /* End of movec ordering constraints.  */
 
   FPI,
index 4307dea406e7d10d65f5dea3d9b779e48bfe04fc..debbbeb49dead04d0d82f5ec0bceebe848a5cc17 100644 (file)
@@ -243,6 +243,10 @@ static const enum m68k_register mcfv4e_ctrl[] = {
   PCR3U0, PCR3L0, PCR3U1, PCR3L1,
   0
 };
+static const enum m68k_register fido_ctrl[] = {
+  SFC, DFC, USP, VBR, CAC, MBB,
+  0
+};
 #define cpu32_ctrl m68010_ctrl
 
 static const enum m68k_register *control_regs;
@@ -296,7 +300,7 @@ struct m68k_it
   reloc[5];                    /* Five is enough???  */
 };
 
-#define cpu_of_arch(x)         ((x) & (m68000up | mcfisa_a))
+#define cpu_of_arch(x)         ((x) & (m68000up | mcfisa_a | fido_a))
 #define float_of_arch(x)       ((x) & mfloat)
 #define mmu_of_arch(x)         ((x) & mmmu)
 #define arch_coldfire_p(x)     ((x) & mcfisa_a)
@@ -433,6 +437,7 @@ static const struct m68k_cpu m68k_archs[] =
   {m68040,                                     m68040_ctrl, "68040", 0},
   {m68060,                                     m68060_ctrl, "68060", 0},
   {cpu32|m68881,                               cpu32_ctrl, "cpu32", 0},
+  {cpu32|fido_a,                               fido_ctrl, "fidoa", 0},
   {mcfisa_a|mcfhwdiv,                          NULL, "isaa", 0},
   {mcfisa_a|mcfhwdiv|mcfisa_aa|mcfusp,         NULL, "isaaplus", 0},
   {mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp,          NULL, "isab", 0},
@@ -575,6 +580,8 @@ static const struct m68k_cpu m68k_cpus[] =
   {mcfisa_a|mcfisa_b|mcfhwdiv|mcfemac|mcfusp|cfloat, mcfv4e_ctrl, "5485", -1},
   {mcfisa_a|mcfisa_b|mcfhwdiv|mcfemac|mcfusp|cfloat, mcfv4e_ctrl, "548x", 0},
   
+  {cpu32|fido_a,                               fido_ctrl, "fido", 1},
+
   {0,NULL,NULL, 0}
   };
 
@@ -1154,6 +1161,21 @@ m68k_ip (char *instring)
   opcode = (const struct m68k_incant *) hash_find (op_hash, instring);
   *p = c;
 
+  /* Fido does not support certain instructions.  Warn about uses
+     of those instructions.  */
+  if ((cpu_of_arch (current_architecture) & fido_a) != 0)
+    {
+      /* Recognize tbl[su]{n,}[bwl].  */
+      if (strncmp (instring, "tbl", 3) == 0
+         && (instring[3] == 's' || instring[3] == 'u')
+         && ((strchr ("bwl", instring[4]) != 0
+              && instring[5] == '\0')
+             || (instring[4] == 'n'
+                 && strchr ("bwl", instring[5]) != 0
+                 && instring[6] == '\0')))
+       as_warn (_("'%s' not supported on Fido"), instring);
+    }
+
   if (pdot != NULL)
     {
       for (pdotmove = p; pdotmove > pdot; pdotmove--)
@@ -3094,6 +3116,12 @@ m68k_ip (char *instring)
             case PCR3U1:
               tmpreg = 0xD0F;
               break;
+            case CAC:
+              tmpreg = 0xFFE;
+              break;
+            case MBB:
+              tmpreg = 0xFFF;
+              break;
            default:
              abort ();
            }
@@ -3818,6 +3846,9 @@ static const struct init_entry init_table[] =
   { "rambar",   RAMBAR },      /* mcf528x registers.  */
 
   { "mbar2",    MBAR2 },       /* mcf5249 registers.  */
+
+  { "cac",    CAC },           /* fido registers.  */
+  { "mbb",    MBB },           /* fido registers.  */
   /* End of control registers.  */
 
   { "ac", AC },
index 07fa817815475f445ec6493f818dd8ae75856467..b7a54cd5126189ae0a52b3e0b53e15ae22e2ef46 100644 (file)
@@ -37,6 +37,7 @@ case ${cpu} in
   c4x*)                        cpu_type=tic4x ;;
   crisv32)             cpu_type=cris arch=crisv32 ;;
   crx*)                        cpu_type=crx endian=little ;;
+  fido)                        cpu_type=m68k ;;
   hppa*)               cpu_type=hppa ;;
   i[3-7]86)            cpu_type=i386 arch=i386;;
   ia64)                        cpu_type=ia64 ;;
index 9516b1ab1dfc6b0299a2add194f50a9b2755482c..cdf94615bf1e7c21476c21fc0cc64b332ed56bcd 100644 (file)
@@ -13,7 +13,7 @@ if [istarget "m6811-*-*"] then {
 if [istarget "m6812-*-*"] then {
    return
 }
-if [istarget m68*-*-*] then {
+if { [istarget m68*-*-*] || [istarget fido*-*-*] } then {
     gas_test "t2.s" "" "" "cross-section branch"
     if [istarget m68*-motorola-sysv] then {
        run_dump_test t2
@@ -29,9 +29,18 @@ if [istarget m68*-*-*] then {
     setup_xfail "*-*"
     clear_xfail "*-*-*elf*" "*-*-sysv4*" "*-*-rtems" "*-*-*gnu*" "*-*-psos*"
     run_dump_test pcrel
-    run_dump_test operands
-    run_dump_test cas
-    run_dump_test bitfield
+
+    # Since fido is basically CPU32, it does not support those
+    # instructions beyond CPU32.  Disable those tests that test them.
+    if ![istarget fido-*-*] then {
+       run_dump_test operands
+       run_dump_test cas
+       run_dump_test bitfield
+    } else {
+       # Test fido-specific instructions.
+       run_dump_test fido
+    }
+
     run_dump_test link
     run_dump_test fmoveml
     run_dump_test mcf-mov3q
diff --git a/gas/testsuite/gas/m68k/fido.d b/gas/testsuite/gas/m68k/fido.d
new file mode 100644 (file)
index 0000000..fff5abb
--- /dev/null
@@ -0,0 +1,41 @@
+#objdump: -d --prefix-addresses
+#name: fido
+
+# Test parsing of the operands of the fido-specific instructions.
+
+.*: +file format .*
+
+Disassembly of section .text:
+0+000 <foo> sleep
+0+002 <foo\+(0x|)2> trapx #0
+0+004 <foo\+(0x|)4> trapx #1
+0+006 <foo\+(0x|)6> trapx #2
+0+008 <foo\+(0x|)8> trapx #3
+0+00a <foo\+(0x|)a> trapx #4
+0+00c <foo\+(0x|)c> trapx #5
+0+00e <foo\+(0x|)e> trapx #6
+0+010 <foo\+(0x|)10> trapx #7
+0+012 <foo\+(0x|)12> trapx #8
+0+014 <foo\+(0x|)14> trapx #9
+0+016 <foo\+(0x|)16> trapx #10
+0+018 <foo\+(0x|)18> trapx #11
+0+01a <foo\+(0x|)1a> trapx #12
+0+01c <foo\+(0x|)1c> trapx #13
+0+01e <foo\+(0x|)1e> trapx #14
+0+020 <foo\+(0x|)20> trapx #15
+0+022 <foo\+(0x|)22> movec %cac,%d0
+0+026 <foo\+(0x|)26> movec %cac,%a0
+0+02a <foo\+(0x|)2a> movec %mbb,%d1
+0+02e <foo\+(0x|)2e> movec %mbb,%a1
+0+032 <foo\+(0x|)32> movec %d2,%cac
+0+036 <foo\+(0x|)36> movec %a2,%cac
+0+03a <foo\+(0x|)3a> movec %d3,%mbb
+0+03e <foo\+(0x|)3e> movec %a3,%mbb
+0+042 <foo\+(0x|)42> movec %cac,%d4
+0+046 <foo\+(0x|)46> movec %cac,%a4
+0+04a <foo\+(0x|)4a> movec %mbb,%d5
+0+04e <foo\+(0x|)4e> movec %mbb,%a5
+0+052 <foo\+(0x|)52> movec %d6,%cac
+0+056 <foo\+(0x|)56> movec %fp,%cac
+0+05a <foo\+(0x|)5a> movec %d7,%mbb
+0+05e <foo\+(0x|)5e> movec %sp,%mbb
diff --git a/gas/testsuite/gas/m68k/fido.s b/gas/testsuite/gas/m68k/fido.s
new file mode 100644 (file)
index 0000000..8aaac7c
--- /dev/null
@@ -0,0 +1,37 @@
+# Test parsing of the operands of the fido-specific instructions.
+       .text
+       .globl  foo
+foo:   
+       sleep
+       trapx #0
+       trapx #1
+       trapx #2
+       trapx #3
+       trapx #4
+       trapx #5
+       trapx #6
+       trapx #7
+       trapx #8
+       trapx #9
+       trapx #10
+       trapx #11
+       trapx #12
+       trapx #13
+       trapx #14
+       trapx #15
+       movec #0xffe,%d0
+       movec #0xffe,%a0
+       movec #0xfff,%d1
+       movec #0xfff,%a1
+       movec %d2,#0xffe
+       movec %a2,#0xffe
+       movec %d3,#0xfff
+       movec %a3,#0xfff
+       movec %cac,%d4
+       movec %cac,%a4
+       movec %mbb,%d5
+       movec %mbb,%a5
+       movec %d6,%cac
+       movec %a6,%cac
+       movec %d7,%mbb
+       movec %a7,%mbb
index b89e9ccf553dbb71fda43905f660df8e88fad646..b14e842c5ebbad28731f96b591cf362b2bd673ce 100644 (file)
@@ -104,18 +104,6 @@ alpha_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
       indirect_child.cg.cyc.head = &indirect_child;
     }
 
-  if (!core_text_space)
-    {
-      return;
-    }
-  if (p_lowpc < s_lowpc)
-    {
-      p_lowpc = s_lowpc;
-    }
-  if (p_highpc > s_highpc)
-    {
-      p_highpc = s_highpc;
-    }
   DBG (CALLDEBUG, printf (_("[find_call] %s: 0x%lx to 0x%lx\n"),
                          parent->name, (unsigned long) p_lowpc,
                          (unsigned long) p_highpc));
@@ -157,7 +145,7 @@ alpha_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
           */
          dest_pc = pc + 4 + (((bfd_signed_vma) (insn & 0x1fffff)
                               ^ 0x100000) - 0x100000);
-         if (dest_pc >= s_lowpc && dest_pc <= s_highpc)
+         if (hist_check_address (dest_pc))
            {
              child = sym_lookup (&symtab, dest_pc);
              DBG (CALLDEBUG,
index a8620efc45f4ab08738f0098f31c622cbcf95fc8..f2350a1f765f56cd253972b7066ecb14dd34e0a4 100644 (file)
@@ -25,6 +25,7 @@
 #include "search_list.h"
 #include "source.h"
 #include "symtab.h"
+#include "hist.h"
 #include "corefile.h"
 
 bfd *core_bfd;
@@ -262,6 +263,11 @@ core_get_text_space (bfd *cbfd)
 void
 find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
 {
+  if (core_text_space == 0)
+    return;
+
+  hist_clip_symbol_address (&p_lowpc, &p_highpc);
+
   switch (bfd_get_arch (core_bfd))
     {
     case bfd_arch_i386:
index e56ab7a369581819f24631488d6168a0b025ba2f..656e7836d0a5420d63884ca1f4502c9d4c595220 100644 (file)
@@ -388,10 +388,10 @@ gmon_out_read (const char *filename)
       int samp_bytes, header_size = 0;
       unsigned long count;
       bfd_vma from_pc, self_pc;
-      static struct hdr h;
       UNIT raw_bin_count;
       struct hdr tmp;
       unsigned int version;
+      unsigned int hist_num_bins;
 
       /* Information from a gmon.out file is in two parts: an array of
         sampling hits within pc ranges, and the arcs.  */
@@ -430,7 +430,7 @@ gmon_out_read (const char *filename)
           if (gmon_io_read_32 (ifp, &profrate))
            goto bad_gmon_file;
 
-         if (!s_highpc)
+         if (!histograms)
            hz = profrate;
          else if (hz != (int) profrate)
            {
@@ -480,35 +480,38 @@ gmon_out_read (const char *filename)
          done (1);
        }
 
-      if (s_highpc && (tmp.low_pc != h.low_pc
-                      || tmp.high_pc != h.high_pc || tmp.ncnt != h.ncnt))
+      samp_bytes = tmp.ncnt - header_size;
+      hist_num_bins = samp_bytes / sizeof (UNIT);
+      if (histograms && (tmp.low_pc != histograms->lowpc
+                        || tmp.high_pc != histograms->highpc
+                        || (hist_num_bins != histograms->num_bins)))
        {
          fprintf (stderr, _("%s: incompatible with first gmon file\n"),
                   filename);
          done (1);
        }
 
-      h = tmp;
-      s_lowpc = (bfd_vma) h.low_pc;
-      s_highpc = (bfd_vma) h.high_pc;
-      lowpc = (bfd_vma) h.low_pc / sizeof (UNIT);
-      highpc = (bfd_vma) h.high_pc / sizeof (UNIT);
-      samp_bytes = h.ncnt - header_size;
-      hist_num_bins = samp_bytes / sizeof (UNIT);
+      if (!histograms)
+       {
+         histograms = (struct histogram *)malloc 
+           (sizeof (struct histogram));
+         histograms->lowpc = tmp.low_pc;
+         histograms->highpc = tmp.high_pc;
+         histograms->num_bins = hist_num_bins;
+         histograms->sample = (int *)malloc (hist_num_bins * sizeof (int));
+         memset (histograms->sample, 0, 
+                 hist_num_bins * sizeof (int));
+       }
 
       DBG (SAMPLEDEBUG,
           printf ("[gmon_out_read] lowpc 0x%lx highpc 0x%lx ncnt %d\n",
-                  (unsigned long) h.low_pc, (unsigned long) h.high_pc,
-                  h.ncnt);
-          printf ("[gmon_out_read]   s_lowpc 0x%lx   s_highpc 0x%lx\n",
-                  (unsigned long) s_lowpc, (unsigned long) s_highpc);
-          printf ("[gmon_out_read]     lowpc 0x%lx     highpc 0x%lx\n",
-                  (unsigned long) lowpc, (unsigned long) highpc);
+                  (unsigned long) tmp.low_pc, (unsigned long) tmp.high_pc,
+                  tmp.ncnt);
           printf ("[gmon_out_read] samp_bytes %d hist_num_bins %d\n",
                   samp_bytes, hist_num_bins));
 
       /* Make sure that we have sensible values.  */
-      if (samp_bytes < 0 || lowpc > highpc)
+      if (samp_bytes < 0 || histograms->lowpc > histograms->highpc)
        {
          fprintf (stderr,
            _("%s: file '%s' does not appear to be in gmon.out format\n"),
@@ -519,14 +522,6 @@ gmon_out_read (const char *filename)
       if (hist_num_bins)
        ++nhist;
 
-      if (!hist_sample)
-       {
-         hist_sample =
-           (int *) xmalloc (hist_num_bins * sizeof (hist_sample[0]));
-
-         memset (hist_sample, 0, hist_num_bins * sizeof (hist_sample[0]));
-       }
-
       for (i = 0; i < hist_num_bins; ++i)
        {
          if (fread (raw_bin_count, sizeof (raw_bin_count), 1, ifp) != 1)
@@ -537,7 +532,8 @@ gmon_out_read (const char *filename)
              done (1);
            }
 
-         hist_sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) raw_bin_count);
+         histograms->sample[i] 
+           += bfd_get_16 (core_bfd, (bfd_byte *) raw_bin_count);
        }
 
       /* The rest of the file consists of a bunch of
@@ -684,9 +680,10 @@ gmon_out_write (const char *filename)
 
       /* Write the parts of the headers that are common to both the
         old BSD and 4.4BSD formats.  */
-      if (gmon_io_write_vma (ofp, s_lowpc)
-          || gmon_io_write_vma (ofp, s_highpc)
-          || gmon_io_write_32 (ofp, hist_num_bins * sizeof (UNIT) + hdrsize))
+      if (gmon_io_write_vma (ofp, histograms->lowpc)
+          || gmon_io_write_vma (ofp, histograms->highpc)
+          || gmon_io_write_32 (ofp, histograms->num_bins 
+                              * sizeof (UNIT) + hdrsize))
        {
          perror (filename);
          done (1);
@@ -714,9 +711,9 @@ gmon_out_write (const char *filename)
        }
 
       /* Dump the samples.  */
-      for (i = 0; i < hist_num_bins; ++i)
+      for (i = 0; i < histograms->num_bins; ++i)
        {
-         bfd_put_16 (core_bfd, (bfd_vma) hist_sample[i],
+         bfd_put_16 (core_bfd, (bfd_vma) histograms->sample[i],
                      (bfd_byte *) &raw_bin_count[0]);
          if (fwrite (&raw_bin_count[0], sizeof (raw_bin_count), 1, ofp) != 1)
            {
index 024f6653e662194638034a85a91a9b7c790901fd..46124e8069632c9bacf71a41ba0aee873af6aaf6 100644 (file)
@@ -31,6 +31,9 @@
 #include "hist.h"
 #include "sym_ids.h"
 #include "utils.h"
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
 
 #define UNITS_TO_CODE (offset_to_code / sizeof(UNIT))
 
@@ -42,11 +45,9 @@ static int cmp_time (const PTR, const PTR);
 /* Declarations of automatically generated functions to output blurbs.  */
 extern void flat_blurb (FILE * fp);
 
-bfd_vma s_lowpc;               /* Lowest address in .text.  */
-bfd_vma s_highpc = 0;          /* Highest address in .text.  */
-bfd_vma lowpc, highpc;         /* Same, but expressed in UNITs.  */
-unsigned int hist_num_bins = 0;        /* Number of histogram samples.  */
-int *hist_sample = 0;          /* Histogram samples (shorts in the file!).  */
+static histogram *find_histogram (bfd_vma lowpc, bfd_vma highpc);
+static histogram *find_histogram_for_pc (bfd_vma pc);
+
 double hist_scale;
 static char hist_dimension[16] = "seconds";
 static char hist_dimension_abbrev = 's';
@@ -76,23 +77,30 @@ SItab[] =
   { 'a', 1e+18 }                               /* ato */
 };
 
+/* Reads just the header part of histogram record into
+   *RECORD from IFP.  FILENAME is the name of IFP and
+   is provided for formatting error messages only.  
 
-/* Read the histogram from file IFP.  FILENAME is the name of IFP and
-   is provided for formatting error messages only.  */
-
-void
-hist_read_rec (FILE * ifp, const char *filename)
+   If FIRST is non-zero, sets global variables HZ, HIST_DIMENSION,
+   HIST_DIMENSION_ABBREV, HIST_SCALE.  If FIRST is zero, checks
+   that the new histogram is compatible with already-set values
+   of those variables and emits an error if that's not so.  */
+static void
+read_histogram_header (histogram *record, 
+                      FILE *ifp, const char *filename,
+                      int first)
 {
-  bfd_vma n_lowpc, n_highpc;
-  unsigned int i, ncnt, profrate;
-  UNIT count;
-
-  if (gmon_io_read_vma (ifp, &n_lowpc)
-      || gmon_io_read_vma (ifp, &n_highpc)
-      || gmon_io_read_32 (ifp, &ncnt)
+  unsigned int profrate;
+  char n_hist_dimension[15];
+  char n_hist_dimension_abbrev;
+  double n_hist_scale;
+
+  if (gmon_io_read_vma (ifp, &record->lowpc)
+      || gmon_io_read_vma (ifp, &record->highpc)
+      || gmon_io_read_32 (ifp, &record->num_bins)
       || gmon_io_read_32 (ifp, &profrate)
-      || gmon_io_read (ifp, hist_dimension, 15)
-      || gmon_io_read (ifp, &hist_dimension_abbrev, 1))
+      || gmon_io_read (ifp, n_hist_dimension, 15)
+      || gmon_io_read (ifp, &n_hist_dimension_abbrev, 1))
     {
       fprintf (stderr, _("%s: %s: unexpected end of file\n"),
               whoami, filename);
@@ -100,94 +108,176 @@ hist_read_rec (FILE * ifp, const char *filename)
       done (1);
     }
 
-  if (!s_highpc)
+  n_hist_scale = (double)((record->highpc - record->lowpc) / sizeof (UNIT)) 
+    / record->num_bins;
+
+  if (first)
     {
-      /* This is the first histogram record.  */
-      s_lowpc = n_lowpc;
-      s_highpc = n_highpc;
-      lowpc = (bfd_vma) n_lowpc / sizeof (UNIT);
-      highpc = (bfd_vma) n_highpc / sizeof (UNIT);
-      hist_num_bins = ncnt;
+      /* We could try to verify it's the same for all records,
+        but it isn't practical, since when profiling is done
+        no by a timer but with a loop running in a stub, polling PC
+        from the target as fast as possible, the rate is not fixed.  */
       hz = profrate;
+      memcpy (hist_dimension, n_hist_dimension, 15);
+      hist_dimension_abbrev = n_hist_dimension_abbrev;
+      hist_scale = n_hist_scale;      
     }
-
-  DBG (SAMPLEDEBUG,
-       printf ("[hist_read_rec] n_lowpc 0x%lx n_highpc 0x%lx ncnt %u\n",
-              (unsigned long) n_lowpc, (unsigned long) n_highpc, ncnt);
-       printf ("[hist_read_rec] s_lowpc 0x%lx s_highpc 0x%lx nsamples %u\n",
-              (unsigned long) s_lowpc, (unsigned long) s_highpc,
-              hist_num_bins);
-       printf ("[hist_read_rec]   lowpc 0x%lx   highpc 0x%lx\n",
-              (unsigned long) lowpc, (unsigned long) highpc));
-
-  if (n_lowpc != s_lowpc || n_highpc != s_highpc
-      || ncnt != hist_num_bins || hz != (int) profrate)
+  else
     {
-      fprintf (stderr, _("%s: `%s' is incompatible with first gmon file\n"),
-              whoami, filename);
-      done (1);
+      if (strncmp (n_hist_dimension, hist_dimension, 15) != 0)
+       {
+         fprintf (stderr, 
+                  _("%s: dimension unit changed between histogram records\n"
+                    "%s: from '%s'\n"
+                    "%s: to '%s'\n"),
+                  whoami, whoami, hist_dimension, whoami, n_hist_dimension);
+         done (1);
+       }
+
+      if (n_hist_dimension_abbrev != hist_dimension_abbrev)
+       {
+         fprintf (stderr, 
+                  _("%s: dimension abbreviation changed between histogram records\n"
+                    "%s: from '%c'\n"
+                    "%s: to '%c'\n"),
+                  whoami, whoami, hist_dimension_abbrev, whoami, n_hist_dimension_abbrev);
+         done (1);       
+       }
+
+      /* The only reason we require the same scale for histograms is that
+        there's code (notably printing code), that prints units,
+        and it would be very confusing to have one unit mean different
+        things for different functions.  */
+      if (fabs (hist_scale - n_hist_scale) > 0.000001)
+       {
+         fprintf (stderr, 
+                  _("%s: different scales in histogram records"),
+                  whoami);
+         done (1);      
+       }
     }
+}
 
-  if (!hist_sample)
+/* Read the histogram from file IFP.  FILENAME is the name of IFP and
+   is provided for formatting error messages only.  */
+
+void
+hist_read_rec (FILE * ifp, const char *filename)
+{
+  bfd_vma lowpc, highpc;
+  histogram n_record;
+  histogram *record, *existing_record;
+  unsigned i;
+
+  /* 1. Read the header and see if there's existing record for the
+     same address range and that there are no overlapping records.  */
+  read_histogram_header (&n_record, ifp, filename, num_histograms == 0);
+
+  existing_record = find_histogram (n_record.lowpc, n_record.highpc);
+  if (existing_record)
     {
-      hist_sample = (int *) xmalloc (hist_num_bins * sizeof (hist_sample[0]));
-      memset (hist_sample, 0, hist_num_bins * sizeof (hist_sample[0]));
+      record = existing_record;
+    }
+  else
+    {
+      /* If this record overlaps, but does not completely match an existing
+        record, it's an error.  */
+      lowpc = n_record.lowpc;
+      highpc = n_record.highpc;
+      hist_clip_symbol_address (&lowpc, &highpc);
+      if (lowpc != highpc)
+       {
+         fprintf (stderr, 
+                  _("%s: overlapping histogram records\n"),
+                  whoami);
+         done (1);      
+       }
+
+      /* This is new record.  Add it to global array and allocate space for
+        the samples.  */
+      histograms = (histogram *)realloc (histograms,
+                                        sizeof (histogram)
+                                        * (num_histograms + 1));
+      memcpy (histograms + num_histograms,
+             &n_record, sizeof (histogram));
+      record = &histograms[num_histograms];      
+      ++num_histograms;
+
+      record->sample = (int *) xmalloc (record->num_bins 
+                                       * sizeof (record->sample[0]));
+      memset (record->sample, 0, record->num_bins * sizeof (record->sample[0]));
     }
 
-  for (i = 0; i < hist_num_bins; ++i)
+  /* 2. We have either a new record (with zeroed histogram data), or an existing
+     record with some data in the histogram already.  Read new data into the
+     record, adding hit counts.  */
+
+  DBG (SAMPLEDEBUG,
+       printf ("[hist_read_rec] n_lowpc 0x%lx n_highpc 0x%lx ncnt %u\n",
+              (unsigned long) record->lowpc, (unsigned long) record->highpc, 
+               record->num_bins));
+           
+  for (i = 0; i < record->num_bins; ++i)
     {
+      UNIT count;
       if (fread (&count[0], sizeof (count), 1, ifp) != 1)
        {
          fprintf (stderr,
                  _("%s: %s: unexpected EOF after reading %u of %u samples\n"),
-                  whoami, filename, i, hist_num_bins);
+                  whoami, filename, i, record->num_bins);
          done (1);
        }
-      hist_sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) & count[0]);
+      record->sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) & count[0]);
       DBG (SAMPLEDEBUG,
           printf ("[hist_read_rec] 0x%lx: %u\n",
-                  (unsigned long) (n_lowpc + i * (n_highpc - n_lowpc) / ncnt),
-                  hist_sample[i]));
+                  (unsigned long) (record->lowpc 
+                                    + i * (record->highpc - record->lowpc) 
+                                    / record->num_bins),
+                  record->sample[i]));
     }
 }
 
 
-/* Write execution histogram to file OFP.  FILENAME is the name
+/* Write all execution histograms file OFP.  FILENAME is the name
    of OFP and is provided for formatting error-messages only.  */
 
 void
 hist_write_hist (FILE * ofp, const char *filename)
 {
   UNIT count;
-  unsigned int i;
-
-  /* Write header.  */
+  unsigned int i, r;
 
-  if (gmon_io_write_8 (ofp, GMON_TAG_TIME_HIST)
-      || gmon_io_write_vma (ofp, s_lowpc)
-      || gmon_io_write_vma (ofp, s_highpc)
-      || gmon_io_write_32 (ofp, hist_num_bins)
-      || gmon_io_write_32 (ofp, hz)
-      || gmon_io_write (ofp, hist_dimension, 15)
-      || gmon_io_write (ofp, &hist_dimension_abbrev, 1))
+  for (r = 0; r < num_histograms; ++r)
     {
-      perror (filename);
-      done (1);
-    }
-
-  for (i = 0; i < hist_num_bins; ++i)
-    {
-      bfd_put_16 (core_bfd, (bfd_vma) hist_sample[i], (bfd_byte *) &count[0]);
-
-      if (fwrite (&count[0], sizeof (count), 1, ofp) != 1)
+      histogram *record = &histograms[r];
+
+      /* Write header.  */
+      
+      if (gmon_io_write_8 (ofp, GMON_TAG_TIME_HIST)
+         || gmon_io_write_vma (ofp, record->lowpc)
+         || gmon_io_write_vma (ofp, record->highpc)
+         || gmon_io_write_32 (ofp, record->num_bins)
+         || gmon_io_write_32 (ofp, hz)
+         || gmon_io_write (ofp, hist_dimension, 15)
+         || gmon_io_write (ofp, &hist_dimension_abbrev, 1))
        {
          perror (filename);
          done (1);
        }
+      
+      for (i = 0; i < record->num_bins; ++i)
+       {
+         bfd_put_16 (core_bfd, (bfd_vma) record->sample[i], (bfd_byte *) &count[0]);
+         
+         if (fwrite (&count[0], sizeof (count), 1, ofp) != 1)
+           {
+             perror (filename);
+             done (1);
+           }
+       }
     }
 }
 
-
 /* Calculate scaled entry point addresses (to save time in
    hist_assign_samples), and, on architectures that have procedure
    entry masks at the start of a function, possibly push the scaled
@@ -205,17 +295,23 @@ scale_and_align_entries ()
   for (sym = symtab.base; sym < symtab.limit; sym++)
     {
       sym->hist.scaled_addr = sym->addr / sizeof (UNIT);
-      bin_of_entry = (sym->hist.scaled_addr - lowpc) / hist_scale;
-      bin_of_code = ((sym->hist.scaled_addr + UNITS_TO_CODE - lowpc)
-                    / hist_scale);
-      if (bin_of_entry < bin_of_code)
+
+      histogram *r = find_histogram_for_pc (sym->addr);
+
+      if (r)
        {
-         DBG (SAMPLEDEBUG,
-              printf ("[scale_and_align_entries] pushing 0x%lx to 0x%lx\n",
-                      (unsigned long) sym->hist.scaled_addr,
-                      (unsigned long) (sym->hist.scaled_addr
-                                       + UNITS_TO_CODE)));
-         sym->hist.scaled_addr += UNITS_TO_CODE;
+         bin_of_entry = (sym->hist.scaled_addr - r->lowpc) / hist_scale;
+         bin_of_code = ((sym->hist.scaled_addr + UNITS_TO_CODE - r->lowpc)
+                    / hist_scale);
+         if (bin_of_entry < bin_of_code)
+           {
+             DBG (SAMPLEDEBUG,
+                  printf ("[scale_and_align_entries] pushing 0x%lx to 0x%lx\n",
+                          (unsigned long) sym->hist.scaled_addr,
+                          (unsigned long) (sym->hist.scaled_addr
+                                           + UNITS_TO_CODE)));
+             sym->hist.scaled_addr += UNITS_TO_CODE;
+           }
        }
     }
 }
@@ -258,8 +354,8 @@ scale_and_align_entries ()
    four bytes of text space and never have any overlap (the two end
    cases, above).  */
 
-void
-hist_assign_samples ()
+static void
+hist_assign_samples_1 (histogram *r)
 {
   bfd_vma bin_low_pc, bin_high_pc;
   bfd_vma sym_low_pc, sym_high_pc;
@@ -268,15 +364,12 @@ hist_assign_samples ()
   unsigned int i, j;
   double time, credit;
 
-  /* Read samples and assign to symbols.  */
-  hist_scale = highpc - lowpc;
-  hist_scale /= hist_num_bins;
-  scale_and_align_entries ();
+  bfd_vma lowpc = r->lowpc / sizeof (UNIT);
 
   /* Iterate over all sample bins.  */
-  for (i = 0, j = 1; i < hist_num_bins; ++i)
+  for (i = 0, j = 1; i < r->num_bins; ++i)
     {
-      bin_count = hist_sample[i];
+      bin_count = r->sample[i];
       if (! bin_count)
        continue;
 
@@ -344,6 +437,18 @@ hist_assign_samples ()
                            total_time));
 }
 
+/* Calls 'hist_assign_sampes_1' for all histogram records read so far. */
+void
+hist_assign_samples ()
+{
+  unsigned i;
+
+  scale_and_align_entries ();
+
+  for (i = 0; i < num_histograms; ++i)
+    hist_assign_samples_1 (&histograms[i]);
+  
+}
 
 /* Print header for flag histogram profile.  */
 
@@ -552,3 +657,88 @@ hist_print ()
   if (print_descriptions && !bsd_style_output)
     flat_blurb (stdout);
 }
+
+int
+hist_check_address (unsigned address)
+{
+  unsigned i;
+
+  for (i = 0; i < num_histograms; ++i)
+    if (histograms[i].lowpc <= address && address < histograms[i].highpc)
+      return 1;
+
+  return 0;        
+}
+
+#if ! defined(min)
+#define min(a,b) (((a)<(b)) ? (a) : (b))
+#endif
+#if ! defined(max)
+#define max(a,b) (((a)>(b)) ? (a) : (b))
+#endif
+
+void
+hist_clip_symbol_address (bfd_vma *p_lowpc, bfd_vma *p_highpc)
+{
+  unsigned i;
+  int found = 0;
+
+  if (num_histograms == 0)
+    {
+      *p_highpc = *p_lowpc;
+      return;
+    }
+
+  for (i = 0; i < num_histograms; ++i)
+    {
+      bfd_vma common_low, common_high;
+      common_low = max (histograms[i].lowpc, *p_lowpc);
+      common_high = min (histograms[i].highpc, *p_highpc);
+
+      if (common_low < common_high)
+       {
+         if (found)
+           {
+             // FIXME: some proper diagnostics.
+             // like: "a symbol covers more than one histogram record"
+             abort ();
+           }
+
+         found = 1;
+         *p_lowpc = common_low;
+         *p_highpc = common_high;
+       }
+    }
+
+  if (!found)
+    *p_highpc = *p_lowpc;
+}
+
+/* Find and return exising histogram record having the same lowpc and
+   highpc as passed via the parameters.  Return NULL if nothing is found.
+   The return value is valid until any new histogram is read.  */
+static histogram *
+find_histogram (bfd_vma lowpc, bfd_vma highpc)
+{
+  unsigned i;
+  for (i = 0; i < num_histograms; ++i)
+    {
+      if (histograms[i].lowpc == lowpc && histograms[i].highpc == highpc)
+       return &histograms[i];
+    }
+  return 0;
+}
+
+/* Given a PC, return histogram record which address range include this PC.
+   Return NULL if there's no such record.  */
+static histogram *
+find_histogram_for_pc (bfd_vma pc)
+{
+  unsigned i;
+  for (i = 0; i < num_histograms; ++i)
+    {
+      if (histograms[i].lowpc <= pc && pc < histograms[i].highpc)
+       return &histograms[i];
+    }
+  return 0;  
+}
index 96624c68b01680927980dfef106a338183b5a85b..4ed69580aedb2499d95253a49957584f6e274b09 100644 (file)
@@ -21,20 +21,37 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 #ifndef hist_h
 #define hist_h
 
-extern bfd_vma s_lowpc;                /* Lowpc from the profile file.  */
-extern bfd_vma s_highpc;       /* Highpc from the profile file.  */
-extern bfd_vma lowpc, highpc;  /* Range profiled, in UNIT's.  */
-extern unsigned int hist_num_bins; /* Number of histogram bins.  */
-extern int *hist_sample;       /* Code histogram.  */
+typedef struct histogram
+{
+  bfd_vma lowpc;
+  bfd_vma highpc;
+  unsigned int num_bins;
+  int *sample;           /* Histogram samples (shorts in the file!).  */
+} histogram;
+
+histogram *histograms;
+unsigned num_histograms;
 
 /* Scale factor converting samples to pc values:
    each sample covers HIST_SCALE bytes.  */
 extern double hist_scale;
 
-
 extern void hist_read_rec        (FILE *, const char *);
 extern void hist_write_hist      (FILE *, const char *);
 extern void hist_assign_samples  (void);
 extern void hist_print           (void);
 
+/* Checks if ADDRESS is within the range of addresses for which
+   we have histogram data.  Returns 1 if so and 0 otherwise.  */
+extern int hist_check_address (unsigned address);
+
+/* Given a range of addresses for a symbol, find a histogram record 
+   that intersects with this range, and clips the range to that
+   histogram record, modifying *P_LOWPC and *P_HIGHPC.
+   
+   If no intersection is found, *P_LOWPC and *P_HIGHPC will be set to
+   one unspecified value.  If more that one intersection is found,
+   an error is emitted.  */
+extern void hist_clip_symbol_address (bfd_vma *p_lowpc, bfd_vma *p_highpc);
+
 #endif /* hist_h */
index 91d38fa06cb53838173e5a344f20e47cdb5074ef..bdf8bd1b83206db11f203303224d456a1d86f053 100644 (file)
@@ -53,18 +53,6 @@ i386_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
   Sym *child;
   bfd_vma pc, destpc;
 
-  if (core_text_space == 0)
-    {
-      return;
-    }
-  if (p_lowpc < s_lowpc)
-    {
-      p_lowpc = s_lowpc;
-    }
-  if (p_highpc > s_highpc)
-    {
-      p_highpc = s_highpc;
-    }
   DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n",
                          parent->name, (unsigned long) p_lowpc,
                          (unsigned long) p_highpc));
@@ -83,7 +71,7 @@ i386_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
           */
 
          destpc = bfd_get_32 (core_bfd, instructp + 1) + pc + 5;
-         if (destpc >= s_lowpc && destpc <= s_highpc)
+         if (hist_check_address (destpc))
            {
              child = sym_lookup (&symtab, destpc);
              if (child && child->addr == destpc)
index 96d2707e054790f4c00b2ab79c816ba392d5ae35..7a7344df0d4e6b7ffbda915fee4d290e5b0f49df 100644 (file)
@@ -56,24 +56,13 @@ mips_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
       indirect_child.cg.cyc.head = &indirect_child;
     }
 
-  if (!core_text_space)
-    {
-      return;
-    }
-  if (p_lowpc < s_lowpc)
-    {
-      p_lowpc = s_lowpc;
-    }
-  if (p_highpc > s_highpc)
-    {
-      p_highpc = s_highpc;
-    }
   DBG (CALLDEBUG, printf (_("[find_call] %s: 0x%lx to 0x%lx\n"),
                          parent->name, (unsigned long) p_lowpc,
                          (unsigned long) p_highpc));
   for (pc = p_lowpc; pc < p_highpc; pc += 4)
     {
-      op = bfd_get_32 (core_bfd, &((char *)core_text_space)[pc - s_lowpc]);
+      op = bfd_get_32 (core_bfd, ((unsigned char *)core_text_space
+                                 + pc - core_text_sect->vma));
       if ((op & 0xfc000000) == 0x0c000000)
        {
          /* This is a "jal" instruction.  Check that the destination
@@ -82,7 +71,7 @@ mips_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
               printf (_("[find_call] 0x%lx: jal"), (unsigned long) pc));
           offset = (op & 0x03ffffff) << 2;
          dest_pc = (pc & ~(bfd_vma) 0xfffffff) | offset;
-         if (dest_pc >= s_lowpc && dest_pc <= s_highpc)
+         if (hist_check_address (dest_pc))
            {
              child = sym_lookup (&symtab, dest_pc);
              DBG (CALLDEBUG,
index 685db2fc4a5275598b15e005dc6765ec42f4f1d4..47592d88670c6087d12cf04c8f7b64729b2d5444 100644 (file)
@@ -48,18 +48,6 @@ sparc_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
   unsigned int insn;
   Sym *child;
 
-  if (core_text_space == 0)
-    {
-      return;
-    }
-  if (p_lowpc < s_lowpc)
-    {
-      p_lowpc = s_lowpc;
-    }
-  if (p_highpc > s_highpc)
-    {
-      p_highpc = s_highpc;
-    }
   DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n",
                          parent->name, (unsigned long) p_lowpc,
                          (unsigned long) p_highpc));
@@ -77,7 +65,7 @@ sparc_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
           */
          dest_pc = pc + (((bfd_signed_vma) (insn & 0x3fffffff)
                           ^ 0x20000000) - 0x20000000);
-         if (dest_pc >= s_lowpc && dest_pc <= s_highpc)
+         if (hist_check_address (dest_pc))
            {
              child = sym_lookup (&symtab, dest_pc);
              DBG (CALLDEBUG,
index de94db6938af3cc18a14d22f865cfb6cef376f47..c1d9c42742ac5fedeb8c865920530abc0100e769 100644 (file)
@@ -235,18 +235,6 @@ tahoe_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
       indirectchild.cg.cyc.head = &indirectchild;
     }
 
-  if (core_text_space == 0)
-    {
-      return;
-    }
-  if (p_lowpc < s_lowpc)
-    {
-      p_lowpc = s_lowpc;
-    }
-  if (p_highpc > s_highpc)
-    {
-      p_highpc = s_highpc;
-    }
   DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n",
                          parent->name, (unsigned long) p_lowpc,
                          (unsigned long) p_highpc));
@@ -307,7 +295,7 @@ tahoe_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
               *      a function.
               */
              destpc = pc + tahoe_offset (instructp + length);
-             if (destpc >= s_lowpc && destpc <= s_highpc)
+             if (hist_check_address (destpc))
                {
                  child = sym_lookup (&symtab, destpc);
                  DBG (CALLDEBUG,
index 6216589d96059faad3cb9e2be24c0738f680cbe9..a6904c1e98811485a6e5786663a0aab88072199a 100644 (file)
@@ -247,18 +247,6 @@ vax_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
       indirectchild.cg.cyc.head = &indirectchild;
     }
 
-  if (core_text_space == 0)
-    {
-      return;
-    }
-  if (p_lowpc < s_lowpc)
-    {
-      p_lowpc = s_lowpc;
-    }
-  if (p_highpc > s_highpc)
-    {
-      p_highpc = s_highpc;
-    }
   DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n",
                          parent->name, (unsigned long) p_lowpc,
                          (unsigned long) p_highpc));
@@ -318,7 +306,7 @@ vax_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
               *      a function.
               */
              destpc = pc + vax_offset (instructp + length);
-             if (destpc >= s_lowpc && destpc <= s_highpc)
+             if (hist_check_address (destpc))
                {
                  child = sym_lookup (&symtab, destpc);
                  DBG (CALLDEBUG,
index f8fdf1beb8ff341f8564ca663d191ebdeac9b56c..ca0b4d98d4c6a5143ea99b0ca2bad24f5b7a76f9 100644 (file)
@@ -31,7 +31,8 @@
 #define        m68881   0x040
 #define        m68851   0x080
 #define cpu32   0x100          /* e.g., 68332 */
-#define m68k_mask  0x1ff
+#define fido_a   0x200
+#define m68k_mask  0x3ff
 
 #define mcfmac   0x400         /* ColdFire MAC. */
 #define mcfemac  0x800         /* ColdFire EMAC. */
index 3f6ef0be842aa14c6de78197710d278aac6add17..7db071a07eac90faa3ca1a6b2e69e81c6017e930 100644 (file)
@@ -120,6 +120,7 @@ d30v-*-*)           targ_emul=d30velf; targ_extra_emuls="d30v_e d30v_o"
                        ;;
 dlx-*-elf*)            targ_emul=elf32_dlx
                        ;;
+fido*-*-elf*)          targ_emul=m68kelf ;;
 fr30-*-*)              targ_emul=elf32fr30
                        ;;
 frv-*-*linux*)         targ_emul=elf32frvfd ;;
index 42fb14582a20aef7bec7edfd9aeba404b7449305..1c4c8c405b3e00ac44ac6b9648666950abdd0070 100644 (file)
@@ -650,7 +650,10 @@ print_insn_arg (const char *d,
             /* Should we be calling this psr like we do in case 'Y'?  */
             {"%mmusr",0x805},
 
-             {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808}};
+             {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808},
+
+            /* Fido added these.  */
+             {"%cac", 0xffe}, {"%mbb", 0xfff}};
 
        val = fetch_arg (buffer, place, 12, info);
        for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
index 601c55a15f658067cb838eb889c7786d86a5daaf..51811d44db54574fec51e5c128521cd0076c8a65 100644 (file)
@@ -2031,6 +2031,8 @@ const struct m68k_opcode m68k_opcodes[] =
 {"svs", 2,     one(0054700),   one(0177700), "$s", m68000up },
 {"svs", 2,     one(0054700),   one(0177700), "Ds", mcfisa_a },
 
+{"sleep", 2,   one(0047170),   one(0177777), "", fido_a },
+
 {"stop", 4,    one(0047162),   one(0177777), "#w", m68000up | mcfisa_a },
 
 {"strldsr", 4, two(0040347,0043374), two(0177777,0177777), "#w", mcfisa_aa},
@@ -2151,6 +2153,8 @@ TBL("tblunb", "tblunw", "tblunl", 0, 0),
 
 {"trapv", 2,   one(0047166),   one(0177777), "", m68000up },
 
+{"trapx", 2,   one(0047060),   one(0177760), "Ts", fido_a },
+
 {"tstb", 2,    one(0045000),   one(0177700), ";b", m68020up|cpu32|mcfisa_a },
 {"tstb", 2,    one(0045000),   one(0177700), "$b", m68000up },
 {"tstw", 2,    one(0045100),   one(0177700), "*w", m68020up|cpu32|mcfisa_a },