diff --git a/include/interfaces/abstract/STARSSegment.h b/include/interfaces/abstract/STARSSegment.h
index 8d9313791d0d6c695cffc1681431c35bdcecd5cd..92798587a8a76a5b8683e48e79f30f1108104b2d 100644
--- a/include/interfaces/abstract/STARSSegment.h
+++ b/include/interfaces/abstract/STARSSegment.h
@@ -12,20 +12,25 @@ class STARS_Segment_t
 		virtual std::size_t get_seg_size() = 0;
 
 		/* figure out what kind of segment this is */
-		virtual bool IsCodeSegment() = 0;
-		virtual bool IsXternSegment() { return false; };
-		virtual bool IsDataSegment() = 0;
-		virtual bool IsCommonSegment() = 0;
-		virtual bool IsBSSSegment() = 0;
+		virtual bool IsCodeSegment() const = 0;
+		virtual bool IsXternSegment() const { return false; };
+		virtual bool IsDataSegment() const = 0;
+		virtual bool IsCommonSegment() const = 0;
+		virtual bool IsBSSSegment() const = 0;
 
 		/* examine segment permissions */
-		virtual bool IsReadableSegment() = 0;
-		virtual bool IsWriteableSegment() = 0;
+		virtual bool IsReadableSegment() const = 0;
+		virtual bool IsWriteableSegment() const = 0;
 
 		/* returns the segments name in the given buffer*/
 		virtual STARS_ssize_t GetSegmentName(char* name, int len) = 0;
 
-		
+		// Fetch read-only data values, if any.
+		virtual bool GetReadOnlyMem64BitValue(STARS_ea_t MemAddr, uint64_t &Value) const = 0;
+		virtual bool GetReadOnlyMem32BitValue(STARS_ea_t MemAddr, uint32_t &Value) const = 0;
+		virtual bool GetReadOnlyMem16BitValue(STARS_ea_t MemAddr, uint16_t &Value) const = 0;
+		virtual bool GetReadOnlyMem8BitValue(STARS_ea_t MemAddr, uint8_t &Value) const = 0;
+
 };
 
 #endif
diff --git a/include/interfaces/idapro/STARSSegment.h b/include/interfaces/idapro/STARSSegment.h
index 444cf541f132db83af225930300fc28b5fe8c313..cc0154e40a78e0de06cb6a9b0138adac3d7e28b2 100644
--- a/include/interfaces/idapro/STARSSegment.h
+++ b/include/interfaces/idapro/STARSSegment.h
@@ -11,18 +11,41 @@ class STARS_IDA_Segment_t : public STARS_Segment_t
 	public:
 		STARS_IDA_Segment_t(segment_t* seg) : the_seg(seg) {}
 
-        	virtual STARS_ea_t get_startEA() { return the_seg->startEA; } 
-        	virtual STARS_ea_t get_endEA() { return the_seg->endEA; } 
-			virtual std::size_t get_seg_size() { return (std::size_t)(get_endEA() - get_startEA()); }
-			virtual bool IsCodeSegment()  { return the_seg->type == SEG_CODE; }
-        	virtual bool IsXternSegment() { return the_seg->type==SEG_XTRN; } 
-        	virtual bool IsDataSegment() { return the_seg->type==SEG_DATA; } 
-        	virtual bool IsCommonSegment() { return the_seg->type==SEG_COMM; } 
-        	virtual bool IsBSSSegment() { return the_seg->type==SEG_BSS; } 
-        	virtual bool IsReadableSegment() { return the_seg->perm & SEGPERM_READ; }
-        	virtual bool IsWriteableSegment() { return the_seg->perm & SEGPERM_WRITE; }
+		virtual STARS_ea_t get_startEA() { return the_seg->startEA; } 
+		virtual STARS_ea_t get_endEA() { return the_seg->endEA; } 
+		virtual std::size_t get_seg_size() { return (std::size_t)(get_endEA() - get_startEA()); }
+		virtual bool IsCodeSegment() const { return the_seg->type == SEG_CODE; }
+		virtual bool IsXternSegment() const { return the_seg->type == SEG_XTRN; }
+		virtual bool IsDataSegment() const { return the_seg->type == SEG_DATA; }
+		virtual bool IsCommonSegment() const { return the_seg->type == SEG_COMM; }
+		virtual bool IsBSSSegment() const { return the_seg->type == SEG_BSS; }
+		virtual bool IsReadableSegment() const { return the_seg->perm & SEGPERM_READ; }
+		virtual bool IsWriteableSegment() const { return the_seg->perm & SEGPERM_WRITE; }
 		virtual STARS_ssize_t GetSegmentName(char* name, int len) { return ::get_segm_name(the_seg,name,len); }
 
