ELF Program Header Names |
Ali Bahrami Wednesday January 10, 2018
The generic ELF format does not assign names to program headers. We've changed that with Solaris 11.4. This article describes how and why.
So much of ELF revolves around naming, particularly for sections and symbols. Today, noting that nearly everything else in an ELF object is explicitly named, and in particular, that sections have names, it seems like an odd oversight that program headers are nameless. However, when ELF was invented, it was always true that each object had only 2 mappings (text, data), and there were very few objects in a process (a.out, libc). As such, a given process had very few mappings, and experienced developers could easily tell them apart based on address, and access mode. In today's world with many mappings per object, many objects, and advanced virtual memory abilities, the lack of names creates an observability gap, where the human reader is required to apply educated guesswork to understand what a process is doing.
We're used to this, and generally don't notice, but last year, while puzzling over some mysterious (to me) pmap output, I realized how easy it would be to do better. That realization led to a project to add program header names to Solaris ELF objects, and to modify libproc, elfdump, elfedit, pmap, pmadvise, and mdb's ::mappings dcmd to use them. The ability to associate a mapping with its segment name takes some of the educated guesswork out of examining the mappings in a process, yielding clear and basic observability benefits. This additional information comes at very little cost: An additional 32-bit word per program header, and the addition of the name strings to the existing .dynstr string table. The overall effect of these changes is to add program header names to Solaris ELF objects, to make that added information available in the output of the utilities that examine mappings, and then to improve the display from those utilities such that the added information does not increase output line lengths unreasonably.
As OS developers, we're used to picking out the text and data segments, and the others, based on the permission flags and order, but sometimes, it isn't so obvious, and we have to take educated guesses. For instance, the output above might raise the following questions.% pmap `pgrep zonestatd` 268: /usr/lib/zones/zonestatd 00000008F1C2E000 388K rw----- [ heap ] 00007FF5B39FF000 4K rw--R-- [ stack tid=5 ] 00007FF5B3BFE000 4K rw--R-- [ stack tid=4 ] 00007FF5B3C00000 28K r-x---- /lib/amd64/libcontract.so.1 00007FF5B3D07000 4K rw----- /lib/amd64/libcontract.so.1 00007FF5B3FEE000 4K rw--R-- [ stack tid=3 ] 00007FF5B3FF0000 64K rw----- [ anon ] 00007FF5B41FE000 4K rw--R-- [ stack tid=2 ] 00007FF5B4200000 68K r-x---- /lib/amd64/libuutil.so.1 00007FF5B4311000 4K rw----- /lib/amd64/libuutil.so.1 00007FF5B4400000 340K r-x---- /lib/amd64/libscf.so.1 00007FF5B4555000 8K rw----- /lib/amd64/libscf.so.1 00007FF5B4557000 4K rw----- /lib/amd64/libscf.so.1 00007FF5B4600000 2048K r-x---- /lib/amd64/libc.so.1 00007FF5B4800000 616K r-x---- /lib/amd64/libc.so.1 00007FF5B499A000 80K rw----- /lib/amd64/libc.so.1 00007FF5B49AE000 40K rw----- /lib/amd64/libc.so.1 00007FF5B4A00000 144K r-x---- /lib/amd64/libumem.so.1 00007FF5B4B24000 32K rw----- /lib/amd64/libumem.so.1 00007FF5B4B2C000 40K rw----- /lib/amd64/libumem.so.1 00007FF5B4C00000 344K r-x---- /lib/amd64/ld.so.1 00007FF5B4D56000 4K r------ /lib/amd64/ld.so.1 00007FF5B4E57000 16K rwx---- /lib/amd64/ld.so.1 00007FF5B4E5B000 8K rwx---- /lib/amd64/ld.so.1 00007FF5B5000000 88K r-x---- /usr/lib/zones/zonestatd 00007FF5B5116000 4K rw----- /usr/lib/zones/zonestatd 00007FF5B51AC000 64K rw----- [ anon ] 00007FF5B51BD000 128K rw----- [ anon ] 00007FF5B51DE000 4K rw-s--- [ anon ] 00007FF5B51E0000 24K rw----- [ anon ] 00007FF5B51E9000 4K r-x---- [ anon ] 00007FF5B51ED000 64K rw----- [ anon ] 00007FF5B51FE000 12K r--s--- [ anon ] 00007FF5B5202000 4K r--s--- [ anon ] 00007FF5B5204000 4K r--s--- [ anon ] FFFF80E85A4C5000 12K rw----- [ stack ] total 4708K
00007FF5B4C00000 344K r-x---- /lib/amd64/ld.so.1 00007FF5B4D56000 4K r------ /lib/amd64/ld.so.1 00007FF5B4E57000 16K rwx---- /lib/amd64/ld.so.1 00007FF5B4E5B000 8K rwx---- /lib/amd64/ld.so.1
00007FF5B4A00000 144K r-x---- /lib/amd64/libumem.so.1 00007FF5B4B24000 32K rw----- /lib/amd64/libumem.so.1 00007FF5B4B2C000 40K rw----- /lib/amd64/libumem.so.1
It is interesting to note that the segments that come from ELF program headers start out with names. These names are assigned by the link-editor (ld) when the object is created. The segments automatically created by ld have names like 'text' and 'data', reflecting their purpose. When you create a segment or a memory reservation with a mapfile, the mapfile syntax requires you to supply a unique name by which they can be referenced. Segment names are used by the link-editor, but traditionally, when the ELF object is written, the segment name information is discarded, leaving the unnamed program headers described above.
Starting with Solaris 11.4, we preserve the segment names within ELF objects that have program headers (executables, shared objects).
To take advantage of this new information, related changes were made to other parts of the system:
The end result of these changes is that tools like pmap can now display segment names for all mappings. The example above becomes:
And the answers to our previous questions are a bit easier to answer:% pmap `pgrep zonestatd` 314: /usr/lib/zones/zonestatd 000000042CC35000 384K rw----- [ heap ] 00007FF6E7FFF000 4K rw--R-- [ stack tid=5 ] 00007FF6E81FE000 4K rw--R-- [ stack tid=4 ] 00007FF6E8200000 28K r-x---- [ text ] /lib/amd64/libcontract.so.1 00007FF6E8307000 4K rw----- [ data ] /lib/amd64/libcontract.so.1 00007FF6E85EE000 4K rw--R-- [ stack tid=3 ] 00007FF6E85F0000 64K rw----- [ anon ] 00007FF6E87FE000 4K rw--R-- [ stack tid=2 ] 00007FF6E8800000 68K r-x---- [ text ] /lib/amd64/libuutil.so.1 00007FF6E8911000 4K rw----- [ data ] /lib/amd64/libuutil.so.1 00007FF6E8A00000 340K r-x---- [ text ] /lib/amd64/libscf.so.1 00007FF6E8B55000 8K rw----- [ data ] /lib/amd64/libscf.so.1 00007FF6E8B57000 4K rw----- [ data ] /lib/amd64/libscf.so.1 00007FF6E8C00000 2048K r-x---- [ text ] /lib/amd64/libc.so.1 00007FF6E8E00000 616K r-x---- [ text ] /lib/amd64/libc.so.1 00007FF6E8F9A000 80K rw----- [ data ] /lib/amd64/libc.so.1 00007FF6E8FAE000 40K rw----- [ data ] /lib/amd64/libc.so.1 00007FF6E9000000 144K r-x---- [ text ] /lib/amd64/libumem.so.1 00007FF6E9124000 32K rw----- [ data ] /lib/amd64/libumem.so.1 00007FF6E912C000 40K rw----- [ data ] /lib/amd64/libumem.so.1 00007FF6E9200000 344K r-x---- [ text ] /lib/amd64/ld.so.1 00007FF6E9356000 4K r------ [ dtrace ] /lib/amd64/ld.so.1 00007FF6E9457000 16K rwx---- [ data ] /lib/amd64/ld.so.1 00007FF6E945B000 8K rwx---- [ data ] /lib/amd64/ld.so.1 00007FF6E9600000 92K r-x---- [ text ] /usr/lib/zones/zonestatd 00007FF6E9717000 4K rw----- [ data ] /usr/lib/zones/zonestatd 00007FF6E977E000 64K rw----- [ anon ] 00007FF6E978F000 128K rw----- [ anon ] 00007FF6E97B0000 24K rw----- [ anon ] 00007FF6E97BC000 4K rw-s--- [ anon ] 00007FF6E97BE000 4K r-x---- [ anon ] 00007FF6E97C2000 64K rw----- [ anon ] 00007FF6E97D3000 12K r--s--- [ anon ] 00007FF6E97D7000 4K r--s--- [ anon ] 00007FF6E97D9000 4K r--s--- [ anon ] FFFF80CCF0817000 16K rw----- [ stack ]
When displaying program headers for older objects that lack name information, and for unnamed program headers in new object (those that do not directly create mappings), no name is shown. In this case, the output is unchanged relative to what was shown in the past.
Here, we examine hello world, and see that the PT_LOAD segments have been given the names 'text' and 'data':
% cc hello.c % elfdump -pNLOAD a.out Program Header[3]: text p_vaddr: 0x8050000 p_flags: [ PF_X PF_R ] p_paddr: 0 p_type: [ PT_LOAD ] p_filesz: 0xb03 p_memsz: 0xb03 p_offset: 0 p_align: 0x10000 Program Header[4]: data p_vaddr: 0x8060b04 p_flags: [ PF_X PF_W PF_R ] p_paddr: 0 p_type: [ PT_LOAD ] p_filesz: 0x1d0 p_memsz: 0x1d0 p_offset: 0xb04 p_align: 0x10000
The changes to pmap output are:
% pmap $$ 19147: -bash ... 0000000000639000 40K rw----- /usr/bin/bash 0000000DADD07000 408K rw----- [ heap ] ...
In the past, when named and unnamed segments were commonly intermingled, this provided a visually helpful contrast between the two cases. Going forward however, nearly all segments will have segment names, and this extra indentation serves no purpose, and adds unnecessary whitespace. As such, it was removed, allowing all of the final column content to line up.
The changes can be easily seen in a comparison of old and new output. The following is from an older version of Solaris. Note the wasteful use of whitespace, and that segments are not named:
And here is the same output, produced by a current version of Solaris:% pmap -x $$ 19147: -bash Address Kbytes RSS Anon Locked Mode Mapped File 0000000000400000 1212 1120 - - r-x---- bash 000000000062F000 40 40 8 - rw----- bash 0000000000639000 40 28 12 - rw----- bash 0000000DADD07000 408 404 40 - rw----- [ heap ] 00007FF44EE00000 32 32 - - r-x---- libgen.so.1 00007FF44EF08000 4 4 - - rw----- libgen.so.1 00007FF44F000000 420 260 - - r-x---- libncurses.so.5.7 00007FF44F169000 20 20 - - rw----- libncurses.so.5.7 00007FF44F200000 2664 2664 - - r-x---- libc.so.1 00007FF44F59A000 80 80 8 - rw----- libc.so.1 00007FF44F5AE000 40 24 - - rw----- libc.so.1 00007FF44F600000 344 344 - - r-x---- ld.so.1 00007FF44F756000 4 4 - - r------ ld.so.1 00007FF44F857000 16 16 4 - rwx---- ld.so.1 00007FF44F85B000 8 8 4 - rwx---- ld.so.1 00007FF44F8B0000 64 16 - - rw----- [ anon ] 00007FF44F8D0000 64 64 - - rw----- [ anon ] 00007FF44F8F0000 24 12 4 - rw----- [ anon ] 00007FF44F8FE000 4 4 - - rw-s--- [ anon ] 00007FF44F900000 64 48 24 - rw----- [ anon ] 00007FF44F911000 12 12 - - r--s--- [ anon ] 00007FF44F915000 4 4 - - r--s--- [ anon ] 00007FF44F917000 4 4 - - r--s--- [ anon ] 00007FF44F919000 4 4 - - r-x---- [ anon ] FFFF80F932605000 28 28 8 - rw----- [ stack ] ---------------- ---------- ---------- ---------- ---------- total Kb 5604 5244 112 -
In addition to the changes described above, the existing pmap support for displaying PT_SUNW_RESERVE, PT_SUNW_SYSTAT, and PT_SUNW_SYSSTAT segments has been improved to show their specific types (rather than anon), as well as their mapfile assigned names. As an example, we apply the following mapfile to hello world:1611: -bash Address Kbytes RSS Anon Lock Mode Mapped File 0000000000400000 1212 1112 - - r-x---- [ text ] bash 000000000062F000 40 40 8 - rw----- [ data ] bash 0000000000639000 40 28 12 - rw----- [ data ] bash 0000000E6CC2C000 432 428 44 - rw----- [ heap ] 00007FD15E400000 32 32 - - r-x---- [ text ] libgen.so.1 00007FD15E508000 4 4 - - rw----- [ data ] libgen.so.1 00007FD15E600000 460 312 - - r-x---- [ text ] libncursesw.so.5.9 00007FD15E773000 20 20 - - rw----- [ data ] libncursesw.so.5.9 00007FD15E800000 2660 2660 - - r-x---- [ text ] libc.so.1 00007FD15EB99000 80 80 8 - rw----- [ data ] libc.so.1 00007FD15EBAD000 40 24 - - rw----- [ data ] libc.so.1 00007FD15EC00000 348 348 - - r-x---- [ text ] ld.so.1 00007FD15ED57000 4 4 - - r------ [ dtrace ] ld.so.1 00007FD15EE58000 20 20 4 - rwx---- [ data ] ld.so.1 00007FD15EE5D000 4 4 4 - rwx---- [ data ] ld.so.1 00007FD15EF60000 64 16 - - rw----- [ anon ] 00007FD15EF80000 64 64 - - rw----- [ anon ] 00007FD15EF9E000 4 4 - - rw-s--- [ anon ] 00007FD15EFA0000 24 20 4 - rw----- [ anon ] 00007FD15EFA9000 64 52 28 - rw----- [ anon ] 00007FD15EFBA000 12 12 - - r--s--- [ anon ] 00007FD15EFBE000 4 4 - - r--s--- [ anon ] 00007FD15EFC0000 4 4 - - r--s--- [ anon ] 00007FD15EFC2000 4 4 - - r-x---- [ anon ] 00007FDE270D3000 24 24 - - rw----- [ stack ] 00007FDE270D9000 4 4 4 - rw----- [ stack ] ---------------- ------ ---- ---- ---- total Kb 5668 5324 116 -
Prior to these changes, pmap would show the following output for this program:% cat mapfile $mapfile_version 2 RESERVE_SEGMENT locus { VADDR = 0x9000000; SIZE = 0x10000; }; RESERVE_SEGMENT my_sysstat { TYPE = sysstat; VADDR = 0xa000000; SIZE = 0x100; }; RESERVE_SEGMENT my_sysstat_zone { TYPE = sysstat_zone; VADDR = 0xb000000; SIZE = 0x100; };
With these changes:% pmap -x 13652 13652: a.out Address Kbytes RSS Anon Locked Mode Mapped File 0000000000400000 4 4 - - r-x---- a.out 0000000000500000 8 8 - - rw----- a.out 0000000009000000 64 - - - ------- [ reserved ] 000000000A000000 4 4 - - r--s--- [ anon ] 000000000B000000 4 4 - - r--s--- [ anon ] FFFF80FFBF400000 344 344 - - r-x---- ld.so.1 FFFF80FFBF556000 4 4 - - r------ ld.so.1 FFFF80FFBF657000 16 16 4 - rwx---- ld.so.1 FFFF80FFBF65B000 8 - - - rwx---- ld.so.1 FFFF80FFBF7F5000 12 12 - - r--s--- [ anon ] FFFF80FFBF7F9000 4 4 - - r--s--- [ anon ] FFFF80FFBF7FB000 4 4 - - r--s--- [ anon ] FFFF80FFBF7FD000 4 4 - - r-x---- [ anon ] FFFF80FFBFFFE000 8 8 8 - rw----- [ stack ] ---------------- ---------- ---------- ---------- ---------- total Kb 488 416 12 -
As shown above, the pmap -x and -S options automatically display the basename of the file that backs memory mappings, rather than the full file paths. When these options are not used, pmap displays full path names. The -b option has been added to allow basenames to be shown in these other modes as well. Often, the filename is all that is needed, and full paths create unnecessary clutter. This option was put to good use in the examples for the revised pmap manpage itself, where its use allowed the examples to fit in the allowed space without the need for artificial edits.% pmap -x 24305 24305: a.out Address Kbytes RSS Anon Lock Mode Mapped File 08050000 4 4 - - r-x---- [ text ] a.out 08060000 4 4 - - rwx---- [ data ] a.out 09000000 64 - - - ------- [ reserved name=locus ] 0A000000 4 4 - - r--s--- [ sysstat name=my_sysstat ] 0B000000 4 4 - - r--s--- [ sysstat_zone name=my_sysstat_zone ] FE790000 236 236 - - r-x---- [ text ] ld.so.1 FE7DB000 4 4 - - r------ [ dtrace ] ld.so.1 FE7EC000 12 12 4 - rwx---- [ data ] ld.so.1 FE7EF000 4 - - - rwx---- [ data ] ld.so.1 FE7F4000 12 12 - - r--s--- [ anon ] FE7F8000 4 4 - - r--s--- [ anon ] FE7FA000 4 4 - - r--s--- [ anon ] FE7FC000 4 4 - - r-x---- [ anon ] FEFFE000 4 4 4 - rw----- [ stack ] -------- ------ --- ---- ---- total Kb 364 296 8 -
Here is an example of normal pmap output:
And here is the same example, with the addition of -b:% pmap $$ | egrep 'bash|\.so' 1378: -bash 0000000000400000 1212K r-x---- /usr/bin/bash 000000000062F000 40K rw----- /usr/bin/bash 0000000000639000 40K rw----- /usr/bin/bash 00007FFFBC800000 32K r-x---- [ text ] /lib/amd64/libgen.so.1 00007FFFBC908000 4K rw----- [ data ] /lib/amd64/libgen.so.1 00007FFFBCA00000 420K r-x---- [ text ] /usr/lib/amd64/libncurses.so.5.7 00007FFFBCB69000 20K rw----- [ data ] /usr/lib/amd64/libncurses.so.5.7 00007FFFBCC00000 2048K r-x---- [ text ] /lib/amd64/libc.so.1 00007FFFBCE00000 616K r-x---- [ text ] /lib/amd64/libc.so.1 00007FFFBCF9A000 80K rw----- [ data ] /lib/amd64/libc.so.1 00007FFFBCFAE000 40K rw----- [ data ] /lib/amd64/libc.so.1 00007FFFBD000000 344K r-x---- [ text ] /lib/amd64/ld.so.1 00007FFFBD156000 4K r------ [ dtrace ] /lib/amd64/ld.so.1 00007FFFBD257000 16K rwx---- [ data ] /lib/amd64/ld.so.1 00007FFFBD25B000 8K rwx---- [ data ] /lib/amd64/ld.so.1
% pmap -b $$ | egrep 'bash|\.so' 1378: -bash 0000000000400000 1212K r-x---- bash 000000000062F000 40K rw----- bash 0000000000639000 40K rw----- bash 00007FFFBC800000 32K r-x---- [ text ] libgen.so.1 00007FFFBC908000 4K rw----- [ data ] libgen.so.1 00007FFFBCA00000 420K r-x---- [ text ] libncurses.so.5.7 00007FFFBCB69000 20K rw----- [ data ] libncurses.so.5.7 00007FFFBCC00000 2048K r-x---- [ text ] libc.so.1 00007FFFBCE00000 616K r-x---- [ text ] libc.so.1 00007FFFBCF9A000 80K rw----- [ data ] libc.so.1 00007FFFBCFAE000 40K rw----- [ data ] libc.so.1 00007FFFBD000000 344K r-x---- [ text ] ld.so.1 00007FFFBD156000 4K r------ [ dtrace ] ld.so.1 00007FFFBD257000 16K rwx---- [ data ] ld.so.1 00007FFFBD25B000 8K rwx---- [ data ] ld.so.1
becomes% pmadvise -o heap=access_lwp,stack=access_default -v $$ 19147: -bash 0000000000400000 1212K r-x---- /usr/bin/bash 000000000062F000 40K rw----- /usr/bin/bash 0000000000639000 40K rw----- /usr/bin/bash 0000000DADD07000 408K rw----- [ heap ] <= access_lwp 00007FF44EE00000 32K r-x---- /lib/amd64/libgen.so.1 00007FF44EF08000 4K rw----- /lib/amd64/libgen.so.1 00007FF44F000000 420K r-x---- /usr/lib/amd64/libncurses.so.5.7 00007FF44F169000 20K rw----- /usr/lib/amd64/libncurses.so.5.7 00007FF44F200000 2048K r-x---- /lib/amd64/libc.so.1 00007FF44F400000 616K r-x---- /lib/amd64/libc.so.1 00007FF44F59A000 80K rw----- /lib/amd64/libc.so.1 00007FF44F5AE000 40K rw----- /lib/amd64/libc.so.1 00007FF44F600000 344K r-x---- /lib/amd64/ld.so.1 00007FF44F756000 4K r------ /lib/amd64/ld.so.1 00007FF44F857000 16K rwx---- /lib/amd64/ld.so.1 00007FF44F85B000 8K rwx---- /lib/amd64/ld.so.1 00007FF44F8B0000 64K rw----- [ anon ] 00007FF44F8D0000 64K rw----- [ anon ] 00007FF44F8F0000 24K rw----- [ anon ] 00007FF44F8FE000 4K rw-s--- [ anon ] 00007FF44F900000 64K rw----- [ anon ] 00007FF44F911000 12K r--s--- [ anon ] 00007FF44F915000 4K r--s--- [ anon ] 00007FF44F917000 4K r--s--- [ anon ] 00007FF44F919000 4K r-x---- [ anon ] FFFF80F932605000 28K rw----- [ stack ] <= access_default
% pmadvise -o heap=access_lwp,stack=access_default -v $$ 23477: -bash 0000000000400000 1212K r-x---- [ text ] /usr/bin/bash 000000000062F000 40K rw----- [ data ] /usr/bin/bash 0000000000639000 40K rw----- [ data ] /usr/bin/bash 0000000E3A310000 432K rw----- [ heap ] <= access_lwp 00007FF131600000 32K r-x---- [ text ] /lib/amd64/libgen.so.1 00007FF131708000 4K rw----- [ data ] /lib/amd64/libgen.so.1 00007FF131800000 420K r-x---- [ text ] /usr/lib/amd64/libncurses.so.5.7 00007FF131969000 20K rw----- [ data ] /usr/lib/amd64/libncurses.so.5.7 00007FF131A00000 2048K r-x---- [ text ] /lib/amd64/libc.so.1 00007FF131C00000 616K r-x---- [ text ] /lib/amd64/libc.so.1 00007FF131D9A000 80K rw----- [ data ] /lib/amd64/libc.so.1 00007FF131DAE000 40K rw----- [ data ] /lib/amd64/libc.so.1 00007FF131E00000 344K r-x---- [ text ] /lib/amd64/ld.so.1 00007FF131F56000 4K r------ [ dtrace ] /lib/amd64/ld.so.1 00007FF132057000 16K rwx---- [ data ] /lib/amd64/ld.so.1 00007FF13205B000 8K rwx---- [ data ] /lib/amd64/ld.so.1 00007FF132070000 64K rw----- [ anon ] 00007FF132090000 64K rw----- [ anon ] 00007FF1320AE000 4K rw-s--- [ anon ] 00007FF1320B0000 24K rw----- [ anon ] 00007FF1320B7000 64K rw----- [ anon ] 00007FF1320C8000 12K r--s--- [ anon ] 00007FF1320CC000 4K r--s--- [ anon ] 00007FF1320CE000 4K r--s--- [ anon ] 00007FF1320D0000 4K r-x---- [ anon ] FFFF80EC736D0000 32K rw----- [ stack ] <= access_default
The following ::mappings output is from an older system:
With the modifications described in this case, the same command produces the following:% mdb a.out a.out> main::bp a.out> ::run mdb: stop at main mdb: target stopped at: main: pushq %rbp a.out:13622*> ::mappings BASE LIMIT SIZE NAME 400000 401000 1000 /tmp/a.out 500000 502000 2000 /tmp/a.out 9000000 9010000 10000 [ reserved ] a000000 a001000 1000 [ anon ] b000000 b001000 1000 [ anon ] ffff80ffbee00000 ffff80ffbf000000 200000 /lib/amd64/libc.so.1 ffff80ffbf000000 ffff80ffbf09a000 9a000 /lib/amd64/libc.so.1 ffff80ffbf19a000 ffff80ffbf1ae000 14000 /lib/amd64/libc.so.1 ffff80ffbf1ae000 ffff80ffbf1b8000 a000 /lib/amd64/libc.so.1 ffff80ffbf400000 ffff80ffbf456000 56000 /lib/amd64/ld.so.1 ffff80ffbf556000 ffff80ffbf557000 1000 /lib/amd64/ld.so.1 ffff80ffbf657000 ffff80ffbf65b000 4000 /lib/amd64/ld.so.1 ffff80ffbf65b000 ffff80ffbf65d000 2000 /lib/amd64/ld.so.1 ffff80ffbf7d0000 ffff80ffbf7d6000 6000 [ anon ] ffff80ffbf7e4000 ffff80ffbf7f4000 10000 [ anon ] ffff80ffbf7f5000 ffff80ffbf7f8000 3000 [ anon ] ffff80ffbf7f9000 ffff80ffbf7fa000 1000 [ anon ] ffff80ffbf7fb000 ffff80ffbf7fc000 1000 [ anon ] ffff80ffbf7fd000 ffff80ffbf7fe000 1000 [ anon ] ffff80ffbfffc000 ffff80ffc0000000 4000 [ stack ]
The -b (basename) option can be used to remove extraneous path details:a.out:1493*> ::mappings BASE LIMIT SIZE NAME 400000 401000 1000 [ text ] /tmp/a.out 500000 502000 2000 [ data ] /tmp/a.out 9000000 9010000 10000 [ reserved name=locus ] a000000 a001000 1000 [ sysstat name=my_sysstat ] b000000 b001000 1000 [ sysstat_zone name=my_sysstat_zone ] ffff80ffbf000000 ffff80ffbf200000 200000 [ text ] /lib/amd64/libc.so.1 ffff80ffbf200000 ffff80ffbf29a000 9a000 [ text ] /lib/amd64/libc.so.1 ffff80ffbf39a000 ffff80ffbf3ae000 14000 [ data ] /lib/amd64/libc.so.1 ffff80ffbf3ae000 ffff80ffbf3b8000 a000 [ anon ] ffff80ffbf400000 ffff80ffbf456000 56000 [ text ] /lib/amd64/ld.so.1 ffff80ffbf556000 ffff80ffbf557000 1000 [ dtrace ] /lib/amd64/ld.so.1 ffff80ffbf657000 ffff80ffbf65b000 4000 [ data ] /lib/amd64/ld.so.1 ffff80ffbf65b000 ffff80ffbf65d000 2000 [ anon ] ffff80ffbf7d0000 ffff80ffbf7d6000 6000 [ anon ] ffff80ffbf7e4000 ffff80ffbf7f4000 10000 [ anon ] ffff80ffbf7f5000 ffff80ffbf7f8000 3000 [ anon ] ffff80ffbf7f9000 ffff80ffbf7fa000 1000 [ anon ] ffff80ffbf7fb000 ffff80ffbf7fc000 1000 [ anon ] ffff80ffbf7fd000 ffff80ffbf7fe000 1000 [ anon ] ffff80ffbfffd000 ffff80ffc0000000 3000 [ stack ]
The -s option can be used to prevent the segment name information from being added at all:a.out:1493*> ::mappings -b BASE LIMIT SIZE NAME 400000 401000 1000 [ text ] a.out 500000 502000 2000 [ data ] a.out 9000000 9010000 10000 [ reserved name=locus ] a000000 a001000 1000 [ sysstat name=my_sysstat ] b000000 b001000 1000 [ sysstat_zone name=my_sysstat_zone ] ffff80ffbf000000 ffff80ffbf200000 200000 [ text ] libc.so.1 ffff80ffbf200000 ffff80ffbf29a000 9a000 [ text ] libc.so.1 ffff80ffbf39a000 ffff80ffbf3ae000 14000 [ data ] libc.so.1 ffff80ffbf3ae000 ffff80ffbf3b8000 a000 [ anon ] ffff80ffbf400000 ffff80ffbf456000 56000 [ text ] ld.so.1 ffff80ffbf556000 ffff80ffbf557000 1000 [ dtrace ] ld.so.1 ffff80ffbf657000 ffff80ffbf65b000 4000 [ data ] ld.so.1 ffff80ffbf65b000 ffff80ffbf65d000 2000 [ anon ] ffff80ffbf7d0000 ffff80ffbf7d6000 6000 [ anon ] ffff80ffbf7e4000 ffff80ffbf7f4000 10000 [ anon ] ffff80ffbf7f5000 ffff80ffbf7f8000 3000 [ anon ] ffff80ffbf7f9000 ffff80ffbf7fa000 1000 [ anon ] ffff80ffbf7fb000 ffff80ffbf7fc000 1000 [ anon ] ffff80ffbf7fd000 ffff80ffbf7fe000 1000 [ anon ] ffff80ffbfffd000 ffff80ffc0000000 3000 [ stack ]
a.out:1493*> ::mappings -bs BASE LIMIT SIZE NAME 400000 401000 1000 a.out 500000 502000 2000 a.out 9000000 9010000 10000 [ reserved ] a000000 a001000 1000 [ sysstat ] b000000 b001000 1000 [ sysstat_zone ] ffff80ffbf000000 ffff80ffbf200000 200000 libc.so.1 ffff80ffbf200000 ffff80ffbf29a000 9a000 libc.so.1 ffff80ffbf39a000 ffff80ffbf3ae000 14000 libc.so.1 ffff80ffbf3ae000 ffff80ffbf3b8000 a000 [ anon ] ffff80ffbf400000 ffff80ffbf456000 56000 ld.so.1 ffff80ffbf556000 ffff80ffbf557000 1000 ld.so.1 ffff80ffbf657000 ffff80ffbf65b000 4000 ld.so.1 ffff80ffbf65b000 ffff80ffbf65d000 2000 [ anon ] ffff80ffbf7d0000 ffff80ffbf7d6000 6000 [ anon ] ffff80ffbf7e4000 ffff80ffbf7f4000 10000 [ anon ] ffff80ffbf7f5000 ffff80ffbf7f8000 3000 [ anon ] ffff80ffbf7f9000 ffff80ffbf7fa000 1000 [ anon ] ffff80ffbf7fb000 ffff80ffbf7fc000 1000 [ anon ] ffff80ffbf7fd000 ffff80ffbf7fe000 1000 [ anon ] ffff80ffbfffd000 ffff80ffc0000000 3000 [ stack ]
[35] How To Strip An ELF Object | [37] Core File Enhancements for elfdump |