<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://try-as400.pocnet.net/index.php?action=history&amp;feed=atom&amp;title=File_Formats%3APGM</id>
	<title>File Formats:PGM - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://try-as400.pocnet.net/index.php?action=history&amp;feed=atom&amp;title=File_Formats%3APGM"/>
	<link rel="alternate" type="text/html" href="http://try-as400.pocnet.net/index.php?title=File_Formats:PGM&amp;action=history"/>
	<updated>2026-08-15T02:55:51Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>http://try-as400.pocnet.net/index.php?title=File_Formats:PGM&amp;diff=1782&amp;oldid=prev</id>
		<title>Friedkiwi: Document the MI *PGM object: segments, SLS pointers, header chain, and where the instruction stream lives (via create-page on MediaWiki MCP Server)</title>
		<link rel="alternate" type="text/html" href="http://try-as400.pocnet.net/index.php?title=File_Formats:PGM&amp;diff=1782&amp;oldid=prev"/>
		<updated>2026-08-09T11:54:41Z</updated>

		<summary type="html">&lt;p&gt;Document the MI *PGM object: segments, SLS pointers, header chain, and where the instruction stream lives (via create-page on MediaWiki MCP Server)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;A &amp;#039;&amp;#039;&amp;#039;&amp;lt;code&amp;gt;*PGM&amp;lt;/code&amp;gt;&amp;#039;&amp;#039;&amp;#039; is a Machine Interface &amp;#039;&amp;#039;program object&amp;#039;&amp;#039;. It is not a file with a text section and a symbol table. It is a set of single-level store &amp;#039;&amp;#039;&amp;#039;segments&amp;#039;&amp;#039;&amp;#039;, chained together by 8-byte SLS pointers, with the executable instructions embedded in the first segment among the metadata that describes them.&lt;br /&gt;
