Exemple #1
0
void
foo (void)
{
  char b[10];
  __builtin_memmove (&a[0], &a[20], 20);
  __builtin_memmove (&b[1], &a[25], 9);
  bar (b);
}
void
foo  (int *a, char *b, char *c)
{
    /* One check for c[0], one check for a[], one check for c and 2 checks for b.  */
    __builtin_memmove (c, b, a[c[0]]);
    /* One check for a[], one check for c and one check for b.  */
    __builtin_memmove (c, b, a[b[0]]);
    /* For a total of 8 checks.  */
}
void
foo  (int *a, char *b, char *c)
{
  /* One check for c[0], one check for a[].  */
  __builtin_memmove (c, b, a[c[0]]);
  /* One check for b[0], one check for a[].  */
  __builtin_memmove (c, b, a[b[0]]);
  /* For a total of 4 checks.  */
  int d = c[0] == b[0];
}
Exemple #4
0
int main () {                    // ***** main *****
  char *pj, *pq, *pr;            // buffer pointers: inp,out,/out
  char *jjj = malloc(JBFSIZE);   // allocate input line buffer
  char *qqq = malloc(QBFSIZE);   // output buffer (dyn. size)
  char *pqstop = qqq+QBFSIZE;    // end-of-buffer pointer
  char xtab[256] = VALL;         // char conversion table

  if (!jjj || !qqq)
    return errex("Buffer allocation", !jjj + !qqq);
  pj = fgets(jjj,JBFSIZE,stdin);         // fetch 1st line
  if (!pj)
    return errex("No input data",0);
  if (*jjj != '>')
    return errex("1st char not '>'", 0);

  while (pj) {                           // MAIN LOOP: process data
    fputs(jjj, stdout);                  // output ID line

    for (pq=qqq+1, pr=pqstop; ; pq++) {  // LOOP: fill output buffer
      pj = fgets(jjj, JBFSIZE, stdin);   // get line from stdin
      if (!pj || (*jjj=='>'))  break;    // EOF or new ID line
      if (pr <= (pq+61)) {               // need to resize buffer
        char *newstop = pqstop + 12777888;
        char *newptr  = realloc(qqq, newstop-qqq);
        if (!newptr)
          return errex("Out of memory", 0);
        if (newptr != qqq) {             // new base: adj. pointers
          size_t x = newptr-qqq;         // offset for pointer update
          pq+=x;  pr+=x;  qqq+=x;
          newstop+=x;  pqstop+=x;
        }
        pr = __builtin_memmove(newstop-(pqstop-pr), pr, pqstop-pr);
        pqstop = newstop;                // buffer resize complete
      }
      while (*pj) {                      // LOOP: conv. & revert line
        char c = xtab[(unsigned char)(*pj++)];
        if (c)                           // conversion valid
          *(--pr) = c;
      }
    }

    for (pq = qqq; pr<pqstop; ) {        // LOOP: format output
      size_t x = (pqstop-pr)<60 ? pqstop-pr : 60;
      __builtin_memmove(pq,pr,x);        // move line to free space
      pr+=x;  pq+=x;  *(pq++) = 0xA;     // adjust pointers, add LF
    }
    fwrite(qqq, 1, pq-qqq, stdout);      // output converted data
  }
  return 0;
}
void
foo  (int *a, char *b, char *c)
{
  /* One check for a[].  */
  __builtin_memmove (c, b, a[0]);
  /* For a total of 1 checks.  */
  int d = a[0] == 0;
}
static inline void
foo (unsigned h, V j, U k, V n)
{
  k /= h;
  __builtin_memmove (&h, &n, 1);
  n[j[1]] *= 0x7FFFFFFFFFFFFFFF;
  j[k[5]] = 0;
  g = n;
  i = h + j + n;
}
int main(int argc, char **argv)
{
	void *ptr;
	unsigned long dst;
	unsigned long src = ~0;

	ptr = __builtin_memmove(&dst, &src, sizeof(dst));
	(void)ptr;

	return 0;
}
void f(void *d, const void *s, __SIZE_TYPE__ n)
{
  void *t1 = __builtin_memcpy (d, s, n);
  if (t1 == 0)
    __builtin_abort ();

  void *t2 = __builtin_memmove (d, s, n);
  if (t2 == 0)
    __builtin_abort ();

  void *t3 = __builtin_memset (d, 0, n);
  if (t3 == 0)
    __builtin_abort ();

  void *t4 = __builtin_strcpy (d, s);
  if (t4 == 0)
    __builtin_abort ();

  void *t5 = __builtin_strncpy (d, s, n);
  if (t5 == 0)
    __builtin_abort ();

  void *t6 = __builtin_strcat (d, s);
  if (t6 == 0)
    __builtin_abort ();

  void *t7 = __builtin_strncat (d, s, n);
  if (t7 == 0)
    __builtin_abort ();

  void *t8 = __builtin_stpcpy (d, s);
  if (t8 == 0)
    __builtin_abort ();

  void *t9 = __builtin_stpncpy (d, s, n);
  if (t9 == 0)
    __builtin_abort ();
}
Exemple #9
0
/*
 * Copyright (c) 2017, 2018, Oracle and/or its affiliates.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are
 * permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or other materials provided
 * with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to
 * endorse or promote products derived from this software without specific prior written
 * permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */
