mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-07-24 18:32:38 +08:00
* cris/traps.c (TARGET_SYS_writev): New macro.
(is_mapped_only, cris_dump_map): New functions. (cris_break_13_handler) <case TARGET_SYS_mmap2>: Handle more flags and prot combinations and a non-zero page-offset. If TARGET_MAP_FIXED, unmap pages before mapping them. <case TARGET_SYS_mprotect>: When checking, allow any length argument. Don't actually do anything. <case TARGET_SYS_writev>: New case.
This commit is contained in:
@ -1,5 +1,14 @@
|
|||||||
2008-12-30 Hans-Peter Nilsson <hp@axis.com>
|
2008-12-30 Hans-Peter Nilsson <hp@axis.com>
|
||||||
|
|
||||||
|
* cris/traps.c (TARGET_SYS_writev): New macro.
|
||||||
|
(is_mapped_only, cris_dump_map): New functions.
|
||||||
|
(cris_break_13_handler) <case TARGET_SYS_mmap2>: Handle more flags
|
||||||
|
and prot combinations and a non-zero page-offset. If
|
||||||
|
TARGET_MAP_FIXED, unmap pages before mapping them.
|
||||||
|
<case TARGET_SYS_mprotect>: When checking, allow any length
|
||||||
|
argument. Don't actually do anything.
|
||||||
|
<case TARGET_SYS_writev>: New case.
|
||||||
|
|
||||||
* cris/Makefile.in (SIM_OBJS): Remove sim-hload.o.
|
* cris/Makefile.in (SIM_OBJS): Remove sim-hload.o.
|
||||||
* cris/sim-if.c: Include elf-bfd.h.
|
* cris/sim-if.c: Include elf-bfd.h.
|
||||||
(struct progbounds): New members end_loadmem, start_nonloadmem.
|
(struct progbounds): New members end_loadmem, start_nonloadmem.
|
||||||
|
195
sim/cris/traps.c
195
sim/cris/traps.c
@ -87,6 +87,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|||||||
#define TARGET_SYS_uname 122
|
#define TARGET_SYS_uname 122
|
||||||
#define TARGET_SYS_mprotect 125
|
#define TARGET_SYS_mprotect 125
|
||||||
#define TARGET_SYS_llseek 140
|
#define TARGET_SYS_llseek 140
|
||||||
|
#define TARGET_SYS_writev 146
|
||||||
#define TARGET_SYS__sysctl 149
|
#define TARGET_SYS__sysctl 149
|
||||||
#define TARGET_SYS_sched_setparam 154
|
#define TARGET_SYS_sched_setparam 154
|
||||||
#define TARGET_SYS_sched_getparam 155
|
#define TARGET_SYS_sched_getparam 155
|
||||||
@ -912,6 +913,57 @@ is_mapped (SIM_DESC sd ATTRIBUTE_UNUSED,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check whether any part of [addr .. addr + len - 1] is *un*mapped.
|
||||||
|
Return 1 if the whole area is mapped, 0 otherwise. */
|
||||||
|
|
||||||
|
static USI
|
||||||
|
is_mapped_only (SIM_DESC sd ATTRIBUTE_UNUSED,
|
||||||
|
struct cris_sim_mmapped_page **rootp,
|
||||||
|
USI addr, USI len)
|
||||||
|
{
|
||||||
|
struct cris_sim_mmapped_page *mapp;
|
||||||
|
|
||||||
|
if (len == 0 || (len & 8191))
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
/* Iterate over the reverse-address sorted pages until we find a page
|
||||||
|
lower than the checked area. */
|
||||||
|
for (mapp = *rootp; mapp != NULL && mapp->addr >= addr; mapp = mapp->prev)
|
||||||
|
if (addr == mapp->addr && len == 8192)
|
||||||
|
return 1;
|
||||||
|
else if (addr + len > mapp->addr)
|
||||||
|
len -= 8192;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Debug helper; to be run from gdb. */
|
||||||
|
|
||||||
|
void
|
||||||
|
cris_dump_map (SIM_CPU *current_cpu)
|
||||||
|
{
|
||||||
|
struct cris_sim_mmapped_page *mapp;
|
||||||
|
USI start, end;
|
||||||
|
|
||||||
|
for (mapp = current_cpu->highest_mmapped_page,
|
||||||
|
start = mapp == NULL ? 0 : mapp->addr + 8192,
|
||||||
|
end = mapp == NULL ? 0 : mapp->addr + 8191;
|
||||||
|
mapp != NULL;
|
||||||
|
mapp = mapp->prev)
|
||||||
|
{
|
||||||
|
if (mapp->addr != start - 8192)
|
||||||
|
{
|
||||||
|
sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
|
||||||
|
end = mapp->addr + 8191;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = mapp->addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_cpu->highest_mmapped_page != NULL)
|
||||||
|
sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
|
||||||
|
}
|
||||||
|
|
||||||
/* Create mmapped memory. */
|
/* Create mmapped memory. */
|
||||||
|
|
||||||
static USI
|
static USI
|
||||||
@ -1617,12 +1669,23 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
|||||||
!= (TARGET_PROT_READ
|
!= (TARGET_PROT_READ
|
||||||
| TARGET_PROT_WRITE
|
| TARGET_PROT_WRITE
|
||||||
| TARGET_PROT_EXEC))
|
| TARGET_PROT_EXEC))
|
||||||
|
&& (prot != (TARGET_PROT_READ | TARGET_PROT_EXEC))
|
||||||
&& prot != TARGET_PROT_READ)
|
&& prot != TARGET_PROT_READ)
|
||||||
|| (flags != (TARGET_MAP_ANONYMOUS | TARGET_MAP_PRIVATE)
|
|| (flags != (TARGET_MAP_ANONYMOUS | TARGET_MAP_PRIVATE)
|
||||||
&& flags != TARGET_MAP_PRIVATE
|
&& flags != TARGET_MAP_PRIVATE
|
||||||
|
&& flags != (TARGET_MAP_ANONYMOUS
|
||||||
|
| TARGET_MAP_PRIVATE | TARGET_MAP_FIXED)
|
||||||
|
&& flags != (TARGET_MAP_PRIVATE | TARGET_MAP_FIXED)
|
||||||
&& flags != TARGET_MAP_SHARED)
|
&& flags != TARGET_MAP_SHARED)
|
||||||
|| (fd != (USI) -1 && prot != TARGET_PROT_READ)
|
|| (fd != (USI) -1
|
||||||
|| pgoff != 0)
|
&& prot != TARGET_PROT_READ
|
||||||
|
&& prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)
|
||||||
|
&& prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
|
||||||
|
|| (fd == (USI) -1 && pgoff != 0)
|
||||||
|
|| (fd != (USI) -1 && (flags & TARGET_MAP_ANONYMOUS))
|
||||||
|
|| ((flags & TARGET_MAP_FIXED) == 0
|
||||||
|
&& is_mapped (sd, ¤t_cpu->highest_mmapped_page,
|
||||||
|
addr, (len + 8191) & ~8191)))
|
||||||
{
|
{
|
||||||
retval
|
retval
|
||||||
= cris_unknown_syscall (current_cpu, pc,
|
= cris_unknown_syscall (current_cpu, pc,
|
||||||
@ -1647,9 +1710,17 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
|||||||
/* A non-aligned argument is allowed for files. */
|
/* A non-aligned argument is allowed for files. */
|
||||||
USI newlen = (len + 8191) & ~8191;
|
USI newlen = (len + 8191) & ~8191;
|
||||||
|
|
||||||
/* We only support read, which we should already have
|
/* We only support read, read|exec, and read|write,
|
||||||
checked. Check again anyway. */
|
which we should already have checked. Check again
|
||||||
if (prot != TARGET_PROT_READ)
|
anyway. */
|
||||||
|
if (prot != TARGET_PROT_READ
|
||||||
|
&& prot != (TARGET_PROT_READ | TARGET_PROT_EXEC)
|
||||||
|
&& prot != (TARGET_PROT_READ | TARGET_PROT_WRITE))
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
if ((flags & TARGET_MAP_FIXED)
|
||||||
|
&& unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
|
||||||
|
addr, newlen) != 0)
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
newaddr
|
newaddr
|
||||||
@ -1663,6 +1734,16 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We were asked for MAP_FIXED, but couldn't. */
|
||||||
|
if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
|
||||||
|
{
|
||||||
|
abort ();
|
||||||
|
unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
|
||||||
|
newaddr, newlen);
|
||||||
|
retval = -cb_host_to_target_errno (cb, EINVAL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find the current position in the file. */
|
/* Find the current position in the file. */
|
||||||
s.func = TARGET_SYS_lseek;
|
s.func = TARGET_SYS_lseek;
|
||||||
s.arg1 = fd;
|
s.arg1 = fd;
|
||||||
@ -1672,6 +1753,17 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
|||||||
abort ();
|
abort ();
|
||||||
pos = s.result;
|
pos = s.result;
|
||||||
|
|
||||||
|
if (s.result < 0)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
/* Move to the correct offset in the file. */
|
||||||
|
s.func = TARGET_SYS_lseek;
|
||||||
|
s.arg1 = fd;
|
||||||
|
s.arg2 = pgoff*8192;
|
||||||
|
s.arg3 = SEEK_SET;
|
||||||
|
if (cb_syscall (cb, &s) != CB_RC_OK)
|
||||||
|
abort ();
|
||||||
|
|
||||||
if (s.result < 0)
|
if (s.result < 0)
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
@ -1702,31 +1794,47 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
USI newaddr
|
USI newlen = (len + 8191) & ~8191;
|
||||||
= create_map (sd, ¤t_cpu->highest_mmapped_page, addr,
|
USI newaddr;
|
||||||
(len + 8191) & ~8191);
|
|
||||||
|
if ((flags & TARGET_MAP_FIXED)
|
||||||
|
&& unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
|
||||||
|
addr, newlen) != 0)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
newaddr = create_map (sd, ¤t_cpu->highest_mmapped_page, addr,
|
||||||
|
newlen);
|
||||||
|
|
||||||
if (newaddr >= (USI) -8191)
|
if (newaddr >= (USI) -8191)
|
||||||
retval = -cb_host_to_target_errno (cb, -(SI) newaddr);
|
retval = -cb_host_to_target_errno (cb, -(SI) newaddr);
|
||||||
else
|
else
|
||||||
retval = newaddr;
|
retval = newaddr;
|
||||||
|
|
||||||
|
if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
|
||||||
|
{
|
||||||
|
abort ();
|
||||||
|
unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
|
||||||
|
newaddr, newlen);
|
||||||
|
retval = -cb_host_to_target_errno (cb, EINVAL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TARGET_SYS_mprotect:
|
case TARGET_SYS_mprotect:
|
||||||
{
|
{
|
||||||
/* We only cover the case of linuxthreads mprotecting out its
|
/* We only cover the case of linuxthreads mprotecting out
|
||||||
stack guard page. */
|
its stack guard page and of dynamic loading mprotecting
|
||||||
|
away the data (for some reason the whole library, then
|
||||||
|
mprotects away the data part and mmap-FIX:es it again. */
|
||||||
USI addr = arg1;
|
USI addr = arg1;
|
||||||
USI len = arg2;
|
USI len = arg2;
|
||||||
USI prot = arg3;
|
USI prot = arg3;
|
||||||
|
|
||||||
if ((addr & 8191) != 0
|
if (prot != TARGET_PROT_NONE
|
||||||
|| len != 8192
|
|| !is_mapped_only (sd, ¤t_cpu->highest_mmapped_page,
|
||||||
|| prot != TARGET_PROT_NONE
|
addr, (len + 8191) & ~8191))
|
||||||
|| !is_mapped (sd, ¤t_cpu->highest_mmapped_page, addr,
|
|
||||||
len))
|
|
||||||
{
|
{
|
||||||
retval
|
retval
|
||||||
= cris_unknown_syscall (current_cpu, pc,
|
= cris_unknown_syscall (current_cpu, pc,
|
||||||
@ -1738,10 +1846,10 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: We should account for pages like this that are
|
/* Just ignore this. We could make this equal to munmap,
|
||||||
"mprotected out". For now, we just tell the simulator
|
but then we'd have to make sure no anon mmaps gets this
|
||||||
core to remove that page from its map. */
|
address before a subsequent MAP_FIXED mmap intended to
|
||||||
sim_core_detach (sd, NULL, 0, 0, addr);
|
override it. */
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2171,6 +2279,55 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
|
||||||
|
where:
|
||||||
|
struct iovec {
|
||||||
|
void *iov_base; Starting address
|
||||||
|
size_t iov_len; Number of bytes to transfer
|
||||||
|
}; */
|
||||||
|
case TARGET_SYS_writev:
|
||||||
|
{
|
||||||
|
SI fd = arg1;
|
||||||
|
SI iov = arg2;
|
||||||
|
SI iovcnt = arg3;
|
||||||
|
SI retcnt = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* We'll ignore strict error-handling and just do multiple write calls. */
|
||||||
|
for (i = 0; i < iovcnt; i++)
|
||||||
|
{
|
||||||
|
int sysret;
|
||||||
|
USI iov_base
|
||||||
|
= sim_core_read_unaligned_4 (current_cpu, pc, 0,
|
||||||
|
iov + 8*i);
|
||||||
|
USI iov_len
|
||||||
|
= sim_core_read_unaligned_4 (current_cpu, pc, 0,
|
||||||
|
iov + 8*i + 4);
|
||||||
|
|
||||||
|
s.func = TARGET_SYS_write;
|
||||||
|
s.arg1 = fd;
|
||||||
|
s.arg2 = iov_base;
|
||||||
|
s.arg3 = iov_len;
|
||||||
|
|
||||||
|
if (cb_syscall (cb, &s) != CB_RC_OK)
|
||||||
|
abort ();
|
||||||
|
sysret = s.result == -1 ? -s.errcode : s.result;
|
||||||
|
|
||||||
|
if (sysret != iov_len)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
abort ();
|
||||||
|
retcnt = sysret;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
retcnt += iov_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = retcnt;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
/* This one does have a generic callback function, but at the time
|
/* This one does have a generic callback function, but at the time
|
||||||
of this writing, cb_syscall does not have code for it, and we
|
of this writing, cb_syscall does not have code for it, and we
|
||||||
need target-specific code for the threads implementation
|
need target-specific code for the threads implementation
|
||||||
|
Reference in New Issue
Block a user