]> Git Repo - binutils.git/blob - gas/config/obj-elf.c
e122d37b46e65355f16d66fbf8cad5435af12dcd
[binutils.git] / gas / config / obj-elf.c
1 /* ELF object file format
2    Copyright (C) 1992, 1993 Free Software Foundation, Inc.
3
4    This file is part of GAS, the GNU Assembler.
5
6    GAS is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as
8    published by the Free Software Foundation; either version 2,
9    or (at your option) any later version.
10
11    GAS is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14    the GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public
17    License along with GAS; see the file COPYING.  If not, write
18    to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 /* HP PA-RISC support was contributed by the Center for Software Science
21    at the University of Utah.  */
22
23 #include "as.h"
24 #include "aout/stab_gnu.h"
25 #include "obstack.h"
26
27 static void obj_elf_stab PARAMS ((int what));
28 static void obj_elf_line PARAMS ((void));
29 static void obj_elf_desc PARAMS ((void));
30 static void obj_elf_version PARAMS ((void));
31 static void obj_elf_section PARAMS ((int));
32 static void obj_elf_size PARAMS ((void));
33 static void obj_elf_type PARAMS ((void));
34 static void obj_elf_ident PARAMS ((void));
35
36 const pseudo_typeS obj_pseudo_table[] = {
37   { "ident",    obj_elf_ident,          0 },
38   { "section",  obj_elf_section,        0 },
39   { "size",     obj_elf_size,           0 },
40   { "type",     obj_elf_type,           0 },
41   { "version",  obj_elf_version,        0 },
42
43   /* These are used for stabs-in-elf configurations.  */
44   { "desc",     obj_elf_desc,           0       },
45   { "line",     obj_elf_line,           0       },
46   { "stabd",    obj_elf_stab,           'd'     },
47   { "stabn",    obj_elf_stab,           'n'     },
48   { "stabs",    obj_elf_stab,           's'     },
49   /* This is used on Solaris 2.x on SPARC, but not supported yet.  */
50   { "xstabs",   s_ignore,               0       },
51
52   { NULL}       /* end sentinel */
53 };
54
55 static void
56 obj_elf_section (xxx)
57      int xxx;
58 {
59   char *string;
60   asection *sec;
61
62   /* Initialize this with inclusive-or of all flags that can be cleared
63      by attributes, but not set by them.  Also include flags that won't
64      get set properly in the assembler, but which the user/compiler
65      shouldn't be expected to set.  */
66   flagword flags = SEC_READONLY | SEC_ALLOC | SEC_RELOC;
67   /* Initialize this with the default flags to be used if none are
68      specified.  */
69   flagword default_flags = SEC_ALLOC | SEC_RELOC;
70
71   string = demand_copy_C_string (&xxx);
72   SKIP_WHITESPACE ();
73   if (*input_line_pointer != ',')
74     flags = default_flags;
75   while (*input_line_pointer == ',')
76     {
77       flagword bit;
78       int len, inv;
79       char *p, oldp;
80
81       input_line_pointer++;
82       if (*input_line_pointer != '#')
83         {
84           as_bad ("unrecognized syntax in .section command");
85           ignore_rest_of_line ();
86           break;
87         }
88       input_line_pointer++;
89
90 #define CHECK(X,BIT,NEG)        \
91       if (!strncmp(X,input_line_pointer,len = sizeof(X) - 1)) { \
92         bit = BIT; inv = NEG; goto match; }
93
94       CHECK ("write", SEC_READONLY, 1);
95       CHECK ("alloc", SEC_ALLOC, 0);
96 #undef CHECK
97
98       p = input_line_pointer;
99       while (!is_end_of_line[*p] && *p != 0 && *p != ',')
100         p++;
101       *p = 0;
102       oldp = *p;
103       as_bad ("unrecognized section attribute `%s' ignored",
104               input_line_pointer);
105       *p = oldp;
106       continue;
107
108     match:
109       if (inv)
110         flags &= ~bit;
111       else
112         flags |= bit;
113       input_line_pointer += len;
114     }
115   demand_empty_rest_of_line ();
116
117   sec = bfd_get_section_by_name (stdoutput, string);
118   if (sec == 0)
119     {
120       sec = bfd_make_section_old_way (stdoutput, string);
121       bfd_set_section_flags (stdoutput, sec,
122                              /* @@ What should the flags be??  */
123                              flags);
124       sec->output_section = sec;
125     }
126   subseg_change (sec, 0);
127 }
128
129 #if 0
130 /* pa-spaces.c -- Space/subspace support for the HP PA-RISC version of GAS */
131
132 /* for space, subspace, and symbol maintenance on HP 9000 Series 800 */
133
134 space_dict_chainS *space_dict_root;
135 space_dict_chainS *space_dict_last;
136
137 space_dict_chainS *current_space;
138 subspace_dict_chainS *current_subspace;
139 #endif
140
141 symbolS *start_symbol_root;
142 symbolS *start_symbol_last;
143
144 #if 0 /* I really don't think this belongs in this file.  */
145 void pa_spaces_begin()
146 {
147   space_dict_chainS *space;
148   int i;
149   subsegT now_subseg    = now_subseg;
150
151   space_dict_root = NULL;
152   space_dict_last = NULL;
153
154   start_symbol_root = NULL;
155   start_symbol_last = NULL;
156
157   /* create default space and subspace dictionaries */
158
159   i = 0;
160   while ( pa_def_spaces[i].name ) {
161           if ( pa_def_spaces[i].alias )
162               pa_def_spaces[i].segment = subseg_new(pa_def_spaces[i].alias,0);
163           else
164               pa_def_spaces[i].segment = bfd_make_section_old_way(stdoutput,pa_def_spaces[i].name);
165
166           create_new_space(pa_def_spaces[i].name,pa_def_spaces[i].spnum,
167                            pa_def_spaces[i].loadable,pa_def_spaces[i].defined,
168                            pa_def_spaces[i].private,pa_def_spaces[i].sort,0,
169                            pa_def_spaces[i].segment);
170           i++;
171   }
172
173   i = 0;
174   while ( pa_def_subspaces[i].name ) {
175           space = pa_segment_to_space(pa_def_spaces[pa_def_subspaces[i].def_space_index].segment);
176           if ( space ) {
177                   create_new_subspace(space,
178                                       pa_def_subspaces[i].name,pa_def_subspaces[i].defined,
179                                       pa_def_subspaces[i].loadable,
180                                       pa_def_subspaces[i].code_only,pa_def_subspaces[i].common,
181                                       pa_def_subspaces[i].dup_common,pa_def_subspaces[i].zero,
182                                       pa_def_subspaces[i].sort,pa_def_subspaces[i].access,
183                                       pa_def_subspaces[i].space_index,
184                                       pa_def_subspaces[i].alignment,
185                                       pa_def_subspaces[i].quadrant,
186                                       pa_def_spaces[pa_def_subspaces[i].def_space_index].segment);
187                   subseg_new(pa_def_subspaces[i].name,pa_def_subspaces[i].subsegment);
188           }
189           else
190               as_fatal("Internal error: space missing for subspace \"%s\"\n",
191                        pa_def_subspaces[i].name);
192           i++;
193   }
194 }
195
196 space_dict_chainS *create_new_space(name,spnum,loadable,defined,private,sort,defined_in_file,seg)
197      char *name;
198      int spnum;
199      char loadable;
200      char defined;
201      char private;
202      char sort;
203      char defined_in_file;
204      asection * seg;
205
206 {
207   Elf_Internal_Shdr *new_space;
208   space_dict_chainS *chain_entry;
209
210   new_space = (Elf_Internal_Shdr *)xmalloc(sizeof(Elf_Internal_Shdr));
211   if ( !new_space )
212     as_fatal("Out of memory: could not allocate new Elf_Internal_Shdr: %s\n",name);
213
214   /*
215   new_space->space_number = spnum;
216   new_space->is_loadable = loadable & 1;
217   new_space->is_defined = defined & 1;
218   new_space->is_private = private & 1;
219   new_space->sort_key = sort & 0xff;
220
221   new_space->loader_fix_index = ~0;
222   new_space->loader_fix_quantity = 0;
223   new_space->init_pointer_index = ~0;
224   new_space->init_pointer_quantity = 0;
225   new_space->subspace_quantity = 0;
226   */
227
228   chain_entry = (space_dict_chainS *)xmalloc(sizeof(space_dict_chainS));
229   if ( !chain_entry )
230     as_fatal("Out of memory: could not allocate new space chain entry: %s\n",name);
231
232   SPACE_NAME(chain_entry) = (char *)xmalloc(strlen(name)+1);
233   strcpy(SPACE_NAME(chain_entry),name);
234
235   chain_entry->sd_entry = new_space;
236   chain_entry->sd_defined = defined_in_file;
237   chain_entry->sd_seg = seg;
238   chain_entry->sd_last_subseg = -1;
239   chain_entry->sd_next = NULL;
240
241   SPACE_SPNUM(chain_entry) = spnum;
242   SPACE_LOADABLE(chain_entry) = loadable & 1;
243   SPACE_DEFINED(chain_entry) = defined & 1;
244   SPACE_PRIVATE(chain_entry) = private & 1;
245   SPACE_SORT(chain_entry) = sort & 0xff;
246
247   /* find spot for the new space based on its sort key */
248
249   if ( !space_dict_last )
250     space_dict_last = chain_entry;
251
252   if ( space_dict_root == NULL )        /* if root is null, it is very easy */
253     space_dict_root = chain_entry;
254   else
255     {
256       space_dict_chainS *sdcP;
257       space_dict_chainS *last_sdcP;
258
259       sdcP = space_dict_root;
260       last_sdcP = NULL;
261
262       while ( sdcP ) {
263         if ( SPACE_SORT(sdcP) < SPACE_SORT(chain_entry) ) {
264           last_sdcP = sdcP;
265           sdcP = sdcP->sd_next;
266         }
267         else if ( SPACE_SORT(sdcP) == SPACE_SORT(chain_entry) ) {
268           last_sdcP = sdcP;
269           sdcP = sdcP->sd_next;
270         }
271         else if ( SPACE_SORT(sdcP) > SPACE_SORT(chain_entry) ) {
272           break;
273         }       
274       }
275
276       if ( last_sdcP ) {
277         chain_entry->sd_next = sdcP;
278         last_sdcP->sd_next = chain_entry;
279       }
280       else {
281         space_dict_root = chain_entry;
282         chain_entry->sd_next = sdcP;
283       }
284
285       if ( chain_entry->sd_next  == NULL )
286         space_dict_last = chain_entry;
287     }
288
289   return chain_entry;
290 }
291
292 subspace_dict_chainS
293 *create_new_subspace(space,name,defined,loadable,code_only,common,dup_common,
294                      is_zero,sort,access,space_index,alignment,quadrant,seg)
295      space_dict_chainS *space;
296      char *name;
297      char defined,loadable,code_only,common,dup_common,is_zero;
298      char sort;
299      int access;
300      int space_index;
301      int alignment;
302      int quadrant;
303      asection * seg;
304 {
305   Elf_Internal_Shdr * new_subspace;
306   subspace_dict_chainS * chain_entry;
307   symbolS * start_symbol;
308
309   new_subspace = (Elf_Internal_Shdr *)xmalloc(sizeof(Elf_Internal_Shdr));
310   if ( !new_subspace )
311     as_fatal("Out of memory: could not allocate new Elf_Internal_Shdr: %s\n",
312             name);
313
314   /*
315   new_subspace->space_index = space_index;
316   new_subspace->fixup_request_index = ~0;
317   */
318
319   chain_entry = (subspace_dict_chainS *)xmalloc(sizeof(subspace_dict_chainS));
320   if ( !chain_entry )
321     as_fatal("Out of memory: could not allocate new subspace chain entry: %s\n",name);
322
323   chain_entry->ssd_entry = new_subspace;
324   SUBSPACE_NAME(chain_entry) = (char *)xmalloc(strlen(name)+1);
325   strcpy(SUBSPACE_NAME(chain_entry),name);
326
327   SUBSPACE_ACCESS(chain_entry) = access & 0x7f;
328   SUBSPACE_LOADABLE(chain_entry) = loadable & 1;
329   SUBSPACE_COMMON(chain_entry) = common & 1;
330   SUBSPACE_DUP_COMM(chain_entry) = dup_common & 1;
331   SUBSPACE_SORT(chain_entry) = sort & 0xff;
332   SET_SUBSPACE_CODE_ONLY(chain_entry,code_only & 1);
333   SUBSPACE_ALIGN(chain_entry) = alignment & 0xffff;
334   SUBSPACE_QUADRANT(chain_entry) = quadrant & 0x3;
335   SUBSPACE_SUBSPACE_START(chain_entry) = pa_subspace_start(space,quadrant);
336
337   chain_entry->ssd_defined = defined;
338   chain_entry->ssd_space_number = space_index;
339   chain_entry->ssd_subseg = pa_next_subseg(space);
340   chain_entry->ssd_seg = seg;
341   SUBSPACE_ZERO(chain_entry) = is_zero;
342   chain_entry->ssd_last_align = 1;
343   chain_entry->ssd_next = NULL;
344
345   /* find spot for the new subspace based on its sort key */
346
347   if ( space->sd_subspaces == NULL )        /* if root is null, it is very easy */
348     space->sd_subspaces = chain_entry;
349   else
350     {
351       subspace_dict_chainS *ssdcP;
352       subspace_dict_chainS *last_ssdcP;
353
354       ssdcP = space->sd_subspaces;
355       last_ssdcP = NULL;
356
357       while ( ssdcP ) {
358         if ( SUBSPACE_SORT(ssdcP) < SUBSPACE_SORT(chain_entry) ) {
359           last_ssdcP = ssdcP;
360           ssdcP = ssdcP->ssd_next;
361         }
362         else if ( SUBSPACE_SORT(ssdcP) == SUBSPACE_SORT(chain_entry) ) {
363           last_ssdcP = ssdcP;
364           ssdcP = ssdcP->ssd_next;
365         }
366         else if ( SUBSPACE_SORT(ssdcP) > SUBSPACE_SORT(chain_entry) ) {
367           break;
368         }       
369       }
370
371       if ( last_ssdcP ) {
372         chain_entry->ssd_next = ssdcP;
373         last_ssdcP->ssd_next = chain_entry;
374       }
375       else {
376         space->sd_subspaces = chain_entry;
377         chain_entry->ssd_next = ssdcP;
378       }
379     }
380
381   start_symbol = pa_set_start_symbol(seg,space->sd_last_subseg);
382   chain_entry->ssd_start_sym = start_symbol;
383   return chain_entry;
384
385 }
386
387 subspace_dict_chainS
388 *update_subspace(name,defined,loadable,code_only,common,dup_common,sort,zero,
389                  access,space_index,alignment,quadrant,subseg)
390      char *name;
391      char defined,loadable,code_only,common,dup_common,zero;
392      char sort;
393      int access;
394      int space_index;
395      int alignment;
396      int quadrant;
397      subsegT subseg;
398 {
399   subspace_dict_chainS *chain_entry;
400   subspace_dict_chainS *is_defined_subspace();
401
402   if ( (chain_entry = is_defined_subspace(name,subseg)) ) {
403
404     SUBSPACE_ACCESS(chain_entry) = access & 0x7f;
405     SUBSPACE_LOADABLE(chain_entry) = loadable & 1;
406     SUBSPACE_COMMON(chain_entry) = common & 1;
407     SUBSPACE_DUP_COMM(chain_entry) = dup_common & 1;
408     SET_SUBSPACE_CODE_ONLY(chain_entry,code_only & 1);
409     SUBSPACE_SORT(chain_entry) = sort & 0xff;
410     /* chain_entry->ssd_entry->space_index = space_index; */
411     SUBSPACE_ALIGN(chain_entry) = alignment & 0xffff;
412     SUBSPACE_QUADRANT(chain_entry) = quadrant & 0x3;
413
414     chain_entry->ssd_defined = defined;
415     chain_entry->ssd_space_number = space_index;
416     SUBSPACE_ZERO(chain_entry) = zero;
417   }
418   else
419     chain_entry = NULL;
420
421   return chain_entry;
422
423 }
424
425 space_dict_chainS *is_defined_space(name)
426      char *name;
427 {
428   space_dict_chainS *spaceCh;
429
430   for (spaceCh = space_dict_root;spaceCh;spaceCh=spaceCh->sd_next ) {
431     if ( strcmp(SPACE_NAME(spaceCh),name) == 0 ) {
432       return spaceCh;
433     }
434   }
435
436   return NULL;
437 }
438
439 space_dict_chainS *pa_segment_to_space(seg)
440      asection * seg;
441 {
442   space_dict_chainS *spaceCh;
443
444   for (spaceCh = space_dict_root;spaceCh;spaceCh=spaceCh->sd_next ) {
445     if ( spaceCh->sd_seg == seg ) {
446       return spaceCh;
447     }
448   }
449
450   return NULL;
451 }
452
453 subspace_dict_chainS *is_defined_subspace(name,subseg)
454      char *name;
455      subsegT subseg;
456 {
457   space_dict_chainS *spaceCh;
458   subspace_dict_chainS *subspCh;
459
460   for ( spaceCh = space_dict_root; spaceCh; spaceCh = spaceCh->sd_next ) {
461     for ( subspCh = spaceCh->sd_subspaces; subspCh; subspCh=subspCh->ssd_next ) {
462       /*
463         if ( strcmp(SUBSPACE_NAME(subspCh),name) == 0 &&
464             subspCh->ssd_subseg == subseg ) {
465        */
466         if ( strcmp(SUBSPACE_NAME(subspCh),name) == 0 ) {
467           return subspCh;
468         }
469     }
470   }
471   return NULL;
472 }
473
474 subspace_dict_chainS *pa_subsegment_to_subspace(seg,subseg)
475     asection * seg;
476     subsegT subseg;
477 {
478   space_dict_chainS *spaceCh;
479   subspace_dict_chainS *subspCh;
480
481   for ( spaceCh = space_dict_root; spaceCh; spaceCh = spaceCh->sd_next ) {
482     if ( spaceCh->sd_seg == seg ) {
483       for (subspCh = spaceCh->sd_subspaces;subspCh;subspCh=subspCh->ssd_next ) {
484         if ( subspCh->ssd_subseg == (int)subseg ) {
485           return subspCh;
486         }
487       }
488     }
489   }
490
491   return NULL;
492 }
493
494 space_dict_chainS *pa_find_space_by_number(number)
495      int number;
496 {
497   space_dict_chainS *spaceCh;
498
499   for (spaceCh = space_dict_root;spaceCh;spaceCh=spaceCh->sd_next ) {
500     if ( SPACE_SPNUM(spaceCh) == number ) {
501       return spaceCh;
502     }
503   }
504
505   return NULL;
506 }
507
508 unsigned int pa_subspace_start(space,quadrant)
509      space_dict_chainS *space;
510      int quadrant;
511 {
512   if ( (strcasecmp(SPACE_NAME(space),"$PRIVATE$") == 0) &&
513        quadrant == 1 ) {
514     return 0x40000000;
515   }
516   else if ( space->sd_seg == data_section && quadrant == 1 ) {  /* in case name is */
517                                                             /* already converted */
518                                                             /* to a space dict- */
519                                                             /* ionary index */
520     return 0x40000000;
521   }
522   else
523     return 0;
524 }
525
526 int pa_next_subseg(space)
527      space_dict_chainS *space;
528 {
529
530   space->sd_last_subseg++;
531   return space->sd_last_subseg;
532 }
533
534 int is_last_defined_subspace(ssd)
535      subspace_dict_chainS *ssd;
536 {
537
538   for ( ;ssd; ssd = ssd->ssd_next ) {
539     if ( ssd->ssd_defined )
540       return FALSE;
541   }
542
543   return TRUE;
544 }
545
546 symbolS *pa_get_start_symbol(seg,subseg)
547      asection * seg;
548      subsegT subseg;
549 {
550   symbolS *start_symbol;
551   subspace_dict_chainS *ssd;
552
553   start_symbol = NULL;
554
555   /* each time a new space is created, build a symbol called LS$START_seg_subseg$ */
556   /* where <space-name> is the name of the space */
557   /* the start symbol will be SS_LOCAL and ST_CODE */
558
559   if ( seg == bfd_make_section_old_way ( stdoutput, ".text" ) ||
560        seg == bfd_make_section_old_way ( stdoutput, ".data" ) ||
561        seg == bfd_make_section_old_way ( stdoutput, GDB_DEBUG_SPACE_NAME ) ) {
562           ssd = pa_subsegment_to_subspace(seg,subseg);
563           if ( ssd ) {
564                   start_symbol = ssd->ssd_start_sym;
565           }
566           else
567               as_fatal("Internal error: missing subspace for (seg,subseg)=('%s',%d)",
568                        seg->name,subseg);
569   }
570   else
571       as_fatal("Internal error: attempt to find start symbol for unloadable segment: '%s'",
572                seg->name);
573
574   return start_symbol;
575 }
576
577 /*
578   Function to define a symbol whose address is the beginning of a subspace.
579   This function assumes the symbol is to be defined for the current subspace.
580  */
581
582 symbolS *pa_set_start_symbol(seg,subseg)
583      asection * seg;
584      subsegT subseg;
585 {
586   symbolS *start_symbol;
587   subspace_dict_chainS *ssd;
588   char *symbol_name;
589
590   symbol_name = (char *)xmalloc(strlen("LS$START__000000$")+strlen(seg->name)+1);
591
592   sprintf(symbol_name,"LS$START_%s_%03d$",seg->name,subseg);
593
594   start_symbol
595       = symbol_new(symbol_name,seg,0,frag_now); /* XXX: not sure if value s.b. 0 or frag s.b. NULL */
596
597   start_symbol->bsym->flags     = BSF_LOCAL;    /* XXX: isn't there a macro defined for this? */
598
599   /* each time a new space is created, build a symbol called LS$START_seg_subseg$ */
600   /* where <space-name> is the name of the space */
601   /* the start symbol will be SS_LOCAL and ST_CODE */
602   /* This function assumes that (seg,subseg) is a new subsegment(subspace) */
603
604   if ( seg == bfd_make_section_old_way ( stdoutput, ".text" ) ||
605        seg == bfd_make_section_old_way ( stdoutput, ".data" ) ||
606        seg == bfd_make_section_old_way ( stdoutput, GDB_DEBUG_SPACE_NAME ) ) {
607           ssd = pa_subsegment_to_subspace(seg,subseg);
608           if ( ssd ) {
609                   ssd->ssd_start_sym = start_symbol;
610           }
611           else
612               as_fatal("Internal error: missing subspace for (seg,subseg)=('%s',%d)",
613                        seg,subseg);
614   }
615   else
616       as_fatal("Internal error: attempt to define start symbol for unloadable segment: '%s'",
617                seg->name);
618
619   return start_symbol;
620 }
621 #endif
622
623 int
624 obj_elf_frob_symbol (sym, punt)
625      symbolS *sym;
626      int *punt;
627 {
628
629         /* If this is a local symbol, are there any relocations for */
630         /* which need this symbol?      */
631
632         /* To find this out, we examine all relocations in all bfd */
633         /* sections that have relocations.  If there is one that */
634         /* references this symbol, we need to keep this symbol.  In */
635         /* this case, we return a true status.  In all other cases, we */
636         /* return a false status.       */
637
638         if ( S_IS_LOCAL(sym) ) {
639                 asymbol *bsym = sym->bsym;      
640                 bfd *abfd = bsym->the_bfd;
641                 asection *bsec;
642
643                 for ( bsec = abfd->sections; bsec; bsec = bsec->next ) {
644                         struct reloc_cache_entry **rlocs = bsec->orelocation;
645                         int rcnt = bsec->reloc_count;
646
647                         if ( rlocs ) {
648                                 int i;
649
650                                 for ( i = 0; i < rcnt; i++ ) {
651                                         if ( rlocs[i]->sym_ptr_ptr
652                                             && rlocs[i]->sym_ptr_ptr[0] == bsym )
653                                                 return 1;
654                                 }
655                         }
656                 }
657         }
658         return 0;
659 }
660
661 static void obj_elf_line() {
662         /* Assume delimiter is part of expression.
663            BSD4.2 as fails with delightful bug, so we
664            are not being incompatible here. */
665         new_logical_line((char *)NULL, (int)(get_absolute_expression()));
666         demand_empty_rest_of_line();
667 } /* obj_elf_line() */
668
669 /*
670  *                      stab()
671  *
672  * Handle .stabX directives, which used to be open-coded.
673  * So much creeping featurism overloaded the semantics that we decided
674  * to put all .stabX thinking in one place. Here.
675  *
676  * We try to make any .stabX directive legal. Other people's AS will often
677  * do assembly-time consistency checks: eg assigning meaning to n_type bits
678  * and "protecting" you from setting them to certain values. (They also zero
679  * certain bits before emitting symbols. Tut tut.)
680  *
681  * If an expression is not absolute we either gripe or use the relocation
682  * information. Other people's assemblers silently forget information they
683  * don't need and invent information they need that you didn't supply.
684  *
685  * .stabX directives always make a symbol table entry. It may be junk if
686  * the rest of your .stabX directive is malformed.
687  */
688
689 /*
690  *                      pa_stab_symbol_string()
691  *
692  * Build a string dictionary entry for a .stabX symbol.
693  * The symbol is added to the .stabstr section.
694  *
695  */
696
697 static unsigned int gdb_string_index = 0;
698
699 static unsigned int
700 elf_stab_symbol_string(string)
701      char *string;
702 {
703   asection *save_seg;
704   asection *seg;
705   subsegT save_subseg;
706   unsigned int length;
707   unsigned int old_gdb_string_index;
708   char *clengthP;
709   int i;
710   char c;
711
712   old_gdb_string_index = 0;
713   length = strlen(string);
714   clengthP = (char *)&length;
715   if ( length > 0 ) {                   /* Ordinary case. */
716     save_seg = now_seg;
717     save_subseg = now_subseg;
718
719     /* Create the stab sections, if they are not already created. */
720     seg = bfd_get_section_by_name(stdoutput,".stabstr");
721     if ( seg == 0 ) {
722             seg = bfd_make_section_old_way(stdoutput,".stabstr");
723             bfd_set_section_flags (stdoutput,
724                                    seg,
725                                    SEC_READONLY | SEC_ALLOC | SEC_LOAD );
726     }
727     subseg_new((char *) seg->name,save_subseg);
728     old_gdb_string_index = gdb_string_index;
729     i = 0;
730     while ( (c = *string++) )
731       {
732         i++;
733         gdb_string_index++;
734         FRAG_APPEND_1_CHAR( c );
735       }
736     {
737       FRAG_APPEND_1_CHAR( (char)0 );
738       i++;
739       gdb_string_index++;
740     }
741     while ( i%4 != 0 ) {
742       FRAG_APPEND_1_CHAR( (char)0 );
743       i++;
744       gdb_string_index++;
745     }
746     subseg_new((char *) save_seg->name,save_subseg);
747   }
748
749   return old_gdb_string_index;
750 }
751
752 unsigned int
753 elf_stab_symbol(symbolP,stab_type)
754      symbolS *symbolP;
755      int stab_type;
756 {
757   unsigned int length;
758   int i;
759   char c;
760   char *toP;
761
762   /* the string index portion of the stab */
763
764   toP = frag_more( sizeof(long) +
765                    sizeof(S_GET_TYPE(symbolP)) +
766                    sizeof(S_GET_OTHER(symbolP)) +
767                    sizeof(S_GET_DESC(symbolP)));
768   md_number_to_chars(toP,symbolP->sy_name_offset,sizeof(long));
769   md_number_to_chars(toP,
770                      S_GET_TYPE(symbolP),
771                      sizeof(S_GET_TYPE(symbolP)));
772   md_number_to_chars(toP + sizeof(S_GET_TYPE(symbolP)),
773                      S_GET_OTHER(symbolP),
774                      sizeof(S_GET_OTHER(symbolP)));
775   md_number_to_chars(toP + sizeof(S_GET_TYPE(symbolP))
776                          + sizeof(S_GET_OTHER(symbolP)),
777                      S_GET_DESC(symbolP),
778                      sizeof(S_GET_DESC(symbolP)));
779
780   /* n_value has to be relocated */
781
782   /* Don't bother relocating if we're only adding in a constant. */
783
784   if ((stab_type == 's' || stab_type == 'n') && symbolP->sy_forward == 0)
785           S_SET_VALUE(symbolP,S_GET_VALUE(symbolP->sy_forward));
786
787   toP = frag_more(4);
788   md_number_to_chars(toP, S_GET_VALUE(symbolP),
789                      sizeof(S_GET_VALUE(symbolP)));
790
791 #if 0
792   if ( (stab_type == 's' || stab_type == 'n') && symbolP->sy_forward )
793     {
794       i = S_GET_TYPE(symbolP) & N_TYPE;
795       fix_new_hppa(frag_now,    /* which frag */
796                    toP-frag_now->fr_literal, /* where */
797                    4,           /* size */
798                    symbolP->sy_forward, /* addr of symbol for this stab */
799                    (asymbol *)NULL,
800                    0,
801                    i == N_UNDF || i == N_ABS,   /* 1 if internal relocation */
802                    R_HPPA,      /* reloc type */
803                    e_fsel,      /* fixup field = F% */
804                    32,
805                    0,           /* arg_reloc descriptor */
806                    (char *)0
807                    );
808     }
809   else if ( stab_type == 'd' )
810     {
811       fix_new_hppa (frag_now,   /* which frag */
812                     toP-frag_now->fr_literal, /* where */
813                     4,          /* size */
814                     symbolP,    /* addr of symbol for this stab */
815                     (asymbol *)NULL,
816                     0,
817                     0,
818                     R_HPPA,     /* reloc type */
819                     e_fsel,     /* fixup field = F% */
820                     32,
821                     0,          /* arg_reloc descriptor */
822                     (char *)0
823                     );
824     }
825 #else
826   /* What needs to replace the above code?  */
827   abort ();
828 #endif
829 }
830
831 static void obj_elf_stab(what)
832      int what;
833 {
834   extern int listing;
835
836   symbolS *     symbolP = 0;
837   char *        string;
838   int saved_type = 0;
839   int length;
840   int goof = 0;
841   long longint;
842   asection *saved_seg = now_seg;
843   asection *seg;
844   subsegT subseg = now_subseg;
845
846   seg = bfd_get_section_by_name(stdoutput,".stab");
847   if ( seg == 0 )
848     {
849       seg = bfd_make_section_old_way(stdoutput,".stab");
850       bfd_set_section_flags (stdoutput,
851                              seg,
852                              SEC_READONLY | SEC_ALLOC | SEC_LOAD | SEC_RELOC);
853     }
854
855   /*
856    * Enter with input_line_pointer pointing past .stabX and any following
857    * whitespace.
858    */
859   if (what == 's') {
860       string = demand_copy_C_string(& length);
861       SKIP_WHITESPACE();
862       if (* input_line_pointer == ',')
863        input_line_pointer ++;
864       else
865         {
866           as_bad("I need a comma after symbol's name");
867           goof = 1;
868         }
869     }
870   else
871     string = "";
872
873   /*
874    * Input_line_pointer->after ','.  String->symbol name.
875    */
876   if (! goof)
877     {
878       symbolP = symbol_new(string, &bfd_und_section, 0, (struct frag *)0);
879
880       /* enter the string in the .stab string table (section .stabstr) */
881       symbolP->sy_name_offset = elf_stab_symbol_string(string);
882
883       switch (what)
884         {
885         case 'd':
886           S_SET_NAME(symbolP, NULL); /* .stabd feature. */
887           S_SET_VALUE(symbolP, obstack_next_free(&frags) - frag_now->fr_literal);
888           S_SET_SEGMENT(symbolP, now_seg);
889           symbolP->sy_frag = frag_now;
890           break;
891
892         case 'n':
893           symbolP->sy_frag = &zero_address_frag;
894           break;
895
896         case 's':
897           symbolP->sy_frag = & zero_address_frag;
898           break;
899
900         default:
901           BAD_CASE(what);
902           break;
903         }
904
905       if (get_absolute_expression_and_terminator(&longint) == ',')
906         {
907           saved_type = longint;
908           S_SET_TYPE (symbolP, saved_type);
909         }
910       else
911         {
912           as_bad("I want a comma after the n_type expression");
913           goof = 1;
914           input_line_pointer --; /* Backup over a non-',' char. */
915         }
916     }
917
918   if (!goof)
919     {
920       if (get_absolute_expression_and_terminator(&longint) == ',')
921         S_SET_OTHER(symbolP, longint);
922       else
923         {
924           as_bad("I want a comma after the n_other expression");
925           goof = 1;
926           input_line_pointer--; /* Backup over a non-',' char. */
927         }
928     }
929
930   if (!goof)
931     {
932       S_SET_DESC(symbolP, get_absolute_expression());
933       if (what == 's' || what == 'n')
934         {
935           if (*input_line_pointer != ',')
936             {
937               as_bad("I want a comma after the n_desc expression");
938               goof = 1;
939             }
940           else
941             {
942               input_line_pointer++;
943             }
944         }
945     }
946
947   if ( !goof ) {
948           if ( what=='s' || what=='n' ) {
949                   pseudo_set(symbolP);
950                   S_SET_TYPE (symbolP, saved_type);
951           }
952           /* Emit the stab symbol. */
953           subseg_new((char *) seg->name,subseg);
954           elf_stab_symbol(symbolP, what);
955           subseg_new((char *) saved_seg->name,subseg);
956
957           if ( what=='s' || what=='n' && symbolP->sy_forward == NULL ) {
958                   /* symbol is not needed in the regular symbol table */
959                   symbol_remove(symbolP,&symbol_rootP,&symbol_lastP);
960           }
961
962   }
963
964 #ifndef NO_LISTING
965   if (listing && !goof)
966     switch (S_GET_TYPE (symbolP))
967       {
968       case N_SLINE:
969         listing_source_line (S_GET_DESC (symbolP));
970         break;
971       case N_SO:
972       case N_SOL:
973         listing_source_file (string);
974         break;
975       }
976 #endif
977
978   if (goof)
979     ignore_rest_of_line();
980   else
981     demand_empty_rest_of_line ();
982 } /* obj_elf_stab() */
983
984 static void obj_elf_desc() {
985         char *name;
986         char c;
987         char *p;
988         symbolS *symbolP;
989         int temp;
990         
991         /*
992          * Frob invented at RMS' request. Set the n_desc of a symbol.
993          */
994         name = input_line_pointer;
995         c = get_symbol_end();
996         p = input_line_pointer;
997         * p = c;
998         SKIP_WHITESPACE();
999         if (*input_line_pointer != ',') {
1000                 *p = 0;
1001                 as_bad("Expected comma after name \"%s\"", name);
1002                 *p = c;
1003                 ignore_rest_of_line();
1004         } else {
1005                 input_line_pointer ++;
1006                 temp = get_absolute_expression();
1007                 *p = 0;
1008                 symbolP = symbol_find_or_make(name);
1009                 *p = c;
1010                 S_SET_DESC(symbolP,temp);
1011         }
1012         demand_empty_rest_of_line();
1013 } /* obj_elf_desc() */
1014
1015 void obj_read_begin_hook()
1016 {
1017 }
1018
1019 void obj_symbol_new_hook(symbolP)
1020 symbolS *symbolP;
1021 {
1022   elf_symbol_type *esym = (elf_symbol_type *)symbolP;
1023
1024   /* There is an Elf_Internal_Sym and an Elf_External_Sym.  For now,
1025      just zero them out.  */
1026
1027   bzero((char *) &esym->internal_elf_sym,sizeof(Elf_Internal_Sym));
1028   bzero((char *) &esym->native_elf_sym,sizeof(Elf_External_Sym));
1029 }
1030
1031 static void obj_elf_version()
1032 {
1033     char *name;
1034     unsigned int c;
1035     char ch;
1036     char *p;
1037     int temp;
1038     symbolS *   symbolP;
1039     asection *seg = now_seg;
1040     subsegT subseg = now_subseg;
1041     Elf_Internal_Note i_note;
1042     Elf_External_Note e_note;
1043     asection *note_secp = (asection *)NULL;
1044     int i, len;
1045
1046     SKIP_WHITESPACE();
1047     if (* input_line_pointer == '\"') {
1048       ++input_line_pointer; /* -> 1st char of string. */
1049       name = input_line_pointer;
1050
1051       while ( is_a_char(c = next_char_of_string()) )
1052               ;
1053       c = *input_line_pointer;
1054       *input_line_pointer = '\0';
1055       *(input_line_pointer-1) = '\0';
1056       *input_line_pointer = c;
1057
1058       /* create the .note section if this is the first version string */
1059
1060       note_secp = bfd_get_section_by_name(stdoutput,".note");
1061       if ( note_secp == (asection *)NULL ) {
1062               note_secp = bfd_make_section_old_way(stdoutput,".note");
1063               bfd_set_section_flags(stdoutput,
1064                                     note_secp,
1065                                     SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS);
1066       }
1067
1068       /* process the version string */
1069
1070       subseg_new((char *)note_secp->name, 0);
1071       len = strlen(name);
1072
1073       i_note.namesz     = ((len + 1) + 3) & ~3; /* round this to word boundary  */
1074       i_note.descsz     = 0;                    /* no description       */
1075       i_note.type       = NT_VERSION;
1076       p = frag_more(sizeof(e_note.namesz));
1077       md_number_to_chars(p, i_note.namesz, 4);
1078       p = frag_more(sizeof(e_note.descsz));
1079       md_number_to_chars(p, i_note.descsz, 4);
1080       p = frag_more(sizeof(e_note.type));
1081       md_number_to_chars(p, i_note.type,   4);
1082
1083       for ( i = 0; i < len; i++ ) {
1084               ch = *(name + i);
1085               {
1086                       FRAG_APPEND_1_CHAR( ch );
1087               }
1088       }
1089       frag_align(2,0);
1090
1091       subseg_new((char *)seg->name,subseg);
1092     }
1093     else {
1094       as_bad( "Expected \"-ed string" );
1095     }
1096     demand_empty_rest_of_line();
1097 }
1098
1099 static void
1100 obj_elf_size ()
1101 {
1102   char *name = input_line_pointer;
1103   char c = get_symbol_end ();
1104   char *p;
1105   expressionS exp;
1106   segT sec;
1107   symbolS *sym;
1108
1109   p = input_line_pointer;
1110   *p = c;
1111   SKIP_WHITESPACE ();
1112   if (*input_line_pointer != ',')
1113     {
1114       *p = 0;
1115       as_bad ("expected comma after name `%s' in .size directive", name);
1116       *p = c;
1117       ignore_rest_of_line ();
1118       return;
1119     }
1120   input_line_pointer++;
1121   sec = expression (&exp);
1122   if (sec == absent_section)
1123     {
1124       as_bad ("missing expression in .size directive");
1125       exp.X_seg = absolute_section;
1126       exp.X_add_number = 0;
1127     }
1128   *p = 0;
1129   sym = symbol_find_or_make (name);
1130   *p = c;
1131   if (sec == absolute_section)
1132     S_SET_SIZE (sym, exp.X_add_number);
1133   else
1134     as_tsktsk (".size not yet supported, ignored");
1135   demand_empty_rest_of_line ();
1136 }
1137
1138 static void
1139 obj_elf_type ()
1140 {
1141   char *name = input_line_pointer;
1142   char c = get_symbol_end ();
1143   char *p;
1144   int type;
1145   symbolS *sym;
1146
1147   p = input_line_pointer;
1148   *p = c;
1149   SKIP_WHITESPACE ();
1150   if (*input_line_pointer != ',')
1151     {
1152       as_bad ("expected comma after name in .type directive");
1153     egress:
1154       ignore_rest_of_line ();
1155       return;
1156     }
1157   input_line_pointer++;
1158   SKIP_WHITESPACE ();
1159   if (*input_line_pointer != '#')
1160     {
1161       as_bad ("expected `#' after comma in .type directive");
1162       goto egress;
1163     }
1164   input_line_pointer++;
1165   if (!strncmp ("function", input_line_pointer, sizeof ("function") - 1))
1166     {
1167       type = BSF_FUNCTION;
1168       input_line_pointer += sizeof ("function") - 1;
1169     }
1170   else
1171     {
1172       as_bad ("unrecognized symbol type, ignored");
1173       goto egress;
1174     }
1175   demand_empty_rest_of_line ();
1176   *p = 0;
1177   sym = symbol_find_or_make (name);
1178   sym->bsym->flags = type;
1179 }
1180
1181 static void
1182 obj_elf_ident ()
1183 {
1184   int xxx;
1185   char * string;
1186
1187   string = demand_copy_C_string (&xxx);
1188   as_tsktsk (".ident not supported, ignoring");
1189 }
This page took 0.078297 seconds and 2 git commands to generate.