ELF sections are a development-time concept that does not exist at runtime when loading an ELF file such as an executable or shared library.
What you're doing with the vDSO is equivalent to what this C++ program does on its main executable:
#include <elf.h>
#include <link.h>
#include <inttypes.h>
#include <stdio.h>
extern "C" ElfW(Ehdr) __ehdr_start;
int main(void) {
printf("shoff %#" PRIx64 ", shnum %#" PRIu16 "\n",
__ehdr_start.e_shoff, __ehdr_start.e_shnum);
const ElfW(Shdr)* shdrs = reinterpret_cast<const ElfW(Shdr)*>(
reinterpret_cast<const char*>(&__ehdr_start) + __ehdr_start.e_shoff);
for (unsigned int i = 0; i < __ehdr_start.e_shnum; ++i) {
printf("[%u] sh_type = %#x\n", i, shdrs[i].sh_type);
}
}
If you build that e.g. on Linux with `g++ -g -o foo foo.cc` and run `./foo` you'll see that e_shoff and e_shnum are set (consistent with that `readelf -WS foo` shows you).
However, the `sh_type` values it prints out don't match up with the actual sections in the file `foo`.
That's because the section table is not part of the runtime image, even though the ELF file header that points to it is.
If you look at `readelf -Wl foo` you'll see the program headers, and specifically the LOAD segments. That shows the regions of the file on disk that actually map to the runtime image. The rest of the file, such as the section table and the debugging information, are part of the file but not part of the runtime image. If you want to look at the section table or the debugging information, you need to look at the file `foo`, not the runtime memory of a process running `foo`.
In the case of the vDSO, there is no original file that you see anywhere on disk in the running system. You can see the runtime memory image in your memory, but that's all you get. If you want to look at the vDSO's development-time details like its debugging information, you can find the original file in the Fuchsia build (easiest way is by build ID lookup) but it will never exist anywhere as a file on a Fuchsia device.