diff options
Diffstat (limited to 'sim')
-rw-r--r-- | sim/arm/ChangeLog | 15 | ||||
-rw-r--r-- | sim/arm/armos.c | 102 |
2 files changed, 104 insertions, 13 deletions
diff --git a/sim/arm/ChangeLog b/sim/arm/ChangeLog index 370cde7..0e32a65 100644 --- a/sim/arm/ChangeLog +++ b/sim/arm/ChangeLog @@ -1,3 +1,18 @@ +2005-11-16 Shaun Jackman <sjackman@gmail.com> + + * sim/arm/armos.c: Include limits.h + (unlink): Remove this macro. It is unused in this file and + conflicts with sim_callback->unlink. + (PATH_MAX): Define as 1024 if not already defined. + (ReadFileName): New function. + (SWIopen): Fix a potential buffer overflow. + (SWIremove): New function. + (SWIrename): Ditto. + (ARMul_OSHandleSWI): Handle the RDP calls SWI_IsTTY, + SWI_Remove, and SWI_Rename, as well as the RDI calls + AngelSWI_Reason_IsTTY, AngelSWI_Reason_Remove, and + AngelSWI_Reason_Rename. + 2005-09-19 Paul Brook <paul@codesourcery.com> * armdefs.h: Define ARMsword and ARMsdword. Use stdint.h when diff --git a/sim/arm/armos.c b/sim/arm/armos.c index 63ca297..5f5ead7 100644 --- a/sim/arm/armos.c +++ b/sim/arm/armos.c @@ -27,6 +27,7 @@ #include <time.h> #include <errno.h> +#include <limits.h> #include <string.h> #include "targ-vals.h" @@ -34,10 +35,6 @@ #define TARGET_O_BINARY 0 #endif -#ifdef __STDC__ -#define unlink(s) remove(s) -#endif - #ifdef HAVE_UNISTD_H #include <unistd.h> /* For SEEK_SET etc. */ #endif @@ -89,6 +86,9 @@ extern ARMword ARMul_Debug (ARMul_State *, ARMword, ARMword); #define FOPEN_MAX 64 #endif #define UNIQUETEMPS 256 +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif /* OS private Information. */ @@ -299,22 +299,35 @@ WriteCommandLineTo (ARMul_State * state, ARMword addr) while (temp != 0); } +static int +ReadFileName (ARMul_State * state, char *buf, ARMword src, size_t n) +{ + struct OSblock *OSptr = (struct OSblock *) state->OSptr; + char *p = buf; + + while (n--) + if ((*p++ = ARMul_SafeReadByte (state, src++)) == '\0') + return 0; + OSptr->ErrorNo = cb_host_to_target_errno (sim_callback, ENAMETOOLONG); + state->Reg[0] = -1; + return -1; +} + static void SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags) { struct OSblock *OSptr = (struct OSblock *) state->OSptr; - char dummy[2000]; + char buf[PATH_MAX]; int flags; - int i; - for (i = 0; (dummy[i] = ARMul_SafeReadByte (state, name + i)); i++) - ; + if (ReadFileName (state, buf, name, sizeof buf) == -1) + return; /* Now we need to decode the Demon open mode. */ flags = translate_open_mode[SWIflags]; /* Filename ":tt" is special: it denotes stdin/out. */ - if (strcmp (dummy, ":tt") == 0) + if (strcmp (buf, ":tt") == 0) { if (flags == TARGET_O_RDONLY) /* opening tty "r" */ state->Reg[0] = 0; /* stdin */ @@ -323,7 +336,7 @@ SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags) } else { - state->Reg[0] = sim_callback->open (sim_callback, dummy, flags); + state->Reg[0] = sim_callback->open (sim_callback, buf, flags); OSptr->ErrorNo = sim_callback->get_errno (sim_callback); } } @@ -403,6 +416,33 @@ SWIflen (ARMul_State * state, ARMword fh) OSptr->ErrorNo = sim_callback->get_errno (sim_callback); } +static void +SWIremove (ARMul_State * state, ARMword path) +{ + char buf[PATH_MAX]; + + if (ReadFileName (state, buf, path, sizeof buf) != -1) + { + struct OSblock *OSptr = (struct OSblock *) state->OSptr; + state->Reg[0] = sim_callback->unlink (sim_callback, buf); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + } +} + +static void +SWIrename (ARMul_State * state, ARMword old, ARMword new) +{ + char oldbuf[PATH_MAX], newbuf[PATH_MAX]; + + if (ReadFileName (state, oldbuf, old, sizeof oldbuf) != -1 + && ReadFileName (state, newbuf, new, sizeof newbuf) != -1) + { + struct OSblock *OSptr = (struct OSblock *) state->OSptr; + state->Reg[0] = sim_callback->rename (sim_callback, oldbuf, newbuf); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + } +} + /* The emulator calls this routine when a SWI instruction is encuntered. The parameter passed is the SWI number (lower 24 bits of the instruction). */ @@ -544,6 +584,30 @@ ARMul_OSHandleSWI (ARMul_State * state, ARMword number) state->Emulate = FALSE; break; + case SWI_Remove: + if (swi_mask & SWI_MASK_DEMON) + SWIremove (state, state->Reg[0]); + else + unhandled = TRUE; + break; + + case SWI_Rename: + if (swi_mask & SWI_MASK_DEMON) + SWIrename (state, state->Reg[0], state->Reg[1]); + else + unhandled = TRUE; + break; + + case SWI_IsTTY: + if (swi_mask & SWI_MASK_DEMON) + { + state->Reg[0] = sim_callback->isatty (sim_callback, state->Reg[0]); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + } + else + unhandled = TRUE; + break; + /* Handle Angel SWIs as well as Demon ones. */ case AngelSWI_ARM: case AngelSWI_Thumb: @@ -566,10 +630,7 @@ ARMul_OSHandleSWI (ARMul_State * state, ARMword number) /* Unimplemented reason codes. */ case AngelSWI_Reason_ReadC: - case AngelSWI_Reason_IsTTY: case AngelSWI_Reason_TmpNam: - case AngelSWI_Reason_Remove: - case AngelSWI_Reason_Rename: case AngelSWI_Reason_System: case AngelSWI_Reason_EnterSVC: default: @@ -684,6 +745,21 @@ ARMul_OSHandleSWI (ARMul_State * state, ARMword number) ARMul_ReadWord (state, addr + 4), ARMul_ReadWord (state, addr + 8)); break; + + case AngelSWI_Reason_IsTTY: + state->Reg[0] = sim_callback->close (sim_callback, + ARMul_ReadWord (state, addr)); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + break; + + case AngelSWI_Reason_Remove: + SWIremove (state, + ARMul_ReadWord (state, addr)); + + case AngelSWI_Reason_Rename: + SWIrename (state, + ARMul_ReadWord (state, addr), + ARMul_ReadWord (state, addr + 4)); } } else |