Committed: sim/cris: options to load programs at an offset and different start-address, run_sim_test progopts

Hans-Peter Nilsson hans-peter.nilsson@axis.com
Sun Jan 18 22:20:00 GMT 2009


...best used to override the default 0 used when executing
binary blobs using the simulator.  I couldn't spot a
miscompilation of the Linux boot-time decompressor, so I had to
execute it.  In hindsight I could have done this some other way,
like dressing the blobs using gas' .incbin, but at least now it
can be done in the expected way, using somewhat-expected sim
options.  Moving the start-address and offset-handling to
generic options would probably be a good thing but isn't as
trivial as it sounds; I had a look, but tweaking that would
involve too much of each simulators' machine-specific code.

Also, a new run_sim_test option, to test passing options to the
executed program, or as used here, to emulate there being no
program argument at all, by passing it as an option argument.
As you might guess, opterr3 was from a failed initial attempt at
loading the blob at a specific address without a "main" program.

Committed.

sim/testsuite:
	* sim/cris/asm/opterr5.ms, sim/cris/asm/opterr4.ms,
	sim/cris/asm/opterr3.ms, sim/cris/asm/bare3.ms: New tests.
	* lib/sim-defs.exp (run_sim_test): New option progopts.

sim:
	* cris/sim-if.c: Include errno.h.
	(cris_start_address, cris_program_offset): New variables.
	(OPTION_CRIS_PROGRAM_OFFSET, OPTION_CRIS_STARTADDR): New option
	enums.
	(cris_options): New options --cris-program-offset and
	--cris-start-address.
	(cris_option_handler): Handle new options.
	(cris_program_offset_write, cris_set_section_offset_iterator)
	(cris_offset_sections, cris_offset_sections): New functions.
	(sim_load): Use cris_program_offset_write as function argument to
	cris_load_elf_file, not sim_write.
	(struct offsetinfo): New struct.
	(cris_handle_interpreter): Fix typo in comment.
	(sim_open): Call cris_offset_sections as soon as the bfd of the
	infile is available.  Gate bfd validity checks on abfd non-NULL.
	(sim_create_inferior): Let cris_start_address when != -1 override
	other start-address choices.

