示例#1
0
static void __attribute__((constructor)) init(void)
{
    char handle[128];

    find_or_make_array_variable("DLHANDLES", 3);

    // RTLD_NEXT and RTLD_DEFAULT are special handles for dlsym. These are
    // stored as strings rather than integers, as otherwise they can
    // be interpreted as flags (they are small negative integers cast to
    // void*).
    snprintf(handle, sizeof handle, "%p", RTLD_NEXT);
    bind_variable("RTLD_NEXT", handle, 0);

    snprintf(handle, sizeof handle, "%p", RTLD_DEFAULT);
    bind_variable("RTLD_DEFAULT", handle, 0);
}
示例#2
0
文件: util.c 项目: jimsrc/MPI-Bash
/* Perform the same operation as bind_variable, but with VALUE being a
 * number, not a string. */
SHELL_VAR *
mpibash_bind_variable_number (const char *name, long value, int flags)
{
  char numstr[25];    /* String version of VALUE */

  sprintf (numstr, "%ld", value);
  return bind_variable (name, numstr, flags);
}
示例#3
0
文件: ctypes.c 项目: sjas/ctypes.sh
// Usage:
//
// dlsym $RTLD_DEFAULT "errno"
//
static int get_symbol_address(WORD_LIST *list)
{
    int opt;
    void *handle;
    void *symbol;
    char *resultname;
    char retval[256];

    resultname = "DLRETVAL";

    reset_internal_getopt();

    // $ dlcall [-n name]
    while ((opt = internal_getopt(list, "n:")) != -1) {
        switch (opt) {
            case 'n':
                resultname = list_optarg;
                break;
            default:
                builtin_usage();
                return EX_USAGE;
        }
    }

    // Skip past any options.
    if ((list = loptend) == NULL || list->next == NULL) {
        builtin_usage();
        return EX_USAGE;
    }

    if (check_parse_ulong(list->word->word, (void *) &handle) == 0) {
        builtin_warning("handle %s %p is not well-formed", list->word->word, handle);
        return EX_USAGE;
    }

    if (!(symbol = dlsym(handle, list->next->word->word))) {
        builtin_warning("failed to resolve symbol %s, %s", list->next->word->word, dlerror());
        return EXECUTION_FAILURE;
    }

    snprintf(retval, sizeof retval, "pointer:%p", symbol);
    
    fprintf(stderr, "%s\n", retval);
    
    bind_variable(resultname, retval, 0);

    return EXECUTION_SUCCESS;
}
示例#4
0
文件: thread.c 项目: budden/sbcl-ita
void
attach_os_thread(init_thread_data *scribble)
{
    os_thread_t os = pthread_self();
    odxprint(misc, "attach_os_thread: attaching to %p", os);

    struct thread *th = create_thread_struct(NIL);
    block_deferrable_signals(&scribble->oldset);
    th->no_tls_value_marker = NO_TLS_VALUE_MARKER_WIDETAG;
    /* We don't actually want a pthread_attr here, but rather than add
     * `if's to the post-mostem, let's just keep that code happy by
     * keeping it initialized: */
    pthread_attr_init(th->os_attr);

#ifndef LISP_FEATURE_WIN32
    /* On windows, arch_os_thread_init will take care of finding the
     * stack. */
    void *stack_addr;
    size_t stack_size;
#ifdef LISP_FEATURE_OPENBSD
    stack_t stack;
    pthread_stackseg_np(os, &stack);
    stack_size = stack.ss_size;
    stack_addr = (void*)((size_t)stack.ss_sp - stack_size);
#elif defined LISP_FEATURE_SUNOS
  stack_t stack;
  thr_stksegment(&stack);
  stack_size = stack.ss_size;
  stack_addr = (void*)((size_t)stack.ss_sp - stack_size);
#elif defined(LISP_FEATURE_DARWIN)
    stack_addr = pthread_get_stackaddr_np(os);
    stack_size = pthread_get_stacksize_np(os);
#else
    pthread_attr_t attr;
#ifdef LISP_FEATURE_FREEBSD
    pthread_attr_get_np(os, &attr);
#else
    int pthread_getattr_np(pthread_t, pthread_attr_t *);
    pthread_getattr_np(os, &attr);
#endif
    pthread_attr_getstack(&attr, &stack_addr, &stack_size);
#endif

    th->control_stack_start = stack_addr;
    th->control_stack_end = (void *) (((uintptr_t) stack_addr) + stack_size);
#endif

    init_new_thread(th, scribble, 0);

    /* We will be calling into Lisp soon, and the functions being called
     * recklessly ignore the comment in target-thread which says that we
     * must be careful to not cause GC while initializing a new thread.
     * Since we first need to create a fresh thread object, it's really
     * tempting to just perform such unsafe allocation though.  So let's
     * at least try to suppress GC before consing, and hope that it
     * works: */
    bind_variable(GC_INHIBIT, T, th);

    uword_t stacksize
        = (uword_t) th->control_stack_end - (uword_t) th->control_stack_start;
    odxprint(misc, "attach_os_thread: attached %p as %p (0x%lx bytes stack)",
             os, th, (long) stacksize);
}
示例#5
0
文件: ctypes.c 项目: sjas/ctypes.sh
// Usage:
//
// dlcall $RTLD_DEFAULT "printf" "hello %s %u %c" $USER 123 int:10
//
static int call_foreign_function(WORD_LIST *list)
{
    unsigned nargs;
    int opt;
    ffi_cif cif;
    ffi_type **argtypes;
    ffi_type *rettype;
    void **values;
    void *handle;
    void *func;
    char *prefix;
    char *format;
    char *resultname;

    nargs       = 0;
    argtypes    = NULL;
    values      = NULL;
    format      = NULL;
    prefix      = NULL;
    rettype     = &ffi_type_void;
    resultname  = "DLRETVAL";

    reset_internal_getopt();

    // $ dlcall [-a abi] [-r type] [-n name]
    while ((opt = internal_getopt(list, "a:r:n:")) != -1) {
        switch (opt) {
            case 'a':
                builtin_warning("FIXME: only abi %u is currently supported", FFI_DEFAULT_ABI);
                return 1;
                break;
            case 'r':
                if (decode_type_prefix(prefix = list_optarg, NULL, &rettype, NULL, &format) != true) {
                    builtin_warning("failed to parse return type");
                    return 1;
                }
                break;
            case 'n':
                resultname = list_optarg;
                break;
            default:
                builtin_usage();
                return 1;
        }
    }

    // Skip past any options.
    if ((list = loptend) == NULL || list->next == NULL) {
        builtin_usage();
        return 1;
    }

    if (check_parse_ulong(list->word->word, (void *) &handle) == 0) {
        builtin_warning("handle %s %p is not well-formed", list->word->word, handle);
        return 1;
    }

    if (!(func = dlsym(handle, list->next->word->word))) {
        builtin_warning("failed to resolve symbol %s, %s", list->next->word->word, dlerror());
        return 1;
    }

    // Skip to optional parameters
    list = list->next->next;

    while (list) {
        argtypes = realloc(argtypes, (nargs + 1) * sizeof(ffi_type *));
        values   = realloc(values, (nargs + 1) * sizeof(void *));

        if (decode_primitive_type(list->word->word, &values[nargs], &argtypes[nargs]) != true) {
            builtin_error("failed to decode type from parameter %s", list->word->word);
            goto error;
        }

        nargs++;
        list = list->next;
    }

    if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, nargs, rettype, argtypes) == FFI_OK) {
        char *retval;
        void *rc = alloca(rettype->size);

        // Do the call.
        ffi_call(&cif, func, rc, values);

        // Print the result.
        if (format) {
            switch (rettype->size) {
                case  1: asprintf(&retval, format, *(uint8_t  *) rc); break;
                case  2: asprintf(&retval, format, *(uint16_t *) rc); break;
                case  4: asprintf(&retval, format, *(uint32_t *) rc, *(float *) rc); break;
                case  8: asprintf(&retval, format, *(uint64_t *) rc, *(double *) rc); break;
                case 16: asprintf(&retval, format, *(long double *) rc); break;
                default:
                    builtin_error("cannot handle size %lu", rettype->size);
                    abort();
            }

            fprintf(stderr, "%s\n", retval);
            bind_variable(resultname, retval, 0);
            free(retval);
        }
    }

    for (unsigned i = 0; i < nargs; i++)
        free(values[i]);
    free(values);
    free(argtypes);
    return 0;

  error:
    for (unsigned i = 0; i < nargs; i++)
        free(values[i]);
    free(values);
    free(argtypes);
    return 1;
}
示例#6
0
// Usage:
//
// dlcall "printf" "hello %s %u %c" $USER 123 int:10
//
static int call_foreign_function(WORD_LIST *list)
{
    unsigned nargs;
    unsigned i;
    int opt;
    ffi_cif cif;
    ffi_type **argtypes;
    ffi_type *rettype;
    void **values;
    void *handle;
    void *func;
    char *prefix;
    char *format;
    char *resultname;

    nargs       = 0;
    argtypes    = NULL;
    values      = NULL;
    format      = NULL;
    prefix      = NULL;
    rettype     = &ffi_type_void;
    resultname  = "DLRETVAL";
    handle      = RTLD_DEFAULT;

    reset_internal_getopt();

    // $ dlcall [-a abi] [-r type] [-n name] [-h handle] symbol args...
    while ((opt = internal_getopt(list, "h:a:r:n:")) != -1) {
        switch (opt) {
            case 'a':
                builtin_warning("FIXME: only abi %u is currently supported", FFI_DEFAULT_ABI);
                return 1;
                break;
            case 'r':
                if (decode_type_prefix(prefix = list_optarg, NULL, &rettype, NULL, &format) != true) {
                    builtin_warning("failed to parse return type");
                    return 1;
                }
                break;
            case 'n':
                resultname = list_optarg;
                break;
            case 'h':
                if (check_parse_ulong(list_optarg, (void *) &handle) == 0) {
                    builtin_warning("handle %s %p is not well-formed", list_optarg, handle);
                    return EXECUTION_FAILURE;
                }
                break;
            default:
                builtin_usage();
                return EX_USAGE;
        }
    }

    // Skip past any options.
    if ((list = loptend) == NULL) {
        builtin_usage();
        return EX_USAGE;
    }

    if (!(func = dlsym(handle, list->word->word))) {
        builtin_warning("failed to resolve symbol %s, %s", list->word->word, dlerror());
        return 1;
    }

    // Skip to optional parameters
    list = list->next;

    while (list) {
        argtypes = realloc(argtypes, (nargs + 1) * sizeof(ffi_type *));
        values   = realloc(values, (nargs + 1) * sizeof(void *));

        if (decode_primitive_type(list->word->word, &values[nargs], &argtypes[nargs]) != true) {
            builtin_error("failed to decode type from parameter %s", list->word->word);
            goto error;
        }

        nargs++;
        list = list->next;
    }

    if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, nargs, rettype, argtypes) == FFI_OK) {
        char *retval;
        void *rc = alloca(rettype->size);

        // Do the call.
        ffi_call(&cif, func, rc, values);

        // Decode the result.
        if (format) {
            retval = encode_primitive_type(format, rettype, rc);

            // If this is an interactive shell, print the output.
            if (interactive_shell) {
                fprintf(stderr, "%s\n", retval);
            }

            // Save the result to the requested location.
            bind_variable(resultname, retval, 0);

            // Bash maintains it's own copy of this string, so we can throw it away.
            free(retval);
        }
    }

    for (i = 0; i < nargs; i++)
        free(values[i]);
    free(values);
    free(argtypes);
    return 0;

  error:
    for (i = 0; i < nargs; i++)
        free(values[i]);
    free(values);
    free(argtypes);
    return 1;
}
示例#7
0
// Usage:
//
// dlsym $RTLD_DEFAULT "errno"
//
static int get_symbol_address(WORD_LIST *list)
{
    int opt;
    void *handle;
    void *symbol;
    char *resultname;
    char *format;
    char *retval;
    ffi_type *rettype;

    handle = RTLD_DEFAULT;
    resultname = "DLRETVAL";
    rettype = NULL;

    reset_internal_getopt();

    // $ dlsym [-n name] [-h handle] symbol
    while ((opt = internal_getopt(list, "d:h:n:")) != -1) {
        switch (opt) {
            case 'd':
                if (decode_type_prefix(list_optarg, NULL, &rettype, NULL, &format) != true) {
                    builtin_warning("failed to parse dereference type");
                    return 1;
                }
                break;
            case 'n':
                resultname = list_optarg;
                break;
            case 'h':
                if (check_parse_ulong(list_optarg, (void *) &handle) == 0) {
                    builtin_warning("handle %s %p is not well-formed", list_optarg, handle);
                    return EXECUTION_FAILURE;
                }
                break;
            default:
                builtin_usage();
                return EX_USAGE;
        }
    }

    // Skip past any options.
    if ((list = loptend) == NULL) {
        builtin_usage();
        return EX_USAGE;
    }

    if (!(symbol = dlsym(handle, list->word->word))) {
        builtin_warning("failed to resolve symbol %s, %s", list->word->word, dlerror());
        return EXECUTION_FAILURE;
    }

    if (rettype == NULL) {
        asprintf(&retval, "pointer:%p", symbol);
    } else {
        retval = encode_primitive_type(format, rettype, symbol);
    }


    if (interactive_shell) {
        fprintf(stderr, "%s\n", retval);
    }

    bind_variable(resultname, retval, 0);

    free(retval);

    return EXECUTION_SUCCESS;
}
示例#8
0
/* The function implementing the builtin.  It uses internal_getopt to
   parse options.  It is the same as getopt(3), but it takes a pointer
   to a WORD_LIST.

   If the builtin takes no options, call no_options(list) before doing
   anything else.  If it returns a non-zero value, your builtin should
   immediately return EX_USAGE.

   A builtin command returns EXECUTION_SUCCESS for success and
   EXECUTION_FAILURE to indicate failure.  */
