Support for linking and loading at different places:
authorSteve Chamberlain <sac@cygnus>
Tue, 30 Mar 1993 22:45:39 +0000 (22:45 +0000)
committerSteve Chamberlain <sac@cygnus>
Tue, 30 Mar 1993 22:45:39 +0000 (22:45 +0000)
* ldlex.l: Add "AT" keyword.
* ldgram.y: Cleanup, and parse AT.
* ldlang.c (print_output_section_statement): Print output address
of section in map. (lang_size_sections): Fill sections' lma with
load address.
* ldlang.h (lang_output_section_statement_type): Add load_base
information.

ld/ChangeLog
ld/ldgram.y
ld/ldlang.c
ld/ldlex.l

index 0812c0b..6ce807f 100644 (file)
@@ -1,5 +1,15 @@
 Tue Mar 30 09:40:25 1993  Steve Chamberlain  (sac@thepub.cygnus.com)
 
+       Support for linking and loading at different places:
+
+       * ldlex.l: Add "AT" keyword.
+       * ldgram.y: Cleanup, and parse AT.
+       * ldlang.c (print_output_section_statement): Print output address
+       of section in map. (lang_size_sections): Fill sections' lma with
+       load address.
+       * ldlang.h (lang_output_section_statement_type): Add load_base
+       information.
+
        * ldindr.c (add_indirect): Keep more information in the alias
        symbol chain.
        * ldlang.c (wild_doit):  Don't inherit NEVER_LOAD section
index eb9000a..e106b5f 100644 (file)
@@ -54,11 +54,11 @@ lang_memory_region_type *region;
 
 lang_memory_region_type *lang_memory_region_lookup();
 lang_output_section_statement_type *lang_output_section_statement_lookup();
-
+etree_type *lang_atin();
 #ifdef __STDC__
 
 void lang_add_data(int type, union etree_union *exp);
-void lang_enter_output_section_statement(char *output_section_statement_name, etree_type *address_exp, int flags, bfd_vma block_value,etree_type*,etree_type*);
+void lang_enter_output_section_statement(char *output_section_statement_name, etree_type *address_exp, int flags, bfd_vma block_value,etree_type*,etree_type*, etree_type*);
 
 #else
 
@@ -103,7 +103,7 @@ struct sec *section;
   
 }
 
-%type <etree> exp  opt_exp_with_type  mustbe_exp
+%type <etree> exp  opt_exp_with_type  mustbe_exp opt_at
 %type <integer> fill_opt
 %type <name> memspec_opt
 %token <integer> INT  
@@ -138,6 +138,7 @@ struct sec *section;
 %token NOLOAD DSECT COPY INFO OVERLAY
 %token NAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY 
 %token OPTION_e OPTION_c OPTION_noinhibit_exec OPTION_s OPTION_S OPTION_sort_common
+%token OPTION_EB OPTION_EL
 %token OPTION_format  OPTION_F OPTION_u OPTION_Bstatic OPTION_N
 %token <integer> SIZEOF NEXT ADDR 
 %token OPTION_d OPTION_dc OPTION_dp OPTION_x OPTION_X OPTION_defsym
@@ -149,7 +150,7 @@ struct sec *section;
 %token OPTION_Ur 
 %token ORIGIN FILL OPTION_g
 %token LENGTH    CREATE_OBJECT_SYMBOLS INPUT OUTPUT  CONSTRUCTORS
-%token OPTION_RETAIN_SYMBOLS_FILE ALIGNMOD
+%token OPTION_RETAIN_SYMBOLS_FILE ALIGNMOD AT
 
 %type <token> assign_op 
 
@@ -196,10 +197,10 @@ command_line_option:
                write_map = true;
                config.map_filename = $2;
                }
-       |       OPTION_M {
-           config.map_filename = "-";
-                           
-                       }
+       |       OPTION_M 
+               {
+                 config.map_filename = "-";
+               }
        |       OPTION_n {
                        config.magic_demand_paged = false;
                        }
@@ -335,6 +336,18 @@ command_line_option:
                        }
        |       OPTION_RETAIN_SYMBOLS_FILE filename
                { lang_add_keepsyms_file ($2); }
