com32.h: cleanups, make OFFS_VALID() take the pointer size into account
authorH. Peter Anvin <hpa@zytor.com>
Wed, 10 Jun 2009 05:50:55 +0000 (22:50 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Wed, 10 Jun 2009 05:50:55 +0000 (22:50 -0700)
Clean up some of the constructs in com32.h, and make OFFS_VALID() take
the pointer type into account for the range check -- the whole object
needs to fit within the segment.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
com32/include/com32.h

index c003f7c..aa7fb4b 100644 (file)
@@ -36,6 +36,8 @@
 #define _COM32_H
 
 #include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
 #include <klibc/compiler.h>    /* For __cdecl */
 
 /*
@@ -132,17 +134,20 @@ static inline uint16_t OFFS(const volatile void *__p)
     return (uint16_t) (uintptr_t) __p & 0x000F;
 }
 
-static inline uint16_t OFFS_WRT(const volatile void *__p, uint16_t seg)
+static inline uint16_t OFFS_WRT(const volatile void *__p, uint16_t __seg)
 {
-    return (uint16_t) ((uintptr_t) __p - ((uintptr_t) seg << 4));
+    return (uint16_t) ((uintptr_t) __p - ((uintptr_t) __seg << 4));
 }
 
-static inline int OFFS_VALID(const volatile void *__p, uint16_t seg)
+#define OFFS_VALID(p,s) _OFFS_VALID((p), sizeof *(p), (s))
+
+static inline bool _OFFS_VALID(const volatile void *__p, size_t __s,
+                              uint16_t __seg)
 {
-    uintptr_t __segstart = (uintptr_t) seg << 4;
-    uintptr_t __ptr = (uintptr_t) __p;
+    uintptr_t __segstart = (uintptr_t)__seg << 4;
+    uintptr_t __offs  = (uintptr_t)__p - __segstart;
 
-    return (__ptr >= __segstart) && (__ptr <= __segstart + 0xffff);
+    return __offs <= 0x10000-__s;
 }
 
 static inline void *MK_PTR(uint16_t __seg, uint16_t __offs)
@@ -153,21 +158,27 @@ static inline void *MK_PTR(uint16_t __seg, uint16_t __offs)
 /* Some tools to handle 16:16 far pointers in memory */
 
 struct __far_ptr {
-    uint32_t __ptr;
+    union {
+       uint32_t ptr;
+       struct {
+           uint16_t offs, seg;
+       };
+    };
 } __attribute__ ((packed));
 
 typedef struct __far_ptr far_ptr_t;
 
 static inline void *GET_PTR(far_ptr_t __fptr)
 {
-    return MK_PTR(__fptr.__ptr >> 16, __fptr.__ptr);
+    return MK_PTR(__fptr.seg, __fptr.offs);
 }
 
 static inline far_ptr_t FAR_PTR(void *__ptr)
 {
     far_ptr_t __fptr;
 
-    __fptr.__ptr = (SEG(__ptr) << 16) + OFFS(__ptr);
+    __fptr.offs = OFFS(__ptr);
+    __fptr.seg  = SEG(__ptr);
     return __fptr;
 }