summaryrefslogtreecommitdiff
path: root/src/ld.h
blob: 860bcdb4e9cff80d18203873b3e7010e370a835c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
/* Copyright (C) 2001, 2002, 2003, 2005, 2006, 2008 Red Hat, Inc.
   This file is part of Red Hat elfutils.
   Written by Ulrich Drepper <drepper@redhat.com>, 2001.

   Red Hat elfutils is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by the
   Free Software Foundation; version 2 of the License.

   Red Hat elfutils is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with Red Hat elfutils; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.

   Red Hat elfutils is an included package of the Open Invention Network.
   An included package of the Open Invention Network is a package for which
   Open Invention Network licensees cross-license their patents.  No patent
   license is granted, either expressly or impliedly, by designation as an
   included package.  Should you wish to participate in the Open Invention
   Network licensing program, please visit www.openinventionnetwork.com
   <http://www.openinventionnetwork.com>.  */

#ifndef LD_H
#define LD_H	1

#include <dlfcn.h>
#include <obstack.h>
#include <stdbool.h>
#include <stdio.h>
#include "xelf.h"


/* Recommended size of the buffer passed to ld_strerror.  */
#define ERRBUFSIZE	(512)

/* Character used to introduce version name after symbol.  */
#define VER_CHR	'@'


/* Methods for handling archives.  */
enum extract_rule
  {
    defaultextract,	/* Weak references don't cause archive member to
			   be used.  */
    weakextract,	/* Weak references cause archive member to be
			   extracted.  */
    allextract		/* Extract all archive members regardless of
			   references (aka whole-archive).  */
  };


/* Type of output file.  */
enum file_type
  {
    no_file_type = 0,		/* None selected so far.  */
    executable_file_type,	/* Executable.  */
    dso_file_type,		/* DSO.  */
    dso_needed_file_type,	/* DSO introduced by DT_NEEDED.  */
    relocatable_file_type,	/* Relocatable object file.  */
    archive_file_type		/* Archive (input only).  */
  };


struct usedfiles
{
  /* The next file given at the command line.  */
  struct usedfiles *next;
  /* Nonzero if this file is the beginning of a group.  */
  bool group_start;
  /* Nonzero if this file is the end of a group.  */
  bool group_end;
  /* Pointer to the beginning of the group.  It is necessary to
     explain why we cannot simply use the 'next' pointer and have a
     circular single-linked list like in many cases.  The problem is
     that the last archive of the group, if it is the last file of the
     group, contains the only existing pointer to the next file we
     have to look at.  All files are initially connected via the
     'next' pointer in a single-linked list.  Therefore we cannot
     overwrite this value.  It instead will be used once the group is
     handled and we go on processing the rest of the files.  */
  struct usedfiles *group_backref;

  /* Name/path of the file.  */
  const char *fname;
  /* Resolved file name.  */
  const char *rfname;
  /* Name used as reference in DT_NEEDED entries.  This is normally
     the SONAME.  If it is missing it's normally the fname above.  */
  const char *soname;
  /* Handle for the SONAME in the string table.  */
  struct Ebl_Strent *sonameent;

  /* Help to identify duplicates.  */
  dev_t dev;
  ino_t ino;

  enum
    {
      not_opened,
      opened,
      in_archive,
      closed
    } status;

  /* How to extract elements from archives.  */
  enum extract_rule extract_rule;

  /* Lazy-loading rule.  */
  bool lazyload;

  /* If this is a DSO the flag indicates whether the file is directly
     used in a reference.  */
  bool used;

  /* True when file should be added to DT_NEEDED list only when
     directly referenced.  */
  bool as_needed;

  /* If nonzero this is the archive sequence number which can be used to
     determine whether back refernces from -( -) or GROUP statements
     have to be followed.  */
  int archive_seq;

  /* Pointer to the record for the archive containing this file.  */
  struct usedfiles *archive_file;

  /* Type of file.  We have to distinguish these types since they
     are searched for differently.  */
  enum file_type file_type;
  /* This is the ELF library handle for this file.  */
  Elf *elf;

  /* The ELF header.  */
#if NATIVE_ELF != 0
  XElf_Ehdr *ehdr;
# define FILEINFO_EHDR(fi) (*(fi))
#else
  XElf_Ehdr ehdr;
# define FILEINFO_EHDR(fi) (fi)
#endif

