1

When a C program calls an external routine under z/OS there a specific linkage used depending on the instructions used to call and return from the external routine.

Use Case - 1

Using the standard Branch and Link sequence, GPR14 has the return to address, GPR15 has the entry point address of the routine being called, GPR13 contains the address of a 72 byte register save area that is used to save GPR14, GPR15, GPR0, GPR1, GPR2, GPR3, GPR4, GPR5, GPR6, GPR7, GPR8, GPR9, GPR10, GPR11 AND GPR12, the first 12 bytes of the register save area contain, a 4 byte value that can have multiple meanings, a backward register save area pointer and a forward register save area pointer. It is the responsibility of the called program to save the callers registers in the passed register save area and to acquire a new register save area for its use and load the address of the gotten register save area into r13.

To return to the calling program, the executing program restores, gpr13 and gpr14, gpr15, gpr0-gpr12 from the register save area and then branches to the address in gpr14, registers gpr0 and gpr1 are not restored but can be used to return values to the calling program.

Use Case - 2 Should the called routing opt to use the branch and stack instruction at entry, the callers registers are stored in a linkage stack entry. It is the called programs responsibility to acquire a new registers save area the and load the address of the gotten register save area into r13. On return the called program issues a PR (program return instruction) this restores the callers gpr14, gpr15 and gpr2-gpr13, gpr0 and gpr1 are not restored but can be used to return values to the calling program. The linkage stack entry is freed.

In both use cases above, the the entry and exit linkages differ depending on whether or not the called program is executing as a non-reentrant or reentrant program.

So getting back to the the question that I asked, under z/Linux if a C program were to call an external routine what would the entry and exit linkages look like.

Thank you for any information you might choose to share.

JD

jdftwrth
  • 45
  • 5
  • What is "external routine"? Where is it located? It is part of which component? – Eugene Sh. Mar 22 '21 at 19:07
  • 2
    @jdwrth: I think you've mixed up the terms "linkage / calling convention" and "program / function". The details of which registers to use, how to save and restore them are part of an ABI's *[calling convention](https://en.wikipedia.org/wiki/Calling_convention)*. And calling conventions are relevent with the call of *functions*. The term "program" is usually reserved for self contained applications that show up as processes. *I'd wager that, if you were using the right terms to look for further information, you'd get much far ahead.* – datenwolf Mar 22 '21 at 19:11
  • for the sake of argument, lets say the the "external routine is a standalone Python application. As to its location, I will show my ignorance of z/Linux (for the umpteenth time) and say it stored as binary file. – jdftwrth Mar 22 '21 at 19:13
  • If you're using the `exec` family of functions to run an external program there's no linkage. The new program replaces the current process in its entirety. – Barmar Mar 22 '21 at 19:15
  • @jdftwrth I will show my ignorance in it as well, because I am ignorant in it :) But in a "conventional" operating system you don't call routines which are parts of separate programs. Instead you either call routines which might be a part of dynamically linked *libraries*, or you can invoke that external program as a separate (child) process as whole. – Eugene Sh. Mar 22 '21 at 19:17
  • datenwolf. Your right, if I knew the right terms I would be much farther ahead. I am at a disadvantage here, granted that I have 50+ years of software development but it has always been in the IBM mainframe environment and always using assembly language. I can spell C and Linux but am not really conversant in either of the architectures. That being said I am trying to get up to speed as quickly as possible. – jdftwrth Mar 22 '21 at 19:21
  • Eugene Sh. well i might have do disagree with that assertion, In the Z/OS environment, if you know the address of a module in storage and it contains a code block that could be executed independently of the program that its part of and you know the offset of the desired code block, you could dummy up the environment and branch to it under certain circumstances, of course you would probably be better off giving a monkey a loaded firearm. just saying... – jdftwrth Mar 22 '21 at 19:26
  • @jdftwrth Is that a common practice on this OS or a "hack"? Otherwise sounds similar to dynamic linking on "common" OS, when a library is being loaded to memory in the runtime and the process is calling specific routines from it. – Eugene Sh. Mar 22 '21 at 19:31
  • 1
    Eugene Sh. I wouldn't want to call it a common practice but it is one way executing a section of code in a module in storage, for the most part its frowned upon by most IT auditors, requires authorization (supervisor state and key zero) and can lead to abrupt changes in employment status. – jdftwrth Mar 22 '21 at 20:01
  • @datenwolf: z/OS is different to other "environments" in many aspects, and it is using it's very own naming convention. *Linkage conventions* is indeed the term describing what is called *calling convention* in other environments. See here: https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.ieaa600/chap2.htm Similar comments apply to other terms the OP is using, such as *program*, *external routine*, etc. – phunsoft Mar 22 '21 at 20:12
  • @barmar: *If you're using the exec family of functions to run an external program there's no linkage. The new program replaces the current process in its entirety.* Not in its entirety, since open file descriptors, environment variables, etc. may be kept, ready for the new program. – phunsoft Mar 22 '21 at 20:22
  • 1
    @jdftwrth The calling convention is specified in the [zSeries ELF ABI Supplement](http://legacy.redhat.com/pub/redhat/linux/7.1/es/os/s390x/doc/lzsabi0.pdf). It should answer all your questions. – fuz Mar 22 '21 at 21:00
  • @phunsoft True, but unrelated to linkage. I was just talking about code. – Barmar Mar 22 '21 at 21:07
  • @phunsoft: Thanks. Learn something new (I guess I was led astray by the linux tag). – datenwolf Mar 22 '21 at 22:08
  • @EugeneSh.: I'd say calling into a function that lives in the address space of a different process isn't that uncommon. It usually goes by the term "remote procedure call", and depending on how deep you want to go, it can go as low as copying the whole darn stack frame of the trampoline over to the other process, adjust a few pointers there, and then do the whole thing backwards again… Hey, don't look at me… just because I recently built exactly that. Oh look over there, a three headed monkey! – datenwolf Mar 22 '21 at 22:11
  • @datenwolf: Calling functions in another address space is in fact a basic building block of z/OS. This dates back to the 24bit memory addressing limit of its predecessors. A set of special instructions, and registers is built into the processor to ease calling those functions: PC (program call) jumps to a function in another address space *as a subroutine*, i.e. without context switch. PR (program return) jumps back from the „subroutine“. The OS (and authorized software) prepare the environment and assign a *unique number* to each function. – phunsoft Mar 23 '21 at 08:37
  • fuz. - thanks for the manual reference! – jdftwrth Mar 23 '21 at 13:05
  • If your "for the sake of argument" use case is representative, [this](https://stackoverflow.com/questions/1056051/how-do-you-call-python-code-from-c-code) might be useful. Or, consider how you would call a standalone Rexx program from classic z/OS Assembler. – cschneid Mar 23 '21 at 14:26
  • @jdftwrth Let me know if you need further information. Also note that to reference another user, prefix the name with an @ sign. Otherwise, Stack Overflow won't pick up the reference and won't send me a notification. – fuz Mar 23 '21 at 16:09
  • I'm late to the party, but I wanted to point out there are many more common linkage conventions on z/OS than the two use-cases you mentioned. LE applications and the CEE* macros, or CICS API calls are examples. The XLC compiler often makes function calls using relative branching and without saving/restoring registers. Your example of running a Python script is also not useful - you're not really running the python program itself - you're running a python interpreter and passing the name of the script, and this is normally done with system services not too different from z/OS LINK or ATTACH. – Valerie R Sep 23 '21 at 14:52

0 Answers0