Operating System - OpenVMS
1825719 Members
2897 Online
109686 Solutions
New Discussion

Re: Utility to change "image file identification"?

 
SOLVED
Go to solution
David R. Lennon
Valued Contributor

Utility to change "image file identification"?

Hi,

   Does anyone know of a program or a way of changing or patching the "image file identification", i.e.. the program version number string that is set by the linker identification keyword, in an existing image file?? I am specifically looking for something that would work under Itanium OpenVMS, which, as I understand it, is a bit more complicated since it is embedded in the ELF image format, however it would ideal if it could work under Alpha, as well. 

   The problem I am trying to solve is that I have a large collection of .EXE files that I'd really like to not re-link (or can't) and the developers didn't conform to the standard of putting the version number in this field, so automated tools built on analyze/image can't retrieve an accurate version number. I'd like to update these "in place". The SET IMAGE command looked promising but this does not seem to be a field it supports changing. I can put in an enhancement request to HP but I was hoping for a solution this century.

  Thanks in advance for any help.

 

- Dave

 

24 REPLIES 24
John Gillings
Honored Contributor

Re: Utility to change "image file identification"?

Dave,

 

  When you say "didn't conform to the standard" do you mean they specified something, but not what you want, or that it's undefined or null? If there's something there which is at least the correct string length, you may be able to fix it using PATCH/ABSOLUTE (this is a one-off isn't it?). Worst case pad it with blanks. Changing the string length might get a bit ugly. 

 

  Most likely your approach will need to be completely different between Alpha and Itanium.

 

  Maybe you can appease your automated tools with dummy images containing the correct string, visible only to the analysis utility via a search list? (without knowing more about your environment...)

A crucible of informative mistakes
John Gillings
Honored Contributor

Re: Utility to change "image file identification"?

FWIW, playing around on Alpha, Isuccessfully changed the image file identification on a copy of ZIP.EXE.

 

 I found the ident string at offset 0F0 in the header as a counted ASCII string. The original value was ZIP 3.0 (with a count byte of 7). There were 2 empty longwords to the next field (looks like the linker ident, also as a counted string). That meant I was able to patch the ident string up to 15 characters. Here's a transcript:

 

Before

        Image Identification Information

                image name: "ZIP"
                image file identification: "ZIP 3.0"
                image file build identification: ""
                link date/time: 26-FEB-2009 21:51:20.33
                linker identification: "A13-03"


$ patch/absolute zip.exe


  OpenVMS PATCH Version T8.2-001

%PATCH-I-NOGBL, some or all global symbols not accessible
%PATCH-I-NOLCL, image does not contain local symbols
PATCH>examine 0f0:0100
000000F0:  50495A07   ! Count byte 7, text ZIP
000000F4:  302E3320   ! text <sp>3.0
000000F8:  00000000   ! empty
000000FC:  00000000   ! empty
00000100:  33314106   ! start of 6 byte linker ident string

PATCH>dep/byte 0f0=0f
old:    000000F0:  07
new:    000000F0:  0F
PATCH>dep/ascii .+1='ZIP'
old:    000000F1:  'ZIP '
new:    000000F1:  'ZIP'
PATCH>dep/ascii .+3=' NEW'
old:    000000F4:  '3.0'
new:    000000F4:  ' NEW'
PATCH>dep/ascii .+4=' V3.'
old:    000000F8:  ''
new:    000000F8:  ' V3.'
PATCH>dep/ascii .+4='1415'
old:    000000FC:  ''
new:    000000FC:  '1415'
PATCH>update
%PATCH-I-WRTFIL, updating image file DISK1:[GILLINGS]ZIP.EXE;4


After

        Image Identification Information

                image name: "ZIP"
                image file identification: "ZIP NEW V3.1415"
                image file build identification: ""
                link date/time: 26-FEB-2009 21:51:20.33
                linker identification: "A13-03"

 

 

I'm not sure if the 0F0 is constant for all images (though a quick look at several images looks like it is). Assuming that's the case it's fairly simple to generate patch scripts, at least on Alpha. When I get a chance I'll see if I can figure out how it works on Itanium

A crucible of informative mistakes
H.Becker
Honored Contributor

Re: Utility to change "image file identification"?

As far as I know, the only public documentation on the image format - either Alpha or Integrity - is in starlet and lib. For C header files look for ei* in sys$lib_c.tlb and elf* in sys$starlet_c.tlb. The image file identification is not at a fixed offset, not even for Alpha.  You probably need a combination of analyze/image and dump/page to determine the offset on Alpha. For Integrity analyze/image prints offsets. Then use your favorite patch utility. (But you can use EDIT/TPU to search for a given string and replace it - and reset the file attributes after TPU wrote a new version of the file.) But you can (or ask others to) write a simple C program to do the work, with code for both formats. It shouldn't be that difficult and expensive. 

John Gillings
Honored Contributor

Re: Utility to change "image file identification"?

Thanks to Hartmut's clue, I found EIHD$L_IMGIDOFF=24 so the longword at offset 24 in the image header is an offset to the image ident area (EIHI$). That block contains major and minor IDs, link time, image name, image ID and linker ID. The Image ID is a counted string at EIHI$T_IMGID=56 within the block. Maximum length of the field (including the size byte) is EIHI$S_LINKID=16

 

So here's a DCL procedure to find the image ident string of an image:

 

$ f=F$PARSE(p1,"SYS$DISK:[].EXE")
$ lf=""
$ SET NOON
$ EIHD$L_IMGIDOFF=24     ! Location of offset to ImageID
$ EIHI$T_IMGID=56
$ ByteSize=8
$ LongSize=32
$ Loop: ff=F$SEARCH(f)
$ IF ff.NES."".AND.ff.NES.lf
$ THEN
$   lf=ff
$   OPEN/READ img 'ff'
$     READ img head          ! Get image header
$   CLOSE img
$     ! Calculate byte offset to Image Ident string
$   idoff=F$CVUI(EIHD$L_IMGIDOFF*ByteSize,LongSize,head)+EIHI$T_IMGID
$   len=F$CVUI(idoff*ByteSize,ByteSize,head)  ! Read Length byte
$   IdStr=F$EXTRACT(idoff+1,len,head)         ! Extract ident string
$   WRITE SYS$OUTPUT "''ff' ''IdStr'"
$   GOTO Loop
$ ENDIF
$ EXIT

 

I get sensible answers for all the images I've tried it on. Including everything in SYS$SYSTEM, SYS$SHARE and SYS$LOADABLE_IMAGES.

 

I found documentation describing the (Alpha) image header in section 28.1.4 in the IDSM V1.5

 

The above DCL could be used to generate a PATCH script to hack the ident string of an image.

A crucible of informative mistakes
John McL
Trusted Contributor

Re: Utility to change "image file identification"?

I think you didn't even need to use PATCH on an Alpha.  The .EXE file is fixed length 512 byte records, so just open the .EXE like a normal file, read the first record/block, modify the field, WRITE/UPDATE/SYMBOL the record, then close the file.  Or, if you wanted to play safe, write the modified record to a new file and copy the rest of the initial file there too.  Of course you'll need to first identify the location of the

 

I wonder if Itanium .EXE's can be processed in a similar fashion. I've got a vague recollection that there's a checksum at the end of each section of the ELF, but hopefully I'm wrong.

H.Becker
Honored Contributor

Re: Utility to change "image file identification"?

>>> that there's a checksum at the end of each section of the ELF
 
No, there isn't. As we all know, the ELF is quite different from the VAX/Alpha image format. The "image file identification" is in the note section. The location of this section is described in the section header table. The location of this table is described in the ELF header. This header is at the beginning of the file. The good thing here is, that the linker developer almost always wrote sections and the section header table starting at disk blocks - an implementation detail which can change any time. So it is doable, even in DCL but it is more work. 

 

Although output parsing is not recommended the most effective way in DCL would be to parse the output of analyze/image/section=note to calculate the file offset. At least for me, writing a small program to do this is much easier. But I didn't receive any request , so far :-)

David R. Lennon
Valued Contributor

Re: Utility to change "image file identification"?

 

Thanks for everyone's input.

 

H.Becker - sure, what can I do to request/bribe you to write a program? Could the program be able to "modify" the field, not just display it?

 

I found a program that looks like it is similar to the SET IMAGE command, I wonder if that could be modified to do this easier than writing one from scratch?

 

http://vouters.dyndns.org/tima/OpenVMS-IA64-THREADCP_rewritten_for_Itanium.html

 

Thanks,

Dave

H.Becker
Honored Contributor

Re: Utility to change "image file identification"?

>>> I found a program that looks like it is similar to the SET IMAGE command, I wonder if that could be modified to do this easier than writing one from scratch?

 

I can't comment on this one, the html page is not available for me. But changing thread related flags is changing DT_VMS_LINKFLAGS in the dynamic table and that is a little bit different. But for a start ... There is probably more available on the net.
 
You are very likely looking for something like
$ mc []imgid main.exe
imgid: 'V1.0'
$ mc []imgid main.exe "V1.0.8.8" 
imgid: 'V1.0'
new imgid too long, supply a string with length < 8
$ mc []imgid main.exe "V1.0.8"
imgid: 'V1.0'
new imgid: 'V1.0.8'
$ mc []imgid main.exe         
imgid: 'V1.0.8'
$
 
Fresh out of the compiler, the bits are still wet. Unfortunately I can't test/analyze the generated image, because this ran on Alpha and I don't have access to an Integrity. 
 
The note's entry for imgid has a max size, a multiple of 8, depending on what is already there. The string is zero-terminated and the terminator counts.
 
Regarding the bribe and how you can get this, send me a mail, or what they call here a private message. And let me know where you want to run the tool, VMS-Alpha/Integrity (or X86/Linux. No, no Win32 code!)
Ph Vouters
Valued Contributor
Solution

Re: Utility to change "image file identification"?

David,

 

For the imgid Alpha source code, be in touch with H. Becker. For the imgid Itanium code, refer to:

http://vouters.dyndns.org/tima/OpenVMS-IA64-Changing_the_image_identitication_of_an_executable.html

 

Yours truly,

Philippe

 

H.Becker
Honored Contributor

Re: Utility to change "image file identification"?

>>>  For the imgid Itanium code, refer to:
   /*
   * The ident string must be no longer than eight characters
   * including the null terminating byte.
   */
 
No, see previous replies. In case the current string length is >=8 characters, your code creates an invalid - or should I say corrupts the ? - note section.
Ph Vouters
Valued Contributor

Re: Utility to change "image file identification"?

Harmut,

 

I did realize that the linker's IDENTIFICATION option string can be longer than 7 characters not including the

terminating null byte. So I reworked the code. The new code has been tested using binutils' readelf and is available at the same URL. I have set the ID string buffer limit to 80 inside the code. I hope it is large enough.

 

I have been misled by your imgid run on Alpha.

Philippe

jreagan
Advisor

Re: Utility to change "image file identification"?

I still think Philippe's code won't do the right thing if you expand an image ident such that the .note section grows past a page boundary.  If you have to bump other sections down inside the file, you have LOTS of work to do to recompute all the section offsets in the header table.

Ph Vouters
Valued Contributor

Re: Utility to change "image file identification"?

John,

 

Do not think ! Send me an actual VMS image where the code I post does not do the trick and I'll rework upon it. On Itanium, I use both analyze/image and binutils' readelf to control. On Alpha, I only know of analyze/image.

 

Regards,

Philippe

Ph Vouters
Valued Contributor

Re: Utility to change "image file identification"?

John,

 

As you can read from this binutils's readelf run, the IA64 VMS Linker aligns the .note section on a disk block boundary and the .note length does not exceed a disk block.

 

$ readelf -a Rudy.EXE
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 0d 02 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            VMS - OpenVMS
  ABI Version:                       2
  Type:                              EXEC (Executable file)
  Machine:                           Intel IA-64
  Version:                           0x1
  Entry point address:               0x501c8
  Start of program headers:          72 (bytes into file)
  Start of section headers:          11784 (bytes into file)
  Flags:                             0x1000014, 64-bit, vms_linkages
  Size of this header:               72 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         6
  Size of section headers:           64 (bytes)
  Number of section headers:         9
  Section header string table index: 1

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .shstrtab         STRTAB           0000000000000000  00002c08
       0000000000000056  0000000000000000           0     0     0
  [ 2] .strtab           STRTAB           0000000000000000  00002a08
       0000000000000001  0000000000000000           0     0     0
  [ 3] .debug_line       VMS_TRACE        0000000000000000  00001e00
       000000000000020f  0000000000000000           0     0     1
  [ 4] .trace_abbrev     VMS_TRACE        0000000000000000  00002200
       000000000000001e  0000000000000000           0     0     1
  [ 5] .trace_info       VMS_TRACE        0000000000000000  00002400
       000000000000006c  0000000000000000           0     0     1
  [ 6] .trace_aranges    VMS_TRACE        0000000000000000  00002600
       0000000000000030  0000000000000000           0     0     1
  [ 7] .note             NOTE             0000000000000000  00002800
       0000000000000188  0000000000000000           0     0     0
  [ 8] .dynstr           STRTAB           0000000000000000  00001750
       000000000000000a  0000000000000000   A       0     0     0
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

There are no section groups in this file.

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000010000 0x0000000000000000
                 0x0000000000000000 0x0000000000001230  RW     10
  LOAD           0x0000000000000200 0x0000000000020000 0x0000000000000000
                 0x0000000000000c90 0x0000000000000c90  R E    10
  LOAD           0x0000000000001000 0x0000000000030000 0x0000000000000000
                 0x00000000000000b0 0x00000000000000b0  R      10
  LOAD           0x0000000000001200 0x0000000000040000 0x0000000000000000
                 0x0000000000000100 0x0000000000000100  R      8
  LOAD           0x0000000000001400 0x0000000000050000 0x0000000000000000
                 0x00000000000001f8 0x00000000000001f8  R      10
  DYNAMIC        0x0000000000001600 0x0000000080000000 0x0000000000000000
                 0x0000000000000668 0x0000000000000668  R      200

 Section to Segment mapping:
  Segment Sections...
   00     
   01     
   02     
   03     
   04     
   05     

Dynamic section at offset 0x1600 contains 21 entries:
  Tag        Type                         Name/Value
 0x0000000060000019 (VMS_IDENT)          0x12c457f1337f3
 0x0000000060000035 (VMS_LINKTIME)       2012-07-14T19:26:47
 0x000000006000004d (VMS_PLTGOT_SEG)     0x4
 0x000000006000004b (VMS_PLTGOT_OFFSET)  0x200000
 0x000000006000002f (VMS_UNWINDSZ)       0x60
 0x0000000060000031 (VMS_UNWIND_CODSEG)  0x1
 0x0000000060000033 (VMS_UNWIND_INFOSEG) 0x3
 0x000000006000003d (VMS_UNWIND_OFFSET)  0x0
 0x000000006000003f (VMS_UNWIND_SEG)     0x3
 0x000000006000004f (VMS_FPMODE)         0x9800000
 0x0000000060000041 (VMS_STRTAB_OFFSET)  0x150
 0x000000000000000a (STRSZ)              10 (bytes)
 0x000000006000001d (VMS_NEEDED_IDENT)   0x2000100000001
 0x0000000000000001 (NEEDED)             Shared library: [DECC$SHR]
 0x0000000060000025 (VMS_FIXUP_NEEDED)   0x0
 0x0000000060000023 (VMS_FIXUP_RELA_CNT) 0x13
 0x0000000060000049 (VMS_FIXUP_RELA_OFF) 0x160
 0x0000000060000015 (VMS_LNKFLAGS)       0x4a0 IMGSTA MAIN TBK_IN_IMG
 0x000000006000001f (VMS_IMG_RELA_CNT)   0x11
 0x0000000060000045 (VMS_IMG_RELA_OFF)   0x3c0
 0x0000000000000000 (NULL)               0xdead

There are no relocations in this file.

There are no unwind sections in this file.

No version information found in this file.

Notes at offset 0x00002800 with length 0x00000188:
  Owner                 Data size       Description
  IPF/VMS              0x00000005       NT_VMS_IMGNAM (image name)
    Image name: RUDY
  IPF/VMS              0x00000005       NT_VMS_GSTNAM (sym table name)
    Global symbol table name: Rudy
  IPF/VMS              0x00000010       NT_VMS_IMGID (image id)
    Image id: 123456789012345
  IPF/VMS              0x00000020       NT_VMS_IMGBID (build id)
  IPF/VMS              0x00000008       NT_VMS_LINKTIME
   Link time: 2012-07-14T19:26:47
  IPF/VMS              0x0000000e       NT_VMS_LINKID (link id)
    Linker id: Linker I02-38
  IPF/VMS              0x00000025       NT_VMS_ORIG_DYN
   Major id: 1,  minor id: 3
   Manip date  : 2012-07-14T19:26:47
   Link flags  : 0x00000000000004a0
   Header flags: 0x01000014
   Image id    : V1.0
  IPF/VMS              0x00000008       NT_VMS_PATCHTIME
   Patch time: 2012-07-14T19:26:47

If you carefully paid attention to the code, this is just 8 + 8 or 16 + 24 bytes I am concerned with (NT_VMS_IMGID above). So, unless I misunderstood it, your remark was purely theoretical. However to satisfy your past (maybe current) developer mind, I did address your remark in an update of the code. Practically speaking, this should have no influence onto the sake of the produced ELF image compared with previously.

 

Kind regards,

Philippe

Ph Vouters
Valued Contributor

Re: Utility to change "image file identification"?

John,

 

You could only be correct provided the NT_VMS_IMGNAM + NT_VMS_GSTNAM .note subentries are so large that the NT_VMS_IMGID spans over two adjacent disk blocks AND the ELF image is not disk [re]written into a new file.

 

One can comment onto IMGNAM and GSTNAM physical limits on VMS.

Regards,

Philippe

H.Becker
Honored Contributor

Re: Utility to change "image file identification"?

>>> the IA64 VMS Linker aligns the .note section on a disk block boundary

 

This was already mentioned in this thread. Except for the dynstr, which for VMS images is part of the dynamic segment, all sections are on disk block boundary. Can you post an output of analyze./image? I'm curious to see that there are two other sections not starting at a block boundary.  But what do I expect.
 
>>> and the .note length does not exceed a disk block.
 
In your example the length is 0x188, so in the disk block there is space left for 0x78 characters.
In ELF, there are no limits for the size of the note entries, except that the descriptor size here has to fit in 64 bits. If there is a limit for the imgnam, then it is very likely in the linker processing options and/or tparse. An option line has to be longer than 1024, which is the maximum symbol length. I wouldn't expect any specific limit for the NAME= option. Gstnam is derived from a filename. All together it seems possible to fill more than a disk block. Not usual, but possible. And, the linker may change and add some more note entries and/or data to the orig area.
Ph Vouters
Valued Contributor

Re: Utility to change "image file identification"?

Harmut and John,

 

Please do refrein yourself from thinking theoretically. Find me a single non corrupted .EXE which matches your hypothesis. I can't find any which does.

 

$ @notes_section.com
Number of .EXE scanned

Grand total of 455 directories, 4563 files.
$ type notes_section.com
$ create notes_section.gawk
{
  blocksize = 512;
  if (/^Notes at offset /) {

     match($0,/^Notes at offset (.*) with length (.*):/,a);
     if ((strtonum(a[1])%blocksize != 0) || (strtonum(a[2]) > blocksize)) {
#          print "Alert : Note section not aligned on a block boundary or ...";
#          print "Notes section length greater than a block size";
          exit 44
     }
     else {
          exit 0
     }
  }
}
$ write sys$output "Number of .EXE scanned"
$ dire/grand sys$sysdevice:[*...]*.EXE;
$ context = 10
$ set process/priv=bypass
$ loop:
$ file = f$search("sys$sysdevice:[*...]*.EXE;",context)
$ if file .eqs. "" then exit
$ pipe readelf --note 'file' | gawk -f notes_section.gawk
$ if $STATUS .eq. 44
$ then
$     write sys$output "Look at this ''file' file"
$ endif
$ goto loop
$ logout


jreagan
Advisor

Re: Utility to change "image file identification"?

I'll refrain from thinking.  I've done that for years... ask my wife.

 

In an .EXE, there is an upperbound for .note section size.

 

linktime + imgnam + imgid + linkid + imgbid + gstnam + orig_dyn + patchtime

 

That should always be under 512 (I didn't actually add the max values, I did some thinking instead)

 

For .OBJ files, the .note sections can theoreticallly (there's that word again) be much larger than 512.  If the compilers decide to emit source file names, title text, and Pascal's "entity ident consistency check".

Bob Blunt
Respected Contributor

Re: Utility to change "image file identification"?

For non-operating system executable images this idea is ducky.  But, from past experience, munging around with the information in these areas for original .EXE files that are part of OpenVMS or it's layered products is generally what could be called A Bad Thing.  There are several utilities that use the information contained within the executable header of O/S images that depend on the data being exactly what DEC/CPQ/HP sent.

 

Having said that...it is your (or your customer's) system and it can be modified however you wish.  Just please be prepared with a backup of the disk or images if things stop working so you can restore what got clobbered.  It would also be polite to let customer support know if you've made changes of this sort because tools they use will also be effectively neutered.

 

bob

H.Becker
Honored Contributor

Re: Utility to change "image file identification"?

The people in the objects and images team in VMS engineering, who did the IA64 linker, did way too much thinking.
 
They anticipated that manipulated images would cause some problems or confusion for customer support. They thought of two things, an area where the original data was stored including a cell for the manipulation date and a cell for the patch time. SET IMAGE was adjusted to update the manipulation date, whenever it changed the image. The only changes it can make are to the data which are kept in the original data area. And sure, there is a simple command to restore the original image. PATCH/ABSOLUTE was adjusted to update the patch time. That is, with all VMS supplied tools there is a timestamp indicating an image manipulation.
 
But it is true, everybody can write her/his own tool (a program, a DCL script or whatever) and change any data anywhere in an image - without knowing how to or even thinking of leaving any (other) footprint.
H.Becker
Honored Contributor

Re: Utility to change "image file identification"?

>>> Find me a single non corrupted .EXE...

 

It took some time, because I usually don't have access to an Integrity. I let the linker create one for you:

Number  Type                 Name                              File Address     
File Size         Flags

...

    7.  NOTE                 .note                             0000000000001200
0000000000000218  ------------------------------

 

I didn't use readef,  but I'm sure you will see that the size of the note section is 0x218.  As I said, it is possible. And if it is possible, it will show up, sooner or later. That's my experience.

Ph Vouters
Valued Contributor

Re: Utility to change "image file identification"?

Bob,

 

Refer to the NT_VMS_ORIG_DYN .notes subsection of the readelf output I posted.  Although the Image identification is changed, the ORIG_DYN .note subsection still shows V1.0. I haven't checked thoroughly but I do not seem to recollect that analyze/image displays such information.

 

I strongly agree with you : this kind of practice makes software support slightly more complicated and should be best effort avoided. However, when developers do not follow strict Linker's IDENTIFICATION option setting, the code I propose is a mean to address such lack. If I refer to David Lennon original post and need, this addresses the problem he is faced with.

 

Yours sincerely,

Philippe Vouters (ex-HP French support)

Dennis Handly
Acclaimed Contributor

Re: Utility to change "image file identification"?

>In an .EXE, there is an upperbound for .note section size.

>For .OBJ files, the .note sections can theoretically (there's that word again) be much larger than 512.

Gee, you are thinking too small.  ;-)

For HP-UX using the aC++ compiler, the compiler ecom itself has, the HP-UX linker just concatenates the .notes:

41     NOTE 0000000000000000 00000000048d5ba8 000fb590 .note
1,029,520 bytes

jreagan
Advisor

Re: Utility to change "image file identification"?

Currently, none of the .note entries in object files are carried over to the executable.  Such things have been suggested in the past for people asking "what source files or compiler versions were used to create my executable".  The answer has always been "you should have saved the linker .MAP file, it tells you almost all of that".  If that would ever changes, then yes, the executable's .note section would be much larger.  It would take up more disk space, but not make the activation that much slower as the .notes would still be in an ELF section, not an ELF segment.