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

Reply via email to