XLATE(4) XLATE(4)
xlate - the address translation object file section of an ELF object
#include <elf.h>
#include <libelf.h>
#include <cmplrs/xlate.h>
An address translation section is created by commands such as pixie(1),
and cord(1) to allow other tools such as dbx(1) and dis(1) to accurately
display information about the program text. There can be a maximum of
two address translation sections (one of each section type (see below))
in a given a.out or DSO.
Translation information is held in ELF sections with sh_type
SHT_MIPS_XLATE (section name .MIPS.Xlate), SHT_MIPS_XLATE_DEBUG (not
currently generated by cord or pixie), or SHT_MIPS_XLATE_OLD (normal
section name .MIPS.Xlate_old). There should be at most one section
marked SHT_MIPS_XLATE. There could be multiple sections marked
SHT_MIPS_XLATE_DEBUG. Each address translation section should have a
unique name: sections are accessed via the section name. Nothing in the
library enforces this naming rule (libelfutil does not create sections).
Section .MIPS.Xlate contains translation information giving the address
translations from the program as executed to and from the original
program text. This is the table generally used. When there are multiple
translations applied to the program text, this gives the overall
translation map, translating from the original before any translations to
the final executable text after all translations. This is the
translation information that dbx and dis use. This information cannot
ordinarily be strip(1)ped since to do so would make stack tracebacks thru
the text impossible.
Section .MIPS.Xlate_old contains translation information given the
original translation (as created by cord(1)) if the program or DSO has
also been processed by pixie. That is, after being corded and pixied,
there may be two translation tables in the Elf file (the cord-created
.MIPS.Xlate is renamed .MIPS.Xlate_old by pixie.).
The format of the two sections is the same.
In an Elf file the section data must be properly aligned: the Elf
section header must show an alignment of at least 4 for a 32-bit Elf file
and at least 8 for a 64-bit Elf file.
A translation section conceptually is a table with one row per
instruction (text) and two entries per row. The first entry is the
address of an instruction in the modified text (the instructions that
will be executed). The second entry is the address of an instruction in
the input-text of the translation (the text before translation).
Page 1
XLATE(4) XLATE(4)
Such a table would, if physically present, be inconveniently large. The
first size reduction is based on the observation that (given the
translations the tools actually do) a table with four entries in each row
newaddress, new-addr-range, oldaddress, old-addr-range
will be more compact: most translations involve a range of instructions
moved together. (The new- and old- range values need not be identical in
a given row. Consider the additional instructions in the longer range to
be an extension of the last instruction of the shorter range.) The
actual data on disk is more compact than a simple encoding of the 4-
entry-per-row table would be but the 4-entry-per-row table is easily
created from the data on disk.
Unless one is quite interested in the details of how the data is recorded
on disk the rest of this man page will not be of interest.
There are two versions in use. Version 1 has a common header format used
for both 64 and 32 bit applications. Version 2 has distinct headers for
each size executable/DSO (the headers have the same fields but the
address fields and length fields are larger in the header for 64-bit
applications). Version 1 and Version 2 have nearly identical field
names: the difference is that Version 1 has fields named
hd_upper32_bits_old and hd_upper32_bits_new and hd_is64_bit whereas
Version 2 has no such fields.
A translation section (all 3 formats) as stored on disk consists of
Translation Header
N Translation Block Headers
N Translation Blocks
(optionally) Register Information Block
The Translation Header and each Translation Block Header is a fixed size.
Each Translation Block is a fixed size. The Translation Header describes
the rest of the section. Each Translation Block Header describes an
individual Translation Block. Each Translation Block describes a portion
of the implicit four-entry table mentioned above. The structures used
are defined in /usr/include/cmplrs/xlate.h. The meaning of the fields in
those structures are given below.
You must install the compiler_eoe.hdr.internal subsystem to get the
headers necessary to work with the xlate functions and leb128 functions
they call.
Translation Header Version 2 - 32 bits [Toc] [Back] This describes the structure xlate_header32_v2_s.
hd_version
Has the value XLATE_TB_32_V2 (5).
Page 2
XLATE(4) XLATE(4)
hd_table_kind
The value is one of xlate_tk_general (0), xlate_tk_preserve_size
(1), or xlate_tk_preserve_order (2). The value here identifies
the format of the array of Translation Block s See the
Translation Block Version 2 section description below.
hd_block_size
The number of bytes in each Translation Block Version 2 . The
number of bytes in each block is fixed, but the number of entries
in each block varies and there may be a few unused bytes at the
end of any given block.
hd_num_blocks
The number of instances of Translation Block Header Version 2 and
the number of instances of Translation Block Version 2 not
including the Register Information Block (all versions) .
hd_num_entries
The number of range entries in the complete section, counting all
range entries in each Translation Block Version 2 .
hd_new_addr_low
The text address of the new (transformed) text.
hd_new_addr_high
The text address one past the highest address in the new
(transformed) text.
hd_old_addr_low
The text address of the old (pre transform) text.
hd_old_addr_high
The text address one past the highest address of the old (pre
transform) text.
hd_data_moved
If the data section was moved (relative to text) this gives the
amount of movement.
hd_startup_fwa
The startup First Word Address is information created by pixie(1)
describing the pixie startup code beginning address.
hd_startup_lwa
The startup Last Word Address is information created by pixie(1)
describing the address just past the end of pixie startup code.
hd_old_text_exists
This is 1 if the untransformed text is in the executable or DSO.
This is 0 if there is no such section. cord(1)ed DSOs normally
do not contain a copy of the untransformed text.
Page 3
XLATE(4) XLATE(4)
hd_old_text_alloc
This is 1 if the original text (before any transformation) is in
a loadable segment (see the elf Program Header documentation).
hd_reg_info_size
If non-zero, then this section has a final block (of size
hd_regInfoSize bytes) (following the Translation Block Version 2
array) which contains the actual register information. Such
information is created by pixie for example, since pixie needs to
use some registers itself and therefore transforms the text to
not use such registers. The information in the Register
Information Block (all versions) describes the physical location
in memory of the registers pixie has appropriated. These
descriptions thus give the location of "shadow" registers in
memory which contain what the untransformed text used as real
registers.
Translation Block Header Version 2 [Toc] [Back] The fields in a block header give a way to quickly determine which
block(s) hold information on range entries of interest.
This describes xlate_blockheader32_v2_s and
xlate_blockheader64_v2_s (the fields contained are 32 and 64 bits,
respectively).
bh_first_new_addr
The new address of the first entry of the corresponding
Translation Block .
bh_first_old_addr
The old address of the first entry of the corresponding
Translation Block .
bh_num_entries
The number of entries actually put into this block.
Translation Block Version 2 [Toc] [Back] The contents are the same for both 32 and 64 bit versions, though for 32
bit versions the numbers represented are 32 bit numbers.
The initial address delta (for each case below) is a delta from the
corresponding address in the applicable Translation Block Header Version
2 .
Each block is composed of a group of translation block entries. A
translation block entry is not fixed length. Each translation block
entry represents a single 4-entry row in the address-range-table
described earlier. There are 3 different variable-length entry formats.
All entries have the same format. The header field hd_table_kind
identifies the format applicable to every Translation Block . Every
number recorded is recorded in a variable length format known as leb_128
format. The leb_128 format is variable length (and can record any size
Page 4
XLATE(4) XLATE(4)
number) but 64-bit values will exist in a block only if the block is part
of a 64-bit executable or DSO translation table. That number format is
described defined and described in the Dwarf Version 2 and libdwarf
documents. Each address or range is shifted right 2 bits before being
written since instructions (and byte ranges, interchangeably also called
lengths) will always be a multiple of 4.
The assumptions which apply equally to all translation translation block
formats is that the new address is increasing and that the new-address
plus the new-range of one range is equal to the new-address of the next
range with no gap. If this is not true then the translations may not
always be recorded correctly.
The following describes each "Translation Block" entry format in turn.
xlate_tk_preserve_order
This case is defined such that transformations leave the text in
the original order so both old and new addresses must increase.
The entry contents recorded are an unsigned new range followed by
the unsigned old range.
xlate_tk_preserve_size
This case it is defined such that transformations leave the
length of the text unchanged (but the old address may increase or
decrease). The entry contents recorded are an unsigned range (of
the old and new addresses since the values must be identical by
definition of xlate_tk_preserve_size) followed by a signed delta
of the previous old address.
xlate_tk_general
In this case there are no guarantees about ordering of the
old_address or value of the old_range in the transformations.
The new address/new range sets must still increase with no gaps,
so the block format does cannot record (and the library does not
allow) truly general transformations (such as where the new
address is not monotonic or where there are gaps in the new
address). The entry contents recorded are an unsigned new range
value followed by a signed delta of the old address followed by a
signed "new_range - old_range".
Translation Header Version 2 - 64 bits [Toc] [Back] This describes the structure xlate_header64_v2_s.
hd_version
Has the value XLATE_TB_64_V2 (6).
The rest of the 64-bit format is identical to xlate_header32_v2_s except
that certain data items are 64 bits.
Page 5
XLATE(4) XLATE(4)
Translation Header Version 1 [Toc] [Back] This describes the structure xlate_header_v1_s.
hd_version
Has the value XLATE_TB_CLASS_MAIN_V1 (1) if this is a
SHT_MIPS_XLATE section. Has the value XLATE_TB_CLASS_COPY_V1 (2)
if this is a SHT_MIPS_XLATE_DEBUG section and there has been only
one translation (not two or more). The values 3 and 4 were
reserved but never used. If the value is XLATE_TB_CLASS_COPY_V1
then this section is a duplicate of the SHT_MIPS_XLATE (and
therefore not interesting, really). A consequence of all this is
that the SHT_MIPS_XLATE_DEBUG section is not useful.
hd_table_kind
The value is one of xlate_tk_general (0), xlate_tk_preserve_size
(1), or xlate_tk_preserve_order (2). The value here identifies
the format of the array of Translation Block s See the
Translation Block Version 1 section description below.
hd_is64bit
The value is 0 for 32-bit executables and DSOs. The value is 1
for 64-bit executables and DSOs.
hd_upper32BitsNew
Is 0 for 32 bit executables and DSOs. For 64 bit executables and
DSOs, this is the upper 32 bits of the new addresses in the
table. All the addresses in each Translation Block Header Version
1 and Translation Block Version 1 describe only the least
significant 32 bits of 64 bit addresses.
hd_upper32_bits_old
Is 0 for 32 bit executables and DSOs. For 64 bit executables and
DSOs, this is the upper 32 bits of the old addresses in the
table. All the addresses in each Translation Block Header Version
1 and Translation Block Version 1 describe only the least
significant 32 bits of 64 bit addresses.
hd_block_size
The number of bytes in each Translation Block Version 1 . The
number of bytes in each block is fixed, but the number of entries
in each block varies and there may be a few unused bytes at the
end of any given block.
hd_num_blocks
The number of instances of Translation Block Header Version 1 and
the number of instances of Translation Block Version 1 not
including the Register Information Block (all versions) .
hd_num_entries
The number of range entries in the complete section, counting all
range entries in each Translation Block Version 1 .
Page 6
XLATE(4) XLATE(4)
hd_new_addr_low
The least significant 32 bits of text address of the new
(transformed) text.
hd_new_addr_high
The least significant 32 bits of the text address one past the
end of of the new (transformed) text.
hd_old_addr_low
The least significant 32 bits of the text address of the old (pre
transform) text.
hd_old_addr_high
The least significant 32 bits of the text address one past the
end of the old (pre transform) text.
hd_data_moved
If the data section was moved (relative to text) this gives the
least significant 32 bits of the amount of movement. Movement
greater than 32 bits cannot be properly described.
hd_startup_fwa
The startup First Word Address is information created by pixie(1)
describing least significant 32 bits of the pixie startup code
beginning address.
hd_startup_lwa
The startup Last Word Address is information created by pixie(1)
describing least significant 32 bits of the address just past the
end of pixie startup code.
hd_old_text_exists
This is 1 if the untransformed text is in the executable or DSO.
This is 0 if there is no such section. cord(1)ed DSOs normally
do not contain a copy of the untransformed text.
hd_old_text_alloc
This is 1 if the original text (before any transformation) is in
a loadable segment (see the elf Program Header documentation).
hd_reg_info_size
If non-zero, then this section has a final block (of size
hd_regInfoSize bytes) (following the Translation Block Version 1
array) which contains the actual register information. Such
information is created by pixie for example, since pixie needs to
use some registers itself and therefore transforms the text to
not use such registers. The information in the Register
Information Block (all versions) describes the physical location
in memory of the registers pixie has appropriated. These
descriptions thus give the location of "shadow" registers in
memory which contain what the untransformed text used as real
registers.
Page 7
XLATE(4) XLATE(4)
Translation Block Header Version 1 [Toc] [Back] The fields in a block header give a way to quickly determine which
block(s) hold information on range entries of interest.
This describes xlate_blockheader_v1_s.
bh_first_new_addr
The low 32 bits of the new address in the first entry of the
corresponding Translation Block .
bh_first_old_addr
The low 32 bits of the old address in the first entry of the
corresponding Translation Block .
bh_num_entries
The number of entries actually put into this block.
Translation Block Version 1 [Toc] [Back] The initial address delta (for each case below) is a delta from the
corresponding address in the applicable Translation Block Header Version
1 . In version 1 blocks, the 0th entry is garbage which must be skipped.
Each block is composed of a group of translation block entries. A
translation block entry is not fixed length. Each translation block
entry represents a single 4-entry row in the address-range-table
described earlier. There are 3 different variable-length entry formats.
All entries have the same format. The header field hd_table_kind
identifies the format applicable to every Translation Block . Every
number recorded is recorded in a variable length format known as leb_128
format. Every number recorded is a 32 bit number (one must OR on the
hd_new_addr_high and hd_old_addr_high to complete addresses in a 64-bit
executable or DSO). That number format is described defined and
described in the Dwarf Version 2 and libdwarf documents. Each address or
range is shifted right 2 bits before being written since instructions
(and byte ranges) will always be a multiple of 4. The following
describes each "Translation Block" entry format in turn.
xlate_tk_preserve_order
This case is defined such that transformations leave the text in
the original order so both old and new addresses must increase.
The entry contents recorded are an unsigned new range followed an
unsigned old range.
xlate_tk_preserve_size
This case it is defined such that transformations leave the
length of the text unchanged (but the old address may increase or
decrease). The entry contents recorded are an unsigned range (of
both old and new addresses) followed by a signed delta of the
previous old address.
Page 8
XLATE(4) XLATE(4)
xlate_tk_general
Never can appear anywhere so it is left undefined.
Register Information Block (all versions)
This block is used to describe the location of pseudo-registers: memory
locations that contain the value of what were, in the untranslated
source, registers but whose value is now in memory. This block contains
a direct encoding of three fields of the Dwarf_Loc structure as defined
in the document "A Consumer Library Interface to DWARF". The three
fields are named lr_atom, lr_number, lr_number2 in that document. In the
xlate creation call the arguments are named op, val1, and val2
respectively. The operation codes described here (such as DW_CFA_offset)
are the only codes supported by xlate functions and are a subset of the
codes supported by libdwarf. See section 6.4 of the "DWARF Debugging
Information Format" document. Where specified, numbers are recorded in
leb_128 form.
The following are the DWARF op codes supported and their encoding in the
block.
DW_CFA_advance_loc
op is recorded as the high 2 bits of a byte. val1 >>2 is
recorded as the low 6 bits of the byte (so the maximum advance
is 64 instructions).
DW_CFA_offset
op is recorded as the high 2 bits of a byte. The low 6 bits of
the byte is val1, a register number. val2, an offset, is
recorded as an unsigned leb_128 number starting in the next byte.
(There is a bug in IRIX6.2: val1 is recorded rather than val2 in
the second leb_128 number)
DW_CFA_restore
op is recorded as the high 2 bits of a byte. The low 6 bits of
val1 are a register numbner recorded in the same byte.
DW_CFA_set_loc
op is recorded in the first byte of the value. For version 1 and
64bit table version 2 the next 8 bytes are 64 bits of the value
val1. For a version 2 32bit table the next 4 bytes of the value
is the address (the least significant 32 bits of val1).
DW_CFA_advance_loc1
op is recorded in the first byte of the value. val1 is shifted
right 2 bits and stored in the low 6 bits of the first byte.
DW_CFA_advance_loc2
op is recorded in the first byte of the value. val1 is shifted
right 2 bits. The resulting 16 bits follow the op. In a version
1 table, the 16 bits are stored little-endian (least significant
byte at lowest address) which is contrary to the way they are
recorded in normal SGI DWARF. In a version 2 table the 16 bits
Page 9
XLATE(4) XLATE(4)
are recorded in big-endian (most significant byte at lowest
address) form (just as in SGI DWARF).
DW_CFA_advance_loc4
op is recorded in the first byte of the value. val1 is shifted
right 2 bits. The resulting 32 bits follow the op. In a version
1 table, the 32 bits are stored little-endian (least significant
byte at lowest address) which is contrary to the way they are
recorded in normal SGI DWARF. In a version 2 table the 32 bits
are recorded in big-endian (most significant byte at lowest
address) form (just as in SGI DWARF).
DW_CFA_offset_extended
op is recorded in the first byte of the value. Then val1 is
stored as an unsigned leb_128 number. Then val2 is stored (after
right shifting by 2) as an unsigned leb_128 number.
DW_CFA_def_cfa
op is recorded in the first byte of the value. Then val1 is
stored as an unsigned leb_128 number. Then val2 is stored (after
right shifting by 2) as an unsigned leb_128 number.
DW_CFA_restore_extended
op is recorded in the first byte of the value. Then val1 is
stored as an unsigned leb_128 number.
DW_CFA_undefined
op is recorded in the first byte of the value. Then val1 is
stored as an unsigned leb_128 number.
DW_CFA_same_value
op is recorded in the first byte of the value. Then val1 is
stored as an unsigned leb_128 number.
DW_CFA_def_cfa_register
op is recorded in the first byte of the value. Then val1 is
stored as an unsigned leb_128 number.
DW_CFA_register
op is recorded in the first byte of the value. Then val1 is
stored as an unsigned leb_128 number. Then val2 is stored as an
unsigned leb_128 number.
DW_CFA_remember_state
op is recorded in the first byte of the value.
DW_CFA_restore_state
op is recorded in the first byte of the value.
DW_CFA_nop
op is recorded in the first byte of the value.
Page 10
XLATE(4) XLATE(4)
DW_CFA_def_cfa_offset
op is recorded in the first byte of the value. Then val1 is
right-shifted by 2 and then stored as an unsigned leb_128 number.
/usr/include/cmplrs/xlate.h
/usr/include/libXlate.h
/usr/include/libdwarf.h
/usr/include/dwarf.h
libelfutil(5), DWARF Debugging Information Format (Version 2.0), A
Consumer Library Interface to DWARF.
PPPPaaaaggggeeee 11111111 [ Back ]
|