+		// Fetch read-only data values, if any.
+		virtual bool GetReadOnlyMem64BitValue(STARS_ea_t MemAddr, uint64_t &Value) const {
+			assert(!IsWriteableSegment());
+			Value = (uint64_t) get_qword(MemAddr);
+			return true;
+		}
+		virtual bool GetReadOnlyMem32BitValue(STARS_ea_t MemAddr, uint32_t &Value) const {
+			assert(!IsWriteableSegment());
+			Value = (uint32_t) get_long(MemAddr);
+			return true;
+		}
+		virtual bool GetReadOnlyMem16BitValue(STARS_ea_t MemAddr, uint16_t &Value) const {
+			assert(!IsWriteableSegment());
+			Value = (uint16_t) get_word(MemAddr);
+			return true;
+		}
+		virtual bool GetReadOnlyMem8BitValue(STARS_ea_t MemAddr, uint8_t &Value) const {
+			assert(!IsWriteableSegment());
+			Value = (uint8_t) get_byte(MemAddr);
+			return true;
+		}
+
+
 	private:
 		segment_t* the_seg;
 		
diff --git a/include/interfaces/irdb/STARSSegment.h b/include/interfaces/irdb/STARSSegment.h
index 238ecfbd88f3bf76f6c6a68ac1be4da2e17cda6b..c86c23712a4e2ba417d0ccfd50c88898f78043d5 100644
--- a/include/interfaces/irdb/STARSSegment.h
+++ b/include/interfaces/irdb/STARSSegment.h
@@ -27,19 +27,19 @@ class STARS_IRDB_Segment_t : public STARS_Segment_t
 		virtual std::size_t get_seg_size() { return (std::size_t) the_seg->get_size(); }
 
 		// return if the EXE bit is set.
-		virtual bool IsCodeSegment()  
+		virtual bool IsCodeSegment() const
 		{ return (the_seg->get_flags() & SHF_EXECINSTR) == SHF_EXECINSTR; }
 
-		virtual bool IsDataSegment() 
+		virtual bool IsDataSegment() const
 		{ return IsReadableSegment() && IsWriteableSegment(); }
 
-		virtual bool IsBSSSegment() 
+		virtual bool IsBSSSegment() const
 		{ return (the_seg->get_type() & SHT_NOBITS) == SHT_NOBITS; }
 
-		virtual bool IsReadableSegment() 
+		virtual bool IsReadableSegment() const
 		{ return (the_seg->get_flags() & SHF_ALLOC) == SHF_ALLOC; }
 
-		virtual bool IsWriteableSegment()
+		virtual bool IsWriteableSegment() const
 		{ return (the_seg->get_flags() & SHF_WRITE) == SHF_WRITE; }
 
 		virtual STARS_ssize_t GetSegmentName(char* name, int len) 
@@ -52,8 +52,15 @@ class STARS_IRDB_Segment_t : public STARS_Segment_t
 		virtual int GetSegmentNumber() { return segno; }
 
 		// these aren't used, impl. later if we know what it means. 
-		virtual bool IsXternSegment() { assert(0); /* leave as error */}
-		virtual bool IsCommonSegment() { assert(0); /* leave as error */}
+		virtual bool IsXternSegment() const { assert(0); /* leave as error */ }
+		virtual bool IsCommonSegment() const { assert(0); /* leave as error */ }
+
+		// Fetch read-only data values, if any.
+		virtual bool GetReadOnlyMem64BitValue(STARS_ea_t MemAddr, uint64_t &Value) const = 0;
+		virtual bool GetReadOnlyMem32BitValue(STARS_ea_t MemAddr, uint32_t &Value) const = 0;
+		virtual bool GetReadOnlyMem16BitValue(STARS_ea_t MemAddr, uint16_t &Value) const = 0;
+		virtual bool GetReadOnlyMem8BitValue(STARS_ea_t MemAddr, uint8_t &Value) const = 0;
+
 
 	private:
 		ELFIO::section* the_seg;
