To get a basic understanding of the ELF format, I'm writing a basic program to generate a valid elf file from the most basic assembly output. I'm going step-by-step so I'll probably ask a few questions here as I make my way through it. I've generated the first 16-bytes of the header and verified that it's the same from a gcc-compiled program on my machine (nothing special, since those first 16-bytes are almost always the same). Here is what I have so far (using python):
# https://refspecs.linuxfoundation.org/elf/elf.pdf b = bytearray() # (1) magic header b.append(0x7F) # starting number b.extend([ord('E'), ord('L'), ord('F')]) # (2) ei-class ('capacity') -- 1 for 32-bit, 2 for 64-bit # uname -m # x86_64 BITS_32 = 1 BITS_64 = 2 b.append(BITS_64) # (3) ei-data ('data-encoding') -- 1 for little-endian (standard), 2 for big-endian LITTLE_ENDIAN = 1 BIG_ENDIAN = 2 b.append(LITTLE_ENDIAN) # (4) ei-version -- always will be 1 -- EV_CURRENT = 1 b.append(EV_CURRENT) # (5) ei-pad -- padding --> pad 0's up to 16 bytes b.extend([0,] * (16-len(b))) print('%s\nLength: %s' % (b, len(b)))
And I get:
bytearray(b'\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00') Length: 16
I have a few questions about this:
- What is the most common way to get whether a machine is
64bits? Is doing
uname -mor one of the
unamevariants the suggested way?
- How do you determine if the machine is little- or big-endian?