<commit_before>//===-- ExecveHandler.c - Replaces execve() to run LLVM files -------------===//
//
// This file implements a replacement execve() to spawn off LLVM programs to run
// transparently, without needing to be (JIT-)compiled manually by the user.
//
//===----------------------------------------------------------------------===//

#include "OSInterface.h"
#include "SysUtils.h"
#include "Config/errno.h"
#include "Config/stdlib.h"
#include "Config/unistd.h"
#include <fcntl.h>
#include <stdio.h>
#include <string.h>

/*
 * This is the expected header for all valid LLVM bytecode files.
 * The first four characters must be exactly this.
 */
static const char llvmHeader[] = "llvm";

/*
 * This replacement execve() function first checks the file to be executed
 * to see if it is a valid LLVM bytecode file, and then either invokes our
 * execution environment or passes it on to the system execve() call.
 */
int execve(const char *filename, char *const argv[], char *const envp[])
{
  /* Open the file, test to see if first four characters are "llvm" */
  size_t headerSize = strlen(llvmHeader);
  char header[headerSize];
  char* realFilename = 0;
  /* 
   * If the program is specified with a relative or absolute path, 
   * then just use the path and filename as is, otherwise search for it.
   */
  if (filename[0] != '.' && filename[0] != '/')
    realFilename = FindExecutable(filename);
  else
    realFilename = (char*) filename;
  if (!realFilename) {
    fprintf(stderr, "Cannot find path to `%s', exiting.\n", filename);
    return -1;
  }
  errno = 0;
  int file = open(realFilename, O_RDONLY);
  /* Check validity of `file' */
  if (errno) return EIO;
  /* Read the header from the file */
  ssize_t bytesRead = read(file, header, headerSize);
  close(file);
  if (bytesRead != (ssize_t)headerSize) return EIO;
  if (!memcmp(llvmHeader, header, headerSize)) {
    /*
     * Check if we have a cached translation on disk
     */ 
    struct stat buf;
    llvmStat(realFilename, &buf);
    if (isExecutable(&buf)) {
      size_t size;
      void *fileAddr = llvmReadFile(realFilename, &size);
      fprintf(stderr, "Found in cache: '%s'\n", realFilename);
      if (fileAddr) {
        free(fileAddr);
      }
      llvmExecve(realFilename, argv, envp);
    } else {
      /* 
       * Not in cache: save translation
       */ 
      //llvmSaveFile(realFilename, addr, len);
      //fprintf(stderr, "Cached: '%s'\n", realFilename);
    }
    
    /* 
     * This is a bytecode file, so execute the JIT with the program and
     * parameters.
     */
    unsigned argvSize, idx;
    for (argvSize = 0, idx = 0; argv[idx] && argv[idx][0]; ++idx)
      ++argvSize;
    char **LLIargs = (char**) malloc(sizeof(char*) * (argvSize+2));
    char *LLIpath = FindExecutable("lli");
    if (!LLIpath) {
      fprintf(stderr, "Cannot find path to `lli', exiting.\n");
      return -1;
    }
    LLIargs[0] = LLIpath;
    LLIargs[1] = realFilename;
    for (idx = 1; idx != argvSize; ++idx)
      LLIargs[idx+1] = argv[idx];
    LLIargs[argvSize + 1] = '\0';
    return executeProgram(LLIpath, LLIargs, envp);
  }<commit_msg>The caching will not live in LLEE's execve() handler; that's suboptimal.<commit_after>//===-- ExecveHandler.c - Replaces execve() to run LLVM files -------------===//
//
// This file implements a replacement execve() to spawn off LLVM programs to run
// transparently, without needing to be (JIT-)compiled manually by the user.
//
//===----------------------------------------------------------------------===//

#include "OSInterface.h"
#include "SysUtils.h"
#include "Config/errno.h"
#include "Config/stdlib.h"
#include "Config/unistd.h"
#include <fcntl.h>
#include <stdio.h>
#include <string.h>

/*
 * This is the expected header for all valid LLVM bytecode files.
 * The first four characters must be exactly this.
 */
static const char llvmHeader[] = "llvm";

/*
 * This replacement execve() function first checks the file to be executed
 * to see if it is a valid LLVM bytecode file, and then either invokes our
 * execution environment or passes it on to the system execve() call.
 */
int execve(const char *filename, char *const argv[], char *const envp[])
{
  /* Open the file, test to see if first four characters are "llvm" */
  size_t headerSize = strlen(llvmHeader);
  char header[headerSize];
  char* realFilename = 0;
  /* 
   * If the program is specified with a relative or absolute path, 
   * then just use the path and filename as is, otherwise search for it.
   */
  if (filename[0] != '.' && filename[0] != '/')
    realFilename = FindExecutable(filename);
  else
    realFilename = (char*) filename;
  if (!realFilename) {
    fprintf(stderr, "Cannot find path to `%s', exiting.\n", filename);
    return -1;
  }
  errno = 0;
  int file = open(realFilename, O_RDONLY);
  /* Check validity of `file' */
  if (errno) return EIO;
  /* Read the header from the file */
  ssize_t bytesRead = read(file, header, headerSize);
  close(file);
  if (bytesRead != (ssize_t)headerSize) return EIO;
  if (!memcmp(llvmHeader, header, headerSize)) {
    /*
     * Check if we have a cached translation on disk
     */ 
    struct stat buf;
    llvmStat(realFilename, &buf);
    if (isExecutable(&buf)) {
      size_t size;
      void *fileAddr = llvmReadFile(realFilename, &size);
      fprintf(stderr, "Found in cache: '%s'\n", realFilename);
      if (fileAddr) {
        free(fileAddr);
      }
      llvmExecve(realFilename, argv, envp);
    }    

    /* 
     * This is a bytecode file, so execute the JIT with the program and
     * parameters.
     */
    unsigned argvSize, idx;
    for (argvSize = 0, idx = 0; argv[idx] && argv[idx][0]; ++idx)
      ++argvSize;
    char **LLIargs = (char**) malloc(sizeof(char*) * (argvSize+2));
    char *LLIpath = FindExecutable("lli");
    if (!LLIpath) {
      fprintf(stderr, "Cannot find path to `lli', exiting.\n");
      return -1;
    }
    LLIargs[0] = LLIpath;
    LLIargs[1] = realFilename;
    for (idx = 1; idx != argvSize; ++idx)
      LLIargs[idx+1] = argv[idx];
    LLIargs[argvSize + 1] = '\0';
    return executeProgram(LLIpath, LLIargs, envp);
  }
{'fraction_non_alphanumeric': 0.1609550105570895, 'fraction_numerical': 0.0051973363651128795, 'mean_word_length': 2.780233271945979, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6244604', 'n_tokens_mistral': 1956, 'n_tokens_neox': 1920, 'n_words': 659}