+       |       OPTION_EB
+               {
+                 /* FIXME: This is currently ignored.  It means
+                    ``produce a big-endian object file''.  It could
+                    be used to select an output format.  */
+               }
+       |       OPTION_EL
+               {
+                 /* FIXME: This is currently ignored.  It means
+                    ``produce a little-endian object file''.  It could
+                    be used to select an output format.  */
+               }
        | '-' NAME
                 { info("%P%F Unrecognized option -%s\n", $2);  }
 
@@ -528,35 +541,38 @@ input_section_spec:
        ;
 
 statement:
-               statement assignment end
-       |       statement CREATE_OBJECT_SYMBOLS
+               assignment end
+       |       CREATE_OBJECT_SYMBOLS
                {
-               
-lang_add_attribute(lang_object_symbols_statement_enum); }
-        |      statement ';'
-        |      statement CONSTRUCTORS
+               lang_add_attribute(lang_object_symbols_statement_enum); 
+               }
+        |      ';'
+        |      CONSTRUCTORS
                {
                
-lang_add_attribute(lang_constructors_statement_enum); }
-
-       |       statement input_section_spec
-        | statement length '(' exp ')'
+                 lang_add_attribute(lang_constructors_statement_enum); 
+               }
+       | input_section_spec
+        | length '(' exp ')'
                        {
-                       lang_add_data($2,$4);
+                       lang_add_data($1,$3);
                        }
   
-       |       statement FILL '(' exp ')'
+       | FILL '(' exp ')'
                        {
                          lang_add_fill
-                           (exp_get_value_int($4,
+                           (exp_get_value_int($3,
                                               0,
                                               "fill value",
-                                       
-lang_first_phase_enum));
+                                              lang_first_phase_enum));
                        }
-       |
        ;
 
+statement_list:
+               statement_list statement
+       |       statement
+       ;
+  
 length:
                LONG
                        { $$ = $1; }
@@ -773,19 +789,23 @@ exp       :
        ;
 
 
-
+opt_at:
+               AT '(' exp ')' { $$ = $3; }
+       |       { $$ = 0; }
+       ;
 
 section:       NAME            { ldlex_expression(); }
-               opt_exp_with_type       { ldlex_popstate(); }
+               opt_exp_with_type 
+               opt_at          { ldlex_popstate(); }
                '{'
-               {
-               lang_enter_output_section_statement($1,$3,typebits,0,0,0);
-               }
-              statement        
+                       {
+                       lang_enter_output_section_statement($1,$3,typebits,0,0,0,$4);
+                       }
+               statement_list  
                '}' {ldlex_expression();} fill_opt memspec_opt
                {
                  ldlex_popstate();
-                 lang_leave_output_section_statement($10, $11);
+                 lang_leave_output_section_statement($11, $12);
                }
 opt_comma
 
@@ -802,9 +822,10 @@ type:
 
 
 opt_exp_with_type:
-               exp ':' { $$ = $1; typebits =0;}
-       |       exp '(' type ')' ':' { $$ = $1; }
-       |       ':'     { $$= (etree_type *)NULL; typebits = 0}
+               exp ':'                 { $$ = $1; typebits =0;}
+       |       exp '(' type ')' ':'    { $$ = $1; }
+       |       ':'                     { $$= (etree_type *)NULL; typebits = 0; }
+       |       '(' type ')' ':'        { $$= (etree_type *)NULL;  }
        ;
 
 memspec_opt:
index 588660b..151fe58 100644 (file)
@@ -95,6 +95,10 @@ extern ld_config_type config;
 extern boolean had_script;
 extern boolean write_map;
 
+
+etree_type *base; /* Relocation base - or null */
+
+
 #ifdef __STDC__
 #define cat(a,b) a##b
 #else
@@ -1091,6 +1095,12 @@ DEFUN (print_output_section_statement, (output_section_statement),
     fprintf (config.map_file, "No attached output section");
   }
   print_nl ();
