+/* Generate a piece of text showing 'ea' is relative to 'invar', if
+ known. If unknown, generate an empty string. 'buf' must be at
+ least 32 bytes in size. Also return the absolute value of the
+ delta, if known, or zero if not known.
+*/
+static void gen_delta_str ( /*OUT*/HChar* buf,
+ /*OUT*/UWord* absDelta,
+ Invar* inv, Addr ea )
+{
+ Addr block = 0;
+ SizeT szB = 0;
+
+ buf[0] = 0;
+ *absDelta = 0;
+
+ switch (inv->tag) {
+ case Inv_Unknown:
+ case Inv_Unset:
+ return; /* unknown */
+ case Inv_Stack0:
+ block = inv->Inv.Stack0.addr;
+ szB = inv->Inv.Stack0.szB;
+ break;
+ case Inv_StackN:
+ block = inv->Inv.StackN.nd->addr;
+ szB = inv->Inv.StackN.nd->szB;
+ break;
+ case Inv_Global:
+ block = inv->Inv.Global.nd->addr;
+ szB = inv->Inv.Global.nd->szB;
+ break;
+ default:
+ tl_assert(0);
+ }
+ tl_assert(szB > 0);
+ if (ea < block) {
+ *absDelta = block - ea;
+ VG_(sprintf)(buf, "%'lu before", *absDelta);
+ }
+ else if (ea >= block + szB) {
+ *absDelta = ea - (block + szB);
+ VG_(sprintf)(buf, "%'lu after", *absDelta);
+ }
+ else {
+ // Leave *absDelta at zero.
+ VG_(sprintf)(buf, "%'lu inside", ea - block);
+ }
+}
+
+