diff --git a/src/base/SMPInstr.cpp b/src/base/SMPInstr.cpp
index 1d03927c9b7d728ae83857a7502c4f15847e9d0a..6067a3a0abccd8483bf2b6b27803f9f2aee79015 100644
--- a/src/base/SMPInstr.cpp
+++ b/src/base/SMPInstr.cpp
@@ -7921,6 +7921,69 @@ void SMPInstr::SCCPFetchConstUseValue(const STARSOpndTypePtr &UseOp, STARS_SCCP_
 			}
 		}
 	}
+	else if (UseOp->IsStaticMemOp()) {
+		// Fetch read-only data value, if any.
+		STARS_ea_t MemAddr = UseOp->GetAddr();
+		bool GoodAddr = (STARS_BADADDR != MemAddr);
+#if 1
+		int BaseReg = (int) UseOp->GetReg();
+		if (MD_STACK_POINTER_REG == BaseReg) {
+			// ESP BaseReg in SIB byte means no base reg for StaticMemOp
+			BaseReg = STARS_x86_R_none;
+		}
+		if (UseOp->HasSIBByte()) {
+			BaseReg = UseOp->MDGetSIBBaseReg();
+			if ((STARS_x86_R_none == BaseReg) || (MD_FRAME_POINTER_REG == BaseReg)) {
+				// EBP BaseReg for StaticMemOp means no base reg
+				BaseReg = UseOp->MDGetSIBIndexReg();
+				if (MD_STACK_POINTER_REG == BaseReg) {
+					// ESP IndexReg in SIB byte means no index reg
+					BaseReg = STARS_x86_R_none;
+				}
+			}
+		}
+		if (STARS_x86_R_none != BaseReg) { // have an offset reg to add to the static mem addr
+			// TODO: Fetch constant value for general purpose reg, with SSANum from USE set.
+			GoodAddr = false;
+		}
+#endif
+		if (GoodAddr) {
+			STARS_Segment_t *MemSeg = global_stars_interface->getseg(MemAddr);
+			if (NULL != MemSeg) {
+				if (!(MemSeg->IsWriteableSegment())) {
+					size_t UseOpByteWidth = UseOp->GetByteWidth();
+					if (UseOpByteWidth == 8) {
+						uint64_t MemValue;
+						if (MemSeg->GetReadOnlyMem64BitValue(MemAddr, MemValue)) {
+							ConstStruct.ConstType = STARS_CONST_HAS_VALUE;
+							ConstStruct.ConstValue = (STARS_uval_t)MemValue;
+						}
+					}
+					else if (UseOpByteWidth == 4) {
+						uint32_t MemValue;
+						if (MemSeg->GetReadOnlyMem32BitValue(MemAddr, MemValue)) {
+							ConstStruct.ConstType = STARS_CONST_HAS_VALUE;
+							ConstStruct.ConstValue = (STARS_uval_t)MemValue;
+						}
+					}
+					else if (UseOpByteWidth == 2) {
+						uint16_t MemValue;
+						if (MemSeg->GetReadOnlyMem16BitValue(MemAddr, MemValue)) {
+							ConstStruct.ConstType = STARS_CONST_HAS_VALUE;
+							ConstStruct.ConstValue = (STARS_uval_t)MemValue;
+						}
+					}
+					else if (UseOpByteWidth == 1) {
+						uint8_t MemValue;
+						if (MemSeg->GetReadOnlyMem8BitValue(MemAddr, MemValue)) {
+							ConstStruct.ConstType = STARS_CONST_HAS_VALUE;
+							ConstStruct.ConstValue = (STARS_uval_t)MemValue;
+						}
+					}
+				}
+			}
+		}
+	}
 	return;
 } // end of SMPInstr::SCCPFetchConstUseValue()