Index: lib/sim-defs.exp
===================================================================
RCS file: /cvs/src/src/sim/testsuite/lib/sim-defs.exp,v
retrieving revision 1.11
diff -p -u -r1.11 sim-defs.exp
--- lib/sim-defs.exp	16 Nov 2004 16:22:09 -0000	1.11
+++ lib/sim-defs.exp	18 Jan 2009 21:59:14 -0000
@@ -161,6 +161,7 @@ proc sim_run { prog sim_opts prog_opts r
 # as[(mach-list)]: <assembler options>
 # ld[(mach-list)]: <linker options>
 # sim[(mach-list)]: <simulator options>
+# progopts: <arguments to the program being simulated>
 # output: program output pattern to match with string-match
 # xerror: program is expected to return with a "failure" exit code
 # xfail: <PRMS-opt> <target-triplets-where-test-fails>
@@ -197,6 +198,7 @@ proc run_sim_test { name requested_machs
     # Clear default options
     set opts(as) ""
     set opts(ld) ""
+    set opts(progopts) ""
     set opts(sim) ""
     set opts(output) ""
     set opts(mach) ""
@@ -330,7 +332,7 @@ proc run_sim_test { name requested_machs
 	    set options "$options timeout=$opts(timeout)"
 	}
 
-	set result [sim_run ${name}.x "$opts(sim,$mach) $global_sim_options" "" "" "$options"]
+	set result [sim_run ${name}.x "$opts(sim,$mach) $global_sim_options" "$opts(progopts)" "" "$options"]
 	set status [lindex $result 0]
 	set output [lindex $result 1]
 
Index: sim/cris/asm/bare3.ms
===================================================================
RCS file: sim/cris/asm/bare3.ms
diff -N sim/cris/asm/bare3.ms
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/cris/asm/bare3.ms	18 Jan 2009 21:59:14 -0000
@@ -0,0 +1,41 @@
+# mach: crisv32
+# ld: -N --oformat binary --section-start=.text=0x10000000
+# sim: --architecture crisv32 --target binary --cris-program-offset=0x10000000 --cris-start-address=0x10000040 --cris-naked --memory-region 0x10000000,0x1000
+ .include "testutils.inc"
+
+; Test that we can load a binary program at a non-zero address.
+; Also serves to exercise the --cris-program-offset and
+; --cris-start-address options.
+
+; Make sure starting at the first address does fail.
+ fail
+
+; ...and that we know an offset we can jump for it to work, and all we
+; have to assume is that "fail" takes no more than 64 bytes.
+ .p2align 6
+ ba _start
+ nop
+
+; 
+ start
+x:
+
+; Make sure we're loaded at the linked address.  Since we're re-used
+; in other tests, we have to provide for non-v32 as well.
+ .if ..asm.arch.cris.v32
+ lapcq .,$r0
+ .else
+ move.d $pc,$r0
+ subq .-x,$r0
+ .endif
+
+ cmp.d x,$r0
+ bne y
+ nop
+ pass
+y:
+ fail
+
+; Make sure we have enough contents for the mapping.
+ .data
+ .fill 4096,1,0
Index: sim/cris/asm/opterr3.ms
===================================================================
RCS file: sim/cris/asm/opterr3.ms
diff -N sim/cris/asm/opterr3.ms
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/cris/asm/opterr3.ms	18 Jan 2009 21:59:14 -0000
@@ -0,0 +1,10 @@
+# mach: crisv3 crisv8 crisv10 crisv32
+# ld: -N --oformat binary --section-start=.text=0x10000000
+# sim: --cris-naked --memory-mapfile
+# xerror:
+# output: Usage: run \[options\] program \[program args\]\n*\n
+# progopts: --memory-region 0x10000000,0x1000
+ .include "bare3.ms"
+
+; Check that we get an error for wrong usage, not a SEGV for lack of
+; bfd when missing the program argument (can't use *only* mapped files).
Index: sim/cris/asm/opterr4.ms
===================================================================
RCS file: sim/cris/asm/opterr4.ms
diff -N sim/cris/asm/opterr4.ms
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/cris/asm/opterr4.ms	18 Jan 2009 21:59:14 -0000
@@ -0,0 +1,7 @@
+# mach: crisv3 crisv8 crisv10 crisv32
+# xerror:
+# output: Invalid option [`']--cris-start-address=x'\n
+# sim: --cris-start-address=x
+ .include "nopv32t.ms"
+
+; Check that we recognize wrong usage of the --cris-start-address option.
Index: sim/cris/asm/opterr5.ms
===================================================================
RCS file: sim/cris/asm/opterr5.ms
diff -N sim/cris/asm/opterr5.ms
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/cris/asm/opterr5.ms	18 Jan 2009 21:59:14 -0000
@@ -0,0 +1,7 @@
+# mach: crisv3 crisv8 crisv10 crisv32
+# xerror:
+# output: Invalid option [`']--cris-program-offset=x'\n
+# sim: --cris-program-offset=x
+ .include "nopv32t.ms"
+
+; Check that we recognize wrong usage of the --cris-program-offset option.
Index: cris/sim-if.c
===================================================================
RCS file: /cvs/src/src/sim/cris/sim-if.c,v
retrieving revision 1.10
diff -p -u -r1.10 sim-if.c
--- cris/sim-if.c	14 Jan 2009 10:53:06 -0000	1.10
+++ cris/sim-if.c	18 Jan 2009 22:07:17 -0000
@@ -29,6 +29,7 @@ along with this program.  If not, see <h
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
+#include <errno.h>
 #include "sim-options.h"
 #include "dis-asm.h"
 
@@ -67,6 +68,15 @@ static char cris_bare_iron = 0;
 /* Whether 0x9000000xx have simulator-specific meanings.  */
 char cris_have_900000xxif = 0;
 
+/* Used to optionally override the default start address of the
+   simulation.  */
+static USI cris_start_address = 0xffffffffu;
+
+/* Used to optionally add offsets to the loaded image and its start
+   address.  (Not used for the interpreter of dynamically loaded
+   programs or the DSO:s.)  */
+static int cris_program_offset = 0;
+
 /* What to do when we face a more or less unknown syscall.  */
 enum cris_unknown_syscall_action_type cris_unknown_syscall_action
   = CRIS_USYSC_MSG_STOP;
@@ -80,6 +90,8 @@ typedef enum {
   OPTION_CRIS_STATS = OPTION_START,
   OPTION_CRIS_TRACE,
   OPTION_CRIS_NAKED,
+  OPTION_CRIS_PROGRAM_OFFSET,
+  OPTION_CRIS_STARTADDR,
   OPTION_CRIS_900000XXIF,
   OPTION_CRIS_UNKNOWN_SYSCALL
 } CRIS_OPTIONS;
@@ -104,6 +116,14 @@ static const OPTION cris_options[] =
      OPTION_CRIS_UNKNOWN_SYSCALL},
      '\0', "stop|enosys|enosys-quiet", "Action at an unknown system call",
      cris_option_handler, NULL },
+  { {"cris-program-offset", required_argument, NULL,
+     OPTION_CRIS_PROGRAM_OFFSET},
+      '\0', "OFFSET",
+    "Offset image addresses and default start address of a program",
+      cris_option_handler },
+  { {"cris-start-address", required_argument, NULL, OPTION_CRIS_STARTADDR},
+      '\0', "ADDRESS", "Set start address",
+      cris_option_handler },
   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
 };
 

