Hi all, As discussed below, Attached is a patch, that allows customizing the linker emulation scripts with device specific parameters. I request you all to review it and give your suggestions/proposals :). Summary of the changes :
1. We put the device specifc configuration files under <install>/avr/lib/defs. 2. Make gcc driver pass --part option to collect2 from mmcu. %{mmcu=*:--part=%*}" 3. From avrelf.em cache the value of --part option from the handle_options hook. 4. Inside after_parse, find the path of defs and append the device name (which gives complete path of the defs file). 5. Add the file to the list of bfd's using lang_add_input_file(...) api. Some observations. * The name --part is because -mmcu when directly passed to collect2 is ambiguous with -m option. * the /defs directly is not detected by the linker, even when put under the lib directory (I misunderstood from the previous conversations that this will be an implicit behavior) * when adding the defs file with the -l option, then the order in which the original linker file is included matters, as it raises unresolved symbol errors. Thanks, Soundararajan ________________________________________ From: avr-gcc-list-bounces+sounderarajan.d=atmel....@nongnu.org [avr-gcc-list-bounces+sounderarajan.d=atmel....@nongnu.org] on behalf of Erik Christiansen [dva...@internode.on.net] Sent: Tuesday, October 22, 2013 2:49 PM To: avr-gcc-list@nongnu.org; Georg-Johann Lay Subject: Re: [avr-gcc-list] Device specific linker scripts On 20.10.13 21:36, Georg-Johann Lay wrote: > Erik Christiansen schrieb: > >On 19.10.13 19:48, Georg-Johann Lay wrote: > >>If such linker scripts shall become the default linker scripts then you need > >>200+ emulations to support the 200+ devices. > > > >One way to follow Johann's good advice might be to just use: > > > > .boot : > > { > > *(.boot_vectors) > > *(.boot) > > } > text > > > >and have gcc set --section-start=.boot=0x12345 > >That should suffice for now. > > > >And yes, 4 x 205 = 820 full linker scripts is about what would happen if > >we were, for example, to proliferate what I sometimes do for the > >Atmega64: > > > >MEMORY > >{ > > text (rx) : ORIGIN = 0, LENGTH = 62K > > boot (rx) : ORIGIN = 62K, LENGTH = 2K > > data (rw!x) : ORIGIN = 0x800100, LENGTH = 4K > > eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 2K > >} > > > >SECTIONS > >{ > >... > > } > text > > > > .boot : > > { > > *(.boot_vectors) > > *(.boot) > > } > boot > > > > .data : AT (ADDR (.text) + SIZEOF (.text)) > > { > > > >That satisfied my strong preference for documenting the memory layout in > >the linker script. (Having all that information in one place can save > >time when coming back to an old project.) > > > Wouldn't this cause problems if no bootloader is present and .text overlaps > empty bootloader section? Well, avr-ld would protest if the text region limit of 62k were exceeded, even if the boot section were removed. I.e. The primary error would be memory region overflow, even if a section overlap didn't follow. (Perhaps that's what you meant, I guess.) The custom linker script (negative) example explicitly amplified your warning of emulation proliferation, using a method which is fine for one-off. Your description of the generalisation issue is quite accurate. Soundararajan is doubtless already oriented toward the preceding positive example, or something similar. The rest of my post looked at a possible way to avoid having to hack avr-gcc to embed linker-related stuff, as is needed in the positive example, since such indirection unnecessarily amplifies the amount of work to be done for each new mcu. ... > Still avr-gcc has to be extended to accept -mmcu=atmega12345, so that file > has to be touched anyway. Well, only if avr-gcc internally requires extension of compiler functionality for the new mcu. The goal of the proposal is to avoid the inefficiency of changing avr-gcc when only link-time changes are necessary. I.e. it is sub-optimal to have to hack avr-gcc to emit --section-start=... for every mcu, old and new, when it can be just dropped into a text file, for avr-ld to use directly. Furthermore, any future linker address customisations for an mcu are just dropped into the same mcu def file, without resort to _any_ coding, macro extension, or fiddling with avr-gcc to drive avr-ld. There seems to be enough work for the available developers for any potential effort reduction to be worth a look. And thank you, Johann, for taking the trouble to discuss - it helps to keep the list from being too moribund. Erik -- Tecoma's struggle reported on BBC: http://www.bbc.co.uk/news/business-24364204 Tecoma's Macca's-striking flash mob: " http://www.youtube.com/watch?v=H7-0T1vbnWE Stop fat food joint opposite Tecoma preschool: www.change.org Taking democracy (98,000 signatures) from Australia to Chicago: http://www.abc.net.au/news/2013-09-17/tecoma-residents-take-fight-against-mcdonalds-to-chicago/4963866 _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
diff --git ld/emultempl/avrelf.em ld/emultempl/avrelf.em index 90894a1..5f064b2 100644 --- ld/emultempl/avrelf.em +++ ld/emultempl/avrelf.em @@ -29,6 +29,8 @@ fragment <<EOF #include "elf32-avr.h" #include "ldctor.h" +#include "libiberty.h" +#include "ldmain.h" /* The fake file and it's corresponding section meant to hold the linker stubs if needed. */ @@ -44,6 +46,7 @@ static bfd_boolean avr_debug_relax = FALSE; static bfd_boolean avr_debug_stubs = FALSE; static bfd_boolean avr_replace_call_ret_sequences = TRUE; static bfd_vma avr_pc_wrap_around = 0x10000000; +static char* device_name = NULL; /* Transfers information to the bfd frontend. */ @@ -176,6 +179,40 @@ avr_elf_before_parse (void) gld${EMULATION_NAME}_before_parse (); } + +static void +add_device_specific_linker_configuration_to_bfd(void) +{ + /* If the device name is not passed, then it could be that the linker is invoked with a emulation name, so skip adding the device specific file. But the variables in the original linker script should be handled properly in that case. */ + if(!device_name) + return; + + /* We are going to assume that the defs file will be in <avr-ld path>/../avr/lib/defs */ + /* first step is to get the parent directory of avr-ld */ + char* binpath = make_relative_prefix(program_name,".","."); + + /*Allocate a string to construct a full path */ + char *defs_path = malloc (strlen(binpath) + strlen("../lib/defs/") + strlen(device_name)); + + /* Now construct the path */ + strcpy(defs_path, binpath); + strcat(defs_path, "../lib/defs/"); /* Check if this path actually exists and if it doesn't then warn/error/ what ? + strcat(defs_path,device_name); + + /* free allocated variables. Note that we also free the global variable device_name, which is used only here. */ + free(binpath); + free(device_name); + + /* Now add the file as a input to the list of bfd's that will be processed */ + lang_add_input_file(defs_path , lang_input_file_is_file_enum, NULL); +} + +static void +avr_elf_after_parse (void) +{ + add_device_specific_linker_configuration_to_bfd(); +} + EOF @@ -186,6 +223,8 @@ PARSE_AND_LIST_PROLOGUE=' #define OPTION_NO_STUBS 303 #define OPTION_DEBUG_STUBS 304 #define OPTION_DEBUG_RELAX 305 +#define OPTION_MCU_PARAMETER 306 + ' PARSE_AND_LIST_LONGOPTS=' @@ -199,6 +238,8 @@ PARSE_AND_LIST_LONGOPTS=' NULL, OPTION_DEBUG_STUBS}, { "debug-relax", no_argument, NULL, OPTION_DEBUG_RELAX}, + { "part", required_argument, + NULL, OPTION_MCU_PARAMETER}, ' PARSE_AND_LIST_OPTIONS=' @@ -228,6 +269,8 @@ PARSE_AND_LIST_OPTIONS=' "Used for debugging avr-ld.\n")); fprintf (file, _(" --debug-relax " "Used for debugging avr-ld.\n")); + fprintf (file, _(" --part " + "The mcu parameter as passed from the compiler. This should be explicitly mentioned when invoking the linker separately.\n")); ' PARSE_AND_LIST_ARGS_CASES=' @@ -266,6 +309,17 @@ PARSE_AND_LIST_ARGS_CASES=' avr_replace_call_ret_sequences = FALSE; } break; + case OPTION_MCU_PARAMETER: + { + /* cache the name of the device here. Then use it in after_parse, where we try to construct the path to the device specific linker configuration file. + */ + if(optarg) + { + /* cache optarg */ + device_name=malloc(strlen(optarg)); + strcpy(device_name,optarg); + } + } ' # @@ -275,3 +329,4 @@ LDEMUL_BEFORE_PARSE=avr_elf_before_parse LDEMUL_BEFORE_ALLOCATION=avr_elf_${EMULATION_NAME}_before_allocation LDEMUL_AFTER_ALLOCATION=avr_elf_after_allocation LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=avr_elf_create_output_section_statements +LDEMUL_AFTER_PARSE=avr_elf_after_parse
_______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-gcc-list