@@ -65,53 +65,6 @@ The run-time lookup uses APIs from `<mach-o/getsect.h>`.
6565
6666### Linux
6767
68- For ELF executables, the resources are added as sections. Unfortunately
69- there is no guaranteed metadata about sections in the ELF format, the
70- section header table (SHT) is optional and can be stripped after linking
71- (` llvm-strip --strip-sections ` ). So while the resources are added as
72- sections, the run-time lookup requires a bespoke implementation, which
73- makes it the most complex and non-standard out of the platforms. There
74- are N+1 sections used for the implementation, where the extra section
75- serves as our own version of the SHT (which can't be stripped). Finding
76- the SHT section at run-time is done via a static pointer in the code
77- which is looked up by its symbol name and has its value updated after
78- the sections are injected.
79-
80- The build-time equivalent is somewhat involved since our version of
81- the SHT has to be manually constructed after adding the sections, and
82- the section updated with the new content. There's also not a standard
83- tool that can change the value of a static variable after linking, so
84- instead the SHT is found by a symbol which is added via
85- ` objcopy --binary-architecture ` . The following instructions show how
86- to embed the binary data at build-time for ELF executables, with the
87- section holding the data name "foobar":
68+ For ELF executables, the resources are added as notes.
8869
89- ``` sh
90- # The binary data should be on disk in a file named foobar - the name
91- # of the file is important as it is used in the added symbols
92- $ objcopy --input binary --output elf64-x86-64 \
93- --binary-architecture i386:x86-64 \
94- --rename-section .data=foobar,CONTENTS,ALLOC,LOAD,READONLY,DATA \
95- foobar foobar.o
96- # Also create an empty section for the SHT
97- $ objcopy --input binary --output elf64-x86-64 \
98- --binary-architecture i386:x86-64 \
99- --rename-section .data=foobar,CONTENTS,ALLOC,LOAD,READONLY,DATA \
100- postject_sht postject_sht.o
101- # Link the created .o files at build-time. Also define
102- # `__POSTJECT_NO_SHT_PTR` so that the run-time code uses the
103- # symbol added by `--binary-architecture` to find the SHT
104- $ clang++ -D__POSTJECT_NO_SHT_PTR test.cpp foobar.o postject_sht.o
105- # Dump the sections with readelf, and grab the virtual address and
106- # size for the "foobar" section
107- $ readelf -S a.out
108- # Manually create the SHT - replace 0xAA with the virtual address
109- # and 0xBB with the size from the readelf output
110- $ python3 -c " import struct; print((struct.pack('<I', 1) + bytes('foobar', 'ascii') + bytes([0]) + struct.pack('<QI', 0xAA, 0xBB)).decode('ascii'), end='');" > postject_sht
111- # Update the SHT section with the correct content
112- $ objcopy --update-section postject_sht=postject_sht a.out
113- ```
114-
115- The run-time lookup finds our version of the SHT through the static
116- pointer, and then parses the contents of our SHT to look for the
117- section with the requested name.
70+ The build-time equivalent is to use a linker script.
0 commit comments