Why have two symbol tables if
.symtab already contains everything that's in
The short answer is that the
.dynsym table is used by the dynamic linker (also referred to as the runtime loader or RTLD) at program load time to determine which DLLs to map into the address space of the program being loaded into memory. As a result, the
.dynsym section is mapped to a loadable segment (specifically, the
text segment) and therefore included in the runtime process image in virtual memory when the kernel loads the program segments. As a reflection of this, the Sys V ABI actually requires the dynamic linking array to contain a dynamic symbol hash table, a string table for symbols and library names, and the dynamic symbol table.
On the other hand, the
.symtab section is not needed for process creation, is not mapped to a loadable segment and therefore is not loaded into memory when the program is executed, and so can be removed, along with section information.
Dynamic linking and its requirements are discussed in much greater detail in the following articles:
Here the author set about creating the smallest possible dynamically-linked ELF binary, which contains only that which is required for the program to successfully load and execute.
The process of dynamic linking and its requirements are discussed in order to explain how it is possible for code inserted into a code cave to make calls to library functions.
Process creation via cooperation between the kernel and dynamic linker is explored using r2 and binaries that have had all section information removed via
For more information, see chapter 5 of the Sys V ABI - "Program Loading and Dynamic Linking", as well as the LWN article How programs get run: ELF binaries .