  /* Index of the section header string table section.  We use a
     separate field and not the e_shstrndx field in the ELF header
     since in case of a file with more than 64000 sections the index
     might be stored in the section header of section zero.  The
     elf_getshstrndx() function can find the value but it is too
     costly to repeat this call over and over.  */
  size_t shstrndx;

  /* Info about the sections of the file.  */
  struct scninfo
  {
    /* Handle for the section.  Note that we can store a section
       handle here because the file is not changing.  This together
       with the knowledge about the libelf library is enough for us to
       assume the section reference remains valid at all times.  */
    Elf_Scn *scn;
    /* Section header.  */
#if NATIVE_ELF != 0
    XElf_Shdr *shdr;
# define SCNINFO_SHDR(si) (*(si))
#else
    XElf_Shdr shdr;
# define SCNINFO_SHDR(si) (si)
#endif
    /* Offset of this files section in the combined section.  */
    XElf_Off offset;
    /* Index of the section in the output file.  */
    Elf32_Word outscnndx;
    /* Index of the output section in the 'allsection' array.  */
    Elf32_Word allsectionsidx;
    /* True if the section is used.  */
    bool used;
    /* True if section is an unused COMDAT section.  */
    bool unused_comdat;
    /* True if this is a COMDAT group section.  */
    bool comdat_group;
    /* Section group number.  This is the index of the SHT_GROUP section.  */
    Elf32_Word grpid;
    /* Pointer back to the containing file information structure.  */
    struct usedfiles *fileinfo;
    /* List of symbols in this section (set only for merge-able sections
       and group sections).  */
    struct symbol *symbols;
    /* Size of relocations in this section.  Only used for relocation
       sections.  */
    size_t relsize;
    /* Pointer to next section which is put in the given output
       section.  */
    struct scninfo *next;
  } *scninfo;

  /* List of section group sections.  */
  struct scninfo *groups;

  /* The symbol table section.

     XXX Maybe support for more than one symbol table is needed.  */
  Elf_Data *symtabdata;
  /* Extra section index table section.  */
  Elf_Data *xndxdata;
  /* Dynamic symbol table section.  */
  Elf_Data *dynsymtabdata;
  /* The version number section.  */
  Elf_Data *versymdata;
  /* The defined versions.  */
  Elf_Data *verdefdata;
  /* Number of versions defined.  */
  size_t nverdef;
  /* True if the version with the given index number is used in the
     output.  */
  XElf_Versym *verdefused;
  /* How many versions are used.  */
  size_t nverdefused;
  /* Handle for name of the version.  */
  struct Ebl_Strent **verdefent;
  /* The needed versions.  */
  Elf_Data *verneeddata;
  /* String table section associated with the symbol table.  */
  Elf32_Word symstridx;
  /* String table section associated with the dynamic symbol table.  */
  Elf32_Word dynsymstridx;
  /* Number of entries in the symbol table.  */
  size_t nsymtab;
  size_t nlocalsymbols;
  size_t ndynsymtab;
  /* Dynamic section.  */
  Elf_Scn *dynscn;

  /* Indirection table for the symbols defined here.  */
  Elf32_Word *symindirect;
  Elf32_Word *dynsymindirect;
  /* For undefined or common symbols we need a reference to the symbol
     record.  */
  struct symbol **symref;
  struct symbol **dynsymref;

  /* This is the file descriptor.  The value is -1 if the descriptor
     was already closed.  This can happen if we needed file descriptors
     to open new files.  */
  int fd;
  /* This flag is true if the descriptor was passed to the generic
     functions from somewhere else.  This is an implementation detail;
     no machine-specific code must use this flag.  */
  bool fd_passed;

  /* True if any of the sections is merge-able.  */
  bool has_merge_sections;
};


/* Functions to test for the various types of files we handle.  */
static inline int
ld_file_rel_p (struct usedfiles *file)
{
  return (elf_kind (file->elf) == ELF_K_ELF
	  && FILEINFO_EHDR (file->ehdr).e_type == ET_REL);
}

static inline int
ld_file_dso_p (struct usedfiles *file)
{
  return (elf_kind (file->elf) == ELF_K_ELF
	  && FILEINFO_EHDR (file->ehdr).e_type == ET_DYN);
}

