Diff for /qemu/arm-semi.c between versions 1.1.1.6 and 1.1.1.7

version 1.1.1.6, 2018/04/24 18:34:19 version 1.1.1.7, 2018/04/24 18:56:34
Line 33 Line 33
 #define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024)  #define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024)
 #else  #else
 #include "qemu-common.h"  #include "qemu-common.h"
 #include "sysemu.h"  
 #include "gdbstub.h"  #include "gdbstub.h"
   #include "hw/arm-misc.h"
 #endif  #endif
   
 #define SYS_OPEN        0x01  #define SYS_OPEN        0x01
Line 370  uint32_t do_arm_semihosting(CPUState *en Line 370  uint32_t do_arm_semihosting(CPUState *en
         return syscall_err;          return syscall_err;
 #endif  #endif
     case SYS_GET_CMDLINE:      case SYS_GET_CMDLINE:
 #ifdef CONFIG_USER_ONLY  
         /* Build a commandline from the original argv.  */  
         {          {
             char *arm_cmdline_buffer;              /* Build a command-line from the original argv.
             const char *host_cmdline_buffer;               *
                * The inputs are:
                *     * ARG(0), pointer to a buffer of at least the size
                *               specified in ARG(1).
                *     * ARG(1), size of the buffer pointed to by ARG(0) in
                *               bytes.
                *
                * The outputs are:
                *     * ARG(0), pointer to null-terminated string of the
                *               command line.
                *     * ARG(1), length of the string pointed to by ARG(0).
                */
   
               char *output_buffer;
               size_t input_size = ARG(1);
               size_t output_size;
               int status = 0;
   
               /* Compute the size of the output string.  */
   #if !defined(CONFIG_USER_ONLY)
               output_size = strlen(ts->boot_info->kernel_filename)
                           + 1  /* Separating space.  */
                           + strlen(ts->boot_info->kernel_cmdline)
                           + 1; /* Terminating null byte.  */
   #else
             unsigned int i;              unsigned int i;
             unsigned int arm_cmdline_len = ARG(1);  
             unsigned int host_cmdline_len =  
                 ts->info->arg_end-ts->info->arg_start;  
   
             if (!arm_cmdline_len || host_cmdline_len > arm_cmdline_len) {              output_size = ts->info->arg_end - ts->info->arg_start;
                 return -1; /* not enough space to store command line */              if (!output_size) {
             }  
   
             if (!host_cmdline_len) {  
                 /* We special-case the "empty command line" case (argc==0).                  /* We special-case the "empty command line" case (argc==0).
                    Just provide the terminating 0. */                     Just provide the terminating 0. */
                 arm_cmdline_buffer = lock_user(VERIFY_WRITE, ARG(0), 1, 0);                  output_size = 1;
                 arm_cmdline_buffer[0] = 0;  
                 unlock_user(arm_cmdline_buffer, ARG(0), 1);  
   
                 /* Adjust the commandline length argument. */  
                 SET_ARG(1, 0);  
                 return 0;  
             }              }
   #endif
   
             /* lock the buffers on the ARM side */              if (output_size > input_size) {
             arm_cmdline_buffer =                   /* Not enough space to store command-line arguments.  */
                 lock_user(VERIFY_WRITE, ARG(0), host_cmdline_len, 0);                  return -1;
             host_cmdline_buffer =  
                 lock_user(VERIFY_READ, ts->info->arg_start,  
                                        host_cmdline_len, 1);  
   
             if (arm_cmdline_buffer && host_cmdline_buffer)  
             {  
                 /* the last argument is zero-terminated;  
                    no need for additional termination */  
                 memcpy(arm_cmdline_buffer, host_cmdline_buffer,  
                        host_cmdline_len);  
   
                 /* separate arguments by white spaces */  
                 for (i = 0; i < host_cmdline_len-1; i++) {  
                     if (arm_cmdline_buffer[i] == 0) {  
                         arm_cmdline_buffer[i] = ' ';  
                     }  
                 }  
   
                 /* Adjust the commandline length argument. */  
                 SET_ARG(1, host_cmdline_len-1);  
             }              }
   
             /* Unlock the buffers on the ARM side.  */              /* Adjust the command-line length.  */
             unlock_user(arm_cmdline_buffer, ARG(0), host_cmdline_len);              SET_ARG(1, output_size - 1);
             unlock_user((void*)host_cmdline_buffer, ts->info->arg_start, 0);  
   
             /* Return success if we could return a commandline.  */              /* Lock the buffer on the ARM side.  */
             return (arm_cmdline_buffer && host_cmdline_buffer) ? 0 : -1;              output_buffer = lock_user(VERIFY_WRITE, ARG(0), output_size, 0);
         }              if (!output_buffer) {
                   return -1;
               }
   
               /* Copy the command-line arguments.  */
   #if !defined(CONFIG_USER_ONLY)
               pstrcpy(output_buffer, output_size, ts->boot_info->kernel_filename);
               pstrcat(output_buffer, output_size, " ");
               pstrcat(output_buffer, output_size, ts->boot_info->kernel_cmdline);
 #else  #else
         return -1;              if (output_size == 1) {
                   /* Empty command-line.  */
                   output_buffer[0] = '\0';
                   goto out;
               }
   
               if (copy_from_user(output_buffer, ts->info->arg_start,
                                  output_size)) {
                   status = -1;
                   goto out;
               }
   
               /* Separate arguments by white spaces.  */
               for (i = 0; i < output_size - 1; i++) {
                   if (output_buffer[i] == 0) {
                       output_buffer[i] = ' ';
                   }
               }
           out:
 #endif  #endif
               /* Unlock the buffer on the ARM side.  */
               unlock_user(output_buffer, ARG(0), output_size);
   
               return status;
           }
     case SYS_HEAPINFO:      case SYS_HEAPINFO:
         {          {
             uint32_t *ptr;              uint32_t *ptr;
Line 441  uint32_t do_arm_semihosting(CPUState *en Line 461  uint32_t do_arm_semihosting(CPUState *en
             /* Some C libraries assume the heap immediately follows .bss, so              /* Some C libraries assume the heap immediately follows .bss, so
                allocate it using sbrk.  */                 allocate it using sbrk.  */
             if (!ts->heap_limit) {              if (!ts->heap_limit) {
                 long ret;                  abi_ulong ret;
   
                 ts->heap_base = do_brk(0);                  ts->heap_base = do_brk(0);
                 limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE;                  limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE;
                 /* Try a big heap, and reduce the size if that fails.  */                  /* Try a big heap, and reduce the size if that fails.  */
                 for (;;) {                  for (;;) {
                     ret = do_brk(limit);                      ret = do_brk(limit);
                     if (ret != -1)                      if (ret >= limit) {
                         break;                          break;
                       }
                     limit = (ts->heap_base >> 1) + (limit >> 1);                      limit = (ts->heap_base >> 1) + (limit >> 1);
                 }                  }
                 ts->heap_limit = limit;                  ts->heap_limit = limit;

Removed from v.1.1.1.6  
changed lines
  Added in v.1.1.1.7


unix.superglobalmegacorp.com