RAA: make pointer vs integer RAAs type safe

Use pseudo-types to make it impossible to confuse RAAs made of
integers and RAAs made of pointers.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
H. Peter Anvin 2018-06-18 17:11:54 -07:00
parent a5992a4c41
commit 2c57d0a5ca
3 changed files with 76 additions and 52 deletions

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
* Copyright 1996-2016 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@ -36,13 +36,52 @@
#include "compiler.h"
struct real_raa;
struct RAA;
union intorptr {
int64_t i;
void *p;
};
struct RAA * never_null raa_init(void);
void raa_free(struct RAA *);
struct real_raa * never_null real_raa_init(void);
static inline struct RAA *never_null raa_init(void)
{
return (struct RAA *)real_raa_init();
}
static inline struct RAAPTR *never_null raa_init_ptr(void)
{
return (struct RAAPTR *)real_raa_init();
}
void real_raa_free(struct real_raa *);
static inline void raa_free(struct RAA *raa)
{
real_raa_free((struct real_raa *)raa);
}
static inline void raa_free_ptr(struct RAAPTR *raa)
{
real_raa_free((struct real_raa *)raa);
}
int64_t raa_read(struct RAA *, int32_t);
void *raa_read_ptr(struct RAA *, int32_t);
struct RAA * never_null raa_write(struct RAA *r, int32_t posn, int64_t value);
struct RAA * never_null raa_write_ptr(struct RAA *r, int32_t posn, void *value);
void *raa_read_ptr(struct RAAPTR *, int32_t);
struct real_raa * never_null
real_raa_write(struct real_raa *r, int32_t posn, union intorptr value);
static inline struct RAA * never_null
raa_write(struct RAA *r, int32_t posn, int64_t value)
{
union intorptr ip;
ip.i = value;
return (struct RAA *)real_raa_write((struct real_raa *)r, posn, ip);
}
static inline struct RAAPTR * never_null
raa_write_ptr(struct RAAPTR *r, int32_t posn, void *value)
{
union intorptr ip;
ip.p = value;
return (struct RAAPTR *)real_raa_write((struct real_raa *)r, posn, ip);
}
#endif /* NASM_RAA_H */

View File