int
readrec_builtin (WORD_LIST *list)
{
  SHELL_VAR *var;
  rec_parser_t parser;
  rec_record_t record;

  no_options (list);

  /* Create a librec parser to operate on the standard input and try
     to read a record.  If there is a parse error then report it and
     fail.  */

  parser = rec_parser_new (stdin, "stdin");
  if (!parser)
    return EXECUTION_FAILURE;

  if (!rec_parse_record (parser, &record))
    {
      return EXECUTION_FAILURE;
    }

  {
    size_t record_str_size = 0;
    char *record_str = NULL;
    char *record_str_dequoted = NULL;
    rec_writer_t writer = rec_writer_new_str (&record_str, &record_str_size);

    if (!writer || !rec_write_record (writer, record))
      return EXIT_FAILURE;
    rec_writer_destroy (writer);

    /* Set the REPLY_REC environment variable to the read record.  */
    record_str_dequoted = dequote_string (record_str);
    var = bind_variable ("REPLY_REC", record_str_dequoted, 0);
    VUNSETATTR (var, att_invisible);
    xfree (record_str_dequoted);

    /* Set the environment variables for the fields.  */
    {
      rec_field_t field = NULL;
      rec_mset_iterator_t iter = rec_mset_iterator (rec_record_mset (record));

      //      rec_record_reset_marks (record);
      while (rec_mset_iterator_next (&iter, MSET_FIELD, (const void **) &field, NULL))
        {
          char *var_name = rec_field_name (field);
          size_t num_fields = rec_record_get_num_fields_by_name (record, var_name);

          //          if (rec_record_field_mark (record, field))
          //            continue;

#if defined ARRAY_VARS
          if (num_fields > 1)
            {
              /* In case several fields share the same field name, create
                 an array variable containing all the values.  */

              size_t i = 0;
              for (; i < num_fields; i++)
                {
                  //                  rec_record_mark_field (record, field, true);
                  field = rec_record_get_field_by_name (record, var_name, i);
                  var = bind_array_variable (var_name, i, rec_field_value (field), 0);
                  VUNSETATTR (var, att_invisible);
                }
            }
          else
            {
              /* Bind a normal variable.  */
              char *var_value = rec_field_value (field);
              var = bind_variable (var_name, var_value, 0);
              VUNSETATTR (var, att_invisible);
            }
#endif /* ARRAY_VARS */
        }
      rec_mset_iterator_free (&iter);
    }
  }

  return EXECUTION_SUCCESS;
}
示例#9
0
static int generate_native_callback(WORD_LIST *list)
{
    int nargs;
    void *callback;
    ffi_cif *cif;
    ffi_closure *closure;
    ffi_type **argtypes;
    ffi_type *rettype;
    char **proto;
    char *resultname = "DLRETVAL";
    char opt;
    reset_internal_getopt();

    // $ dlcall [-a abi] [-r type] [-n name]
    while ((opt = internal_getopt(list, "a:r:n:")) != -1) {
        switch (opt) {
            case 'n':
                resultname = list_optarg;
                break;
            default:
                builtin_usage();
                return EX_USAGE;
        }
    }

    // Skip past any options.
    if ((list = loptend) == NULL || !list->next) {
        builtin_usage();
        return EX_USAGE;
    }

    closure     = ffi_closure_alloc(sizeof(ffi_closure), &callback);
    cif         = malloc(sizeof(ffi_cif));
    argtypes    = NULL;
    proto       = malloc(sizeof(char *));
    proto[0]    = strdup(list->word->word);
    nargs       = 0;
    list        = list->next;

    // Second parameter must be the return type
    if (decode_type_prefix(list->word->word,
                           NULL,
                           &rettype,
                           NULL,
                           NULL) != true) {
        builtin_warning("couldnt parse the return type %s", list->word->word);
        return EXECUTION_FAILURE;
    }

    // Skip past return type
    list = list->next;

    while (list) {
        argtypes        = realloc(argtypes, (nargs + 1) * sizeof(ffi_type *));
        proto           = realloc(proto, (nargs + 1 + 1) * sizeof(char *));

        if (decode_type_prefix(list->word->word, NULL, &argtypes[nargs], NULL, &proto[nargs+1]) != true) {
            builtin_error("failed to decode type from parameter %s", list->word->word);
            goto error;
        }

        list = list->next;
        nargs++;
    }

    if (ffi_prep_cif(cif, FFI_DEFAULT_ABI, nargs, rettype, argtypes) == FFI_OK) {
        // Initialize the closure.
        if (ffi_prep_closure_loc(closure, cif, execute_bash_trampoline, proto, callback) == FFI_OK) {
            char retval[1024];
            snprintf(retval, sizeof retval, "pointer:%p", callback);
            fprintf(stderr, "%s\n", retval);
            bind_variable(resultname, retval, 0);
        }
    }

    //free(argtypes);
    return 0;

  error:
    //free(argtypes);
    return 1;
}