@@ -130,6 +150,7 @@ cris_option_handler (SIM_DESC sd, sim_cp
      to the module-specific CPU data when we store things in the
      cpu-specific structure.  */
   char *tracefp = STATE_TRACE_FLAGS (sd);
+  char *chp = arg;
 
   switch ((CRIS_OPTIONS) opt)
     {
@@ -173,6 +194,30 @@ cris_option_handler (SIM_DESC sd, sim_cp
 	cris_have_900000xxif = 1;
 	break;
 
+      case OPTION_CRIS_STARTADDR:
+	errno = 0;
+	cris_start_address = (USI) strtoul (chp, &chp, 0);
+
+	if (errno != 0 || *chp != 0)
+	  {
+	    sim_io_eprintf (sd, "Invalid option `--cris-start-address=%s'\n",
+			    arg);
+	    return SIM_RC_FAIL;
+	  }
+	break;
+
+      case OPTION_CRIS_PROGRAM_OFFSET:
+	errno = 0;
+	cris_program_offset = (int) strtol (chp, &chp, 0);
+
+	if (errno != 0 || *chp != 0)
+	  {
+	    sim_io_eprintf (sd, "Invalid option `--cris-program-offset=%s'\n",
+			    arg);
+	    return SIM_RC_FAIL;
+	  }
+	break;
+
       case OPTION_CRIS_UNKNOWN_SYSCALL:
 	if (strcmp (arg, "enosys") == 0)
 	  cris_unknown_syscall_action = CRIS_USYSC_MSG_ENOSYS;
@@ -284,6 +329,16 @@ cris_load_elf_file (SIM_DESC sd, struct 
   return TRUE;
 }
 
+/* Helper for sim_load (needed just for ELF files): like sim_write,
+   but offset load at cris_program_offset offset.  */
+
+static int
+cris_program_offset_write (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf,
+			   int length)
+{
+  return sim_write (sd, mem + cris_program_offset, buf, length);
+}
+
 /* Replacement for ../common/sim-hload.c:sim_load, so we can treat ELF
    files differently.  */
 
@@ -316,7 +371,7 @@ sim_load (SIM_DESC sd, char *prog_name, 
       return SIM_RC_OK;
     }
 
-  return cris_load_elf_file (sd, prog_bfd, sim_write)
+  return cris_load_elf_file (sd, prog_bfd, cris_program_offset_write)
     ? SIM_RC_OK : SIM_RC_FAIL;
 }
 
@@ -331,6 +386,60 @@ free_state (SIM_DESC sd)
   sim_state_free (sd);
 }
 
+/* Helper struct for cris_set_section_offset_iterator.  */
+
+struct offsetinfo
+{
+  SIM_DESC sd;
+  int offset;
+};
+
+/* BFD section iterator to offset the LMA and VMA.  */
+
+static void
+cris_set_section_offset_iterator (bfd *abfd, asection *s, void *vp)
+{
+  struct offsetinfo *p = (struct offsetinfo *) vp;
+  SIM_DESC sd = p->sd;
+  int offset = p->offset;
+
+  if ((bfd_get_section_flags (abfd, s) & SEC_ALLOC))
+    {
+      bfd_vma vma = bfd_get_section_vma (abfd, s);
+      
+      bfd_set_section_vma (abfd, s, vma + offset);
+    }
+
+  /* This seems clumsy and inaccurate, but let's stick to doing it the
+     same way as sim_analyze_program for consistency.  */
+  if (strcmp (bfd_get_section_name (abfd, s), ".text") == 0)
+    STATE_TEXT_START (sd) = bfd_get_section_vma (abfd, s);
+}
+
+/* Adjust the start-address, LMA and VMA of a SD.  Must be called
+   after sim_analyze_program.  */
+
+static void
+cris_offset_sections (SIM_DESC sd, int offset)
+{
+  bfd_boolean ret;
+  struct bfd *abfd = STATE_PROG_BFD (sd);
+  asection *text;
+  struct offsetinfo oi;
+
+  /* Only happens for usage error.  */
+  if (abfd == NULL)
+    return;
+
+  oi.sd = sd;
+  oi.offset = offset;
+
+  bfd_map_over_sections (abfd, cris_set_section_offset_iterator, &oi);
+  ret = bfd_set_start_address (abfd, bfd_get_start_address (abfd) + offset);
+
+  STATE_START_ADDR (sd) = bfd_get_start_address (abfd);
+}
+
 /* BFD section iterator to find the highest and lowest allocated and
    non-allocated section addresses (plus one).  */
 
@@ -520,7 +629,7 @@ cris_handle_interpreter (SIM_DESC sd, st
       if (ibfd == NULL)
 	goto interpname_failed;
 
-      /* The interpreter is at leat something readable to BFD; make
+      /* The interpreter is at least something readable to BFD; make
 	 sure it's an ELF non-archive file.  */
       if (!bfd_check_format (ibfd, bfd_object)
 	  || bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
@@ -688,7 +797,12 @@ sim_open (SIM_OPEN_KIND kind, host_callb
   if (abfd == NULL)
     abfd = STATE_PROG_BFD (sd);
 
-  if (bfd_get_arch (abfd) == bfd_arch_unknown)
+  /* Adjust the addresses of the program at this point.  Unfortunately
+     this does not affect ELF program headers, so we have to handle
+     that separately.  */
+  cris_offset_sections (sd, cris_program_offset);
+
+  if (abfd != NULL && bfd_get_arch (abfd) == bfd_arch_unknown)
     {
       if (STATE_PROG_ARGV (sd) != NULL)
 	sim_io_eprintf (sd, "%s: `%s' is not a CRIS program\n",
@@ -963,8 +1077,11 @@ sim_create_inferior (SIM_DESC sd, struct
   SIM_ADDR addr;
 
   if (sd != NULL)
-    addr = interp_start_addr != 0
-      ? interp_start_addr : bfd_get_start_address (abfd);
+    addr = cris_start_address != (SIM_ADDR) -1
+      ? cris_start_address
+      : (interp_start_addr != 0
+	 ? interp_start_addr
+	 : bfd_get_start_address (abfd));
   else
     addr = 0;
   sim_pc_set (current_cpu, addr);


brgds, H-P



More information about the Gdb-patches mailing list