@ -45,17 +45,11 @@
#define RAA_LAYERSHIFT 15 /* 2**this many _pointers_ allocated */
#define RAA_LAYERSIZE (1 << RAA_LAYERSHIFT)
typedef struct RAA RAA;
typedef union RAA_UNION RAA_UNION;
typedef struct RAA_LEAF RAA_LEAF;
typedef struct RAA_BRANCH RAA_BRANCH;
union intorptr {
int64_t i;
void *p;
};
struct RAA {
struct real_raa {
/*
* Number of layers below this one to get to the real data. 0
* means this structure is a leaf, holding RAA_BLKSIZE real
@ -79,19 +73,26 @@ struct RAA {
union intorptr data[RAA_BLKSIZE];
} l;
struct RAA_BRANCH {
struct RAA *data[RAA_LAYERSIZE];
struct real_raa *data[RAA_LAYERSIZE];
} b;
} u;
};
#define LEAFSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_LEAF))
#define BRANCHSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH))
struct RAA {
struct real_raa raa;
};
struct RAAPTR {
struct real_raa raa;
};
#define LEAFSIZ (sizeof(struct real_raa)-sizeof(RAA_UNION)+sizeof(RAA_LEAF))
#define BRANCHSIZ (sizeof(struct real_raa)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH))
#define LAYERSHIFT(r) ( (r)->layers==0 ? RAA_BLKSHIFT : RAA_LAYERSHIFT )
static struct RAA *real_raa_init(int layers)
static struct real_raa *raa_init_layer(int layers)
{
struct RAA *r;
struct real_raa *r;
if (layers == 0) {
r = nasm_zalloc(LEAFSIZ);
@ -104,23 +105,23 @@ static struct RAA *real_raa_init(int layers)
return r;
}
struct RAA *raa_init(void)
struct real_raa *real_raa_init(void)
{
return real_raa_init(0);
return raa_init_layer(0);
}
void raa_free(struct RAA *r)
void real_raa_free(struct real_raa *r)
{
if (r->layers) {
struct RAA **p;
struct real_raa **p;
for (p = r->u.b.data; p - r->u.b.data < RAA_LAYERSIZE; p++)
if (*p)
raa_free(*p);
real_raa_free(*p);
}
nasm_free(r);
}
static const union intorptr *real_raa_read(struct RAA *r, int32_t posn)
static const union intorptr *real_raa_read(struct real_raa *r, int32_t posn)
{
if ((uint32_t) posn >= (UINT32_C(1) << (r->shift + LAYERSHIFT(r))))
return NULL; /* Beyond the end */
@ -138,23 +139,23 @@ int64_t raa_read(struct RAA *r, int32_t pos)
{
const union intorptr *ip;
ip = real_raa_read(r, pos);
ip = real_raa_read((struct real_raa *)r, pos);
return ip ? ip->i : 0;
}
void *raa_read_ptr(struct RAA *r, int32_t pos)
void *raa_read_ptr(struct RAAPTR *r, int32_t pos)
{
const union intorptr *ip;
ip = real_raa_read(r, pos);
ip = real_raa_read((struct real_raa *)r, pos);
return ip ? ip->p : NULL;
}
static struct RAA *
real_raa_write(struct RAA *r, int32_t posn, union intorptr value)
struct real_raa *
real_raa_write(struct real_raa *r, int32_t posn, union intorptr value)
{
struct RAA *result;
struct real_raa *result;
nasm_assert(posn >= 0);
@ -162,7 +163,7 @@ real_raa_write(struct RAA *r, int32_t posn, union intorptr value)
/*
* Must add a layer.
*/
struct RAA *s;
struct real_raa *s;
s = nasm_zalloc(BRANCHSIZ);
s->layers = r->layers + 1;
@ -174,12 +175,12 @@ real_raa_write(struct RAA *r, int32_t posn, union intorptr value)
result = r;
while (r->layers > 0) {
struct RAA **s;
struct real_raa **s;
int32_t l = posn >> r->shift;
posn &= (UINT32_C(1) << r->shift) - 1;
s = &r->u.b.data[l];
if (!*s)
*s = real_raa_init(r->layers - 1);
*s = raa_init_layer(r->layers - 1);
r = *s;
}
@ -187,19 +188,3 @@ real_raa_write(struct RAA *r, int32_t posn, union intorptr value)
return result;
}
struct RAA *raa_write(struct RAA *r, int32_t posn, int64_t value)
{
union intorptr ip;
ip.i = value;
return real_raa_write(r, posn, ip);
}
struct RAA *raa_write_ptr(struct RAA *r, int32_t posn, void *value)
{
union intorptr ip;
ip.p = value;
return real_raa_write(r, posn, ip);
}

View File

@ -313,7 +313,7 @@ static uint64_t rel_padcnt = 0;
ALIGN(x, fmt.ptrsize) /* align x to output format width */
static struct hash_table section_by_name;
static struct RAA *section_by_index;
static struct RAAPTR *section_by_index;
static struct section * never_null
find_or_add_section(const char *segname, const char *sectname)
@ -436,7 +436,7 @@ static void macho_init(void)
extsyms = raa_init();
strs = saa_init(1L);
section_by_index = raa_init();
section_by_index = raa_init_ptr();
hash_init(&section_by_name, HASH_MEDIUM);
/* string table starts with a zero byte so index 0 is an empty string */
@ -1808,7 +1808,7 @@ static void macho_cleanup(void)
nasm_free(extdefsyms);
nasm_free(undefsyms);
nasm_free(sectstab);
raa_free(section_by_index);
raa_free_ptr(section_by_index);
hash_free(&section_by_name);
}