int main() {
  unsigned int a = 0x11223344;
  unsigned int b = 0;
  __builtin_memmove(&a, &b, sizeof(a));
  return a != b;
}
Exemple #10
0
void move(char *target, char *source, int length) {
  __builtin_memmove(target, source, length);
}
Exemple #11
0
static void __attribute__((constructor)) startup(void)
{
#else
#define RETURN_VALUE 0
static void *ignore_ud2_addr;
// scratch test code
int main(void)
{
#endif

	char *debug_level_str = getenv("TRAP_SYSCALLS_DEBUG");
	char *footprint_fd_str = getenv("TRAP_SYSCALLS_FOOTPRINT_FD");
	char *trace_fd_str = getenv("TRAP_SYSCALLS_TRACE_FD");
	char *sleep_for_seconds_str = getenv("TRAP_SYSCALLS_SLEEP_FOR_SECONDS");
	char *stop_self_str = getenv("TRAP_SYSCALLS_STOP_SELF");
	stop_self = (stop_self_str != NULL);
	footprints_spec_filename = getenv("TRAP_SYSCALLS_FOOTPRINT_SPEC_FILENAME");
	struct timespec one_second = { /* seconds */ 1, /* nanoseconds */ 0 };
	if (debug_level_str) debug_level = atoi(debug_level_str);
	if (trace_fd_str) trace_fd = atoi(trace_fd_str);
	if (footprint_fd_str) footprint_fd = atoi(footprint_fd_str);
	if (sleep_for_seconds_str) sleep_for_seconds = atoi(sleep_for_seconds_str);
	debug_printf(0, "Debug level is %s=%d.\n", debug_level_str, debug_level);
	if (stop_self) {
		self_pid = raw_getpid();
		debug_printf(0, "TRAP_SYSCALLS_STOP_SELF is set, sending SIGSTOP to self (pid %d)\n", self_pid);
		raw_kill(self_pid, SIGSTOP);
	}
	debug_printf(0, "TRAP_SYSCALLS_SLEEP_FOR_SECONDS is %s, pausing for %d seconds", sleep_for_seconds_str, sleep_for_seconds);
	for (int i = 0; i < sleep_for_seconds; i++) {
		raw_nanosleep(&one_second, NULL);
		debug_printf(0, ".");
	}
	debug_printf(0, "\n");

	/* Is fd open? If so, it's the input fd for our sanity check info
	 * from systemtap. */
	debug_printf(0, "TRAP_SYSCALLS_FOOTPRINT_FD is %s, ", footprint_fd_str);
	if (footprint_fd > 2)
	{
		struct stat buf;
		int stat_ret = raw_fstat(footprint_fd, &buf);
		if (stat_ret == 0) {
			debug_printf(0, "fd %d is open; outputting systemtap cross-check info.\n", footprint_fd);
			/* PROBLEM: ideally we'd read in the stap script's output ourselves, and process
			 * it at every system call. But by reading in stuff from stap, we're doing more
			 * copying to/from userspace, so creating a feedback loop which would blow up.
			 *
			 * Instead we write out what we think we touched, and do a diff outside the process.
			 * This also adds noise to stap's output, but without the feedback cycle: we ourselves
			 * won't read the extra output, hence won't write() more stuff in response.
			 */
			__write_footprints = 1;
			footprints_out = fdopen(footprint_fd, "a");
			if (!footprints_out)
				{
					debug_printf(0, "Could not open footprints output stream for writing!\n");
				}

			if (footprints_spec_filename) {

				 footprints = parse_footprints_from_file(footprints_spec_filename, &footprints_env);
				 
			} else {
				 debug_printf(0, "no footprints spec filename provided\n", footprints_spec_filename);
			}

			
		} else {
			debug_printf(0, "fd %d is closed; skipping systemtap cross-check info.\n", footprint_fd);
		}

	}
	else
	{
		debug_printf(0, "skipping systemtap cross-check info\n");
	}

	debug_printf(0, "TRAP_SYSCALLS_TRACE_FD is %s, ", trace_fd_str);
	if (!trace_fd_str || trace_fd == 2) {
		debug_printf(0, "dup'ing stderr, ");
		trace_fd = dup(2);
	}
	
	if (trace_fd >= 0) {
		struct stat buf;
		int stat_ret = raw_fstat(trace_fd, &buf);
		if (stat_ret == 0) {
			debug_printf(0, "fd %d is open; outputting traces there.\n", trace_fd);
			__write_traces = 1;
			traces_out = fdopen(trace_fd, "a");
			if (!traces_out)
				{
					debug_printf(0, "Could not open traces output stream for writing!\n");
				}
		} else {
			debug_printf(0, "fd %d is closed; not outputting traces.\n", trace_fd);
		}
	} else {
		debug_printf(0, "not outputting traces.\n");
	}

	int fd = raw_open("/proc/self/maps", O_RDONLY);

	if (fd != -1)
	{
		// we use a simple buffer and a read loop
		char buf[8192];
		unsigned int ret;
		char *buf_pos = &buf[0]; // the next position to fill in the buffer
		char *entry_start_pos = &buf[0]; // the position
		size_t size_requested;
		do
		{
			// read some stuff, perhaps filling up the buffer
			size_requested = sizeof buf - (buf_pos - buf);
			ret = raw_read(fd, buf_pos, size_requested);
			char *buf_limit = buf_pos + ret;
			assert(buf_limit <= &buf[sizeof buf]);

			// we have zero or more complete entries in the buffer; iterate over them
			char *seek_pos;
			while (1)
			{
				seek_pos = entry_start_pos;
				// search forward for a newline
				while (seek_pos != buf_limit && *seek_pos != '\n')
				{ ++seek_pos; }

				// did we find one?
				if (seek_pos == buf_limit)
				{
					// no!
					// but we have a partial entry in the buffer
					// between entry_start_pos and seek_pos;
					// copy it to the start, re-set and continue
					__builtin_memmove(&buf[0], entry_start_pos, seek_pos - entry_start_pos);
					buf_pos = &buf[seek_pos - entry_start_pos];
					entry_start_pos = &buf[0];
					break;
				}
				else
				{
					assert(*seek_pos == '\n');
					// we have a complete entry; read it and advance entry_start_pos
					char debug_buf1[seek_pos - entry_start_pos + 1];
					strncpy(debug_buf1, entry_start_pos, seek_pos - entry_start_pos);
					debug_buf1[sizeof debug_buf1 - 1] = '\0';
					debug_printf(1, "DEBUG: entry is: %s\n", debug_buf1);
					char debug_buf2[buf_pos - buf];
					strncpy(debug_buf2, buf, buf_pos - buf);
					debug_buf2[sizeof debug_buf2 - 1] = '\0';
					debug_printf(1, "DEBUG: buffer is: %s", debug_buf2);
					saw_mapping(entry_start_pos, seek_pos);
					entry_start_pos = seek_pos + 1;
					// if the newline was the last in the buffer, break and read more
					if (entry_start_pos == buf_pos + sizeof buf)
					{ buf_pos = entry_start_pos = &buf[0]; break; }

					// else we might have another entry; go round again
					continue;
				}
			}
		} while (ret > 0);
		raw_close(fd);
	}

	/* Install our SIGILL (was SIGTRAP, but that interferes with gdb) handler.
	 * Linux seems to require us to provide a restorer; the code is in restore_rt. */
	struct sigaction action = {
		//.sa_sigaction = &handle_sigtrap,
		.sa_handler = &handle_sigill,
		.sa_mask = 0,
		.sa_flags = /*SA_SIGINFO |*/ 0x04000000u /* SA_RESTORER */ | /*SA_RESTART |*/ SA_NODEFER,
		.sa_restorer = restore_rt
	};
	struct sigaction oldaction;
	raw_rt_sigaction(SIGILL, &action, &oldaction);

	/* Un-executablize our own code, except for the signal handler and the remainder of
	 * this function and those afterwards.
	 *
	 * For this, we need our load address. How can we get this? We've already seen it! */
	// long int len = &&exit_and_return - our_text_begin_address;
	// long int ret;
	// long int longprot = PROT_NONE;
	// long int op = SYS_mprotect;

	//	__asm__ (".align 4096");
exit_and_return:
	//__asm__ volatile ("movq %0, %%rdi      # \n\
	//		   movq %1, %%rsi      # \n\
	//		   movq %2, %%rdx      # \n\
	//		  "FIX_STACK_ALIGNMENT " \n\
	//		   movq %3, %%rax      # \n\
	//		   syscall	     # do the syscall \n\
	//		  "UNFIX_STACK_ALIGNMENT " \n"
	//  : /* no output*/ : "rm"(our_text_begin_address), "rm"(len), "rm"(longprot), "rm"(op) :  "%rax", "r12", SYSCALL_CLOBBER_LIST);

#ifdef EXECUTABLE
	// HACK for testing: do a ud2 right now!
	ignore_ud2_addr = &&ud2_addr;
ud2_addr:
	__asm__ ("ud2\n");

	// we must also exit without running any libdl exit handlers,
	// because we're an executable so our csu/startfiles include some cleanup
	// that will now cause traps (this isn't necessary in the shared library case)
	raw_exit(0);
#endif
	return RETURN_VALUE;
}

// For debug printing inside handle_sigill we have to know
// that it's our own debug printing in order to filter it
// out of the footprints, hence this noinline function
// rather than using the normal macro
__attribute__ ((noinline)) static void _handle_sigill_debug_printf(int level, const char *fmt, ...) {
	 va_list vl;
	 va_start(vl, fmt);
	 if ((level) <= debug_level) {
		  vfprintf(*p_err_stream, fmt, vl);
		  fflush(*p_err_stream);
	 }
	 va_end(vl);
}
domem (void *dest, const void *src, int len)
{
	__builtin_memmove (dest, src, len);
}
Exemple #13
0
static inline VOID
EmulatorMoveMemory(OUT VOID UNALIGNED *Destination,
                   IN const VOID UNALIGNED *Source,
                   IN SIZE_T Length)
{
#if 1
    /*
     * We use a switch here to detect small moves of memory, as these
     * constitute the bulk of our moves.
     * Using RtlMoveMemory for all these small moves would be slow otherwise.
     */
    switch (Length)
    {
        case 0:
            return;

        case sizeof(UCHAR):
            *(PUCHAR)Destination = *(PUCHAR)Source;
            return;

        case sizeof(USHORT):
            *(PUSHORT)Destination = *(PUSHORT)Source;
            return;

        case sizeof(ULONG):
            *(PULONG)Destination = *(PULONG)Source;
            return;

        case sizeof(ULONGLONG):
            *(PULONGLONG)Destination = *(PULONGLONG)Source;
            return;

        default:
#if defined(__GNUC__)
            __builtin_memmove(Destination, Source, Length);
#else
            RtlMoveMemory(Destination, Source, Length);
#endif
    }

#else // defined(_MSC_VER)

    PUCHAR Dest = (PUCHAR)Destination;
    PUCHAR Src  = (PUCHAR)Source;

    SIZE_T Count, NewSize = Length;

    /* Move dword */
    Count   = NewSize >> 2; // NewSize / sizeof(ULONG);
    NewSize = NewSize  & 3; // NewSize % sizeof(ULONG);
    __movsd(Dest, Src, Count);
    Dest += Count << 2; // Count * sizeof(ULONG);
    Src  += Count << 2;

    /* Move word */
    Count   = NewSize >> 1; // NewSize / sizeof(USHORT);
    NewSize = NewSize  & 1; // NewSize % sizeof(USHORT);
    __movsw(Dest, Src, Count);
    Dest += Count << 1; // Count * sizeof(USHORT);
    Src  += Count << 1;

    /* Move byte */
    Count   = NewSize; // NewSize / sizeof(UCHAR);
    // NewSize = NewSize; // NewSize % sizeof(UCHAR);
    __movsb(Dest, Src, Count);

#endif
}
void test_warn() {
  memset(&x1, 0, sizeof x1); // \
      // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}
  memset(&x2, 0, sizeof x2); // \
      // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}

  memmove(&x1, 0, sizeof x1); // \
      // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}
  memmove(0, &x1, sizeof x1); // \
      // expected-warning{{source of this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be moved}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}
  memcpy(&x1, 0, sizeof x1); // \
      // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}
  memcpy(0, &x1, sizeof x1); // \
      // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be copied}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}
  memcmp(&x1, 0, sizeof x1); // \
      // expected-warning{{first operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}
  memcmp(0, &x1, sizeof x1); // \
      // expected-warning{{second operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}

  __builtin_memset(&x1, 0, sizeof x1); // \
      // expected-warning {{destination for this '__builtin_memset' call is a pointer to dynamic class}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}
  __builtin_memset(&x2, 0, sizeof x2); // \
      // expected-warning {{destination for this '__builtin_memset' call is a pointer to dynamic class}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}

  __builtin_memmove(&x1, 0, sizeof x1); // \
      // expected-warning{{destination for this '__builtin_memmove' call is a pointer to dynamic class}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}
  __builtin_memmove(0, &x1, sizeof x1); // \
      // expected-warning{{source of this '__builtin_memmove' call is a pointer to dynamic class}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}
  __builtin_memcpy(&x1, 0, sizeof x1); // \
      // expected-warning{{destination for this '__builtin_memcpy' call is a pointer to dynamic class}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}
  __builtin_memcpy(0, &x1, sizeof x1); // \
      // expected-warning{{source of this '__builtin_memcpy' call is a pointer to dynamic class}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}

  __builtin___memset_chk(&x1, 0, sizeof x1, sizeof x1); //                    \
      // expected-warning {{destination for this '__builtin___memset_chk' call is a pointer to dynamic class}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}
  __builtin___memset_chk(&x2, 0, sizeof x2, sizeof x2); //                    \
      // expected-warning {{destination for this '__builtin___memset_chk' call is a pointer to dynamic class}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}

  __builtin___memmove_chk(&x1, 0, sizeof x1, sizeof x1); //                   \
      // expected-warning{{destination for this '__builtin___memmove_chk' call is a pointer to dynamic class}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}
  __builtin___memmove_chk(0, &x1, sizeof x1, sizeof x1); //                   \
      // expected-warning{{source of this '__builtin___memmove_chk' call is a pointer to dynamic class}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}
  __builtin___memcpy_chk(&x1, 0, sizeof x1, sizeof x1); //                    \
      // expected-warning{{destination for this '__builtin___memcpy_chk' call is a pointer to dynamic class}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}
  __builtin___memcpy_chk(0, &x1, sizeof x1, sizeof x1); //                    \
      // expected-warning{{source of this '__builtin___memcpy_chk' call is a pointer to dynamic class}} \
      // expected-note {{explicitly cast the pointer to silence this warning}}
}