https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126277

            Bug ID: 126277
           Summary: gcobol: DEBUG-* special registers reference missing
                    `__gg__data_debug_*` symbols
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: cobol
          Assignee: unassigned at gcc dot gnu.org
          Reporter: peeterjoot at protonmail dot com
  Target Milestone: ---

Created attachment 65054
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65054&action=edit
debug-register-data-symbol.cob from the report above (also specified inline)

# Summary

Any program that references a Debug-module special register (`DEBUG-LINE`,
`DEBUG-NAME`, `DEBUG-CONTENTS`, …) **compiles** but **fails to link** with:

```
undefined reference to `__gg__data_debug_line'
```

(and likewise `__gg__data_debug_name` when that register is used).

The frontend and `libgcobol` disagree on the external symbol name for the
runtime data of these registers. Other special registers (`SPACE`, `ZEROS`, …)
pair `__ggsr__*` metadata with a matching `__gg__data_*` buffer; `DEBUG-*`
fields use a shared buffer named `__gg__debug_item_data` instead, so the
`__gg__data_debug_*` symbols the frontend emits do not exist.

# Environment

- Compiler: gcobol from GCC trunk (`gcobol (GCC) 17.0.0 20260710
(experimental)`)
- Also observed with the packaged Ubuntu gcobol when Debug special registers
  are referenced
- Platform: Linux aarch64 (also expected on x86-64)
- No special options required

# Reproducer

`debug-register-data-symbol.cob` (in this directory):

```cobol
       IDENTIFICATION DIVISION.
       PROGRAM-ID. DBGLINE.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-LINE PIC X(6).
       PROCEDURE DIVISION.
           MOVE DEBUG-LINE TO WS-LINE
           DISPLAY WS-LINE
           STOP RUN.
```

```
gcobol -o /tmp/dbgline debug-register-data-symbol.cob
```

(A `USE FOR DEBUGGING` declarative that MOVEs `DEBUG-LINE` / `DEBUG-NAME` hits
the same undefined symbols; NIST COBOL85 `DB101A`–`DB104A` / `DB204A` fail this
way.)

# Observed

Compile of the COBOL source succeeds; the link step fails:

```
undefined reference to `__gg__data_debug_line'
collect2: error: ld returned 1 exit status
```

Installed `libgcobol` exports (via `nm -D`):

```
D __gg__debug_item_data
D __ggsr__debug_item
D __ggsr__debug_line
D __ggsr__debug_name
D __ggsr__debug_contents
… 
```

but **not** `__gg__data_debug_line` / `__gg__data_debug_name` / …

For comparison, ordinary special registers do export both sides, e.g.
`__ggsr__space` + `__gg__data_space`.

# Expected

The program links and runs. Reading `DEBUG-LINE` should use the existing
runtime register backed by `__gg__debug_item_data` (offset 0 within the
`DEBUG-ITEM` group), the same storage `__ggsr__debug_line.data` already points
at in `libgcobol/constants.cc`.

# Root cause (frontend / libgcobol mismatch)

In `gcc/cobol/genapi.cc`, `psa_global()` declares two externals for every
special register:

1. `__ggsr__<name>` — the `cblc_field_t` (this matches `libgcobol`)
2. `__gg__data_<name>` — a presumed dedicated data buffer

```c
  // finding their name … "__ggsr__" is prepended
  snprintf(ach, sizeof(ach), "__ggsr__%s", new_var->name);
  …
  new_var->var_decl_node = gg_declare_variable(…, ach, …,
vs_external_reference);

  strcpy(ach, "__gg__data_");
  strcat(ach, new_var->name);
  …
  new_var->data_decl_node = gg_declare_variable(UCHAR, ach, …,
vs_external_reference);
```

In `libgcobol/constants.cc`, the Debug registers are **not** given per-field
`__gg__data_*` buffers. The whole `DEBUG-ITEM` group shares one array:

```c
unsigned char __gg__debug_item_data[132] = …;

struct cblc_field_t __ggsr__debug_line = {
  .data = __gg__debug_item_data + 0,
  …
};
struct cblc_field_t __ggsr__debug_name = {
  .data = __gg__debug_item_data + 7,
  …
};
```

So the linker finds `__ggsr__debug_line` but not `__gg__data_debug_line`.

`symbols.cc` also notes that special registers must be kept in sync with
`constants.cc`:

> When adding special registers, be sure to create the actual cblc_field_t
> in libgcobol/constants.cc.

The metadata side was added; the `__gg__data_*` naming expected by `psa_global`
was not.

# Suggested fix (either side)

1. **libgcobol:** export `__gg__data_debug_line` (etc.) as aliases / symbols at
   the appropriate offsets into `__gg__debug_item_data` (and likely
   `__gg__data_debug_item` for the group), matching the convention used for
   `SPACE`/`ZEROS`; or
2. **Frontend (`psa_global`):** for `DEBUG-*` registers, reference
   `__gg__debug_item_data` (plus offset) instead of synthesizing
   `__gg__data_<name>`.

# Impact

Programs that use the Debug module special registers — including the NIST
COBOL85 Debug-module tests that successfully parse `USE FOR DEBUGGING` —
cannot be linked. Found while attempting to build the NIST COBOL85 suite with
gcobol.

# Disclaimer:

The root cause analysis for this bug report was generated by cursor, when I
pointed it at the gcc repo to help understand the link error -- I have not
vouched for it's correctness.

Reply via email to