Sujet : Re: C23 thoughts and opinions
De : tr.17687 (at) *nospam* z991.linuxsc.com (Tim Rentsch)
Groupes : comp.lang.cDate : 01. Jun 2024, 13:17:12
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <86frtwq2lz.fsf@linuxsc.com>
References : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
User-Agent : Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
bart <
bc@freeuk.com> writes:
On 01/06/2024 02:25, Scott Lurndal wrote:
>
bart <bc@freeuk.com> writes:
>
Little of this seems to work, sorry. You guys keep saying, do this, do
that, no do it that way, go RTFM, but nobody has shown a complete
program that correctly shows the -size symbol to be giving anything
meaningful.
>
If I run this: [attempt to reproduce example]
>
$ cat /tmp/m.c
#include <stdio.h>
#include <stdint.h>
>
extern uint64_t _binary_main_cpp_size;
extern uint8_t *_binary_main_cpp_start;
extern uint8_t *_binary_main_cpp_end;
>
int main()
{
printf("%p\n", &_binary_main_cpp_size);
printf("%p\n", &_binary_main_cpp_start);
printf("%p\n", &_binary_main_cpp_end);
return 0;
}
$ objcopy -I binary -B i386 -O elf64-x86-64 main.cpp /tmp/test.o
$ cc -o /tmp/m /tmp/m.c /tmp/test.o
$ /tmp/m
0x30e2
0x601034
0x604116
$ nm /tmp/m | grep _binary_main
0000000000604116 D _binary_main_cpp_end
00000000000030e2 A _binary_main_cpp_size
0000000000601034 D _binary_main_cpp_start
$ wc -c main.cpp
12514 main.cpp
$ printf 0x%x\n 12514
0x30e2
>
The size symbol requires no space in the resulting
executable memory image, and it's more convenient than
having to do the math (at run time, since the compiler
can't know the actual values).
>
Here's my transcript:
>
-------------------------------------
C:\c>copy hello.c main.cpp # create main.cpp, here it's 70 bytes
1 file(s) copied.
>
C:\c>type m.c # exact same code as yours
#include <stdio.h>
#include <stdint.h>
>
extern uint64_t _binary_main_cpp_size;
extern uint8_t *_binary_main_cpp_start;
extern uint8_t *_binary_main_cpp_end;
>
int main()
{
printf("%p\n", &_binary_main_cpp_size);
printf("%p\n", &_binary_main_cpp_start);
printf("%p\n", &_binary_main_cpp_end);
return 0;
}
>
C:\c>objcopy -I binary -O elf64-x86-64 main.cpp test.o # make test.o
>
C:\c>gcc m.c test.o -o m.exe # build m executable
>
C:\c>m # run m.exe
00007ff5d5480046 # and the size is ...
00007ff715492010
00007ff715492056
[similar results under WSL]
For what it's worth I see the same behavior running on linux.
It looks like the culprit is gcc, which apparently relocates
the symbol even though it is marked with an A type. After
running around in circles for a goodly amount of time, it
occurred to me to try compiling using clang, and that worked.
I suppose it's good to know about the &_binary_main_cpp_size
trick, but it's kind of the worst of both worlds: the size
is baked into the executable (or half-baked I might say), but
the value can't be used at compile time. Bleah. If I wanted
to use the objcopy method of inserting raw text into a C
program, I would either do a run-time subtraction to find out
what the size is, or simply add an extra step to the makefile
to extract the size out of the 'nm' output and produce a .h
file with a (named) value that could be used at compile time.
And both of these methods work under gcc as well as clang.