Add memcheck client requests VALGRIND_GET_VBITS / VALGRIND_SET_VBITS
for fetching/setting metadata so that it can be sent between
unconnected address spaces (or whatever).
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1718 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c
index 1a9f4d6..38a6ae9 100644
--- a/memcheck/mc_main.c
+++ b/memcheck/mc_main.c
@@ -255,6 +255,21 @@
}
+static void __inline__ set_vbytes4_ALIGNED ( Addr a, UInt vbytes )
+{
+ SecMap* sm;
+ UInt sm_off;
+ ENSURE_MAPPABLE(a, "set_vbytes4_ALIGNED");
+ sm = primary_map[a >> 16];
+ sm_off = a & 0xFFFF;
+ PROF_EVENT(23);
+# ifdef VG_DEBUG_MEMORY
+ sk_assert(IS_ALIGNED4_ADDR(a));
+# endif
+ ((UInt*)(sm->vbyte))[sm_off >> 2] = vbytes;
+}
+
+
/*------------------------------------------------------------*/
/*--- Setting permissions over address ranges. ---*/
/*------------------------------------------------------------*/
@@ -1311,6 +1326,76 @@
/*------------------------------------------------------------*/
+/*--- Metadata get/set functions, for client requests. ---*/
+/*------------------------------------------------------------*/
+
+/* Copy Vbits for src into vbits. Returns: 1 == OK, 2 == alignment
+ error, 3 == addressing error. */
+Int MC_(get_or_set_vbits_for_client) (
+ Addr dataV,
+ Addr vbitsV,
+ UInt size,
+ Bool setting /* True <=> set vbits, False <=> get vbits */
+)
+{
+ Bool addressibleD = True;
+ Bool addressibleV = True;
+ UInt* data = (UInt*)dataV;
+ UInt* vbits = (UInt*)vbitsV;
+ UInt szW = size / 4; /* sigh */
+ UInt i;
+
+ /* Check alignment of args. */
+ if (!(IS_ALIGNED4_ADDR(data) && IS_ALIGNED4_ADDR(vbits)))
+ return 2;
+ if ((size & 3) != 0)
+ return 2;
+
+ /* Check that arrays are addressible. */
+ for (i = 0; i < szW; i++) {
+ UInt* dataP = &data[i];
+ UInt* vbitsP = &vbits[i];
+ if (get_abits4_ALIGNED((Addr)dataP) != VGM_NIBBLE_VALID) {
+ addressibleD = False;
+ break;
+ }
+ if (get_abits4_ALIGNED((Addr)vbitsP) != VGM_NIBBLE_VALID) {
+ addressibleV = False;
+ break;
+ }
+ }
+ if (!addressibleD) {
+ MAC_(record_address_error)( dataV, size,
+ setting ? True : False );
+ return 3;
+ }
+ if (!addressibleV) {
+ MAC_(record_address_error)( vbitsV, size,
+ setting ? False : True );
+ return 3;
+ }
+
+ /* Do the copy */
+ if (setting) {
+ /* setting */
+ for (i = 0; i < szW; i++) {
+ if (get_vbytes4_ALIGNED( (Addr)&vbits[i] ) != VGM_WORD_VALID)
+ MC_(record_value_error)(4);
+ set_vbytes4_ALIGNED( (Addr)&data[i], vbits[i] );
+ }
+ } else {
+ /* getting */
+ for (i = 0; i < szW; i++) {
+ vbits[i] = get_vbytes4_ALIGNED( (Addr)&data[i] );
+ set_vbytes4_ALIGNED( (Addr)&vbits[i], VGM_WORD_VALID );
+ }
+ }
+
+ return 1;
+}
+
+
+/*------------------------------------------------------------*/
/*--- Detecting leaked (unreachable) malloc'd blocks. ---*/
/*------------------------------------------------------------*/