+  if (output_section_statement->load_base)
+    {
+      int b = exp_get_value_int(output_section_statement->load_base,
+                               0, "output base", lang_final_phase_enum);
+      printf("Output address   %08x\n", b);
+    }
   if (output_section_statement->section_alignment >= 0
       || output_section_statement->section_alignment >= 0) 
   {
@@ -1583,6 +1593,11 @@ DEFUN (lang_size_sections, (s, output_section_statement, prev, fill,
 
         dot = align_power (dot, os->bfd_section->alignment_power);
         bfd_set_section_vma (0, os->bfd_section, dot);
+        
+        if (os->load_base) {
+          os->bfd_section->lma 
+            = exp_get_value_int(os->load_base, 0,"load base", lang_final_phase_enum);
+        }
        }
 
 
@@ -1609,18 +1624,18 @@ DEFUN (lang_size_sections, (s, output_section_statement, prev, fill,
        {
         os->region->current = dot;
         /* Make sure this isn't silly */
-        if (os->region->current >
-            os->region->origin +
-            os->region->length)
-        {
-          einfo ("%X%P: Region %s is full (%B section %s)\n",
-                 os->region->name,
-                 os->bfd_section->owner,
-                 os->bfd_section->name);
-          /* Reset the region pointer */
-          os->region->current = 0;
+        if (( os->region->current
+              > os->region->origin + os->region->length)
+            || ( os->region->origin > os->region->current ))
+          {
+            einfo ("%X%P: Region %s is full (%B section %s)\n",
+                   os->region->name,
+                   os->bfd_section->owner,
+                   os->bfd_section->name);
+            /* Reset the region pointer */
+            os->region->current = 0;
 
-        }
+          }
 
        }
      }
@@ -2319,13 +2334,14 @@ DEFUN (lang_enter_output_section_statement,
        address_exp,
        flags,
        block_value, 
-       align, subalign),
+       align, subalign, base),
        char *output_section_statement_name AND
        etree_type * address_exp AND
        int flags AND
        bfd_vma block_value AND
        etree_type *align AND
-       etree_type *subalign)
+       etree_type *subalign AND
+       etree_type *base)
 {
   lang_output_section_statement_type *os;
 
@@ -2361,8 +2377,11 @@ DEFUN (lang_enter_output_section_statement,
   os->section_alignment = topower(
    exp_get_value_int(align, -1,
                     "section alignment", 0));
+
+  os->load_base = base;
 }
 
+
 void
 DEFUN_VOID (lang_final)
 {
@@ -2765,3 +2784,4 @@ DEFUN (lang_add_output_format, (format),
 {
   output_target = format;
 }
+
index d43cf49..98ea160 100644 (file)
@@ -184,6 +184,12 @@ NOCFILENAMECHAR    [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
 
 <COMMAND>"-retain-symbols-file"        { return OPTION_RETAIN_SYMBOLS_FILE; }
 
+<COMMAND>"-EB"                         {
+                                return OPTION_EB;
+                              }
+<COMMAND>"-EL"                         {
+                                return OPTION_EL;
+                              }
 <MRI,EXPRESSION>"$"([0-9A-Fa-f])+ {
                                yylval.integer = strtoul(yytext+1, 0,16);
                                return INT;
@@ -208,7 +214,7 @@ NOCFILENAMECHAR     [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
                                   yylval.integer = strtoul(yytext+1, 0, base); 
                                   return INT;
                                 }
-<DEFSYMEXP,MRI,BOTH,EXPRESSION>"$"?"0x"?([0-9A-Fa-f])+(M|K|m|k)? {
+<SCRIPT,DEFSYMEXP,MRI,BOTH,EXPRESSION>"$"?"0x"?([0-9A-Fa-f])+(M|K|m|k)? {
                                  yylval.integer = strtoul(yytext,0,hex_mode);
                                  if (yytext[yyleng-1]=='M'
                                        || yytext[yyleng-1] == 'm') {
@@ -305,6 +311,7 @@ NOCFILENAMECHAR     [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
 <BOTH,SCRIPT>"l"                       { RTOKEN( LENGTH);}
 <BOTH,SCRIPT>"len"                     { RTOKEN( LENGTH);}
 <BOTH,SCRIPT>"INCLUDE"                 { RTOKEN(INCLUDE);}
+<EXPRESSION,BOTH,SCRIPT>"AT"                   { RTOKEN(AT);}
 <MRI>"\n"                      { ++ lineno;  RTOKEN(NEWLINE); }
 <MRI>"*".*                     { /* Mri comment line */ }
 <MRI>"END"                      { RTOKEN(ENDWORD); }
@@ -383,6 +390,7 @@ NOCFILENAMECHAR     [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
   }
   else 
   {
+    BEGIN(SCRIPT);
     ldfile_input_filename = file_name_stack[include_stack_ptr-1];
   }