static inline int
ld_file_ar_p (struct usedfiles *file)
{
  return elf_kind (file->elf) == ELF_K_AR;
}


struct pathelement
{
  /* The next path to search.  */
  struct pathelement *next;
  /* The path name.  */
  const char *pname;
  /* Larger than zero if the directory exists, smaller than zero if not,
     zero if it is not yet known.  */
  int exist;
};


/* Forward declaration.  */
struct ld_state;


/* Callback functions.  */
struct callbacks
{
  /* Library names passed to the linker as -lXXX represent files named
     libXXX.YY.  The YY part can have different forms, depending on the
     architecture.  The generic set is .so and .a (in this order).  */
  const char **(*lib_extensions) (struct ld_state *)
       __attribute__ ((__const__));
#define LIB_EXTENSION(state) \
  DL_CALL_FCT ((state)->callbacks.lib_extensions, (state))

  /* Process the given file.  If the file is not yet open, open it.
     The first parameter is a file descriptor for the file which can
     be -1 to indicate the file has not yet been found.  The second
     parameter describes the file to be opened, the last one is the
     state of the linker which among other information contain the
     paths we look at.*/
  int (*file_process) (int fd, struct usedfiles *, struct ld_state *,
		       struct usedfiles **);
#define FILE_PROCESS(fd, file, state, nextp) \
  DL_CALL_FCT ((state)->callbacks.file_process, (fd, file, state, nextp))

  /* Close the given file.  */
  int (*file_close) (struct usedfiles *, struct ld_state *);
#define FILE_CLOSE(file, state) \
  DL_CALL_FCT ((state)->callbacks.file_close, (file, state))

  /* Create the output sections now.  This requires knowledge about
     all the sections we will need.  It may be necessary to sort the
     sections in the order they are supposed to appear in the
     executable.  The sorting use many different kinds of information
     to optimize the resulting binary.  Important is to respect
     segment boundaries and the needed alignment.  The mode of the
     segments will be determined afterwards automatically by the
     output routines.  */
  void (*create_sections) (struct ld_state *);
#define CREATE_SECTIONS(state) \
  DL_CALL_FCT ((state)->callbacks.create_sections, (state))

  /* Determine whether we have any non-weak unresolved references left.  */
  int (*flag_unresolved) (struct ld_state *);
#define FLAG_UNRESOLVED(state) \
  DL_CALL_FCT ((state)->callbacks.flag_unresolved, (state))

  /* Create the sections which are generated by the linker and are not
     present in the input file.  */
  void (*generate_sections) (struct ld_state *);
#define GENERATE_SECTIONS(state) \
  DL_CALL_FCT ((state)->callbacks.generate_sections, (state))

  /* Open the output file.  The file name is given or "a.out".  We
     create as much of the ELF structure as possible.  */
  int (*open_outfile) (struct ld_state *, int, int, int);
#define OPEN_OUTFILE(state, machine, class, data) \
  DL_CALL_FCT ((state)->callbacks.open_outfile, (state, machine, class, data))

  /* Create the data for the output file.  */
  int (*create_outfile) (struct ld_state *);
#define CREATE_OUTFILE(state) \
  DL_CALL_FCT ((state)->callbacks.create_outfile, (state))

  /* Process a relocation section.  */
  void (*relocate_section) (struct ld_state *, Elf_Scn *, struct scninfo *,
			    const Elf32_Word *);
#define RELOCATE_SECTION(state, outscn, first, dblindirect) \
  DL_CALL_FCT ((state)->callbacks.relocate_section, (state, outscn, first,    \
						     dblindirect))

  /* Allocate a data buffer for the relocations of the given output
     section.  */
  void (*count_relocations) (struct ld_state *, struct scninfo *);
#define COUNT_RELOCATIONS(state, scninfo) \
  DL_CALL_FCT ((state)->callbacks.count_relocations, (state, scninfo))

  /* Create relocations for executable or DSO.  */
  void (*create_relocations) (struct ld_state *, const Elf32_Word *);
#define CREATE_RELOCATIONS(state, dlbindirect) \
  DL_CALL_FCT ((state)->callbacks.create_relocations, (state, dblindirect))

  /* Finalize the output file.  */
  int (*finalize) (struct ld_state *);
#define FINALIZE(state) \
  DL_CALL_FCT ((state)->callbacks.finalize, (state))

