NetBSD Documentation: Vendor-specific ELF Note Elements


Introduction

Various operating system vendors are shipping ELF binaries and those binaries expect different system call interfaces. In order to help operating systems correctly determine whether or not they can run an ELF program, and how to run it (e.g. what OS emulation to use), some operating system vendors have begun marking their ELF binaries with vendor-specific note elements, and placing those notes in the binaries' PT_NOTE sections.

This page is meant to be a repository of knowledge about vendor-specific note elements used in binaries PT_NOTE sections for operating system identification.

If your operating system uses vendor-specific note elements to mark its binaries and is not listed here, please send mail to NetBSD documentation list with information about those notes.

Format of an ELF Note Element

All ELF Note elements have the same basic structure:

Name Size
4 bytes (integer)
Desc Size
4 bytes (integer)
Type
4 bytes (usually interpreted as an integer)
Name
variable size, padded to a 4 byte boundary
Desc
variable size, padded to a 4 byte boundary

The "Name Size" and "Desc Size" fields are integers (in the byte order specified by the binary's ELF header) which specify the size of the "Name" and "Desc" fields (excluding padding).

The "Name" field specifies the vendor who defined the format of the Note. Typically, vendors use names which are related to their project and/or company names. For instance, the GNU Project uses "GNU" as its name. No two vendors should use the same ELF Note Name, lest there be confusion when trying to interpret the meanings of notes.

The "Type" field is vendor specific, but it is usually treated as an integer which identifies the type of the note.

The "Desc" field is vendor specific, and usually contains data which depends on the note type.

Known ELF Note Names

The following are the strings known to be used as ELF Note Names, along with the organizations that use them. Names with lengths that are not a multiples of 4 are padded in the note, but only the given length should be checked.

Note Name String Byte encoding of string Length Organization
"NetBSD\0" 0x4e 0x65 0x74 0x42 0x53 0x44 0x00 7 The NetBSD Project
"PaX\0" 0x50 0x61 0x58 0x00 4 specific to The NetBSD Project ?
"GNU\0" 0x47 0x4e 0x55 0x00 4 The GNU Project

Vendor-specific ELF Notes

This section contains information about the formats of ELF notes which vendors use in their PT_NOTE sections, and is split up by vendor.

The NetBSD Project

There are four vendor-specific ELF Notes for NetBSD and the PaX note also included in this list, as currently it is not know wether it is used with other operating systems as well.

The OS Version note is used to indicate what OS Version native binaries were built with, and can be used to identify native binaries.

The format is:

Name Size
7
Desc Size
4
Type
4-byte integer containing the value 0x01
Name
"NetBSD\0" (padded to 8 bytes)
Desc
4-byte integer containing the NetBSD OS version constant

The Emulation Name note is used to mark binaries (both native an non-native) with a name that indicates which set of binary emulation code is to be used when they are run.

The format is:

Name Size
7
Desc Size
variable
Type
4-byte integer containing the value 0x02
Name
"NetBSD\0" (padded to 8 bytes)
Desc
NUL-terminated string naming the emulation to be used to run the binary (padded to the next 4-byte boundary)

The PaX note encodes execution protection and addrss space layout randomization flags.

The format is:

Name Size
4
Desc Size
4
Type
4-byte integer containing the value 0x03
Name
"PaX\0"
Desc
4-byte bitmask with the following bits:
Bit Meaning
0x01 Force enable Mprotect
0x02 Force disable Mprotect
0x04 Force enable Segvguard
0x08 Force disable Segvguard
0x10 Force enable ASLR
0x20 Force disable ASLR

The Architecture Note encodes machine architecture details.

The format is:

Name Size
7
Desc Size
variable
Type
4-byte integer containing the value 0x05
Name
"NetBSD\0" (padded to 8 bytes)
Desc
A string describing the architecture the binary was compiled for (for example used on ARM to distinguish hardware floating point ABI and softfloat)

The Code Model Note encodes code model details.

The format is:

Name Size
7
Desc Size
variable
Type
4-byte integer containing the value 0x06
Name
"NetBSD\0" (padded to 8 bytes)
Desc
A string describing the code model the binary was compiled for. Used for example on sparc64 to tell binaries compiled with -mcmodel=medlow apart from standard (-mcmodel=medmid) ones, because the former are not eligible for top-down virtual memory layout.

The GNU Project

Starting with glibc 2.1, the GNU project will be using a single ELF Note to indicate which GNU operating system and which version of that system a binary was built for. The format of that note is:

Name Size
4
Desc Size
16
Type
4-byte integer containing the value 0x01
Name
"GNU\0"
Desc
Four 4-byte integers containing, in order:
  1. OS (0 = Linux, 1 = Hurd, 2 = Solaris)
  2. Major
  3. Minor
  4. Teeny
The major, minor and teeny versions are that of the earliest OS version that supports this ABI.

For more documentation on the GNU C Library's use of ELF notes, consult the sources: abi-tags and csu/abi-note.S.

Creating ELF PT_NOTE Sections

If you're using the GNU binutils 2.8 or greater to create your binaries, you can generate PT_NOTE sections in your final object files. To create a PT_NOTE section, create a section in one of your object files (for systems which generate PT_NOTE entries by default, this is typically the runtime startup code) with a name starting with ".note" and having the "allocate" property set. Put properly formed ELF Notes entries in that section. When final linking is done, all sections which have names starting with ".note" and which are marked "allocate" will be put into PT_NOTE sections in the final object file.

An example of GNU assembler input which will create a PT_NOTE section during final link is:

    .section ".note.ident", "a"
    .p2align 2
    .long 1f - 0f           # name size (not including padding)
    .long 3f - 2f           # desc size (not including padding)
    .long 0x01234567        # type
0:  .asciz "NaMe"	    # name
1:  .p2align 2
2:  .long 0x76543210        # desc
    .long 0x89abcdef
3:  .p2align 2

That example will create a section called ".note.ident", marked "allocate" (so that it will be turned into a PT_NOTE section during final link), which contains a single note. That note has a type of 0x012345678, has the name "NaMe\0", and has a desc value consisting of two 4-byte integers, 0x76543210 and 0x89abcdef.

Creating a NetBSD ELF PT_NOTE Section

The NetBSD kernel will return ENOEXEC if an ELF binary does not contain a recognized PT_NOTE section. Normally, crtbegin.c contains this section for native NetBSD applications. The example below creates such a section on NetBSD/sparc. (Other ports may use slightly different assembler syntax, for example arm uses %note - since @ starts a comment, but, except for endian variations, they all use the same bits.)

        .section ".note.netbsd.ident", "", @note
        .long   2f-1f
        .long   4f-3f
        .long   1
1:      .asciz "NetBSD"
2:      .p2align 2
3:      .long   499003600
4:      .p2align 2