In program a
EXEC CICS LINK
PROGRAM(PGMB)
COMMAREA(COMMA)
LENGTH(LENGTH OF COMMA)
RESP(CICS-RESP)
END-EXEC
In program b
EXEC CICS RETURN
END-EXEC
Does program b only return the commarea that program a passed? Or does it return the whole LINKAGE SECTION?
Program B returns neither the entire LINKAGE SECTION nor the commarea (COMMA in your example).
It returns nothing.
Why does it return nothing? Because nothing gets passed to it.
Or, rather, what gets passed to it is simply the address(es) of the parameter(s). Nothing else. That is all. Importantly, no length.
PROGA
PROGB
a-bit-of-stuff is define as only one byte. This makes no difference. It is the definition, in the LINKAGE SECTION, of the item on the PROCEDURE DIVISION USING ... which matches, in order of reference, nothing else, to the CALL ... USING ...
PROGB will be "passed" the address of a-bit-of-stuff. If that address is then mapped to 100 bytes in the LINKAGE SECTION of the CALLed program, COBOL does not mind at all.
If we change that example CALL to use instead some-stuff, since some-stuff has the same starting address as a-bit-of-stuff, there would be absolutely no change in the generated code, and no change in the execution of the two programs.
Defining different sizes of data "between" CALLer and CALLed is usually not done, because it makes things less clear to us, humans. The compiler cares not one jot.
What you need to look at the 01s (or 77s if that silly idea takes your fancy) as is a REDEFINES. They are a REDEFINES, an implicit one, of data which is defined somewhere else. No data is defined for items in the LINKAGE SECTION (there is one exception to that on the Mainframe). The 01-levels in the LINKAGE SECTION are just redefining, or mapping, the address of the data that is passed to the program. The data does not "leave" the CALLing program, and the data is never "passed back".
Things can go wrong, of course, if you use different lengths for matching items on the USINGs. If the storage from the CALLer is "acquired" (like a GETMAIN in CICS) then attempting to referencing data outside of that storage, even one byte further on, can get you an abend due to an Addressing Exception (a S0C4, which CICS will kindly name something else for you, an AKEA).
Even without acquired storage, other fields after the one "passed" can be accidentally trashed, or the field itself may not get the expected amount of data MOVEd to it by the CALLed program, if the definition is short in the CALLed program.
There are actually two things which get "returned" from a CALLed program. They are the special-register RETURN-CODE, and the single item on the RETURNING of the PROCEDURE DIVISION (if used, likely not).
Even so, the mechanisms of how those are achieved are different from the normal misunderstanding of data "passed" between CALLing and CALLed programs.
I have not had the joy of programming CICS for sometime now, this answer is based on what knowledge I still remember.
The calling program gets at most an amount of data less than or equal to the size of the data area sent in the calling program (or as specified by the optional LENGTH parameter). Don't try to access data beyond what you have sent.
"So if program x LINKS to program y, any updates done to the COMMAREA in y will be visible in x." Source: SOVF:How CICS Shared Memory Works.
"When a communication area is passed by way of an EXEC CICS LINK command, the invoked program is passed a pointer to the communication area itself. Any changes that are made to the contents of the data area in the invoked program are available to the invoking program, when control returns to it; to access any such changes, the program names the data area that is specified in the original COMMAREA option." Source: IBM-CICS-Ref.
So,
does program b only return the commarea that program a passed?
I would answer the above as Yes.
As for this one, it depends on the structure of the DFHCOMMAREA of the linked program. If it only contains 1 such area, then the answer is that it returns as many bytes as was sent on link command from that area (either implicitly or explicitly). Remember that this area is outside your caller. So, if the caller sends 100 bytes and the linkage section has an area of 500 bytes, you only get 100 back at the most.
If you want to allow your linked program to modify data in the commarea, there are some very serious limitations.
Will expose a changes in a commarea to the LINKing program, but only by accident and only if both tasks execute on the same CICS region. This is because the commarea is actually a pointer. On a distributed program link, the area is copied, but not copied back.