  /* Check whether special section number is known.  */
  bool (*special_section_number_p) (struct ld_state *, size_t);
#define SPECIAL_SECTION_NUMBER_P(state, number) \
  DL_CALL_FCT ((state)->callbacks.special_section_number_p, (state, number))

  /* Check whether section type is known.  */
  bool (*section_type_p) (struct ld_state *, XElf_Word);
#define SECTION_TYPE_P(state, type) \
  DL_CALL_FCT ((state)->callbacks.section_type_p, (state, type))

  /* Return section flags for .dynamic section.  */
  XElf_Xword (*dynamic_section_flags) (struct ld_state *);
#define DYNAMIC_SECTION_FLAGS(state) \
  DL_CALL_FCT ((state)->callbacks.dynamic_section_flags, (state))

  /* Create the data structures for the .plt section and initialize it.  */
  void (*initialize_plt) (struct ld_state *, Elf_Scn *scn);
#define INITIALIZE_PLT(state, scn) \
  DL_CALL_FCT ((state)->callbacks.initialize_plt, (state, scn))

  /* Create the data structures for the .rel.plt section and initialize it.  */
  void (*initialize_pltrel) (struct ld_state *, Elf_Scn *scn);
#define INITIALIZE_PLTREL(state, scn) \
  DL_CALL_FCT ((state)->callbacks.initialize_pltrel, (state, scn))

  /* Finalize the .plt section the what belongs to them.  */
  void (*finalize_plt) (struct ld_state *, size_t, size_t, struct symbol **);
#define FINALIZE_PLT(state, nsym, nsym_dyn, ndxtosym) \
  DL_CALL_FCT ((state)->callbacks.finalize_plt, (state, nsym, nsym_dyn, \
						 ndxtosym))

  /* Create the data structures for the .got section and initialize it.  */
  void (*initialize_got) (struct ld_state *, Elf_Scn *scn);
#define INITIALIZE_GOT(state, scn) \
  DL_CALL_FCT ((state)->callbacks.initialize_got, (state, scn))

  /* Create the data structures for the .got.plt section and initialize it.  */
  void (*initialize_gotplt) (struct ld_state *, Elf_Scn *scn);
#define INITIALIZE_GOTPLT(state, scn) \
  DL_CALL_FCT ((state)->callbacks.initialize_gotplt, (state, scn))

  /* Return the tag corresponding to the native relocation type for
     the platform.  */
  int (*rel_type) (struct ld_state *);
#define REL_TYPE(state) \
  DL_CALL_FCT ((state)->callbacks.rel_type, (state))
};


/* Structure for symbol representation.  This data structure is used a
   lot, so size is important.  */
struct symbol
{
  /* Symbol name.  */
  const char *name;
  /* Size of the object.  */
  XElf_Xword size;
  /* Index of the symbol in the symbol table of the object.  */
  size_t symidx;
  /* Index of the symbol in the symbol table of the output file.  */
  size_t outsymidx;

  /* Description where the symbol is found/needed.  */
  size_t scndx;
  struct usedfiles *file;
  /* Index of the symbol table.  */
  Elf32_Word symscndx;

  /* Index of the symbol in the dynamic symbol table of the output
     file.  Note that the value only needs to be 16 bit wide since
     there cannot be more sections in an executable or DSO.  */
  unsigned int outdynsymidx:16;

  /* Type of the symbol.  */
  unsigned int type:4;
  /* Various flags.  */
  unsigned int defined:1;
  unsigned int common:1;
  unsigned int weak:1;
  unsigned int added:1;
  unsigned int merged:1;
  unsigned int local:1;
  unsigned int hidden:1;
  /* Nonzero if the symbol is on the from_dso list.  */
  unsigned int on_dsolist:1;
  /* Nonzero if symbol needs copy relocation, reset when the
     relocation has been created.  */
  unsigned int need_copy:1;
  unsigned int in_dso:1;

  union
  {
    /* Pointer to the handle created by the functions which create
       merged section contents.  We use 'void *' because there are
       different implementations used.  */
    void *handle;
    XElf_Addr value;
  } merge;

  /* Pointer to next/previous symbol on whatever list the symbol is.  */
  struct symbol *next;
  struct symbol *previous;
  /* Pointer to next symbol of the same section (only set for merge-able
     sections).  */
  struct symbol *next_in_scn;
};


