Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/changes.src
Original file line number Diff line number Diff line change
Expand Up @@ -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...
Expand Down
4 changes: 4 additions & 0 deletions doc/outfmt.src
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
53 changes: 40 additions & 13 deletions output/outobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 == '.')
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down