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
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1988 AT&T
* All Rights Reserved
*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Local include file for ld library.
*/
#ifndef _LIBLD_DOT_H
#define _LIBLD_DOT_H
#include <libld.h>
#include <_libelf.h>
#include <debug.h>
#include <conv.h>
#include <msg.h>
#include <reloc_defs.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* In order to allow for cross linking, we need to be able to build
* libld with support for multiple targets within a single object.
* This is done using a global variable (ld_targ) of type Target to
* access target-specific code for the current target via indirection.
*/
/*
* Machine information for target
*/
typedef struct {
Half m_mach; /* ELF machine code for target */
Half m_machplus; /* Alt ELF machine code for target */
/* Used for EM_SPARC32PLUS */
Word m_flagsplus; /* ELF header flags used to identify */
/* a machplus object */
uchar_t m_class; /* Target ELFCLASS */
uchar_t m_data; /* Target byte order */
Xword m_segm_align; /* segment alignment */
Xword m_segm_origin; /* Default 1st segment origin */
Xword m_segm_aorigin; /* Alternative 1st segment origin */
Word m_dataseg_perm; /* data segment permission mask */
Word m_stack_perm; /* ABI default stack permission mask */
Word m_word_align; /* alignment to use for Word sections */
const char *m_def_interp; /* Def. interpreter for dyn objects */
/* Relocation type codes */
Word m_r_arrayaddr;
Word m_r_copy;
Word m_r_glob_dat;
Word m_r_jmp_slot;
Word m_r_num;
Word m_r_none;
Word m_r_relative;
Word m_r_register;
/* Relocation related constants */
Word m_rel_dt_count; /* Either DT_REL or DT_RELA */
Word m_rel_dt_ent; /* Either DT_RELENT or DT_RELAENT */
Word m_rel_dt_size; /* Either DT_RELSZ or DT_RELASZ */
Word m_rel_dt_type; /* Either DT_RELCOUNT or DT_RELACOUNT */
Word m_rel_sht_type; /* Either SHT_REL or SHT_RELA */
/* GOT related constants */
Word m_got_entsize;
Word m_got_xnumber; /* reserved # of got ents */
/* PLT related constants */
Word m_plt_align;
Word m_plt_entsize;
Word m_plt_reservsz;
Word m_plt_shf_flags;
/* Section type of .eh_frame/.eh_frame_hdr sections */
Word m_sht_unwind;
Word m_dt_register;
} Target_mach;
/*
* Section identifiers, used to order sections in output object
*/
typedef struct {
Word id_array;
Word id_bss;
Word id_cap;
Word id_capinfo;
Word id_capchain;
Word id_data;
Word id_dynamic;
Word id_dynsort;
Word id_dynstr;
Word id_dynsym;
Word id_dynsym_ndx;
Word id_got;
Word id_gotdata;
Word id_hash;
Word id_interp;
Word id_lbss;
Word id_ldynsym;
Word id_note;
Word id_null;
Word id_plt;
Word id_rel;
Word id_strtab;
Word id_syminfo;
Word id_symtab;
Word id_symtab_ndx;
Word id_text;
Word id_tls;
Word id_tlsbss;
Word id_unknown;
Word id_unwind;
Word id_unwindhdr;
Word id_user;
Word id_version;
} Target_machid;
/*
* Target_nullfunc supplies machine code for generating a
*
* void (*)(void)
*
* unnamed function. Such a function can be called, and returns
* immediately without doing any work. This is used to back FUNC
* symbol definitions added with a mapfile.
*
* The machine instructions are specified as an array of bytes rather
* than a larger integer type in order to avoid byte order issues that
* can otherwise occur in cross linking.
*/
typedef struct {
const uchar_t *nf_template; /* Array of machine inst. bytes */
size_t nf_size; /* # bytes in nf_template */
} Target_nullfunc;
/*
* Target_fill supplies machine code for fill bytes in executable output
* sections. Normally, libelf fills the gaps caused by alignment and size
* requirements of the constituent input sections with 0. Depending on the
* target architecture, it may be desirable to instead fill with executable
* NOP instructions. There are two reasons to do this:
*
* - So that .init/.fini sections will not contain unexecutable gaps
* that cause the executing program to trap and die.
*
* - To eliminate confusing garbage instructions between sections containing
* executable code when viewed with a disassembler.
*
* The ff_execfill function is allowed to be NULL if the underlying target
* does not require a special fill for executable sections.
*/
typedef struct {
_elf_execfill_func_t *ff_execfill;
} Target_fillfunc;
/*
* Target_machrel holds pointers to the reloc_table and machrel functions
* for a given target machine.
*
* The following function pointers are allowed to be NULL, if the
* underlying target does not require the specified operation. All
* other functions must be supplied:
*
* mr_assign_got
* mr_reloc_register
* mr_reloc_GOTOP
* mr_allocate_got
*/
typedef struct {
const Rel_entry *mr_reloc_table;
Word (* mr_init_rel)(Rel_desc *, Word *, void *);
void (* mr_mach_eflags)(Ehdr *, Ofl_desc *);
void (* mr_mach_make_dynamic)(Ofl_desc *, size_t *);
void (* mr_mach_update_odynamic)(Ofl_desc *, Dyn **);
Xword (* mr_calc_plt_addr)(Sym_desc *, Ofl_desc *);
uintptr_t (* mr_perform_outreloc)(Rel_desc *, Ofl_desc *,
Boolean *);
uintptr_t (* mr_do_activerelocs)(Ofl_desc *);
uintptr_t (* mr_add_outrel)(Word, Rel_desc *, Ofl_desc *);
uintptr_t (* mr_reloc_register)(Rel_desc *, Is_desc *,
Ofl_desc *);
uintptr_t (* mr_reloc_local)(Rel_desc *, Ofl_desc *);
uintptr_t (* mr_reloc_GOTOP)(Boolean, Rel_desc *, Ofl_desc *);
uintptr_t (* mr_reloc_TLS)(Boolean, Rel_desc *, Ofl_desc *);
uintptr_t (* mr_assign_got)(Ofl_desc *, Sym_desc *);
Gotndx *(* mr_find_got_ndx)(Alist *, Gotref, Ofl_desc *,
Rel_desc *);
Xword (* mr_calc_got_offset)(Rel_desc *, Ofl_desc *);
uintptr_t (* mr_assign_got_ndx)(Alist **, Gotndx *, Gotref,
Ofl_desc *, Rel_desc *, Sym_desc *);
void (* mr_assign_plt_ndx)(Sym_desc *, Ofl_desc *);
uintptr_t (* mr_allocate_got)(Ofl_desc *);
uintptr_t (* mr_fillin_gotplt)(Ofl_desc *);
} Target_machrel;
/*
* Target_machsym holds pointers to the machsym functions
* for a given target machine.
*
* These fields are allowed to be NULL for targets that do not require
* special handling of register symbols. Register symbols are used by
* sparc targets. If any of these fields are non-NULL, all of them are
* required to be present (use empty stub routines if necessary).
*/
typedef struct {
int (* ms_reg_check)(Sym_desc *, Sym *, const char *,
Ifl_desc *, Ofl_desc *);
int (* ms_mach_sym_typecheck)(Sym_desc *, Sym *,
Ifl_desc *, Ofl_desc *);
const char *(* ms_is_regsym)(Ofl_desc *, Ifl_desc *, Sym *,
const char *, int, Word, const char *, sd_flag_t *);
Sym_desc *(* ms_reg_find)(Sym * sym, Ofl_desc * ofl);
int (* ms_reg_enter)(Sym_desc *, Ofl_desc *);
} Target_machsym;
typedef struct {
Target_mach t_m;
Target_machid t_id;
Target_nullfunc t_nf;
Target_fillfunc t_ff;
Target_machrel t_mr;
Target_machsym t_ms;
} Target;
/*
* Structure to manage the update of weak symbols from their associated alias.
*/
typedef struct wk_desc {
Sym *wk_symtab; /* the .symtab entry */
Sym *wk_dynsym; /* the .dynsym entry */
Sym_desc *wk_weak; /* the original weak symbol */
Sym_desc *wk_alias; /* the real symbol */
} Wk_desc;
/*
* Structure to manage the support library interfaces.
*/
typedef struct func_list {
const char *fl_obj; /* name of support object */
/* function is from */
void (*fl_fptr)(); /* function pointer */
uint_t fl_version; /* ld_version() level */
} Func_list;
typedef struct support_list {
const char *sup_name; /* ld_support function name */
Alist *sup_funcs; /* list of support functions */
} Support_list;
/*
* Structure to manage a sorted output relocation list.
*
* rl_key1 -> pointer to needed ndx
* rl_key2 -> pointer to symbol relocation is against
* rl_key3 -> virtual offset of relocation
*/
typedef struct reloc_list {
Sym_desc *rl_key2;
Xword rl_key3;
Rel_desc *rl_rsp;
Half rl_key1;
} Reloc_list;
typedef struct sym_s_list {
Word sl_hval;
Sym_desc *sl_sdp;
} Sym_s_list;
/*
* Dynamic per-symbol filtee string table descriptor. This associates filtee
* strings that will be created in the .dynstr, with .dynamic entries.
*/
typedef struct {
const char *dft_str; /* dynstr string */
Word dft_flag; /* auxiliary/filtee type */
Half dft_ndx; /* eventual ndx into .dynamic */
} Dfltr_desc;
/*
* Per-symbol filtee descriptor. This associates symbol definitions with
* their filtees.
*/
typedef struct {
Sym_desc *sft_sdp; /* symbol descriptor */
Aliste sft_idx; /* index into dtstr descriptor */
} Sfltr_desc;
/*
* Capabilities descriptor, and capabilities group descriptor, used to track
* the symbol capabilities of any input files and the output file.
*
* A relocatable object input file may contain one or more symbol capabilities
* groups. The Cap_desc structures keep track of all unique groups that are
* collected for the output file. Relocatable objects that contain an object
* capabilities group, and the -z symbolcap option is in effect, have their
* object group translated to a symbol capabilities group.
*
* Individual capabilities groups are maintained with the Cap_group descriptor.
* A group can consist of one or more capabilities definitions. One or more
* symbols can be associated with each group.
*
* For the output file, capabilities families are used to track the symbols of
* a given family, each symbol being associated with a different group. This
* collection of data is used to create the final Capinfo structure, and for
* dynamic objects, the Capchain structure.
*
* For example, an object may contain two capabilities groups:
*
* CA_SUNW_MACH - sun4u CA_SUNW_MACH - sun4v
*
* Two symbols can be associated with each group:
*
* foo%sun4u foo%sun4v
* bar%sun4u bar%sun4v
*
* Two families are maintained, and include the generic, or lead, instance of
* the capabilities members:
*
* foo, foo%sun4u, foo%sun4v
* bar, bar%sun4u, bar%sun4v
*/
struct cap_desc {
APlist *ca_groups; /* capabilities groups (Cap_group) */
APlist *ca_syms; /* copies of symbols that are being */
/* translated from object to */
}; /* symbol capabilities */
typedef struct {
Objcapset cg_set; /* unpacked SHT_SUNW_cap elements */
APlist *cg_secs; /* sections, and hence files, that */
/* use this descriptor */
Word cg_num; /* number of comparable elements in */
/* the group */
Word cg_ndx; /* final capability group index */
} Cap_group;
/*
* A Capabilities family node, extends a symbol node, and provides for tracking
* capabilities families. A family is defined by its lead symbol (for example,
* a generic, non-capabilities aware foo()), and one or more capabilities
* members (for example, capabilities instances foo%sun4u(), foo%sun4v(), etc.).
*
* Each member associates a symbol with its group using a Cap_sym structure.
*/
typedef struct {
Sym_avlnode cn_symavlnode;
APlist *cn_members;
APlist *cn_aliases;
} Cap_avlnode;
typedef struct {
Sym_desc *cs_sdp; /* capabilities symbol descriptor */
Cap_group *cs_group; /* associated capabilities group */
} Cap_sym;
/*
* Define Alist initialization sizes.
*/
#define AL_CNT_IFL_GROUPS 20 /* ifl_groups */
#define AL_CNT_IFL_RELSECS 6 /* ifl_relsect */
#define AL_CNT_CAP_DESCS 4 /* symbol capabilities descriptors */
#define AL_CNT_CAP_SYMS 20 /* capabilities symbols */
#define AL_CNT_CAP_SECS 10 /* capabilities sections */
#define AL_CNT_CAP_NAMES 10 /* Objcapset platform and machine */
/* names */
#define AL_CNT_CAP_MEMS 10 /* capability family members */
#define AL_CNT_CAP_PAIRS 10 /* capability symbol pairs */
#define AL_CNT_CAP_ALIASES 2 /* capability lead symbol aliases */
#define AL_CNT_OFL_DTSFLTRS 4 /* ofl_dtsfltrs */
#define AL_CNT_OFL_SYMFLTRS 20 /* ofl_symfltrs */
#define AL_CNT_OFL_MAPSECS 10 /* ofl_map{text|data} */
#define AL_CNT_OFL_OBJS 50 /* ofl_objs */
#define AL_CNT_OFL_LIBS 10 /* ofl_sos */
#define AL_CNT_OFL_LIBDIRS 10 /* ofl_[ud]libdirs */
#define AL_CNT_OFL_MAPFILES 6 /* ofl_maps */
#define AL_CNT_OFL_ENTRANCE 10 /* ofl_ents */
#define AL_CNT_OFL_RELS 4 /* ofl_outrels */
#define AL_CNT_OFL_COPYRELS 10 /* ofl_copyrels */
#define AL_CNT_OFL_ARRAYS 10 /* ofl_{init|fini|prei}array */
#define AL_CNT_OFL_OSGROUPS 10 /* ofl_osgroups */
#define AL_CNT_OFL_OSTLSSEG 4 /* ofl_ostlsseg */
#define AL_CNT_OFL_ORDERED 4 /* ofl_ordered */
#define AL_CNT_OFL_SYMINFOSYMS 50 /* ofl_syminfsyms */
#define AL_CNT_OFL_MOVE 10 /* ofl_ismove */
#define AL_CNT_OFL_UNWIND 1 /* ofl_unwind */
#define AL_CNT_OFL_PARSYMS 10 /* ofl_parsyms */
#define AL_CNT_OS_MSTRISDESCS 10 /* os_mstrisdescs */
#define AL_CNT_OS_RELISDESCS 100 /* os_relisdescs */
#define AL_CNT_OS_COMDATS 20 /* os_comdats */
#define AL_CNT_OS_ISDESCS_BA 4 /* os_isdesc: BEFORE|AFTER */
#define AL_CNT_OS_ISDESCS 60 /* os_isdesc: ORDERED|DEFAULT */
#define AL_CNT_SG_IS_ORDER 40 /* sg_is_order */
#define AL_CNT_SG_OSDESC 40 /* sg_osdescs */
#define AL_CNT_SG_SECORDER 40 /* sg_secorder */
#define AL_CNT_SG_SIZESYM 1 /* sg_sizesym */
#define AL_CNT_SDP_GOT 1 /* sd_GOTndxs */
#define AL_CNT_SDP_MOVE 1 /* sd_move */
#define AL_CNT_SDP_DFILES 1 /* sa_dfiles */
#define AL_CNT_SDF_VERSIONS 2 /* sdf_{vers|verneed} */
#define AL_CNT_EC_FILES 1 /* ec_files */
#define AL_CNT_VERDESCS 20 /* version desc */
#define AL_CNT_WEAK 20 /* weak desc */
#define AL_CNT_SUPPORT 2 /* support libraries */
#define AL_CNT_STRMRGREL 500 /* ld_make_strmerge() reloc alist cnt */
#define AL_CNT_STRMRGSYM 20 /* ld_make_strmerge() sym alist cnt */
#define AL_CNT_SEGMENTS 20 /* ofl_segs */
#define AL_CNT_ASSDEFLIB 4 /* ofl_assdeflib exceptions count */
#define AL_CNT_MAPASSERT 10 /* mapfile assertions */
/*
* Return codes for {tls|got}_fixups() routines
*/
typedef enum {
FIX_ERROR, /* fatal error - time to punt */
FIX_DONE, /* relocation done - no further processing required */
FIX_RELOC /* do_reloc() relocation processing required */
} Fixupret;
#ifndef FILENAME_MAX
#define FILENAME_MAX BUFSIZ /* maximum length of a path name */
#endif
/*
* We pad the end of the .dynstr section with a block of DYNSTR_EXTRA_PAD
* bytes, and we insert DYNAMIC_EXTRA_ELTS unused items into the
* .dynamic section (with value DT_NULL). This provides the resources needed
* to add and/or alter string items in the .dynamic section, such as runpath.
*/
#define DYNSTR_EXTRA_PAD 512
#define DYNAMIC_EXTRA_ELTS 10
/*
* Default relocation cache allocation unit. This number should be small
* enough to not hurt memory use significantly, but large enough to avoid
* the need for too many subsequent allocations.
*/
#define REL_CACHEBUF_ALLOC 3000
#define RELAUX_CACHEBUF_ALLOC 1500
/*
* Given a symbol of a type that is allowed within a .SUNW_dynsymsort or
* .SUNW_dyntlssort section, examine the symbol attributes to determine
* if this particular symbol should be included or not.
*
* entry:
* The symbol must have an allowed type: Either a type verified by
* dynsymsort_symtype[] or STT_TLS.
*
* _sdp - Pointer to symbol descriptor
* _sym - Pointer to symbol referenced by _sdp.
*
* _sym is derivable from _sdp: _sdp->sd_sym
* However, most callers assign it to a local variable for efficiency,
* and this macro allows such a variable to be used within. If you
* don't have such a variable, supply _sdp->sd_sym.
*
* The tests used require some explanation:
*
* (_sdp->sd_flags & FLG_SY_DYNSORT)
* Some special symbols are kept even if they don't meet the
* usual requirements. These symbols have the FLG_SY_DYNSORT
* bit set. If this bit isn't set then we look at the other
* attributes.
*
* (((_sdp->sd_ref != REF_DYN_NEED) &&
* (_sdp->sd_sym->st_shndx != SHN_UNDEF))
* || (_sdp->sd_flags & FLG_SY_MVTOCOMM))
* We do not want to include symbols that are not defined within
* the object we are creating. REF_DYN_NEED corresponds to those
* UNDEF items. However, if the symbol is the target of a copy
* relocation, then it effectively becomes defined within the
* object after all. FLG_SY_MVTOCOMM indicates a copy relocation,
* and prevents us from culling those exceptions.
*
* (_sym->st_size != 0)
* Symbols with 0 length are labels injected by the compilers
* or the linker for purposes of code generation, and do
* not directly correspond to actual code. In fact, most of the
* symbols we mark with FLG_SY_DYNSORT need that flag set because
* they have size 0. This size test filters out the others.
*
* !(_sdp->sd_flags & FLG_SY_NODYNSORT)
* Some symbols are not kept, even though they do meet the usual
* requirements. These symbols have FLG_SY_NODYNSORT set.
* For example, if there are weak and non-weak versions of a given
* symbol, we only want to keep one of them. So, we set
* FLG_SY_NODYNSORT on the one we don't want.
*/
#define DYNSORT_TEST_ATTR(_sdp, _sym) \
((_sdp->sd_flags & FLG_SY_DYNSORT) || \
((((_sdp->sd_ref != REF_DYN_NEED) && \
(_sdp->sd_sym->st_shndx != SHN_UNDEF)) || \
(_sdp->sd_flags & FLG_SY_MVTOCOMM)) && \
(_sym->st_size != 0) && \
!(_sdp->sd_flags & FLG_SY_NODYNSORT)))
/*
* We use output section descriptor counters to add up the number of
* symbol indexes to put in the .SUNW_dynsort and .SUNW_dyntlssort sections.
* Non-TLS symbols are counted by ofl->ofl_dynsymsortcnt, while TLS symbols are
* counted by ofl->ofl_dyntlssortcnt. This computation is done inline in
* several places. The DYNSORT_COUNT macro allows us to generate this from
* a single description.
*
* entry:
* _sdp, _sym - As per DYNSORT_TEST_ATTR
* _type - Type of symbol (STT_*)
* _inc_or_dec_op - Either ++, or --. This specifies the operation
* to be applied to the counter, and determines whether we
* are adding, or removing, a symbol from .SUNW_dynsymsort.
*
* Note that _type is derivable from _sym: ELF_ST_TYPE(_sdp->sd_sym->st_info).
* Most callers already have it in a variable, so this allows us to use that
* variable. If you don't have such a variable, use ELF_ST_TYPE() as shown.
*/
#define DYNSORT_COUNT(_sdp, _sym, _type, _inc_or_dec_op) \
{ \
Word *_cnt_var; \
\
if (dynsymsort_symtype[_type]) { /* Non-TLS counter */ \
_cnt_var = &ofl->ofl_dynsymsortcnt; \
} else if ((_type) == STT_TLS) { /* TLS counter */ \
_cnt_var = &ofl->ofl_dyntlssortcnt; \
} else { /* Don't count this symbol */ \
_cnt_var = NULL; \
} \
if ((_cnt_var != NULL) && DYNSORT_TEST_ATTR(_sdp, _sym)) \
(*_cnt_var)_inc_or_dec_op; /* Increment/Decrement */ \
}
/*
* The OFL_SWAP_RELOC macros are used to determine whether
* relocation processing needs to swap the data being relocated.
* It is an optimization to ld_swap_reloc_data(), as it avoids
* the function call in the case where the linker host and the
* target have the same byte order.
*/
#define OFL_SWAP_RELOC_DATA(_ofl, _rel) \
(((_ofl)->ofl_flags1 & FLG_OF1_ENCDIFF) && \
ld_swap_reloc_data(_ofl, _rel))
/*
* Define an AVL node for maintaining input section descriptors. AVL trees of
* these descriptors are used to process group and COMDAT section.
*
* Pure COMDAT uses the input section name as the search key, while
* SHT_GROUP sections use the name of a special signature symbol. We
* support both by using the isd_name field to carry the name. An alternative
* design would be to use a separate type for each use, saving the cost
* of the unneeded pointer for pure COMDAT. We favor a single implementation
* because we believe that SHT_GROUP comdat will be more common going forward,
* particularly in the largest objects produced by C++ where SHT_GROUP is
* needed to manage the complex section relationships. In contrast, we think
* that pure COMDAT is both more rare, and used in smaller objects where the
* cost of an extra pointer per node is relatively unimportant.
*/
typedef struct {
avl_node_t isd_avl; /* avl book-keeping (see SGSOFFSETOF) */
Is_desc *isd_isp; /* input section descriptor */
const char *isd_name; /* name used as search key */
uint_t isd_hash; /* input section name hash value */
} Isd_node;
/*
* Type used to break down an input file path into its component parts,
* as used by ld_place_section() to compare an input file path to
* entrance criteria ec_files file strings.
*
* We define a path in the usual Unix '/' separated manner, augmented
* with an optional archive member suffix enclosed in parenthesis:
*
* /dir/.../dir/basename(armember)
*
* The basename is the final path component, and includes the archive
* member, if present. The meaning of "object name" depends on whether or
* not the file comes from an archive or not. If not an archive, it is the
* same as the basename. If an archive, it is the name of the archive member
* from within the file.
*
* Variables of this type are initialized with ld_place_path_info_init().
*/
typedef struct {
const char *ppi_path; /* Full path */
const char *ppi_bname; /* basename(ppi_path) */
const char *ppi_oname; /* object name: Not NULL terminated */
Boolean ppi_isar; /* TRUE if path has archive member */
size_t ppi_path_len; /* strlen(ppi_path) */
size_t ppi_bname_len; /* strlen(ppi_bname) */
size_t ppi_oname_len; /* strlen(ppi_oname) */
} Place_path_info;
/*
* Local data items.
*/
extern char *Plibpath;
extern char *Llibdir;
extern char *Ulibdir;
extern APlist *lib_support;
extern int demangle_flag;
extern const Msg reject[];
extern int Verbose;
extern const int ldynsym_symtype[];
extern const int dynsymsort_symtype[];
/*
* Local functions.
*/
extern char *add_string(char *, char *);
extern const char *demangle(const char *);
extern int cap_names_match(Alist *, Alist *);
extern void lds_atexit(Ofl_desc *, int);
/*
* Note that libld has a long history of assuming that all allocations are
* 0-initialized. libld_malloc must maintain this.
*/
#define libld_free(x) free(x)
#define libld_malloc(x) calloc(1, x)
#define libld_realloc(x, s) realloc(x, s)
#define libld_calloc(n, s) calloc(n, s)
extern int isdavl_compare(const void *, const void *);
extern Sdf_desc *sdf_add(const char *, APlist **);
extern Sdf_desc *sdf_find(const char *, APlist *);
#if defined(_ELF64)
#define ld_add_actrel ld64_add_actrel
#define ld_add_libdir ld64_add_libdir
#define ld_adj_movereloc ld64_adj_movereloc
#define ld_am_I_partial ld64_am_I_partial
#define ld_ar_member ld64_ar_member
#define ld_ar_setup ld64_ar_setup
#define ld_assign_got_TLS ld64_assign_got_TLS
#define ld_bswap_Word ld64_bswap_Word
#define ld_bswap_Xword ld64_bswap_Xword
#define ld_cap_add_family ld64_cap_add_family
#define ld_cap_move_symtoobj ld64_cap_move_symtoobj
#define ld_comdat_validate ld64_comdat_validate
#define ld_disp_errmsg ld64_disp_errmsg
#define ld_ent_check ld64_ent_check
#define ld_ent_lookup ld64_ent_lookup
#define ld_eprintf ld64_eprintf
#define ld_exit ld64_exit
#define ld_find_library ld64_find_library
#define ld_finish_libs ld64_finish_libs
#define ld_get_group ld64_get_group
#define ld_group_process ld64_group_process
#define ld_lib_setup ld64_lib_setup
#define ld_init_sighandler ld64_init_sighandler
#define ld_lcm ld64_lcm
#define ld_make_bss ld64_make_bss
#define ld_make_data ld64_make_data
#define ld_make_got ld64_make_got
#define ld_make_parexpn_data ld64_make_parexpn_data
#define ld_make_sunwmove ld64_make_sunmove
#define ld_make_text ld64_make_text
#define ld_map_out ld64_map_out
#define ld_map_parse ld64_map_parse
#define ld_map_post_process ld64_map_post_process
#define ld_open_outfile ld64_open_outfile
#define ld_os_first_isdesc ld64_os_first_isdesc
#define ld_place_path_info_init ld64_place_path_info_init
#define ld_place_section ld64_place_section
#define ld_process_archive ld64_process_archive
#define ld_process_files ld64_process_files
#define ld_process_flags ld64_process_flags
#define ld_process_ifl ld64_process_ifl
#define ld_process_move ld64_process_move
#define ld_process_open ld64_process_open
#define ld_process_ordered ld64_process_ordered
#define ld_process_sym_reloc ld64_process_sym_reloc
#define ld_reloc_enter ld64_reloc_enter
#define ld_reloc_GOT_relative ld64_reloc_GOT_relative
#define ld_reloc_plt ld64_reloc_plt
#define ld_reloc_remain_entry ld64_reloc_remain_entry
#define ld_reloc_set_aux_osdesc ld64_reloc_set_aux_osdesc
#define ld_reloc_set_aux_usym ld64_reloc_set_aux_usym
#define ld_reloc_sym_name ld64_reloc_sym_name
#define ld_reloc_targval_get ld64_reloc_targval_get
#define ld_reloc_targval_set ld64_reloc_targval_set
#define ld_sec_validate ld64_sec_validate
#define ld_seg_lookup ld64_seg_lookup
#define ld_sort_ordered ld64_sort_ordered
#define ld_stt_section_sym_name ld64_stt_section_sym_name
#define ld_sunw_ldmach ld64_sunw_ldmach
#define ld_sup_atexit ld64_sup_atexit
#define ld_sup_open ld64_sup_open
#define ld_sup_file ld64_sup_file
#define ld_sup_loadso ld64_sup_loadso
#define ld_sup_input_done ld64_sup_input_done
#define ld_sup_input_section ld64_sup_input_section
#define ld_sup_section ld64_sup_section
#define ld_sup_start ld64_sup_start
#define ld_swap_reloc_data ld64_swap_reloc_data
#define ld_sym_add_u ld64_sym_add_u
#define ld_sym_adjust_vis ld64_sym_adjust_vis
#define ld_sym_avl_comp ld64_sym_avl_comp
#define ld_sym_copy ld64_sym_copy
#define ld_sym_enter ld64_sym_enter
#define ld_sym_find ld64_sym_find
#define ld_sym_nodirect ld64_sym_nodirect
#define ld_sym_process ld64_sym_process
#define ld_sym_resolve ld64_sym_resolve
#define ld_sym_reducable ld64_sym_reducable
#define ld_sym_spec ld64_sym_spec
#define ld_targ ld64_targ
#define ld_targ_init_sparc ld64_targ_init_sparc
#define ld_targ_init_x86 ld64_targ_init_x86
#define ld_unwind_make_hdr ld64_unwind_make_hdr
#define ld_unwind_populate_hdr ld64_unwind_populate_hdr
#define ld_unwind_register ld64_unwind_register
#define ld_vers_base ld64_vers_base
#define ld_vers_check_defs ld64_vers_check_defs
#define ld_vers_check_need ld64_vers_check_need
#define ld_vers_def_process ld64_vers_def_process
#define ld_vers_desc ld64_vers_desc
#define ld_vers_find ld64_vers_find
#define ld_vers_need_process ld64_vers_need_process
#define ld_vers_promote ld64_vers_promote
#define ld_vers_sym_process ld64_vers_sym_process
#define ld_vers_verify ld64_vers_verify
#define ld_wrap_enter ld64_wrap_enter
#else
#define ld_add_actrel ld32_add_actrel
#define ld_add_libdir ld32_add_libdir
#define ld_adj_movereloc ld32_adj_movereloc
#define ld_am_I_partial ld32_am_I_partial
#define ld_ar_member ld32_ar_member
#define ld_ar_setup ld32_ar_setup
#define ld_assign_got_TLS ld32_assign_got_TLS
#define ld_bswap_Word ld32_bswap_Word
#define ld_bswap_Xword ld32_bswap_Xword
#define ld_cap_add_family ld32_cap_add_family
#define ld_cap_move_symtoobj ld32_cap_move_symtoobj
#define ld_comdat_validate ld32_comdat_validate
#define ld_disp_errmsg ld32_disp_errmsg
#define ld_ent_check ld32_ent_check
#define ld_ent_lookup ld32_ent_lookup
#define ld_eprintf ld32_eprintf
#define ld_exit ld32_exit
#define ld_find_library ld32_find_library
#define ld_finish_libs ld32_finish_libs
#define ld_get_group ld32_get_group
#define ld_group_process ld32_group_process
#define ld_lib_setup ld32_lib_setup
#define ld_init_sighandler ld32_init_sighandler
#define ld_lcm ld32_lcm
#define ld_make_bss ld32_make_bss
#define ld_make_data ld32_make_data
#define ld_make_got ld32_make_got
#define ld_make_parexpn_data ld32_make_parexpn_data
#define ld_make_sunwmove ld32_make_sunmove
#define ld_make_text ld32_make_text
#define ld_map_out ld32_map_out
#define ld_map_parse ld32_map_parse
#define ld_map_post_process ld32_map_post_process
#define ld_open_outfile ld32_open_outfile
#define ld_os_first_isdesc ld32_os_first_isdesc
#define ld_place_path_info_init ld32_place_path_info_init
#define ld_place_section ld32_place_section
#define ld_process_archive ld32_process_archive
#define ld_process_files ld32_process_files
#define ld_process_flags ld32_process_flags
#define ld_process_ifl ld32_process_ifl
#define ld_process_move ld32_process_move
#define ld_process_open ld32_process_open
#define ld_process_ordered ld32_process_ordered
#define ld_process_sym_reloc ld32_process_sym_reloc
#define ld_reloc_enter ld32_reloc_enter
#define ld_reloc_GOT_relative ld32_reloc_GOT_relative
#define ld_reloc_plt ld32_reloc_plt
#define ld_reloc_remain_entry ld32_reloc_remain_entry
#define ld_reloc_set_aux_osdesc ld32_reloc_set_aux_osdesc
#define ld_reloc_set_aux_usym ld32_reloc_set_aux_usym
#define ld_reloc_sym_name ld32_reloc_sym_name
#define ld_reloc_targval_get ld32_reloc_targval_get
#define ld_reloc_targval_set ld32_reloc_targval_set
#define ld_sec_validate ld32_sec_validate
#define ld_seg_lookup ld32_seg_lookup
#define ld_sort_ordered ld32_sort_ordered
#define ld_stt_section_sym_name ld32_stt_section_sym_name
#define ld_sunw_ldmach ld32_sunw_ldmach
#define ld_sup_atexit ld32_sup_atexit
#define ld_sup_open ld32_sup_open
#define ld_sup_file ld32_sup_file
#define ld_sup_loadso ld32_sup_loadso
#define ld_sup_input_done ld32_sup_input_done
#define ld_sup_input_section ld32_sup_input_section
#define ld_sup_section ld32_sup_section
#define ld_sup_start ld32_sup_start
#define ld_swap_reloc_data ld32_swap_reloc_data
#define ld_sym_add_u ld32_sym_add_u
#define ld_sym_adjust_vis ld32_sym_adjust_vis
#define ld_sym_avl_comp ld32_sym_avl_comp
#define ld_sym_copy ld32_sym_copy
#define ld_sym_enter ld32_sym_enter
#define ld_sym_find ld32_sym_find
#define ld_sym_nodirect ld32_sym_nodirect
#define ld_sym_process ld32_sym_process
#define ld_sym_resolve ld32_sym_resolve
#define ld_sym_reducable ld32_sym_reducable
#define ld_sym_spec ld32_sym_spec
#define ld_targ ld32_targ
#define ld_targ_init_sparc ld32_targ_init_sparc
#define ld_targ_init_x86 ld32_targ_init_x86
#define ld_unwind_make_hdr ld32_unwind_make_hdr
#define ld_unwind_populate_hdr ld32_unwind_populate_hdr
#define ld_unwind_register ld32_unwind_register
#define ld_vers_base ld32_vers_base
#define ld_vers_check_defs ld32_vers_check_defs
#define ld_vers_check_need ld32_vers_check_need
#define ld_vers_def_process ld32_vers_def_process
#define ld_vers_desc ld32_vers_desc
#define ld_vers_find ld32_vers_find
#define ld_vers_need_process ld32_vers_need_process
#define ld_vers_promote ld32_vers_promote
#define ld_vers_sym_process ld32_vers_sym_process
#define ld_vers_verify ld32_vers_verify
#define ld_wrap_enter ld32_wrap_enter
#endif
extern void dbg_cleanup(void);
extern int dbg_setup(Ofl_desc *, const char *, int);
extern uintptr_t ld_add_actrel(Word, Rel_desc *, Ofl_desc *);
extern uintptr_t ld_add_libdir(Ofl_desc *, const char *);
extern void ld_adj_movereloc(Ofl_desc *, Rel_desc *);
extern Sym_desc * ld_am_I_partial(Rel_desc *, Xword);
extern void ld_ar_member(Ar_desc *, Elf_Arsym *, Ar_aux *,
Ar_mem *);
extern Ar_desc *ld_ar_setup(const char *, Elf *, Ofl_desc *);
extern uintptr_t ld_assign_got_TLS(Boolean, Rel_desc *, Ofl_desc *,
Sym_desc *, Gotndx *, Gotref, Word, Word,
Word, Word);
extern Word ld_bswap_Word(Word);
extern Xword ld_bswap_Xword(Xword);
extern uintptr_t ld_cap_add_family(Ofl_desc *, Sym_desc *, Sym_desc *,
Cap_group *, APlist **);
extern void ld_cap_move_symtoobj(Ofl_desc *);
extern void ld_comdat_validate(Ofl_desc *, Ifl_desc *);
extern void ld_disp_errmsg(const char *, Rel_desc *, Ofl_desc *);
extern void ld_ent_check(Ofl_desc *);
extern Ent_desc *ld_ent_lookup(Ofl_desc *, const char *name,
avl_index_t *where);
extern void ld_eprintf(Ofl_desc *, Error, const char *, ...);
extern int ld_exit(Ofl_desc *);
extern uintptr_t ld_find_library(const char *, Ofl_desc *);
extern uintptr_t ld_finish_libs(Ofl_desc *);
extern const char *ld_stt_section_sym_name(Is_desc *);
extern Group_desc *ld_get_group(Ofl_desc *, Is_desc *);
extern uintptr_t ld_group_process(Is_desc *, Ofl_desc *);
extern uintptr_t ld_lib_setup(Ofl_desc *);
extern void ld_init_sighandler(Ofl_desc *);
extern Xword ld_lcm(Xword, Xword);
extern uintptr_t ld_make_bss(Ofl_desc *, Xword, Xword, uint_t);
extern Is_desc *ld_make_data(Ofl_desc *, size_t);
extern uintptr_t ld_make_got(Ofl_desc *);
extern uintptr_t ld_make_parexpn_data(Ofl_desc *, size_t, Xword);
extern uintptr_t ld_make_sunwmove(Ofl_desc *, int);
extern Is_desc *ld_make_text(Ofl_desc *, size_t);
extern void ld_map_out(Ofl_desc *);
extern Boolean ld_map_parse(const char *, Ofl_desc *);
extern Boolean ld_map_post_process(Ofl_desc *);
extern uintptr_t ld_open_outfile(Ofl_desc *);
extern Is_desc *ld_os_first_isdesc(Os_desc *);
extern Place_path_info *ld_place_path_info_init(Ofl_desc *, Ifl_desc *,
Place_path_info *);
extern Os_desc *ld_place_section(Ofl_desc *, Is_desc *,
Place_path_info *path_info, int, const char *);
extern Boolean ld_process_archive(const char *, int, Ar_desc *,
Ofl_desc *);
extern uintptr_t ld_process_files(Ofl_desc *, int, char **);
extern uintptr_t ld_process_flags(Ofl_desc *, int, char **);
extern uintptr_t ld_process_ifl(const char *, const char *, int, Elf *,
Word, Ofl_desc *, Rej_desc *, Ifl_desc **);
extern uintptr_t ld_process_move(Ofl_desc *);
extern uintptr_t ld_process_open(const char *, const char *, int *,
Ofl_desc *, Word, Rej_desc *, Ifl_desc **);
extern uintptr_t ld_process_ordered(Ofl_desc *, Ifl_desc *,
Place_path_info *path_info, Word);
extern uintptr_t ld_process_sym_reloc(Ofl_desc *, Rel_desc *, Rel *,
Is_desc *, const char *, Word);
extern Rel_desc *ld_reloc_enter(Ofl_desc *, Rel_cache *, Rel_desc *,
Word);
extern uintptr_t ld_reloc_GOT_relative(Boolean, Rel_desc *, Ofl_desc *);
extern uintptr_t ld_reloc_plt(Rel_desc *, Ofl_desc *);
extern void ld_reloc_remain_entry(Rel_desc *, Os_desc *,
Ofl_desc *, Boolean *);
extern Boolean ld_reloc_set_aux_osdesc(Ofl_desc *, Rel_desc *,
Os_desc *);
extern Boolean ld_reloc_set_aux_usym(Ofl_desc *, Rel_desc *,
Sym_desc *);
extern const char *ld_reloc_sym_name(Rel_desc *);
extern int ld_reloc_targval_get(Ofl_desc *, Rel_desc *,
uchar_t *, Xword *);
extern int ld_reloc_targval_set(Ofl_desc *, Rel_desc *,
uchar_t *, Xword);
extern Sg_desc *ld_seg_lookup(Ofl_desc *, const char *,
avl_index_t *where);
extern void ld_sec_validate(Ofl_desc *);
extern uintptr_t ld_sort_ordered(Ofl_desc *);
extern Half ld_sunw_ldmach();
extern void ld_sup_atexit(Ofl_desc *, int);
extern void ld_sup_open(Ofl_desc *, const char **, const char **,
int *, int, Elf **, Elf *ref, size_t,
const Elf_Kind);
extern void ld_sup_file(Ofl_desc *, const char *, const Elf_Kind,
int flags, Elf *);
extern uintptr_t ld_sup_loadso(Ofl_desc *, const char *);
extern void ld_sup_input_done(Ofl_desc *);
extern void ld_sup_section(Ofl_desc *, const char *, Shdr *, Word,
Elf_Data *, Elf *);
extern uintptr_t ld_sup_input_section(Ofl_desc*, Ifl_desc *,
const char *, Shdr **, Word, Elf_Scn *, Elf *);
extern void ld_sup_start(Ofl_desc *, const Half, const char *);
extern int ld_swap_reloc_data(Ofl_desc *, Rel_desc *);
extern Sym_desc *ld_sym_add_u(const char *, Ofl_desc *, Msg);
extern void ld_sym_adjust_vis(Sym_desc *, Ofl_desc *);
extern int ld_sym_avl_comp(const void *, const void *);
extern uintptr_t ld_sym_copy(Sym_desc *);
extern Sym_desc *ld_sym_enter(const char *, Sym *, Word, Ifl_desc *,
Ofl_desc *, Word, Word, sd_flag_t, avl_index_t *);
extern Sym_desc *ld_sym_find(const char *, Word, avl_index_t *,
Ofl_desc *);
extern uintptr_t ld_sym_nodirect(Is_desc *, Ifl_desc *, Ofl_desc *);
extern uintptr_t ld_sym_process(Is_desc *, Ifl_desc *, Ofl_desc *);
extern uintptr_t ld_sym_resolve(Sym_desc *, Sym *, Ifl_desc *,
Ofl_desc *, int, Word, sd_flag_t);
extern Boolean ld_sym_reducable(Ofl_desc *, Sym_desc *);
extern uintptr_t ld_sym_spec(Ofl_desc *);
extern Target ld_targ;
extern const Target *ld_targ_init_sparc(void);
extern const Target *ld_targ_init_x86(void);
extern uintptr_t ld_unwind_make_hdr(Ofl_desc *);
extern uintptr_t ld_unwind_populate_hdr(Ofl_desc *);
extern uintptr_t ld_unwind_register(Os_desc *, Ofl_desc *);
extern Ver_desc *ld_vers_base(Ofl_desc *);
extern uintptr_t ld_vers_check_defs(Ofl_desc *);
extern uintptr_t ld_vers_check_need(Ofl_desc *);
extern uintptr_t ld_vers_def_process(Is_desc *, Ifl_desc *, Ofl_desc *);
extern Ver_desc *ld_vers_desc(const char *, Word, APlist **);
extern Ver_desc *ld_vers_find(const char *, Word, APlist *);
extern uintptr_t ld_vers_need_process(Is_desc *, Ifl_desc *, Ofl_desc *);
extern void ld_vers_promote(Sym_desc *, Word, Ifl_desc *,
Ofl_desc *);
extern int ld_vers_sym_process(Ofl_desc *, Is_desc *, Ifl_desc *);
extern int ld_vers_verify(Ofl_desc *);
extern WrapSymNode *ld_wrap_enter(Ofl_desc *, const char *);
extern uintptr_t add_regsym(Sym_desc *, Ofl_desc *);
extern Word hashbkts(Word);
extern Xword lcm(Xword, Xword);
/*
* Most platforms have both a 32 and 64-bit variant (e.g. EM_SPARC and
* EM_SPARCV9). To support this, there many files in libld that are built
* twice, once for ELFCLASS64 (_ELF64), and once for ELFCLASS32. In these
* files, we sometimes want to supply one value for the ELFCLASS32 case
* and another for ELFCLASS64. The LD_TARG_BYCLASS macro is used to do
* this. It is called with both both alternatives, and yields the one
* that applies to the current compilation environment.
*/
#ifdef _ELF64
#define LD_TARG_BYCLASS(_ec32, _ec64) (_ec64)
#else
#define LD_TARG_BYCLASS(_ec32, _ec64) (_ec32)
#endif
#ifdef __cplusplus
}
#endif
#endif /* _LIBLD_DOT_H */
|