A string table stores names as zero-terminated byte sequences. Symbol and section records refer to those names by byte offset rather than storing a separate pointer or fixed-width name in every entry.
The beginning of .strtab for the reference object is:
Byte offset String 0 "" 1 ".strtab" 9 ".symtab" 17 "target" 24 "my_data" 32 "slot" 37 ".relamy_data"
Each next offset includes the preceding string's terminating zero. For example, target occupies seven bytes including its terminator, so the following name begins at offset twenty-four.
ivss uses Elf_AddUniqueString() to reuse a name already present and append it otherwise. Elf_Sym.st_name and section-header sh_name values select entries from this shared storage.
The human-readable string dump numbers strings by ordinal position; those printed numbers are not their byte offsets. Thus target can appear as string number three while its symbol record contains st_name = 17. Distinguishing these indices avoids interpreting the name field as a symbol number or memory address.
Source: elf.c.