/* Get the definition for the symbol table.  */
#include <symbolhash.h>

/* Simple single linked list of file names.  */
struct filename_list
{
  const char *name;
  struct usedfiles *real;
  struct filename_list *next;
  bool group_start;
  bool group_end;
  bool as_needed;
};


/* Data structure to describe expression in linker script.  */
struct expression
{
  enum expression_tag
    {
      exp_num,
      exp_sizeof_headers,
      exp_pagesize,
      exp_id,
      exp_mult,
      exp_div,
      exp_mod,
      exp_plus,
      exp_minus,
      exp_and,
      exp_or,
      exp_align
    } tag;

  union
  {
    uintmax_t num;
    struct expression *child;
    struct
    {
      struct expression *left;
      struct expression *right;
    } binary;
    const char *str;
  } val;
};


/* Data structure for section name with flags.  */
struct input_section_name
{
  const char *name;
  bool sort_flag;
};

/* File name mask with section name.  */
struct filemask_section_name
{
  const char *filemask;
  const char *excludemask;
  struct input_section_name *section_name;
  bool keep_flag;
};

/* Data structure for assignments.  */
struct assignment
{
  const char *variable;
  struct expression *expression;
  struct symbol *sym;
  bool provide_flag;
};


/* Data structure describing input for an output section.  */
struct input_rule
{
  enum
    {
      input_section,
      input_assignment
    } tag;

  union
  {
    struct assignment *assignment;
    struct filemask_section_name *section;
  } val;

  struct input_rule *next;
};


/* Data structure to describe output section.  */
struct output_section
{
  const char *name;
  struct input_rule *input;
  XElf_Addr max_alignment;
  bool ignored;
};


/* Data structure to describe output file format.  */
struct output_rule
{
  enum
    {
      output_section,
      output_assignment
    } tag;

  union
  {
    struct assignment *assignment;
    struct output_section section;
  } val;

  struct output_rule *next;
};


/* List of all the segments the linker script describes.  */
struct output_segment
{
  int mode;
  struct output_rule *output_rules;
  struct output_segment *next;

  XElf_Off offset;
  XElf_Addr addr;
  XElf_Xword align;
};


/* List of identifiers.  */
struct id_list
{
  union
  {
    enum id_type
      {
	id_str,		/* Normal string.  */
	id_all,		/* "*", matches all.  */
	id_wild		/* Globbing wildcard string.  */
      } id_type;
    struct
    {
      bool local;
      const char *versionname;
    } s;
  } u;
  const char *id;
  struct id_list *next;
};


/* Version information.  */
struct version
{
  struct version *next;
  struct id_list *local_names;
  struct id_list *global_names;
  const char *versionname;
  const char *parentname;
};


/* Head for list of sections.  */
struct scnhead
{
  /* Name of the sections.  */
  const char *name;

  /* Accumulated flags for the sections.  */
  XElf_Xword flags;

  /* Type of the sections.  */
  XElf_Word type;

  /* Entry size.  If there are differencs between the sections with
     the same name this field contains 1.  */
  XElf_Word entsize;

  /* If non-NULL pointer to group signature.  */
  const char *grp_signature;

  /* Maximum alignment for all sections.  */
  XElf_Word align;

  /* Distinguish between normal sections coming from the input file
     and sections generated by the linker.  */
  enum scn_kind
    {
      scn_normal,		/* Section from the input file(s).  */
      scn_dot_interp,		/* Generated .interp section.  */
      scn_dot_got,		/* Generated .got section.  */
      scn_dot_gotplt,		/* Generated .got.plt section.  */
      scn_dot_dynrel,		/* Generated .rel.dyn section.  */
      scn_dot_dynamic,		/* Generated .dynamic section.  */
      scn_dot_dynsym,		/* Generated .dynsym section.  */
      scn_dot_dynstr,		/* Generated .dynstr section.  */
      scn_dot_hash,		/* Generated .hash section.  */
      scn_dot_gnu_hash,		/* Generated .gnu.hash section.  */
      scn_dot_plt,		/* Generated .plt section.  */
      scn_dot_pltrel,		/* Generated .rel.plt section.  */
      scn_dot_version,		/* Generated .gnu.version section.  */
      scn_dot_version_r,	/* Generated .gnu.version_r section.  */
      scn_dot_note_gnu_build_id	/* Generated .note.gnu.build-id section.  */
    } kind;

