summaryrefslogtreecommitdiff
path: root/perl.h
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2012-01-26 11:30:32 +0100
committerNicholas Clark <nick@ccl4.org>2012-01-26 11:44:38 +0100
commit27287bba2c2ae5afdeaf015ace7f9010013916cd (patch)
tree207a43ec589b2ab66320805980bc13cce58140db /perl.h
parent2a7afa746140382bc9615f6d66ae6f04d3469e48 (diff)
downloadperl-smoke-me/Copy-overlap-wrapper-proto.tar.gz
PROOF OF CONCEPT for a wrapper for Copy() to detect overlap.smoke-me/Copy-overlap-wrapper-proto
Should be conditionally compilable. Tests shouldn't run unless it's compiled in, as overlapping memcpy() is undefined behaviour and may SEGV. Needs handy.h untangled so that Copy, Move, Zero live in the same place.
Diffstat (limited to 'perl.h')
-rw-r--r--perl.h18
1 files changed, 18 insertions, 0 deletions
diff --git a/perl.h b/perl.h
index fe1eaecfb6..90aa206de2 100644
--- a/perl.h
+++ b/perl.h
@@ -5769,6 +5769,24 @@ extern void moncontrol(int);
#define PERL_PV_PRETTY_DUMP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_QUOTE
#define PERL_PV_PRETTY_REGPROP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_LTGT|PERL_PV_ESCAPE_RE|PERL_PV_ESCAPE_NONASCII
+
+PERL_STATIC_INLINE void *
+S_memcpy_checker(const char *s, char *d, MEM_SIZE num, MEM_SIZE size,
+ const char *type_name)
+{
+ const MEM_SIZE len = num * size;
+ if (s >= d && s < d + len)
+ Perl_croak_nocontext("Copy(%p, %p, %"UVuf", %s) From[%p To %p) [%p %p)",
+ s, d, num, type_name, s, d, s + len, d + len);
+ if (d >= s && d < s + len)
+ Perl_croak_nocontext("Copy(%p, %p, %"UVuf", %s) To[%p From %p) [%p %p)",
+ s, d, num, type_name, d, s, d + len, s + len);
+ return memcpy(d, s, len);
+}
+
+#define Copy(s,d,n,t) (MEM_WRAP_CHECK_(n,t) (void)S_memcpy_checker((const char*)(s),(char*)(d), (n), sizeof(t), STRINGIFY(t)))
+#define CopyD(s,d,n,t) (MEM_WRAP_CHECK_(n,t) S_memcpy_checker((const char*)(s),(char*)(d), (n), sizeof(t), STRINGIFY(t)))
+
/*
(KEEP THIS LAST IN perl.h!)