- If You Use Linux, You Lose Out If You Can’t Do This #3 – Executable files and ways of using shell variables
- What are Linux executable files?
- What is the ELF format?
- Prior to ELF
- ELF format
- Static Links and Dynamic Links
- Features of static links
- Features of dynamic links
- To be continued in the next column
- Which are the Linux Executable Files, and How do We Create Them?
- Any File can be Executed in Linux
- Explaining File Permissions in Linux
- Using chmod to Make a Linux File Executable
- Actually Executing the File
If You Use Linux, You Lose Out If You Can’t Do This #3 – Executable files and ways of using shell variables
In the last column, I shared some nifty ways of using shell variables. In this installment, I’d like to introduce Linux executable files.
What are Linux executable files?
In general, Linux executable files contain programs written in a language like C and compiled so they can run in the Linux environment. In recent years, programs are often compiled in modern languages like Python, Java, Golang, and node.js, and you don’t have to care much about what the executable format is. But many kernels and GNU commands are still written in C, so it is important to know about this basic foundation.
` ` `
$ file /bin/ls
/bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=9567f9a28e66f4d7ec4baf31cfbf68d0410f0ae6, stripped
` ` `
Let’s take a look at items of note here.
Item | Explanation |
—————— | ————————— |
/bin/ls | file command’s target file |
ELF 64bit | Format of the executable file |
LSB | Linux Standard Base-compliant |
shared object | The file uses a shared library. |
x64-64 | 64-bit binary |
version 1 | version1 |
(SYSV) | SysV-compliant |
dynamically linked | Uses dynamically-linked shared libraries |
stripped | Information about symbols are removed from the file. |
Using the command ` ` ` elfread -h /bin/ls ` ` ` here gives useful information.
` ` `
$ readelf -h /bin/ls
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2’s complement, little endian
Version: 1 (current)
OS/ABI: UNIX – System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x5850
Start of program headers: 64 (bytes into file)
Start of section headers: 132000 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 9
Size of section headers: 64 (bytes)
Number of section headers: 28
Section header string table index: 27
` ` `
For more information, read elfread’s documentation with ` ` ` man elfread ` ` ` .
What is the ELF format?
ELF (Executable and Linkable Format) is an executable file format for compiler-generated objects and executable files linked to libraries. ELF format is the successor of UNIX’s first executable file format, a.out, and its extension, the Common Object File Format (COFF). ELF Format is widely used by System VR4 and later UNIX systems and Linux.
Prior to ELF
COFF is a format used on 32-bit System V platforms. It allows the use of shared libraries and debugs information. However, it has shortcomings in its limits on the maximum number of sections and length of section names. It also couldn’t provide symbolic debugging information for languages like C++. However, extensions like XCOFF (AIX) and ECOFF (DEC, SGI) overcame these weaknesses, and there are versions of UNIX using these formats. Window’s PE+ format is also based on COFF.
ELF format
ELF’s feature is its flexible design that allows support for files in non-contiguous memory and when the load memory position and the execution memory position differ.
There are three types of ELF files:
- Relocatable files
- Contain sections with code and data
- Applicable for creating executable files, shared objects, and other relocatable objects.
- Contain executable programs
- Designate the program’s image creation method with exec(2).
- A shared object file Contains code and data to be linked in two contexts:
- The link-editor can process it with other relocatable and shared object files to create other object files.
- The runtime linker combines it with a dynamic executable file and other shared objects to create a process image.
ELF’s object file format is as follows:
Linking View Execution View ———————————— ———————————— ELF header ELF header Program header table (optional) Program header table Section 1 Segment 1 … Segment 2 Section n … .. … Section header table Section header table (optional) - ELF header
- Usually resides at the beginning of the object file. It maintains a roadmap describing the file’s organization.
- Except for the ELF header, there is no specified order for header tables, sections, and segments
- Tells the system how to create a process image.
- Files used to build a process image (execute a program) must have a program header table.
- Relocatable files do not need a program header
- Smallest unit that can be processed within an ELF file
- Holds the bulk of object file information for the linking view (instructions, data, symbol table, and relocation information)
- Smallest individual unit that can be mapped to a memory image by exec(2) or by the runtime linker.
- Every section has an entry in the header table.
- Each entry gives information such as the section name and section size.
- Files that are used in link-editing must have a section header table.
- A section header table is not required in other object files.
Static Links and Dynamic Links
With current versions of Linux, almost all binaries are created by dynamically linking ELF binaries. A dynamic link is a format composed of the executable format and libraries (shared objects). A static link, on the other hand, contains libraries in executable format.
Features of static links
When creating static links, a library in *.a format and compiled objects are linked by the ld command. A library in the *.a format is an archive of objects compiled using the ar command.
A statically-linked binary has the following features:1. Because a file contains multiple libraries, the file size becomes great.
2. You don’t have to be mindful of the libraries’ dependencies.
3. The version of the library used can be locked.
4. You can execute the program just by copying the file.Features of dynamic links
When dynamic links are created, libraries in .so (shared object) format and compiled objects are linked. .so is dynamically read during execution time.
1. Because shared libraries (so) are dynamically linked, the size of the executable file is small.
2. The dependencies of libraries are automatically resolved.
3. Updating the version is possible at the library level.
4. Not only files but also dependent libraries must be copied. Otherwise, the program won’t work.To be continued in the next column
In this installment, I explained the ELF format. In the next column, I’ll explain how ELF is executed and how to handle the ELF format.
Which are the Linux Executable Files, and How do We Create Them?
Everyone knows that there are certain files in Windows that will execute when you just double click them. These are special files that are programs. These typically have the extension “.exe”. Every software on your PC probably has an executable file somewhere that acts as the starting point for the program. Each game, word processor, and even your browser starts up with an exe file. But it’s not just exe files that can execute. There are also “.com” files though these are pretty rare (I haven’t seen one since the DOS days). Batch files of course contain DOS like instructions. And then there are some installers with extensions like “.msi” which initiate installation of programs.
The point is, that executable files in Windows are identified based on their extensions. If you take a regular program exe file and rename it to something else, it won’t execute. But when it comes to Linux, things are very different.
Any File can be Executed in Linux
Unlike Windows, Linux doesn’t have the concept of file extension based executables. Any file can be executable – you just need to have the right permissions. So whether your script has the extension “.sh”, or no extension at all, you can make it executable with a simple command.
I won’t say that either system is better or worse that the other, but the Linux method gives us a bit more flexibility in what we choose to do with a file. But before we see how to make files executable, let’s have a quick look at file permissions.
Explaining File Permissions in Linux
In Linux, we have three different actions that can be taken with a file:
Each type of user can have one, or all of the permissions in the first list. So if we want to make a file executable, we have to ask “Who should be allowed to execute this file”. And if the answer is “anyone or everyone”, then we can simply assign the “x” permission to all three types of users. We do this with the command called “chmod”.
Using chmod to Make a Linux File Executable
chmod is the standard command for making changes to the permissions of files. We first specify which users we’re referencing, and then we use a plus sign (+) or a minus sign (-) to add or take away permissions. For example, let’s say we want a file to be only executable by the owner. We use the following command:
This command specifies that the owner of the file (u), should have execute permissions (x) added to the file (+). On the other hand, if we want everyone to be able to execute the file, we would use the following command instead:
This means that all users (owner, others, and group members) should have the execute permissions added to the existing set of permissions.
Actually Executing the File
If you’re running a DOS prompt in Windows, you will be able to execute an exe file just by specifying the name provided that it’s in the current directory. However, for security reasons this will not work in Linux. You need to specify the complete path to the executable file. If it’s in the current directory, you can accomplish this with the command:
This is to prevent someone from creating duplicates of existing commands (like “ls” for example), and placing it in the current directory. For safety, Linux makes sure that we know exactly what we’re running. Either that, or we explicitly place the program in the system’s $PATH variable.
As you can see, making a file executable is pretty easy in Linux once you know how. All you need to do is know exactly who should execute a particular file and you’re done!