Reputation: 95
Sorry if this might be off-topic.
In the process of generating .hex(Intel HEX format) files using avr-gcc or avr-ld the output(final result) is significantly different. As an minimal clarification I am talking about the step of generating ELF file just after generating the Object files.
On my first attempt, I used avr-ld
to generate my ELF file. Process works smoothly but after generating HEX files and uploading to my board it did nothing (as in uploading an blank HEX file).
On my second try, I followed the advice found here:
It is important to specify the MCU type when linking. The compiler uses the -mmcu option to choose start-up files and run-time libraries that get linked together. If this option isn't specified, the compiler defaults to the 8515 processor environment, which is most certainly what you didn't want.
It did as I expected. Uploaded the HEX file and my board updated accordingly.
So my questions are as follows:
avr-ld
) lose information about the micro-controller I am using. I thought that the MCU information is stored in the Object files.avr-gcc
for compilation/generating .o files, avr-ld
to link the .o files and generate the EFL files, and avr-objcopy
to strip only usefull information and changing the format of the file ELF -> HEX)?avr-ld
as when using avr-gcc
for generating my ELF file?Upvotes: 2
Views: 1151
Reputation: 3993
- Why did the linker (avr-ld) lose information about the micro-controller I am using. I thought that the MCU information is stored in the Object files.
The linker doesn't lose that information, it was never supplied in the first place. Object files resp. ELF headers are on level of "emulation", i.e. granularity like -mmcu=arch
where arch
is one of avr2
, avr25
, avrxmega2
, avrtiny
etc.
- using
avr-gcc
for compilation/generating .o files,avr-ld
to link the .o files and generate the ELF files, andavr-objcopy
to strip only usefull information and changing the format of the file ELF → HEX?
avr-gcc
is not a compiler, it's just a driver program that calls other programs like compiler proper cc1
or cc1plus
, assembler as
, linker ld
depending on file type and options provided. The driver will add options to these programs which greatly simplifies their usage, many of which are described in specs-attiny25
(since v5 onwards).
As an example, take a simple main.c
with a main function returning 0, and process it with
avr-gcc main.c -o main.elf -mmcu=attiny25 -save-temps -v -Wl,-v
The -v
makes the driver show the commands it is issuing, and -save-temps
stores intermediate files like assembly. For avr-gcc v8.5, the link process starts with a call of collect2
:
.../bin/../libexec/gcc/avr/8.5.0/collect2 -plugin .../bin/../libexec/gcc/avr/8.5.0/liblto_plugin.so -plugin-opt=.../bin/../libexec/gcc/avr/8.5.0/lto-wrapper -plugin-opt=-fresolution=main.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lm -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lattiny25 -mavr25 -o main.elf .../bin/../lib/gcc/avr/8.5.0/../../../../avr/lib/avr25/tiny-stack/crtattiny25.o -L.../bin/../lib/gcc/avr/8.5.0/avr25/tiny-stack -L.../bin/../lib/gcc/avr/8.5.0/../../../../avr/lib/avr25/tiny-stack -L.../bin/../lib/gcc/avr/8.5.0 -L.../bin/../lib/gcc -L.../bin/../lib/gcc/avr/8.5.0/../../../../avr/lib main.o -v --start-group -lgcc -lm -lc -lattiny25 --end-group
where ...
stands for the absolute path where the tools are installed. As you can see, the driver adds some salt, for example it links against startup code crtattiny25.o
, standard libs like libc.a
, libm.a
, libgcc.a
. collect2
gathers some extra information needed to build startup code, and then calls back the compiler1 and finally ld
.
The options provided to ld
look very much like the ones provided to collect2
. The only device-specific stuff is: startup code crtattiny25.o
and device lib libattiny25.a
. Many other device-specific stuff has already been compiled into the code, like SFR addresses, #ifdef __AVR_ATtiny25__
etc.
- Is any way in achieving the same output using
avr-ld
as when usingavr-gcc
for generating my ELF file?
You could provide all that options by hand. Though in almost all cases, you want to link using avr-gcc
so that all these gory options are correct and complete.
1Calling back the compiler is needed for LTO (link-time optimization) as of -flto
. The linker calls a plugin which calls the compiler with LTO byte-code, compiles it to assemblwith the LTO-compiler lto1
, then as
, then ld
. Newer versions of the tool are always using linker plugin when without lto compilation; one can -fno-use-linker-plugin
which makes the call chain and options somewhat simpler.
Upvotes: 1