diff --git a/doc/changes.src b/doc/changes.src index ac50b2d0..38a6233b 100644 --- a/doc/changes.src +++ b/doc/changes.src @@ -14,6 +14,8 @@ It is the production version of NASM since 2025. Put the updates for NASM 3.01 here... +\b Now \c{GROUP} directive cumulates sections for the same group. + \S{cl-3.00.01} Version 3.00.01 Put the updates for NASM 3.00.01 here... diff --git a/doc/outfmt.src b/doc/outfmt.src index aeb829cc..fb0bd7a0 100644 --- a/doc/outfmt.src +++ b/doc/outfmt.src @@ -327,6 +327,10 @@ A group does not have to contain any segments; you can still make you are referring to. OS/2, for example, defines the special group \c{FLAT} with no segments in it. +\c{GROUP} is cumulative. The above example can be done like this: + +\c group dgroup data +\c group dgroup bss \S{uppercase} \i\c{UPPERCASE}: Disabling Case Sensitivity in Output diff --git a/output/outobj.c b/output/outobj.c index 5645928e..585cdd6a 100644 --- a/output/outobj.c +++ b/output/outobj.c @@ -1574,6 +1574,8 @@ obj_directive(enum directive directive, char *value) struct Segment *seg; struct External **extp; int obj_idx; + const char *segname; + int i; q = value; while (*q == '.') @@ -1602,22 +1604,23 @@ obj_directive(enum directive directive, char *value) for (grp = grphead; grp; grp = grp->next) { obj_idx++; if (!strcmp(grp->name, v)) { - nasm_nonfatal("group `%s' defined twice", v); - return DIRR_ERROR; + break; } } - *grptail = grp = nasm_malloc(sizeof(*grp)); - grp->next = NULL; - grptail = &grp->next; - grp->index = seg_alloc(); - grp->obj_index = obj_idx; - grp->nindices = grp->nentries = 0; - grp->name = NULL; - - obj_grp_needs_update = grp; - backend_label(v, grp->index + 1, 0L); - obj_grp_needs_update = NULL; + if (!grp) { + *grptail = grp = nasm_malloc(sizeof(*grp)); + grp->next = NULL; + grptail = &grp->next; + grp->index = seg_alloc(); + grp->obj_index = obj_idx; + grp->nindices = grp->nentries = 0; + grp->name = NULL; + + obj_grp_needs_update = grp; + backend_label(v, grp->index + 1, 0L); + obj_grp_needs_update = NULL; + } while (*q) { p = q; @@ -1631,6 +1634,30 @@ obj_directive(enum directive directive, char *value) /* * Now p contains a segment name. Find it. */ + for (i = 0; i < grp->nentries; i++) { + if (i < grp->nindices) { + segname = NULL; /* make compiler happy */ + for (seg = seghead; seg; seg = seg->next) { + if (grp->segs[i].index == seg->obj_index) { + segname = seg->name; + break; + } + } + } + else + segname = grp->segs[i].name; + /* + * See if this segment is defined in this group. + */ + if (!strcmp(segname, p)) + break; + } + if (i < grp->nentries) { + /* + * We have already this segment. Skip. + */ + continue; + } for (seg = seghead; seg; seg = seg->next) if (!strcmp(seg->name, p)) break;