From 3d70e706407072f7d19dfdba5edd02f1446888d3 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 14 Jun 2024 14:49:30 -0700 Subject: [PATCH] Add dbPvt2Rec() cast Reverse of dbRec2Pvt() pacify -D_FORTIFY_SOURCE=3 and __builtin_object_size() as "&precord->common" does not know than common as actually the prefix of a variable sized struct. --- modules/database/src/ioc/db/dbCommonPvt.h | 12 ++++++++++-- modules/database/src/ioc/dbStatic/dbStaticRun.c | 16 +++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/modules/database/src/ioc/db/dbCommonPvt.h b/modules/database/src/ioc/db/dbCommonPvt.h index eda8b18a7..4d41902a2 100644 --- a/modules/database/src/ioc/db/dbCommonPvt.h +++ b/modules/database/src/ioc/db/dbCommonPvt.h @@ -15,13 +15,21 @@ typedef struct dbCommonPvt { /* Thread which is currently processing this record */ struct epicsThreadOSD* procThread; - struct dbCommon common; + /* actually followed by: + * struct dbCommon common; + */ } dbCommonPvt; static EPICS_ALWAYS_INLINE dbCommonPvt* dbRec2Pvt(struct dbCommon *prec) { - return CONTAINER(prec, dbCommonPvt, common); + return (dbCommonPvt*)((char*)prec - sizeof(dbCommonPvt)); +} + +static EPICS_ALWAYS_INLINE +dbCommon* dbPvt2Rec(struct dbCommonPvt *pvt) +{ + return (dbCommon*)&pvt[1]; } #endif // DBCOMMONPVT_H diff --git a/modules/database/src/ioc/dbStatic/dbStaticRun.c b/modules/database/src/ioc/dbStatic/dbStaticRun.c index ee9480c54..a4e93d5ca 100644 --- a/modules/database/src/ioc/dbStatic/dbStaticRun.c +++ b/modules/database/src/ioc/dbStatic/dbStaticRun.c @@ -66,7 +66,17 @@ void devExtend(dsxt *pdsxt) pthisDevSup->pdsxt = pdsxt; } } - + +/* Ensure that: sizeof(dbCommonPvt) + pdbRecordType->rec_size + * accounts for necessary alignment of record type struct + */ +typedef struct { + dbCommonPvt prefix; + /* ensure no padding needed... */ + dbCommon suffix; +} dbCommonPvtAlignmentTest; +STATIC_ASSERT(offsetof(dbCommonPvtAlignmentTest, suffix)==sizeof(dbCommonPvt)); + long dbAllocRecord(DBENTRY *pdbentry,const char *precordName) { dbRecordType *pdbRecordType = pdbentry->precordType; @@ -90,8 +100,8 @@ long dbAllocRecord(DBENTRY *pdbentry,const char *precordName) precordName, pdbRecordType->name, pdbRecordType->rec_size); return(S_dbLib_noRecSup); } - ppvt = dbCalloc(1, offsetof(dbCommonPvt, common) + pdbRecordType->rec_size); - precord = &ppvt->common; + ppvt = dbCalloc(1, sizeof(dbCommonPvt) + pdbRecordType->rec_size); + precord = dbPvt2Rec(ppvt); ppvt->recnode = precnode; precord->rdes = pdbRecordType; precnode->precord = precord;