Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my simple `main` program's ELF header say it's a `DYN (Shared object file)` instead of an executable? [duplicate]

Tags:

c++

g++

elf

readelf

Here's a very simple C++ program:

// main.cpp
int main() {}

My Makefile generates the following command to compile the program.

❯ make
g++ -O0 -fverbose-asm  -o main main.cpp

I check with the command file to see it's an ELF executable:

❯ file main
main: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=921d352e49a0e4262aece7e72418290189520782, for GNU/Linux 3.2.0, not stripped

Everything seems fine until I try to inspect the ELF header:

❯ readelf -e main
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
...
  Type:                              DYN (Shared object file)

From wikipedia here, it appears that there are different types of files such as EXEC. Why does it say my simple main program is a shared object and not an executable on the ELF header?

From the limited scope of knowledge I have on .so's, I thought they were libraries that is linked but not loaded until runtime. How does that make sense in this context?

Extra information:

❯ g++ --version
g++ (Arch Linux 9.3.0-1) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.

❯ readelf --version
GNU readelf (GNU Binutils) 2.34
Copyright (C) 2020 Free Software Foundation, Inc.

❯ lsb_release -a
LSB Version:    1.4
Distributor ID: Arch
Description:    Arch Linux
Release:    rolling
Codename:   n/a
like image 709
OneRaynyDay Avatar asked May 02 '20 23:05

OneRaynyDay


People also ask

What is dyn shared object?

A dynamic shared object (DSO) is an object file that is meant to be used simultaneously (or shared) by multiple applications (a. out files) while they are executing.

How do I decode an elf file?

you can use readelf and objdump to read parts of an elf file. You can also use 'hexdump filename' to get a hexdump of the contents of a binary file (this is likely only useful if you like reading machine code or you are writing an assembler).

What is elf file header?

The ELF header defines whether to use 32-bit or 64-bit addresses. The header contains three fields that are affected by this setting and offset other fields that follow them. The ELF header is 52 or 64 bytes long for 32-bit and 64-bit binaries respectively.

How elf file is executed?

An ELF file consists of zero or more segments, and describe how to create a process/memory image for runtime execution. When the kernel sees these segments, it uses them to map them into virtual address space, using the mmap(2) system call. In other words, it converts predefined instructions into a memory image.

What is the difference between elf and program header?

So depending upon the type of object file, the ELF header gives detailed information about the file. Mostly in case of executable files, an ELF header is followed by program header table. A program header table helps in creating process image.

Why can’t I run an elf file?

If your ELF file is a normal binary, it requires these program headers. Otherwise, it simply won’t run. It uses these headers, with the underlying data structure, to form a process. This process is similar for shared libraries.

What is the structure of an elf file?

On a Linux terminal, the command man elf gives you a handy summary about the structure of an ELF file: files. Amongst these files are normal executable files, relocatable object files, core files and shared libraries. followed by a program header table or a section header table, or both. The ELF header is always at offset zero of the file.

What does the ELF header magic mean?

This ELF header magic provides information about the file. The first 4 hexadecimal parts define that this is an ELF file (45= E ,4c= L ,46= F ), prefixed with the 7f value.


1 Answers

Executables that are as compiled as "position independent executables" (with -pie/-fPIE) should be relocated to a random address at runtime. To achieve this, they use the DYN type.

Your version of g++ was configured with --enable-default-pie, so it sets -pie and -fPIE by default. You can disable this, and generate a normal executable, by linking with -no-pie.

like image 157
Mikel Rychliski Avatar answered Oct 28 '22 06:10

Mikel Rychliski