  /* True is the section is used in the output.  */
  bool used;

  /* Total size (only determined this way for relocation sections).  */
  size_t relsize;

  /* Filled in by the section sorting to indicate which segment the
     section goes in.  */
  int segment_nr;

  /* Index of the output section.  We cannot store the section handle
     directly here since the handle is a pointer in a dynamically
     allocated table which might move if it becomes too small for all
     the sections.  Using the index the correct value can be found at
     all times.  */
  XElf_Word scnidx;

  /* Index of the STT_SECTION entry for this section in the symbol
     table.  */
  XElf_Word scnsymidx;

  /* Address of the section in the output file.  */
  XElf_Addr addr;

  /* Handle for the section name in the output file's section header
     string table.  */
  struct Ebl_Strent *nameent;

  /* Tail of list of symbols for this section.  Only set if the
     section is merge-able.  */
  struct symbol *symbols;

  /* Pointer to last section.  */
  struct scninfo *last;
};


/* Define hash table for sections.  */
#include <sectionhash.h>

/* Define hash table for version symbols.  */
#include <versionhash.h>


/* State of the linker.  */
struct ld_state
{
  /* ELF backend library handle.  */
  Ebl *ebl;

  /* List of all archives participating, in this order.  */
  struct usedfiles *archives;
  /* End of the list.  */
  struct usedfiles *tailarchives;
  /* If nonzero we are looking for the beginning of a group.  */
  bool group_start_requested;
  /* Pointer to the archive starting the group.  */
  struct usedfiles *group_start_archive;

  /* List of the DSOs we found.  */
  struct usedfiles *dsofiles;
  /* Number of DSO files.  */
  size_t ndsofiles;
  /* Ultimate list of object files which are linked in.  */
  struct usedfiles *relfiles;

  /* List the DT_NEEDED DSOs.  */
  struct usedfiles *needed;

  /* Temporary storage for the parser.  */
  struct filename_list *srcfiles;

  /* List of all the paths to look at.  */
  struct pathelement *paths;
  /* Tail of the list.  */
  struct pathelement *tailpaths;

  /* User provided paths for lookup of DSOs.  */
  struct pathelement *rpath;
  struct pathelement *rpath_link;
  struct pathelement *runpath;
  struct pathelement *runpath_link;
  struct Ebl_Strent *rxxpath_strent;
  int rxxpath_tag;

  /* From the environment variable LD_LIBRARY_PATH.  */
  struct pathelement *ld_library_path1;
  struct pathelement *ld_library_path2;

  /* Name of the output file.  */
  const char *outfname;
  /* Name of the temporary file we initially create.  */
  const char *tempfname;
  /* File descriptor opened for the output file.  */
  int outfd;
  /* The ELF descriptor for the output file.  */
  Elf *outelf;

  /* Type of output file.  */
  enum file_type file_type;

  /* Is this a system library or not.  */
  bool is_system_library;

  /* Page size to be assumed for the binary.  */
  size_t pagesize;

  /* Name of the interpreter for dynamically linked objects.  */
  const char *interp;
  /* Index of the .interp section.  */
  Elf32_Word interpscnidx;

  /* Optimization level.  */
  unsigned long int optlevel;

  /* If true static linking is requested.  */
  bool statically;

  /* If true, add DT_NEEDED entries for following files if they are
     needed.  */
  bool as_needed;

  /* How to extract elements from archives.  */
  enum extract_rule extract_rule;

  /* Sequence number of the last archive we used.  */
  int last_archive_used;

  /* If true print to stdout information about the files we are
     trying to open.  */
  bool trace_files;

  /* If true multiple definitions are not considered an error; the
     first is used.  */
  bool muldefs;

  /* If true undefined symbols when building DSOs are not fatal.  */
  bool nodefs;

  /* If true add line indentifying link-editor to .comment section.  */
  bool add_ld_comment;

  /* Stripping while linking.  */
  enum
    {
      strip_none,
      strip_debug,
      strip_all,
      strip_everything
    } strip;

  /* The callback function vector.  */
  struct callbacks callbacks;

  /* Name of the entry symbol.  Can also be a numeric value.  */
  const char *entry;

