* 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.
This commit is contained in:
Hans-Peter Nilsson 2009-01-18 22:17:03 +00:00
parent aefc706471
commit c10b360549
2 changed files with 142 additions and 5 deletions

View File

@ -1,3 +1,23 @@
2009-01-18 Hans-Peter Nilsson <hp@axis.com>
* 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.
2009-01-06 Hans-Peter Nilsson <hp@axis.com> 2009-01-06 Hans-Peter Nilsson <hp@axis.com>
* cris/traps.c (abort): Define to call sim_io_error. * cris/traps.c (abort): Define to call sim_io_error.

View File

@ -29,6 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_STDLIB_H #ifdef HAVE_STDLIB_H
#include <stdlib.h> #include <stdlib.h>
#endif #endif
#include <errno.h>
#include "sim-options.h" #include "sim-options.h"
#include "dis-asm.h" #include "dis-asm.h"
@ -67,6 +68,15 @@ static char cris_bare_iron = 0;
/* Whether 0x9000000xx have simulator-specific meanings. */ /* Whether 0x9000000xx have simulator-specific meanings. */
char cris_have_900000xxif = 0; 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. */ /* What to do when we face a more or less unknown syscall. */
enum cris_unknown_syscall_action_type cris_unknown_syscall_action enum cris_unknown_syscall_action_type cris_unknown_syscall_action
= CRIS_USYSC_MSG_STOP; = CRIS_USYSC_MSG_STOP;
@ -80,6 +90,8 @@ typedef enum {
OPTION_CRIS_STATS = OPTION_START, OPTION_CRIS_STATS = OPTION_START,
OPTION_CRIS_TRACE, OPTION_CRIS_TRACE,
OPTION_CRIS_NAKED, OPTION_CRIS_NAKED,
OPTION_CRIS_PROGRAM_OFFSET,
OPTION_CRIS_STARTADDR,
OPTION_CRIS_900000XXIF, OPTION_CRIS_900000XXIF,
OPTION_CRIS_UNKNOWN_SYSCALL OPTION_CRIS_UNKNOWN_SYSCALL
} CRIS_OPTIONS; } CRIS_OPTIONS;
@ -104,6 +116,14 @@ static const OPTION cris_options[] =
OPTION_CRIS_UNKNOWN_SYSCALL}, OPTION_CRIS_UNKNOWN_SYSCALL},
'\0', "stop|enosys|enosys-quiet", "Action at an unknown system call", '\0', "stop|enosys|enosys-quiet", "Action at an unknown system call",
cris_option_handler, NULL }, 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 } { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
}; };
@ -130,6 +150,7 @@ cris_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
to the module-specific CPU data when we store things in the to the module-specific CPU data when we store things in the
cpu-specific structure. */ cpu-specific structure. */
char *tracefp = STATE_TRACE_FLAGS (sd); char *tracefp = STATE_TRACE_FLAGS (sd);
char *chp = arg;
switch ((CRIS_OPTIONS) opt) switch ((CRIS_OPTIONS) opt)
{ {
@ -173,6 +194,30 @@ cris_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
cris_have_900000xxif = 1; cris_have_900000xxif = 1;
break; 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: case OPTION_CRIS_UNKNOWN_SYSCALL:
if (strcmp (arg, "enosys") == 0) if (strcmp (arg, "enosys") == 0)
cris_unknown_syscall_action = CRIS_USYSC_MSG_ENOSYS; cris_unknown_syscall_action = CRIS_USYSC_MSG_ENOSYS;
@ -284,6 +329,16 @@ cris_load_elf_file (SIM_DESC sd, struct bfd *abfd, sim_write_fn do_write)
return TRUE; 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 /* Replacement for ../common/sim-hload.c:sim_load, so we can treat ELF
files differently. */ files differently. */
@ -316,7 +371,7 @@ sim_load (SIM_DESC sd, char *prog_name, struct bfd *prog_bfd,
return SIM_RC_OK; 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; ? SIM_RC_OK : SIM_RC_FAIL;
} }
@ -331,6 +386,60 @@ free_state (SIM_DESC sd)
sim_state_free (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 /* BFD section iterator to find the highest and lowest allocated and
non-allocated section addresses (plus one). */ non-allocated section addresses (plus one). */
@ -520,7 +629,7 @@ cris_handle_interpreter (SIM_DESC sd, struct bfd *abfd)
if (ibfd == NULL) if (ibfd == NULL)
goto interpname_failed; 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. */ sure it's an ELF non-archive file. */
if (!bfd_check_format (ibfd, bfd_object) if (!bfd_check_format (ibfd, bfd_object)
|| bfd_get_flavour (ibfd) != bfd_target_elf_flavour) || bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
@ -688,7 +797,12 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
if (abfd == NULL) if (abfd == NULL)
abfd = STATE_PROG_BFD (sd); 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) if (STATE_PROG_ARGV (sd) != NULL)
sim_io_eprintf (sd, "%s: `%s' is not a CRIS program\n", sim_io_eprintf (sd, "%s: `%s' is not a CRIS program\n",
@ -963,8 +1077,11 @@ sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
SIM_ADDR addr; SIM_ADDR addr;
if (sd != NULL) if (sd != NULL)
addr = interp_start_addr != 0 addr = cris_start_address != (SIM_ADDR) -1
? interp_start_addr : bfd_get_start_address (abfd); ? cris_start_address
: (interp_start_addr != 0
? interp_start_addr
: bfd_get_start_address (abfd));
else else
addr = 0; addr = 0;
sim_pc_set (current_cpu, addr); sim_pc_set (current_cpu, addr);