&lt;br /&gt;
This page describes enough of that structure to walk a program object offline — that is, without a console session and without printing a storage dump for every object of interest. The bytes can come from a [[File Formats:SAVF|save file]], which makes any distribution medium, PTF or backup a source of real program objects to examine.&lt;br /&gt;
&lt;br /&gt;
Everything below is big endian, and text fields are EBCDIC.&lt;br /&gt;
&lt;br /&gt;
== Addressing ==&lt;br /&gt;
Pointers are 8 bytes: a 40-bit segment identifier in the high bits and a 24-bit offset in the low bits, so a segment is 16&amp;amp;thinsp;MiB. This is the same split used throughout the machine, including by the DST &amp;#039;&amp;#039;Display/Alter storage&amp;#039;&amp;#039; panel and by the SLS address field of a [[Data Structures:LID|LID]] directory record.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
segment = pointer &amp;gt;&amp;gt; 24&lt;br /&gt;
offset  = pointer &amp;amp; 0xFFFFFF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An all-zero pointer means the object has no data for that structure. That is precisely what the &amp;lt;code&amp;gt;###INFO: OBJECT DOES NOT CONTAIN DATA FOR THIS SECTION&amp;lt;/code&amp;gt; line in a Display/Alter/Dump printout is reporting.&lt;br /&gt;
&lt;br /&gt;
Some fields are not pointers but &amp;#039;&amp;#039;&amp;#039;&amp;lt;code&amp;gt;SEGOFF&amp;lt;/code&amp;gt;&amp;#039;&amp;#039;&amp;#039; pairs: a 4-byte segment &amp;#039;&amp;#039;index&amp;#039;&amp;#039;, counting from one into the object&amp;#039;s own segment table, followed by a 4-byte offset. These appear where a genuine pointer would have to be relocated when the object moves.&lt;br /&gt;
&lt;br /&gt;
The segments of one program have unrelated segment identifiers. A decoder therefore needs the whole set: a single segment cannot resolve its own pointers.&lt;br /&gt;
&lt;br /&gt;
== Segments ==&lt;br /&gt;
A single-module bound program typically has four segments, distinguished by the type field in each segment&amp;#039;s own header:&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Role&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;0x0001&amp;lt;/code&amp;gt;&lt;br /&gt;
|The program object proper: all headers, tables, and the instruction stream.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;0x0022&amp;lt;/code&amp;gt;&lt;br /&gt;
|Module constants and the module string directory.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;0x0018&amp;lt;/code&amp;gt;&lt;br /&gt;
|Static storage.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;0x0028&amp;lt;/code&amp;gt;&lt;br /&gt;
|Trace-back and mapping data.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that a program&amp;#039;s segment table records a segment &amp;#039;&amp;#039;use&amp;#039;&amp;#039; code, while each segment&amp;#039;s own header records a &amp;#039;&amp;#039;type&amp;#039;&amp;#039;. They are different numberings and should not be conflated.&lt;br /&gt;
&lt;br /&gt;
=== Segment header ===&lt;br /&gt;
Every MI segment opens with a header, called &amp;lt;code&amp;gt;YYSGHDR&amp;lt;/code&amp;gt; in IBM&amp;#039;s own dump formatting.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Size&lt;br /&gt;
!Field&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x00&amp;lt;/code&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|Segment type&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x02&amp;lt;/code&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|Size, in 512-byte units&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x04&amp;lt;/code&amp;gt;&lt;br /&gt;
|1&lt;br /&gt;
|New flags&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x05&amp;lt;/code&amp;gt;&lt;br /&gt;
|1&lt;br /&gt;
|Flags&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x08&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Address of the owning object&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x18&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Space address&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Object header ===&lt;br /&gt;
Immediately after it, at &amp;lt;code&amp;gt;+0x20&amp;lt;/code&amp;gt; of the first segment, sits the object header, &amp;lt;code&amp;gt;YYEPAHDR&amp;lt;/code&amp;gt;. Offsets below are relative to it.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Size&lt;br /&gt;
!Field&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x02&amp;lt;/code&amp;gt;&lt;br /&gt;
|1&lt;br /&gt;
|MI object type&lt;br /&gt;
|Together with the next byte, &amp;lt;code&amp;gt;0x0201&amp;lt;/code&amp;gt; for a program.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x03&amp;lt;/code&amp;gt;&lt;br /&gt;
|1&lt;br /&gt;
|MI object subtype&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x04&amp;lt;/code&amp;gt;&lt;br /&gt;
|30&lt;br /&gt;
|Object name&lt;br /&gt;
|EBCDIC.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x24&amp;lt;/code&amp;gt;&lt;br /&gt;
|4&lt;br /&gt;
|Space size&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x30&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Creation timestamp&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x38&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Owning user profile&lt;br /&gt;
|A pointer to the profile object.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x48&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Context&lt;br /&gt;
|That is, the library.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x50&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Object space&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;The pointer to the program header.&amp;#039;&amp;#039;&amp;#039; Everything else hangs off this.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x5A&amp;lt;/code&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|ASP&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x60&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Last-modified timestamp&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The type and subtype pair uses the same code space as the item descriptors in a save file, so one table of MI type codes serves both.&lt;br /&gt;
&lt;br /&gt;
== The program header ==&lt;br /&gt;
Found through the object header&amp;#039;s object-space pointer; in practice it sits at offset &amp;lt;code&amp;gt;0x1000&amp;lt;/code&amp;gt; of the first segment.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Size&lt;br /&gt;
!Field&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x00&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Program attributes&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x08&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to the version table&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x10&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to the segment table&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x18&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to the activation header&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x20&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to the signature table&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x28&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to the program string directory&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x30&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to activation group information&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x40&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Activation start&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x48&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Activation end&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x50&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;Activation and PEP end&amp;#039;&amp;#039;&amp;#039; — the last byte of the code&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x58&amp;lt;/code&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|Flags&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x5C&amp;lt;/code&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|Program state&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x90&amp;lt;/code&amp;gt;&lt;br /&gt;
|1&lt;br /&gt;
|Program type&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x94&amp;lt;/code&amp;gt;&lt;br /&gt;
|4&lt;br /&gt;
|Program entry procedure module number&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x9C&amp;lt;/code&amp;gt;&lt;br /&gt;
|4&lt;br /&gt;
|Program entry procedure string ID&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0xA0&amp;lt;/code&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|Minimum parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0xA2&amp;lt;/code&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|Maximum parameters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0xD0&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to the program header extension&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0xD8&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to the trace-back locator&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0xE0&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to the module table&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0xE8&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to observability information&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0xF0&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to the maintenance header&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The header extension adds a pointer to the GLU code list, &amp;lt;code&amp;gt;SEGOFF&amp;lt;/code&amp;gt; pairs for the program history and the segment table extension, and a 16-byte hardware feature set at &amp;lt;code&amp;gt;+0x50&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Version table ===&lt;br /&gt;
Forty bytes of packed version-release-modification halfwords, where &amp;lt;code&amp;gt;0x0740&amp;lt;/code&amp;gt; reads as V7R4M0. Among them are the binder&amp;#039;s internal and MI levels at &amp;lt;code&amp;gt;+0x02&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;+0x04&amp;lt;/code&amp;gt;, the &amp;#039;&amp;#039;&amp;#039;target&amp;#039;&amp;#039;&amp;#039; release at &amp;lt;code&amp;gt;+0x06&amp;lt;/code&amp;gt;, the &amp;#039;&amp;#039;&amp;#039;created-on&amp;#039;&amp;#039;&amp;#039; release at &amp;lt;code&amp;gt;+0x08&amp;lt;/code&amp;gt;, the language release at &amp;lt;code&amp;gt;+0x10&amp;lt;/code&amp;gt;, the CCSID at &amp;lt;code&amp;gt;+0x1E&amp;lt;/code&amp;gt; and the low and high optimisation levels at &amp;lt;code&amp;gt;+0x20&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;+0x22&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The target and created-on values here are what decide whether an object will restore onto a given release, so they are worth reading before attempting a restore that might fail.&lt;br /&gt;
&lt;br /&gt;
=== Segment table ===&lt;br /&gt;
A header of allocated size, entry count and version, then the entries beginning at &amp;lt;code&amp;gt;+0x10&amp;lt;/code&amp;gt;. &amp;#039;&amp;#039;&amp;#039;Entries are a fixed 48 bytes&amp;#039;&amp;#039;&amp;#039;; the size field is the allocation, not header plus count times entry, so deriving the stride from it gives the wrong answer.&lt;br /&gt;
&lt;br /&gt;
Each entry holds the segment address at &amp;lt;code&amp;gt;+0x00&amp;lt;/code&amp;gt;, a limbo address at &amp;lt;code&amp;gt;+0x08&amp;lt;/code&amp;gt;, a declared page count at &amp;lt;code&amp;gt;+0x10&amp;lt;/code&amp;gt;, and a one-byte &amp;#039;&amp;#039;segment use&amp;#039;&amp;#039; at &amp;lt;code&amp;gt;+0x12&amp;lt;/code&amp;gt;: &amp;lt;code&amp;gt;0x01&amp;lt;/code&amp;gt; static storage, &amp;lt;code&amp;gt;0x02&amp;lt;/code&amp;gt; the program object, &amp;lt;code&amp;gt;0x04&amp;lt;/code&amp;gt; constants, &amp;lt;code&amp;gt;0x06&amp;lt;/code&amp;gt; trace-back.&lt;br /&gt;
&lt;br /&gt;
A parallel &amp;#039;&amp;#039;segment table extension&amp;#039;&amp;#039;, reached by a &amp;lt;code&amp;gt;SEGOFF&amp;lt;/code&amp;gt; in the program header extension, records how much of each segment is actually used as opposed to allocated. Its entries begin at &amp;lt;code&amp;gt;+0x18&amp;lt;/code&amp;gt; and are 24 bytes, of which the first four are the byte count.&lt;br /&gt;
&lt;br /&gt;
=== Activation header ===&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Size&lt;br /&gt;
!Field&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x00&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;Program entry procedure entry point&amp;#039;&amp;#039;&amp;#039; — the first instruction&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x08&amp;lt;/code&amp;gt;&lt;br /&gt;
|4&lt;br /&gt;
|PBV size&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x10&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to the PBV relocation array&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x18&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to the static PBV array&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x20&amp;lt;/code&amp;gt;&lt;br /&gt;
|4&lt;br /&gt;
|PBV relocation count&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x24&amp;lt;/code&amp;gt;&lt;br /&gt;
|4&lt;br /&gt;
|Dependent service program count&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x28&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to the dependent service program array&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x4C&amp;lt;/code&amp;gt;&lt;br /&gt;
|4&lt;br /&gt;
|Constant frame count&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x50&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to the constant frame definition array&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x58&amp;lt;/code&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|Pointer to the program export array&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x60&amp;lt;/code&amp;gt;&lt;br /&gt;
|4&lt;br /&gt;
|Export count&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For a bound program with no exports most of these are zero. For a service program they are the published interface, and the dependent service program array is the object&amp;#039;s dependency list — which makes it possible to work out what a program binds to without a machine to run &amp;lt;code&amp;gt;DSPPGM&amp;lt;/code&amp;gt; on.&lt;br /&gt;
&lt;br /&gt;
=== Maintenance header ===&lt;br /&gt;
Holds the copyright list size and count and a &amp;lt;code&amp;gt;SEGOFF&amp;lt;/code&amp;gt; to the copyright text — a 4-byte length followed by EBCDIC — along with &amp;lt;code&amp;gt;SEGOFF&amp;lt;/code&amp;gt; pairs for the external object list, static activation and export information, the last non-observable segment and size, and the lowest and highest PBV identifiers.&lt;br /&gt;
&lt;br /&gt;
== Modules ==&lt;br /&gt;
The module table has the same shape as the segment table: header, then 48-byte entries from &amp;lt;code&amp;gt;+0x10&amp;lt;/code&amp;gt;, each giving a pointer to a module header, a module domain and a module subtype.&lt;br /&gt;
&lt;br /&gt;
A module header is a long run of pointers: to the program header it belongs to, the copyright table, the module version table, binding information, static information, the end-of-line table, observability information, the module string directory, the entry point table, the VLIC table, the procedure table, module constants, and the module header extension. It also carries the module type at &amp;lt;code&amp;gt;+0x01&amp;lt;/code&amp;gt; — &amp;lt;code&amp;gt;0x01&amp;lt;/code&amp;gt; for OPM and &amp;lt;code&amp;gt;0x03&amp;lt;/code&amp;gt; for ILE — the module attributes at &amp;lt;code&amp;gt;+0xA8&amp;lt;/code&amp;gt;, and the program entry procedure&amp;#039;s dictionary ID, string ID, procedure number and parameter counts from &amp;lt;code&amp;gt;+0xAC&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;+0xBC&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Two of its pointers characteristically leave the program segment: the module string directory and the module constants both live in the &amp;lt;code&amp;gt;0x0022&amp;lt;/code&amp;gt; segment. When hunting for literal data referenced by the code — message identifiers, format names, table constants — that is the segment to search, and these two pointers give its exact extent.&lt;br /&gt;
&lt;br /&gt;
=== Module version table ===&lt;br /&gt;
This is the most immediately informative structure in the whole object.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Size&lt;br /&gt;
!Field&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x02&amp;lt;/code&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|Language release&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x0A&amp;lt;/code&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|Instruction release&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x0C&amp;lt;/code&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|Target release&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x0E&amp;lt;/code&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|Created-on release&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x10&amp;lt;/code&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|Optimisation level&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x14&amp;lt;/code&amp;gt;&lt;br /&gt;
|30&lt;br /&gt;
|Source module name&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x32&amp;lt;/code&amp;gt;&lt;br /&gt;
|30&lt;br /&gt;
|Source module qualifier&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x50&amp;lt;/code&amp;gt;&lt;br /&gt;
|20&lt;br /&gt;
|Compiler name&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;+0x64&amp;lt;/code&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|Earliest compiler release&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Read the compiler name before spending any time on a disassembly. A module reporting &amp;lt;code&amp;gt;MX CONVERTED&amp;lt;/code&amp;gt; was &amp;#039;&amp;#039;translated&amp;#039;&amp;#039; from an older object rather than compiled from source at this release, and the generated code will not resemble what a current compiler emits.&lt;br /&gt;
&lt;br /&gt;
== The instruction stream ==&lt;br /&gt;
The code is a single contiguous run inside the first segment, bounded by two fields already listed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
start = activation header, program entry procedure entry point&lt;br /&gt;
end   = program header, activation and PEP end        (inclusive)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is 64-bit big-endian &amp;#039;&amp;#039;&amp;#039;PowerPC AS&amp;#039;&amp;#039;&amp;#039;. A stock disassembler invoked as &amp;lt;code&amp;gt;objdump -D -b binary -m powerpc:common64 -EB&amp;lt;/code&amp;gt;, with the load address adjusted to the start offset, will produce a listing whose addresses line up with anything printed by Display/Alter/Dump.&lt;br /&gt;
&lt;br /&gt;
Two caveats apply, and both matter.&lt;br /&gt;
&lt;br /&gt;
PowerPC AS is not plain PowerPC. The tagged-pointer instructions and other AS-only operations have no encoding in a stock PowerPC disassembler and will appear as invalid, or worse, as an unrelated mnemonic that looks plausible. Treat such a listing as a starting point rather than as authority.&lt;br /&gt;
&lt;br /&gt;
The run is also not pure code. Trace-back tables and constants are interleaved with instructions, so a linear sweep will decode data as code somewhere. For an object that still has its observability information, the trace-back locator and the module tables provide the boundaries needed to separate the two; for an object whose observability has been removed, they do not, and the separation has to be inferred from the code itself.&lt;br /&gt;
&lt;br /&gt;
== Scope of this description ==&lt;br /&gt;
Field offsets were derived by lining a printed Display/Alter/Dump of a program object up against the same object&amp;#039;s bytes extracted from a save file, and then checked by decoding the object independently and comparing every field against the printout. Structures that the dump prints but that were empty in the object used — the signature table, the export and import arrays, the service program tables and the secondary entry point table — are located by pointer but their contents are not described here; establishing those needs a service program to work from.&lt;br /&gt;
&lt;br /&gt;
Only &amp;lt;code&amp;gt;*PGM&amp;lt;/code&amp;gt; is covered. &amp;lt;code&amp;gt;*SRVPGM&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;*MODULE&amp;lt;/code&amp;gt; share much of this layout but have additional tables of their own.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[File Formats:SAVF]] — how to get a program object&amp;#039;s bytes off a machine or out of a distribution medium&lt;br /&gt;
* [[Data Structures:LID]] — the same single-level store address split, in a different container&lt;br /&gt;
&lt;br /&gt;
[[Category: System Internals]]&lt;/div&gt;</summary>
		<author><name>Friedkiwi</name></author>
	</entry>
</feed>