  /* The description of the segments in the output file.  */
  struct output_segment *output_segments;

  /* List of the symbols we created from linker script definitions.  */
  struct symbol *lscript_syms;
  size_t nlscript_syms;

  /* Table with known symbols.  */
  ld_symbol_tab symbol_tab;

  /* Table with used sections.  */
  ld_section_tab section_tab;

  /* The list of sections once we collected them.   */
  struct scnhead **allsections;
  size_t nallsections;
  size_t nusedsections;
  size_t nnotesections;

  /* Beginning of the list of symbols which are still unresolved.  */
  struct symbol *unresolved;
  /* Number of truely unresolved entries in the list.  */
  size_t nunresolved;
  /* Number of truely unresolved, non-weak entries in the list.  */
  size_t nunresolved_nonweak;

  /* List of common symbols.  */
  struct symbol *common_syms;
  /* Section for the common symbols.  */
  struct scninfo *common_section;

  /* List of symbols defined in DSOs and used in a relocatable file.
     DSO symbols not referenced in the relocatable files are not on
     the list.  If a symbol is on the list the on_dsolist field in the
     'struct symbol' is nonzero.  */
  struct symbol *from_dso;
  /* Number of entries in from_dso.  */
  size_t nfrom_dso;
  /* Number of entries in the dynamic symbol table.  */
  size_t ndynsym;
  /* Number of PLT entries from DSO references.  */
  size_t nplt;
  /* Number of PLT entries from DSO references.  */
  size_t ngot;
  /* Number of copy relocations.  */
  size_t ncopy;
  /* Section for copy relocations.  */
  struct scninfo *copy_section;

  /* Keeping track of the number of symbols in the output file.  */
  size_t nsymtab;
  size_t nlocalsymbols;

  /* Special symbols.  */
  struct symbol *init_symbol;
  struct symbol *fini_symbol;

  /* The description of the segments in the output file as described
     in the default linker script.  This information will be used in
     addition to the user-provided information.  */
  struct output_segment *default_output_segments;
  /* Search paths added by the default linker script.  */
  struct pathelement *default_paths;

#ifndef BASE_ELF_NAME
  /* The handle of the ld backend library.  */
  void *ldlib;
#endif

  /* String table for the section headers.  */
  struct Ebl_Strtab *shstrtab;

  /* True if output file should contain symbol table.  */
  bool need_symtab;
  /* Symbol table section.  */
  Elf32_Word symscnidx;
  /* Extended section table section.  */
  Elf32_Word xndxscnidx;
  /* Symbol string table section.  */
  Elf32_Word strscnidx;

  /* True if output file should contain dynamic symbol table.  */
  bool need_dynsym;
  /* Dynamic symbol table section.  */
  Elf32_Word dynsymscnidx;
  /* Dynamic symbol string table section.  */
  Elf32_Word dynstrscnidx;
  /* Dynamic symbol hash tables.  */
  size_t hashscnidx;
  size_t gnuhashscnidx;

  /* Procedure linkage table section.  */
  Elf32_Word pltscnidx;
  /* Number of entries already in the PLT section.  */
  size_t nplt_used;
  /* Relocation for procedure linkage table section.  */
  Elf32_Word pltrelscnidx;

  /* Global offset table section.  */
  Elf32_Word gotscnidx;
  /* And the part of the PLT.  */
  Elf32_Word gotpltscnidx;

  /* This section will hole all non-PLT relocations.  */
  Elf32_Word reldynscnidx;

  /* Index of the sections to handle versioning.  */
  Elf32_Word versymscnidx;
  Elf32_Word verneedscnidx;
  /* XXX Should the following names be verneed...?  */
  /* Number of version definitions in input DSOs used.  */
  int nverdefused;
  /* Number of input DSOs using versioning.  */
  int nverdeffile;
  /* Index of next version.  */
  int nextveridx;

  /* Hash table for version symbol strings.  Only strings without
     special characters are hashed here.  */
  ld_version_str_tab version_str_tab;
  /* At most one of the following two variables is set to true if either
     global or local symbol binding is selected as the default.  */
  bool default_bind_local;
  bool default_bind_global;

  /* Execuatable stack selection.  */
  enum execstack
    {
      execstack_false = 0,
      execstack_true,
      execstack_false_force
    } execstack;

