aboutsummaryrefslogtreecommitdiff
path: root/ld/ld.h
blob: 1de1853b55ec4cd9370ccc9a24dc419bd450da25 (plain) (blame)
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
/*-
 * Copyright (c) 2010-2013 Kai Wang
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $Id: ld.h 3174 2015-03-27 17:13:41Z emaste $
 */

#include <sys/mman.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <ar.h>
#include <assert.h>
#include <dirent.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <gelf.h>
#include <inttypes.h>
#include <libelftc.h>
#include <libgen.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "dwarf.h"
#define oom() ld_fatal(ld, "out of memory")
#include "utarray.h"
#define uthash_fatal(msg) ld_fatal(ld, msg)
#include "uthash.h"
#include "_elftc.h"

struct ld_file;
struct ld_input_section_head;
struct ld_path;
struct ld_symbol;
struct ld_symbol_head;
struct ld_output_data_buffer;
struct ld_wildcard_match;
struct ld_ehframe_cie_head;
struct ld_ehframe_fde_head;
struct ld_section_group;

#define	LD_MAX_NESTED_GROUP	16

struct ld_state {
	Elftc_Bfd_Target *ls_itgt;	/* input bfd target set by -b */
	struct ld_file *ls_file;	/* current open file */
	unsigned ls_static;		/* use static library */
	unsigned ls_whole_archive;	/* include whole archive */
	unsigned ls_as_needed;		/* DT_NEEDED */
	unsigned ls_group_level;	/* archive group level */
	unsigned ls_extracted[LD_MAX_NESTED_GROUP + 1];
					/* extracted from archive group */
	unsigned ls_search_dir;		/* search library directories */
	uint64_t ls_loc_counter;	/* location counter */
	uint64_t ls_offset;		/* cur. output section file offset */
	STAILQ_HEAD(, ld_path) ls_lplist; /* search path list */
	STAILQ_HEAD(, ld_path) ls_rplist; /* rpath list */
	STAILQ_HEAD(, ld_path) ls_rllist; /* rpath-link list */
	unsigned ls_arch_conflict;	/* input arch conflict with output */
	unsigned ls_first_elf_object;	/* first ELF object to process */
	unsigned ls_rerun;		/* ld(1) restarted */
	unsigned ls_archive_mb_header;	/* extracted list header printed */
	unsigned ls_first_output_sec;	/* flag indicates 1st output section */
	unsigned ls_ignore_next_plt;	/* ignore next PLT relocation */
	unsigned ls_version_local;	/* version entry is local */
	uint64_t ls_relative_reloc;	/* number of *_RELATIVE relocations */
	struct ld_input_section_head *ls_gc;
					/* garbage collection search list */
};

struct ld {
	const char *ld_progname;	/* ld(1) program name */
	struct ld_arch *ld_arch;	/* arch-specific callbacks */
	struct ld_arch *ld_arch_list;	/* list of supported archs */
	Elftc_Bfd_Target *ld_otgt;	/* default output format */
	Elftc_Bfd_Target *ld_otgt_be;	/* big-endian output format */
	Elftc_Bfd_Target *ld_otgt_le;	/* little-endian output format */
	char *ld_otgt_name;		/* output format name */
	char *ld_otgt_be_name;		/* big-endian output format name */
	char *ld_otgt_le_name;		/* little-endian output format name */
	struct ld_output *ld_output;	/* output object */
	char *ld_output_file;		/* output file name */
	char *ld_entry;			/* entry point set by -e */
	char *ld_scp_entry;		/* entry point set by linker script */
	char *ld_interp;		/* dynamic linker */
	char *ld_soname;		/* DT_SONAME */
	struct ld_script *ld_scp;	/* linker script */
	struct ld_state ld_state;	/* linker state */
	struct ld_strtab *ld_shstrtab;	/* section name table */
	struct ld_symbol_head *ld_ext_symbols; /* -u/EXTERN symbols */
	struct ld_symbol_head *ld_var_symbols; /* ldscript var symbols */
	struct ld_symbol *ld_sym;	/* internal symbol table */
	struct ld_symbol *ld_symtab_import; /* hash for import symbols */
	struct ld_symbol *ld_symtab_export; /* hash for export symbols */
	struct ld_symbol_defver *ld_defver; /* default version table */
	struct ld_symbol_table *ld_symtab; /* .symtab symbol table */
	struct ld_strtab *ld_strtab;	/* .strtab string table */
	struct ld_symbol_table *ld_dynsym; /* .dynsym symbol table */
	struct ld_strtab *ld_dynstr;	/* .dynstr string table */
	struct ld_symbol_head *ld_dyn_symbols; /* dynamic symbol list */
	struct ld_wildcard_match *ld_wm; /* wildcard hash table */
	struct ld_input_section *ld_dynbss; /* .dynbss section */
	struct ld_input_section *ld_got;    /* .got section */
	struct ld_ehframe_cie_head *ld_cie; /* ehframe CIE list */
	struct ld_ehframe_fde_head *ld_fde; /* ehframe FDE list */
	struct ld_section_group *ld_sg;	/* included section groups */
	unsigned char ld_common_alloc;	/* always alloc space for common sym */
	unsigned char ld_common_no_alloc; /* never alloc space for common sym */
	unsigned char ld_emit_reloc;	/* emit relocations */
	unsigned char ld_gen_gnustack;	/* generate PT_GNUSTACK */
	unsigned char ld_print_linkmap;	/* print link map */
	unsigned char ld_stack_exec;	/* stack executable */
	unsigned char ld_stack_exec_set; /* stack executable override */
	unsigned char ld_exec;		/* output normal executable */
	unsigned char ld_pie;		/* position-independent executable */
	unsigned char ld_dso;		/* output shared library */
	unsigned char ld_reloc;		/* output relocatable object */
	unsigned char ld_dynamic_link;	/* perform dynamic linking */
	unsigned char ld_print_version; /* linker version printed */
	unsigned char ld_gc;		/* perform garbage collection */
	unsigned char ld_gc_print;	/* print removed sections */
	unsigned char ld_ehframe_hdr;	/* create .eh_frame_hdr section */
	STAILQ_HEAD(ld_input_head, ld_input) ld_lilist; /* input object list */
	TAILQ_HEAD(ld_file_head, ld_file) ld_lflist; /* input file list */
};

void	ld_err(struct ld *, const char *, ...);
void	ld_fatal(struct ld *, const char *, ...);
void	ld_fatal_std(struct ld *, const char *, ...);
void	ld_warn(struct ld *, const char *, ...);
void	ld_info(struct ld *, const char *, ...);