  /* True if only used sections are used.  */
  bool gc_sections;

  /* Array to determine final index of symbol.  */
  Elf32_Word *dblindirect;

  /* Section group handling.  */
  struct scngroup
  {
    Elf32_Word outscnidx;
    int nscns;
    struct member
    {
      struct scnhead *scn;
      struct member *next;
    } *member;
    struct Ebl_Strent *nameent;
    struct symbol *symbol;
    struct scngroup *next;
  } *groups;

  /* True if the output file needs a .got section.  */
  bool need_got;
  /* Number of relocations for GOT section caused.  */
  size_t nrel_got;

  /* Number of entries needed in the .dynamic section.  */
  int ndynamic;
  /* To keep track of added entries.  */
  int ndynamic_filled;
  /* Index for the dynamic section.  */
  Elf32_Word dynamicscnidx;

  /* Flags set in the DT_FLAGS word.  */
  Elf32_Word dt_flags;
  /* Flags set in the DT_FLAGS_1 word.  */
  Elf32_Word dt_flags_1;
  /* Flags set in the DT_FEATURE_1 word.  */
  Elf32_Word dt_feature_1;

  /* Lazy-loading state for dependencies.  */
  bool lazyload;

  /* True if an .eh_frame_hdr section should be generated.  */
  bool eh_frame_hdr;

  /* What hash style to generate.  */
  enum
    {
      hash_style_none = 0,
      hash_style_sysv = 1,
#define GENERATE_SYSV_HASH ((ld_state.hash_style & hash_style_sysv) != 0)
      hash_style_gnu = 2
#define GENERATE_GNU_HASH ((ld_state.hash_style & hash_style_gnu) != 0)
    }
  hash_style;


  /* True if in executables all global symbols should be exported in
     the dynamic symbol table.  */
  bool export_all_dynamic;

  /* Build-ID style.  NULL is none.  */
  const char *build_id;
  Elf32_Word buildidscnidx;

  /* If DSO is generated, this is the SONAME.  */
  const char *soname;

  /* List of all relocation sections.  */
  struct scninfo *rellist;
  /* Total size of non-PLT relocations.  */
  size_t relsize_total;

  /* Record for the GOT symbol, if known.  */
  struct symbol *got_symbol;
  /* Record for the dynamic section symbol, if known.  */
  struct symbol *dyn_symbol;

  /* Obstack used for small objects which will not be deleted.  */
  struct obstack smem;
};


/* The interface to the scanner.  */

/* Parser entry point.  */
extern int ldparse (void);

/* The input file.  */
extern FILE *ldin;

/* Name of the input file.  */
extern const char *ldin_fname;

/* Current line number.  Must be reset for a new file.  */
extern int ldlineno;

/* If nonzero we are currently parsing a version script.  */
extern int ld_scan_version_script;

/* Flags defined in ld.c.  */
extern int verbose;
extern int conserve_memory;


/* Linker state.  This contains all global information.  */
extern struct ld_state ld_state;


/* Generic ld helper functions.  */

/* Append a new directory to search libraries in.  */
extern void ld_new_searchdir (const char *dir);

/* Append a new file to the list of input files.  */
extern struct usedfiles *ld_new_inputfile (const char *fname,
					   enum file_type type);


/* These are the generic implementations for the callbacks used by ld.  */

/* Initialize state object.  This callback function is called after the
   parameters are parsed but before any file is searched for.  */
extern int ld_prepare_state (const char *emulation);


/* Function to determine whether an object will be dynamically linked.  */
extern bool dynamically_linked_p (void);

/* Helper functions for the architecture specific code.  */

/* Checked whether the symbol is undefined and referenced from a DSO.  */
extern bool linked_from_dso_p (struct scninfo *scninfo, size_t symidx);
#ifdef __GNUC_STDC_INLINE__
__attribute__ ((__gnu_inline__))
#endif
extern inline bool
linked_from_dso_p (struct scninfo *scninfo, size_t symidx)
{
  struct usedfiles *file = scninfo->fileinfo;

  /* If this symbol is not undefined in this file it cannot come from
     a DSO.  */
  if (symidx < file->nlocalsymbols)
    return false;

  struct symbol *sym = file->symref[symidx];

  return sym->defined && sym->in_dso;
}

#endif	/* ld.h */