xref: /illumos-gate/usr/src/lib/libdtrace/common/dt_link.c (revision 6c19201566ac520f0d4eef6ed2f70bf9a4815eae)
1  /*
2   * CDDL HEADER START
3   *
4   * The contents of this file are subject to the terms of the
5   * Common Development and Distribution License (the "License").
6   * You may not use this file except in compliance with the License.
7   *
8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9   * or http://www.opensolaris.org/os/licensing.
10   * See the License for the specific language governing permissions
11   * and limitations under the License.
12   *
13   * When distributing Covered Code, include this CDDL HEADER in each
14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15   * If applicable, add the following below this CDDL HEADER, with the
16   * fields enclosed by brackets "[]" replaced with your own identifying
17   * information: Portions Copyright [yyyy] [name of copyright owner]
18   *
19   * CDDL HEADER END
20   */
21  
22  /*
23   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24   * Use is subject to license terms.
25   * Copyright 2016 Mark Johnston.
26   */
27  
28  #define	ELF_TARGET_ALL
29  #include <elf.h>
30  
31  #include <sys/types.h>
32  #include <sys/sysmacros.h>
33  
34  #include <unistd.h>
35  #include <strings.h>
36  #include <alloca.h>
37  #include <limits.h>
38  #include <stddef.h>
39  #include <stdlib.h>
40  #include <stdio.h>
41  #include <fcntl.h>
42  #include <errno.h>
43  #include <wait.h>
44  #include <assert.h>
45  #include <sys/ipc.h>
46  
47  #include <dt_impl.h>
48  #include <dt_provider.h>
49  #include <dt_program.h>
50  #include <dt_string.h>
51  
52  #define	ESHDR_NULL	0
53  #define	ESHDR_SHSTRTAB	1
54  #define	ESHDR_DOF	2
55  #define	ESHDR_STRTAB	3
56  #define	ESHDR_SYMTAB	4
57  #define	ESHDR_REL	5
58  #define	ESHDR_NUM	6
59  
60  #define	PWRITE_SCN(index, data) \
61  	(lseek64(fd, (off64_t)elf_file.shdr[(index)].sh_offset, SEEK_SET) != \
62  	(off64_t)elf_file.shdr[(index)].sh_offset || \
63  	dt_write(dtp, fd, (data), elf_file.shdr[(index)].sh_size) != \
64  	elf_file.shdr[(index)].sh_size)
65  
66  static const char DTRACE_SHSTRTAB32[] = "\0"
67  ".shstrtab\0"		/* 1 */
68  ".SUNW_dof\0"		/* 11 */
69  ".strtab\0"		/* 21 */
70  ".symtab\0"		/* 29 */
71  #ifdef __sparc
72  ".rela.SUNW_dof";	/* 37 */
73  #else
74  ".rel.SUNW_dof";	/* 37 */
75  #endif
76  
77  static const char DTRACE_SHSTRTAB64[] = "\0"
78  ".shstrtab\0"		/* 1 */
79  ".SUNW_dof\0"		/* 11 */
80  ".strtab\0"		/* 21 */
81  ".symtab\0"		/* 29 */
82  ".rela.SUNW_dof";	/* 37 */
83  
84  static const char DOFSTR[] = "__SUNW_dof";
85  static const char DOFLAZYSTR[] = "___SUNW_dof";
86  
87  typedef struct dt_link_pair {
88  	struct dt_link_pair *dlp_next;	/* next pair in linked list */
89  	void *dlp_str;			/* buffer for string table */
90  	void *dlp_sym;			/* buffer for symbol table */
91  } dt_link_pair_t;
92  
93  typedef struct dof_elf32 {
94  	uint32_t de_nrel;		/* relocation count */
95  #ifdef __sparc
96  	Elf32_Rela *de_rel;		/* array of relocations for sparc */
97  #else
98  	Elf32_Rel *de_rel;		/* array of relocations for x86 */
99  #endif
100  	uint32_t de_nsym;		/* symbol count */
101  	Elf32_Sym *de_sym;		/* array of symbols */
102  	uint32_t de_strlen;		/* size of of string table */
103  	char *de_strtab;		/* string table */
104  	uint32_t de_global;		/* index of the first global symbol */
105  } dof_elf32_t;
106  
107  static int
prepare_elf32(dtrace_hdl_t * dtp,const dof_hdr_t * dof,dof_elf32_t * dep)108  prepare_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf32_t *dep)
109  {
110  	dof_sec_t *dofs, *s;
111  	dof_relohdr_t *dofrh;
112  	dof_relodesc_t *dofr;
113  	char *strtab;
114  	int i, j, nrel;
115  	size_t strtabsz = 1;
116  	uint32_t count = 0;
117  	size_t base;
118  	Elf32_Sym *sym;
119  #ifdef __sparc
120  	Elf32_Rela *rel;
121  #else
122  	Elf32_Rel *rel;
123  #endif
124  
125  	/*LINTED*/
126  	dofs = (dof_sec_t *)((char *)dof + dof->dofh_secoff);
127  
128  	/*
129  	 * First compute the size of the string table and the number of
130  	 * relocations present in the DOF.
131  	 */
132  	for (i = 0; i < dof->dofh_secnum; i++) {
133  		if (dofs[i].dofs_type != DOF_SECT_URELHDR)
134  			continue;
135  
136  		/*LINTED*/
137  		dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset);
138  
139  		s = &dofs[dofrh->dofr_strtab];
140  		strtab = (char *)dof + s->dofs_offset;
141  		assert(strtab[0] == '\0');
142  		strtabsz += s->dofs_size - 1;
143  
144  		s = &dofs[dofrh->dofr_relsec];
145  		/*LINTED*/
146  		dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset);
147  		count += s->dofs_size / s->dofs_entsize;
148  	}
149  
150  	dep->de_strlen = strtabsz;
151  	dep->de_nrel = count;
152  	dep->de_nsym = count + 1; /* the first symbol is always null */
153  
154  	if (dtp->dt_lazyload) {
155  		dep->de_strlen += sizeof (DOFLAZYSTR);
156  		dep->de_nsym++;
157  	} else {
158  		dep->de_strlen += sizeof (DOFSTR);
159  		dep->de_nsym++;
160  	}
161  
162  	if ((dep->de_rel = calloc(dep->de_nrel,
163  	    sizeof (dep->de_rel[0]))) == NULL) {
164  		return (dt_set_errno(dtp, EDT_NOMEM));
165  	}
166  
167  	if ((dep->de_sym = calloc(dep->de_nsym, sizeof (Elf32_Sym))) == NULL) {
168  		free(dep->de_rel);
169  		return (dt_set_errno(dtp, EDT_NOMEM));
170  	}
171  
172  	if ((dep->de_strtab = calloc(dep->de_strlen, 1)) == NULL) {
173  		free(dep->de_rel);
174  		free(dep->de_sym);
175  		return (dt_set_errno(dtp, EDT_NOMEM));
176  	}
177  
178  	count = 0;
179  	strtabsz = 1;
180  	dep->de_strtab[0] = '\0';
181  	rel = dep->de_rel;
182  	sym = dep->de_sym;
183  	dep->de_global = 1;
184  
185  	/*
186  	 * The first symbol table entry must be zeroed and is always ignored.
187  	 */
188  	bzero(sym, sizeof (Elf32_Sym));
189  	sym++;
190  
191  	/*
192  	 * Take a second pass through the DOF sections filling in the
193  	 * memory we allocated.
194  	 */
195  	for (i = 0; i < dof->dofh_secnum; i++) {
196  		if (dofs[i].dofs_type != DOF_SECT_URELHDR)
197  			continue;
198  
199  		/*LINTED*/
200  		dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset);
201  
202  		s = &dofs[dofrh->dofr_strtab];
203  		strtab = (char *)dof + s->dofs_offset;
204  		bcopy(strtab + 1, dep->de_strtab + strtabsz, s->dofs_size);
205  		base = strtabsz;
206  		strtabsz += s->dofs_size - 1;
207  
208  		s = &dofs[dofrh->dofr_relsec];
209  		/*LINTED*/
210  		dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset);
211  		nrel = s->dofs_size / s->dofs_entsize;
212  
213  		s = &dofs[dofrh->dofr_tgtsec];
214  
215  		for (j = 0; j < nrel; j++) {
216  #if defined(__i386) || defined(__amd64)
217  			rel->r_offset = s->dofs_offset +
218  			    dofr[j].dofr_offset;
219  			rel->r_info = ELF32_R_INFO(count + dep->de_global,
220  			    R_386_32);
221  #elif defined(__sparc)
222  			/*
223  			 * Add 4 bytes to hit the low half of this 64-bit
224  			 * big-endian address.
225  			 */
226  			rel->r_offset = s->dofs_offset +
227  			    dofr[j].dofr_offset + 4;
228  			rel->r_info = ELF32_R_INFO(count + dep->de_global,
229  			    R_SPARC_32);
230  #else
231  #error unknown ISA
232  #endif
233  
234  			sym->st_name = base + dofr[j].dofr_name - 1;
235  			sym->st_value = 0;
236  			sym->st_size = 0;
237  			sym->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_FUNC);
238  			sym->st_other = 0;
239  			sym->st_shndx = SHN_UNDEF;
240  
241  			rel++;
242  			sym++;
243  			count++;
244  		}
245  	}
246  
247  	/*
248  	 * Add a symbol for the DOF itself. We use a different symbol for
249  	 * lazily and actively loaded DOF to make them easy to distinguish.
250  	 */
251  	sym->st_name = strtabsz;
252  	sym->st_value = 0;
253  	sym->st_size = dof->dofh_filesz;
254  	sym->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT);
255  	sym->st_other = 0;
256  	sym->st_shndx = ESHDR_DOF;
257  	sym++;
258  
259  	if (dtp->dt_lazyload) {
260  		bcopy(DOFLAZYSTR, dep->de_strtab + strtabsz,
261  		    sizeof (DOFLAZYSTR));
262  		strtabsz += sizeof (DOFLAZYSTR);
263  	} else {
264  		bcopy(DOFSTR, dep->de_strtab + strtabsz, sizeof (DOFSTR));
265  		strtabsz += sizeof (DOFSTR);
266  	}
267  
268  	assert(count == dep->de_nrel);
269  	assert(strtabsz == dep->de_strlen);
270  
271  	return (0);
272  }
273  
274  
275  typedef struct dof_elf64 {
276  	uint32_t de_nrel;
277  	Elf64_Rela *de_rel;
278  	uint32_t de_nsym;
279  	Elf64_Sym *de_sym;
280  
281  	uint32_t de_strlen;
282  	char *de_strtab;
283  
284  	uint32_t de_global;
285  } dof_elf64_t;
286  
287  static int
prepare_elf64(dtrace_hdl_t * dtp,const dof_hdr_t * dof,dof_elf64_t * dep)288  prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
289  {
290  	dof_sec_t *dofs, *s;
291  	dof_relohdr_t *dofrh;
292  	dof_relodesc_t *dofr;
293  	char *strtab;
294  	int i, j, nrel;
295  	size_t strtabsz = 1;
296  	uint32_t count = 0;
297  	size_t base;
298  	Elf64_Sym *sym;
299  	Elf64_Rela *rel;
300  
301  	/*LINTED*/
302  	dofs = (dof_sec_t *)((char *)dof + dof->dofh_secoff);
303  
304  	/*
305  	 * First compute the size of the string table and the number of
306  	 * relocations present in the DOF.
307  	 */
308  	for (i = 0; i < dof->dofh_secnum; i++) {
309  		if (dofs[i].dofs_type != DOF_SECT_URELHDR)
310  			continue;
311  
312  		/*LINTED*/
313  		dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset);
314  
315  		s = &dofs[dofrh->dofr_strtab];
316  		strtab = (char *)dof + s->dofs_offset;
317  		assert(strtab[0] == '\0');
318  		strtabsz += s->dofs_size - 1;
319  
320  		s = &dofs[dofrh->dofr_relsec];
321  		/*LINTED*/
322  		dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset);
323  		count += s->dofs_size / s->dofs_entsize;
324  	}
325  
326  	dep->de_strlen = strtabsz;
327  	dep->de_nrel = count;
328  	dep->de_nsym = count + 1; /* the first symbol is always null */
329  
330  	if (dtp->dt_lazyload) {
331  		dep->de_strlen += sizeof (DOFLAZYSTR);
332  		dep->de_nsym++;
333  	} else {
334  		dep->de_strlen += sizeof (DOFSTR);
335  		dep->de_nsym++;
336  	}
337  
338  	if ((dep->de_rel = calloc(dep->de_nrel,
339  	    sizeof (dep->de_rel[0]))) == NULL) {
340  		return (dt_set_errno(dtp, EDT_NOMEM));
341  	}
342  
343  	if ((dep->de_sym = calloc(dep->de_nsym, sizeof (Elf64_Sym))) == NULL) {
344  		free(dep->de_rel);
345  		return (dt_set_errno(dtp, EDT_NOMEM));
346  	}
347  
348  	if ((dep->de_strtab = calloc(dep->de_strlen, 1)) == NULL) {
349  		free(dep->de_rel);
350  		free(dep->de_sym);
351  		return (dt_set_errno(dtp, EDT_NOMEM));
352  	}
353  
354  	count = 0;
355  	strtabsz = 1;
356  	dep->de_strtab[0] = '\0';
357  	rel = dep->de_rel;
358  	sym = dep->de_sym;
359  	dep->de_global = 1;
360  
361  	/*
362  	 * The first symbol table entry must be zeroed and is always ignored.
363  	 */
364  	bzero(sym, sizeof (Elf64_Sym));
365  	sym++;
366  
367  	/*
368  	 * Take a second pass through the DOF sections filling in the
369  	 * memory we allocated.
370  	 */
371  	for (i = 0; i < dof->dofh_secnum; i++) {
372  		if (dofs[i].dofs_type != DOF_SECT_URELHDR)
373  			continue;
374  
375  		/*LINTED*/
376  		dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset);
377  
378  		s = &dofs[dofrh->dofr_strtab];
379  		strtab = (char *)dof + s->dofs_offset;
380  		bcopy(strtab + 1, dep->de_strtab + strtabsz, s->dofs_size);
381  		base = strtabsz;
382  		strtabsz += s->dofs_size - 1;
383  
384  		s = &dofs[dofrh->dofr_relsec];
385  		/*LINTED*/
386  		dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset);
387  		nrel = s->dofs_size / s->dofs_entsize;
388  
389  		s = &dofs[dofrh->dofr_tgtsec];
390  
391  		for (j = 0; j < nrel; j++) {
392  #if defined(__i386) || defined(__amd64)
393  			rel->r_offset = s->dofs_offset +
394  			    dofr[j].dofr_offset;
395  			rel->r_info = ELF64_R_INFO(count + dep->de_global,
396  			    R_AMD64_64);
397  #elif defined(__sparc)
398  			rel->r_offset = s->dofs_offset +
399  			    dofr[j].dofr_offset;
400  			rel->r_info = ELF64_R_INFO(count + dep->de_global,
401  			    R_SPARC_64);
402  #else
403  #error unknown ISA
404  #endif
405  
406  			sym->st_name = base + dofr[j].dofr_name - 1;
407  			sym->st_value = 0;
408  			sym->st_size = 0;
409  			sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_FUNC);
410  			sym->st_other = 0;
411  			sym->st_shndx = SHN_UNDEF;
412  
413  			rel++;
414  			sym++;
415  			count++;
416  		}
417  	}
418  
419  	/*
420  	 * Add a symbol for the DOF itself. We use a different symbol for
421  	 * lazily and actively loaded DOF to make them easy to distinguish.
422  	 */
423  	sym->st_name = strtabsz;
424  	sym->st_value = 0;
425  	sym->st_size = dof->dofh_filesz;
426  	sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_OBJECT);
427  	sym->st_other = 0;
428  	sym->st_shndx = ESHDR_DOF;
429  	sym++;
430  
431  	if (dtp->dt_lazyload) {
432  		bcopy(DOFLAZYSTR, dep->de_strtab + strtabsz,
433  		    sizeof (DOFLAZYSTR));
434  		strtabsz += sizeof (DOFLAZYSTR);
435  	} else {
436  		bcopy(DOFSTR, dep->de_strtab + strtabsz, sizeof (DOFSTR));
437  		strtabsz += sizeof (DOFSTR);
438  	}
439  
440  	assert(count == dep->de_nrel);
441  	assert(strtabsz == dep->de_strlen);
442  
443  	return (0);
444  }
445  
446  /*
447   * Write out an ELF32 file prologue consisting of a header, section headers,
448   * and a section header string table.  The DOF data will follow this prologue
449   * and complete the contents of the given ELF file.
450   */
451  static int
dump_elf32(dtrace_hdl_t * dtp,const dof_hdr_t * dof,int fd)452  dump_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
453  {
454  	struct {
455  		Elf32_Ehdr ehdr;
456  		Elf32_Shdr shdr[ESHDR_NUM];
457  	} elf_file;
458  
459  	Elf32_Shdr *shp;
460  	Elf32_Off off;
461  	dof_elf32_t de;
462  	int ret = 0;
463  	uint_t nshdr;
464  
465  	if (prepare_elf32(dtp, dof, &de) != 0)
466  		return (-1); /* errno is set for us */
467  
468  	/*
469  	 * If there are no relocations, we only need enough sections for
470  	 * the shstrtab and the DOF.
471  	 */
472  	nshdr = de.de_nrel == 0 ? ESHDR_SYMTAB + 1 : ESHDR_NUM;
473  
474  	bzero(&elf_file, sizeof (elf_file));
475  
476  	elf_file.ehdr.e_ident[EI_MAG0] = ELFMAG0;
477  	elf_file.ehdr.e_ident[EI_MAG1] = ELFMAG1;
478  	elf_file.ehdr.e_ident[EI_MAG2] = ELFMAG2;
479  	elf_file.ehdr.e_ident[EI_MAG3] = ELFMAG3;
480  	elf_file.ehdr.e_ident[EI_VERSION] = EV_CURRENT;
481  	elf_file.ehdr.e_ident[EI_CLASS] = ELFCLASS32;
482  #if defined(_BIG_ENDIAN)
483  	elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
484  #elif defined(_LITTLE_ENDIAN)
485  	elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
486  #endif
487  	elf_file.ehdr.e_type = ET_REL;
488  #if defined(__sparc)
489  	elf_file.ehdr.e_machine = EM_SPARC;
490  #elif defined(__i386) || defined(__amd64)
491  	elf_file.ehdr.e_machine = EM_386;
492  #endif
493  	elf_file.ehdr.e_version = EV_CURRENT;
494  	elf_file.ehdr.e_shoff = sizeof (Elf32_Ehdr);
495  	elf_file.ehdr.e_ehsize = sizeof (Elf32_Ehdr);
496  	elf_file.ehdr.e_phentsize = sizeof (Elf32_Phdr);
497  	elf_file.ehdr.e_shentsize = sizeof (Elf32_Shdr);
498  	elf_file.ehdr.e_shnum = nshdr;
499  	elf_file.ehdr.e_shstrndx = ESHDR_SHSTRTAB;
500  	off = sizeof (elf_file) + nshdr * sizeof (Elf32_Shdr);
501  
502  	shp = &elf_file.shdr[ESHDR_SHSTRTAB];
503  	shp->sh_name = 1; /* DTRACE_SHSTRTAB32[1] = ".shstrtab" */
504  	shp->sh_type = SHT_STRTAB;
505  	shp->sh_offset = off;
506  	shp->sh_size = sizeof (DTRACE_SHSTRTAB32);
507  	shp->sh_addralign = sizeof (char);
508  	off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8);
509  
510  	shp = &elf_file.shdr[ESHDR_DOF];
511  	shp->sh_name = 11; /* DTRACE_SHSTRTAB32[11] = ".SUNW_dof" */
512  	shp->sh_flags = SHF_ALLOC;
513  	shp->sh_type = SHT_SUNW_dof;
514  	shp->sh_offset = off;
515  	shp->sh_size = dof->dofh_filesz;
516  	shp->sh_addralign = 8;
517  	off = shp->sh_offset + shp->sh_size;
518  
519  	shp = &elf_file.shdr[ESHDR_STRTAB];
520  	shp->sh_name = 21; /* DTRACE_SHSTRTAB32[21] = ".strtab" */
521  	shp->sh_flags = SHF_ALLOC;
522  	shp->sh_type = SHT_STRTAB;
523  	shp->sh_offset = off;
524  	shp->sh_size = de.de_strlen;
525  	shp->sh_addralign = sizeof (char);
526  	off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 4);
527  
528  	shp = &elf_file.shdr[ESHDR_SYMTAB];
529  	shp->sh_name = 29; /* DTRACE_SHSTRTAB32[29] = ".symtab" */
530  	shp->sh_flags = SHF_ALLOC;
531  	shp->sh_type = SHT_SYMTAB;
532  	shp->sh_entsize = sizeof (Elf32_Sym);
533  	shp->sh_link = ESHDR_STRTAB;
534  	shp->sh_offset = off;
535  	shp->sh_info = de.de_global;
536  	shp->sh_size = de.de_nsym * sizeof (Elf32_Sym);
537  	shp->sh_addralign = 4;
538  	off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 4);
539  
540  	if (de.de_nrel == 0) {
541  		if (dt_write(dtp, fd, &elf_file,
542  		    sizeof (elf_file)) != sizeof (elf_file) ||
543  		    PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB32) ||
544  		    PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) ||
545  		    PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) ||
546  		    PWRITE_SCN(ESHDR_DOF, dof)) {
547  			ret = dt_set_errno(dtp, errno);
548  		}
549  	} else {
550  		shp = &elf_file.shdr[ESHDR_REL];
551  		shp->sh_name = 37; /* DTRACE_SHSTRTAB32[37] = ".rel.SUNW_dof" */
552  		shp->sh_flags = SHF_ALLOC;
553  #ifdef __sparc
554  		shp->sh_type = SHT_RELA;
555  #else
556  		shp->sh_type = SHT_REL;
557  #endif
558  		shp->sh_entsize = sizeof (de.de_rel[0]);
559  		shp->sh_link = ESHDR_SYMTAB;
560  		shp->sh_info = ESHDR_DOF;
561  		shp->sh_offset = off;
562  		shp->sh_size = de.de_nrel * sizeof (de.de_rel[0]);
563  		shp->sh_addralign = 4;
564  
565  		if (dt_write(dtp, fd, &elf_file,
566  		    sizeof (elf_file)) != sizeof (elf_file) ||
567  		    PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB32) ||
568  		    PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) ||
569  		    PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) ||
570  		    PWRITE_SCN(ESHDR_REL, de.de_rel) ||
571  		    PWRITE_SCN(ESHDR_DOF, dof)) {
572  			ret = dt_set_errno(dtp, errno);
573  		}
574  	}
575  
576  	free(de.de_strtab);
577  	free(de.de_sym);
578  	free(de.de_rel);
579  
580  	return (ret);
581  }
582  
583  /*
584   * Write out an ELF64 file prologue consisting of a header, section headers,
585   * and a section header string table.  The DOF data will follow this prologue
586   * and complete the contents of the given ELF file.
587   */
588  static int
dump_elf64(dtrace_hdl_t * dtp,const dof_hdr_t * dof,int fd)589  dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
590  {
591  	struct {
592  		Elf64_Ehdr ehdr;
593  		Elf64_Shdr shdr[ESHDR_NUM];
594  	} elf_file;
595  
596  	Elf64_Shdr *shp;
597  	Elf64_Off off;
598  	dof_elf64_t de;
599  	int ret = 0;
600  	uint_t nshdr;
601  
602  	if (prepare_elf64(dtp, dof, &de) != 0)
603  		return (-1); /* errno is set for us */
604  
605  	/*
606  	 * If there are no relocations, we only need enough sections for
607  	 * the shstrtab and the DOF.
608  	 */
609  	nshdr = de.de_nrel == 0 ? ESHDR_SYMTAB + 1 : ESHDR_NUM;
610  
611  	bzero(&elf_file, sizeof (elf_file));
612  
613  	elf_file.ehdr.e_ident[EI_MAG0] = ELFMAG0;
614  	elf_file.ehdr.e_ident[EI_MAG1] = ELFMAG1;
615  	elf_file.ehdr.e_ident[EI_MAG2] = ELFMAG2;
616  	elf_file.ehdr.e_ident[EI_MAG3] = ELFMAG3;
617  	elf_file.ehdr.e_ident[EI_VERSION] = EV_CURRENT;
618  	elf_file.ehdr.e_ident[EI_CLASS] = ELFCLASS64;
619  #if defined(_BIG_ENDIAN)
620  	elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
621  #elif defined(_LITTLE_ENDIAN)
622  	elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
623  #endif
624  	elf_file.ehdr.e_type = ET_REL;
625  #if defined(__sparc)
626  	elf_file.ehdr.e_machine = EM_SPARCV9;
627  #elif defined(__i386) || defined(__amd64)
628  	elf_file.ehdr.e_machine = EM_AMD64;
629  #endif
630  	elf_file.ehdr.e_version = EV_CURRENT;
631  	elf_file.ehdr.e_shoff = sizeof (Elf64_Ehdr);
632  	elf_file.ehdr.e_ehsize = sizeof (Elf64_Ehdr);
633  	elf_file.ehdr.e_phentsize = sizeof (Elf64_Phdr);
634  	elf_file.ehdr.e_shentsize = sizeof (Elf64_Shdr);
635  	elf_file.ehdr.e_shnum = nshdr;
636  	elf_file.ehdr.e_shstrndx = ESHDR_SHSTRTAB;
637  	off = sizeof (elf_file) + nshdr * sizeof (Elf64_Shdr);
638  
639  	shp = &elf_file.shdr[ESHDR_SHSTRTAB];
640  	shp->sh_name = 1; /* DTRACE_SHSTRTAB64[1] = ".shstrtab" */
641  	shp->sh_type = SHT_STRTAB;
642  	shp->sh_offset = off;
643  	shp->sh_size = sizeof (DTRACE_SHSTRTAB64);
644  	shp->sh_addralign = sizeof (char);
645  	off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8);
646  
647  	shp = &elf_file.shdr[ESHDR_DOF];
648  	shp->sh_name = 11; /* DTRACE_SHSTRTAB64[11] = ".SUNW_dof" */
649  	shp->sh_flags = SHF_ALLOC;
650  	shp->sh_type = SHT_SUNW_dof;
651  	shp->sh_offset = off;
652  	shp->sh_size = dof->dofh_filesz;
653  	shp->sh_addralign = 8;
654  	off = shp->sh_offset + shp->sh_size;
655  
656  	shp = &elf_file.shdr[ESHDR_STRTAB];
657  	shp->sh_name = 21; /* DTRACE_SHSTRTAB64[21] = ".strtab" */
658  	shp->sh_flags = SHF_ALLOC;
659  	shp->sh_type = SHT_STRTAB;
660  	shp->sh_offset = off;
661  	shp->sh_size = de.de_strlen;
662  	shp->sh_addralign = sizeof (char);
663  	off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8);
664  
665  	shp = &elf_file.shdr[ESHDR_SYMTAB];
666  	shp->sh_name = 29; /* DTRACE_SHSTRTAB64[29] = ".symtab" */
667  	shp->sh_flags = SHF_ALLOC;
668  	shp->sh_type = SHT_SYMTAB;
669  	shp->sh_entsize = sizeof (Elf64_Sym);
670  	shp->sh_link = ESHDR_STRTAB;
671  	shp->sh_offset = off;
672  	shp->sh_info = de.de_global;
673  	shp->sh_size = de.de_nsym * sizeof (Elf64_Sym);
674  	shp->sh_addralign = 8;
675  	off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8);
676  
677  	if (de.de_nrel == 0) {
678  		if (dt_write(dtp, fd, &elf_file,
679  		    sizeof (elf_file)) != sizeof (elf_file) ||
680  		    PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB64) ||
681  		    PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) ||
682  		    PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) ||
683  		    PWRITE_SCN(ESHDR_DOF, dof)) {
684  			ret = dt_set_errno(dtp, errno);
685  		}
686  	} else {
687  		shp = &elf_file.shdr[ESHDR_REL];
688  		shp->sh_name = 37; /* DTRACE_SHSTRTAB64[37] = ".rel.SUNW_dof" */
689  		shp->sh_flags = SHF_ALLOC;
690  		shp->sh_type = SHT_RELA;
691  		shp->sh_entsize = sizeof (de.de_rel[0]);
692  		shp->sh_link = ESHDR_SYMTAB;
693  		shp->sh_info = ESHDR_DOF;
694  		shp->sh_offset = off;
695  		shp->sh_size = de.de_nrel * sizeof (de.de_rel[0]);
696  		shp->sh_addralign = 8;
697  
698  		if (dt_write(dtp, fd, &elf_file,
699  		    sizeof (elf_file)) != sizeof (elf_file) ||
700  		    PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB64) ||
701  		    PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) ||
702  		    PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) ||
703  		    PWRITE_SCN(ESHDR_REL, de.de_rel) ||
704  		    PWRITE_SCN(ESHDR_DOF, dof)) {
705  			ret = dt_set_errno(dtp, errno);
706  		}
707  	}
708  
709  	free(de.de_strtab);
710  	free(de.de_sym);
711  	free(de.de_rel);
712  
713  	return (ret);
714  }
715  
716  static int
dt_symtab_lookup(Elf_Data * data_sym,int nsym,uintptr_t addr,uint_t shn,GElf_Sym * sym)717  dt_symtab_lookup(Elf_Data *data_sym, int nsym, uintptr_t addr, uint_t shn,
718      GElf_Sym *sym)
719  {
720  	int i, ret = -1;
721  	GElf_Sym s;
722  
723  	for (i = 0; i < nsym && gelf_getsym(data_sym, i, sym) != NULL; i++) {
724  		if (GELF_ST_TYPE(sym->st_info) == STT_FUNC &&
725  		    shn == sym->st_shndx &&
726  		    sym->st_value <= addr &&
727  		    addr < sym->st_value + sym->st_size) {
728  			if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL)
729  				return (0);
730  
731  			ret = 0;
732  			s = *sym;
733  		}
734  	}
735  
736  	if (ret == 0)
737  		*sym = s;
738  	return (ret);
739  }
740  
741  #if defined(__sparc)
742  
743  #define	DT_OP_RET		0x81c7e008
744  #define	DT_OP_NOP		0x01000000
745  #define	DT_OP_CALL		0x40000000
746  #define	DT_OP_CLR_O0		0x90102000
747  
748  #define	DT_IS_MOV_O7(inst)	(((inst) & 0xffffe000) == 0x9e100000)
749  #define	DT_IS_RESTORE(inst)	(((inst) & 0xc1f80000) == 0x81e80000)
750  #define	DT_IS_RETL(inst)	(((inst) & 0xfff83fff) == 0x81c02008)
751  
752  #define	DT_RS2(inst)		((inst) & 0x1f)
753  #define	DT_MAKE_RETL(reg)	(0x81c02008 | ((reg) << 14))
754  
755  /*ARGSUSED*/
756  static int
dt_modtext(dtrace_hdl_t * dtp,char * p,int isenabled,GElf_Rela * rela,uint32_t * off)757  dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
758      uint32_t *off)
759  {
760  	uint32_t *ip;
761  
762  	if ((rela->r_offset & (sizeof (uint32_t) - 1)) != 0)
763  		return (-1);
764  
765  	/*LINTED*/
766  	ip = (uint32_t *)(p + rela->r_offset);
767  
768  	/*
769  	 * We only know about some specific relocation types.
770  	 */
771  	if (GELF_R_TYPE(rela->r_info) != R_SPARC_WDISP30 &&
772  	    GELF_R_TYPE(rela->r_info) != R_SPARC_WPLT30)
773  		return (-1);
774  
775  	/*
776  	 * We may have already processed this object file in an earlier linker
777  	 * invocation. Check to see if the present instruction sequence matches
778  	 * the one we would install below.
779  	 */
780  	if (isenabled) {
781  		if (ip[0] == DT_OP_NOP) {
782  			(*off) += sizeof (ip[0]);
783  			return (0);
784  		}
785  	} else {
786  		if (DT_IS_RESTORE(ip[1])) {
787  			if (ip[0] == DT_OP_RET) {
788  				(*off) += sizeof (ip[0]);
789  				return (0);
790  			}
791  		} else if (DT_IS_MOV_O7(ip[1])) {
792  			if (DT_IS_RETL(ip[0]))
793  				return (0);
794  		} else {
795  			if (ip[0] == DT_OP_NOP) {
796  				(*off) += sizeof (ip[0]);
797  				return (0);
798  			}
799  		}
800  	}
801  
802  	/*
803  	 * We only expect call instructions with a displacement of 0.
804  	 */
805  	if (ip[0] != DT_OP_CALL) {
806  		dt_dprintf("found %x instead of a call instruction at %llx\n",
807  		    ip[0], (u_longlong_t)rela->r_offset);
808  		return (-1);
809  	}
810  
811  	if (isenabled) {
812  		/*
813  		 * It would necessarily indicate incorrect usage if an is-
814  		 * enabled probe were tail-called so flag that as an error.
815  		 * It's also potentially (very) tricky to handle gracefully,
816  		 * but could be done if this were a desired use scenario.
817  		 */
818  		if (DT_IS_RESTORE(ip[1]) || DT_IS_MOV_O7(ip[1])) {
819  			dt_dprintf("tail call to is-enabled probe at %llx\n",
820  			    (u_longlong_t)rela->r_offset);
821  			return (-1);
822  		}
823  
824  
825  		/*
826  		 * On SPARC, we take advantage of the fact that the first
827  		 * argument shares the same register as for the return value.
828  		 * The macro handles the work of zeroing that register so we
829  		 * don't need to do anything special here. We instrument the
830  		 * instruction in the delay slot as we'll need to modify the
831  		 * return register after that instruction has been emulated.
832  		 */
833  		ip[0] = DT_OP_NOP;
834  		(*off) += sizeof (ip[0]);
835  	} else {
836  		/*
837  		 * If the call is followed by a restore, it's a tail call so
838  		 * change the call to a ret. If the call if followed by a mov
839  		 * of a register into %o7, it's a tail call in leaf context
840  		 * so change the call to a retl-like instruction that returns
841  		 * to that register value + 8 (rather than the typical %o7 +
842  		 * 8); the delay slot instruction is left, but should have no
843  		 * effect. Otherwise we change the call to be a nop. We
844  		 * identify the subsequent instruction as the probe point in
845  		 * all but the leaf tail-call case to ensure that arguments to
846  		 * the probe are complete and consistent. An astute, though
847  		 * largely hypothetical, observer would note that there is the
848  		 * possibility of a false-positive probe firing if the function
849  		 * contained a branch to the instruction in the delay slot of
850  		 * the call. Fixing this would require significant in-kernel
851  		 * modifications, and isn't worth doing until we see it in the
852  		 * wild.
853  		 */
854  		if (DT_IS_RESTORE(ip[1])) {
855  			ip[0] = DT_OP_RET;
856  			(*off) += sizeof (ip[0]);
857  		} else if (DT_IS_MOV_O7(ip[1])) {
858  			ip[0] = DT_MAKE_RETL(DT_RS2(ip[1]));
859  		} else {
860  			ip[0] = DT_OP_NOP;
861  			(*off) += sizeof (ip[0]);
862  		}
863  	}
864  
865  	return (0);
866  }
867  
868  #elif defined(__i386) || defined(__amd64)
869  
870  #define	DT_OP_NOP		0x90
871  #define	DT_OP_RET		0xc3
872  #define	DT_OP_CALL		0xe8
873  #define	DT_OP_JMP32		0xe9
874  #define	DT_OP_REX_RAX		0x48
875  #define	DT_OP_XOR_EAX_0		0x33
876  #define	DT_OP_XOR_EAX_1		0xc0
877  
878  static int
dt_modtext(dtrace_hdl_t * dtp,char * p,int isenabled,GElf_Rela * rela,uint32_t * off)879  dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
880      uint32_t *off)
881  {
882  	uint8_t *ip = (uint8_t *)(p + rela->r_offset - 1);
883  	uint8_t ret;
884  
885  	/*
886  	 * On x86, the first byte of the instruction is the call opcode and
887  	 * the next four bytes are the 32-bit address; the relocation is for
888  	 * the address operand. We back up the offset to the first byte of
889  	 * the instruction. For is-enabled probes, we later advance the offset
890  	 * so that it hits the first nop in the instruction sequence.
891  	 */
892  	(*off) -= 1;
893  
894  	/*
895  	 * We only know about some specific relocation types. Luckily
896  	 * these types have the same values on both 32-bit and 64-bit
897  	 * x86 architectures.
898  	 */
899  	if (GELF_R_TYPE(rela->r_info) != R_386_PC32 &&
900  	    GELF_R_TYPE(rela->r_info) != R_386_PLT32)
901  		return (-1);
902  
903  	/*
904  	 * We may have already processed this object file in an earlier linker
905  	 * invocation. Check to see if the present instruction sequence matches
906  	 * the one we would install. For is-enabled probes, we advance the
907  	 * offset to the first nop instruction in the sequence to match the
908  	 * text modification code below.
909  	 */
910  	if (!isenabled) {
911  		if ((ip[0] == DT_OP_NOP || ip[0] == DT_OP_RET) &&
912  		    ip[1] == DT_OP_NOP && ip[2] == DT_OP_NOP &&
913  		    ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP)
914  			return (0);
915  	} else if (dtp->dt_oflags & DTRACE_O_LP64) {
916  		if (ip[0] == DT_OP_REX_RAX &&
917  		    ip[1] == DT_OP_XOR_EAX_0 && ip[2] == DT_OP_XOR_EAX_1 &&
918  		    (ip[3] == DT_OP_NOP || ip[3] == DT_OP_RET) &&
919  		    ip[4] == DT_OP_NOP) {
920  			(*off) += 3;
921  			return (0);
922  		}
923  	} else {
924  		if (ip[0] == DT_OP_XOR_EAX_0 && ip[1] == DT_OP_XOR_EAX_1 &&
925  		    (ip[2] == DT_OP_NOP || ip[2] == DT_OP_RET) &&
926  		    ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP) {
927  			(*off) += 2;
928  			return (0);
929  		}
930  	}
931  
932  	/*
933  	 * We expect either a call instrution with a 32-bit displacement or a
934  	 * jmp instruction with a 32-bit displacement acting as a tail-call.
935  	 */
936  	if (ip[0] != DT_OP_CALL && ip[0] != DT_OP_JMP32) {
937  		dt_dprintf("found %x instead of a call or jmp instruction at "
938  		    "%llx\n", ip[0], (u_longlong_t)rela->r_offset);
939  		return (-1);
940  	}
941  
942  	ret = (ip[0] == DT_OP_JMP32) ? DT_OP_RET : DT_OP_NOP;
943  
944  	/*
945  	 * Establish the instruction sequence -- all nops for probes, and an
946  	 * instruction to clear the return value register (%eax/%rax) followed
947  	 * by nops for is-enabled probes. For is-enabled probes, we advance
948  	 * the offset to the first nop. This isn't stricly necessary but makes
949  	 * for more readable disassembly when the probe is enabled.
950  	 */
951  	if (!isenabled) {
952  		ip[0] = ret;
953  		ip[1] = DT_OP_NOP;
954  		ip[2] = DT_OP_NOP;
955  		ip[3] = DT_OP_NOP;
956  		ip[4] = DT_OP_NOP;
957  	} else if (dtp->dt_oflags & DTRACE_O_LP64) {
958  		ip[0] = DT_OP_REX_RAX;
959  		ip[1] = DT_OP_XOR_EAX_0;
960  		ip[2] = DT_OP_XOR_EAX_1;
961  		ip[3] = ret;
962  		ip[4] = DT_OP_NOP;
963  		(*off) += 3;
964  	} else {
965  		ip[0] = DT_OP_XOR_EAX_0;
966  		ip[1] = DT_OP_XOR_EAX_1;
967  		ip[2] = ret;
968  		ip[3] = DT_OP_NOP;
969  		ip[4] = DT_OP_NOP;
970  		(*off) += 2;
971  	}
972  
973  	return (0);
974  }
975  
976  #else
977  #error unknown ISA
978  #endif
979  
980  /*PRINTFLIKE5*/
981  static int
dt_link_error(dtrace_hdl_t * dtp,Elf * elf,int fd,dt_link_pair_t * bufs,const char * format,...)982  dt_link_error(dtrace_hdl_t *dtp, Elf *elf, int fd, dt_link_pair_t *bufs,
983      const char *format, ...)
984  {
985  	va_list ap;
986  	dt_link_pair_t *pair;
987  
988  	va_start(ap, format);
989  	dt_set_errmsg(dtp, NULL, NULL, NULL, 0, format, ap);
990  	va_end(ap);
991  
992  	if (elf != NULL)
993  		(void) elf_end(elf);
994  
995  	if (fd >= 0)
996  		(void) close(fd);
997  
998  	while ((pair = bufs) != NULL) {
999  		bufs = pair->dlp_next;
1000  		dt_free(dtp, pair->dlp_str);
1001  		dt_free(dtp, pair->dlp_sym);
1002  		dt_free(dtp, pair);
1003  	}
1004  
1005  	return (dt_set_errno(dtp, EDT_COMPILER));
1006  }
1007  
1008  static int
process_obj(dtrace_hdl_t * dtp,const char * obj,int * eprobesp)1009  process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
1010  {
1011  	static const char dt_prefix[] = "__dtrace";
1012  	static const char dt_enabled[] = "enabled";
1013  	static const char dt_symprefix[] = "$dtrace";
1014  	static const char dt_symfmt[] = "%s%d.%s";
1015  	char probename[DTRACE_NAMELEN];
1016  	int fd, i, ndx, eprobe, mod = 0;
1017  	Elf *elf = NULL;
1018  	GElf_Ehdr ehdr;
1019  	Elf_Scn *scn_rel, *scn_sym, *scn_str, *scn_tgt;
1020  	Elf_Data *data_rel, *data_sym, *data_str, *data_tgt;
1021  	GElf_Shdr shdr_rel, shdr_sym, shdr_str, shdr_tgt;
1022  	GElf_Sym rsym, fsym, dsym;
1023  	GElf_Rela rela;
1024  	char *s, *p, *r;
1025  	char pname[DTRACE_PROVNAMELEN];
1026  	dt_provider_t *pvp;
1027  	dt_probe_t *prp;
1028  	uint32_t off, eclass, emachine1, emachine2;
1029  	size_t symsize, nsym, isym, istr, len;
1030  	key_t objkey;
1031  	dt_link_pair_t *pair, *bufs = NULL;
1032  	dt_strtab_t *strtab;
1033  
1034  	if ((fd = open64(obj, O_RDWR)) == -1) {
1035  		return (dt_link_error(dtp, elf, fd, bufs,
1036  		    "failed to open %s: %s", obj, strerror(errno)));
1037  	}
1038  
1039  	if ((elf = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL) {
1040  		return (dt_link_error(dtp, elf, fd, bufs,
1041  		    "failed to process %s: %s", obj, elf_errmsg(elf_errno())));
1042  	}
1043  
1044  	switch (elf_kind(elf)) {
1045  	case ELF_K_ELF:
1046  		break;
1047  	case ELF_K_AR:
1048  		return (dt_link_error(dtp, elf, fd, bufs, "archives are not "
1049  		    "permitted; use the contents of the archive instead: %s",
1050  		    obj));
1051  	default:
1052  		return (dt_link_error(dtp, elf, fd, bufs,
1053  		    "invalid file type: %s", obj));
1054  	}
1055  
1056  	if (gelf_getehdr(elf, &ehdr) == NULL) {
1057  		return (dt_link_error(dtp, elf, fd, bufs, "corrupt file: %s",
1058  		    obj));
1059  	}
1060  
1061  	if (dtp->dt_oflags & DTRACE_O_LP64) {
1062  		eclass = ELFCLASS64;
1063  #if defined(__sparc)
1064  		emachine1 = emachine2 = EM_SPARCV9;
1065  #elif defined(__i386) || defined(__amd64)
1066  		emachine1 = emachine2 = EM_AMD64;
1067  #endif
1068  		symsize = sizeof (Elf64_Sym);
1069  	} else {
1070  		eclass = ELFCLASS32;
1071  #if defined(__sparc)
1072  		emachine1 = EM_SPARC;
1073  		emachine2 = EM_SPARC32PLUS;
1074  #elif defined(__i386) || defined(__amd64)
1075  		emachine1 = emachine2 = EM_386;
1076  #endif
1077  		symsize = sizeof (Elf32_Sym);
1078  	}
1079  
1080  	if (ehdr.e_ident[EI_CLASS] != eclass) {
1081  		return (dt_link_error(dtp, elf, fd, bufs,
1082  		    "incorrect ELF class for object file: %s", obj));
1083  	}
1084  
1085  	if (ehdr.e_machine != emachine1 && ehdr.e_machine != emachine2) {
1086  		return (dt_link_error(dtp, elf, fd, bufs,
1087  		    "incorrect ELF machine type for object file: %s", obj));
1088  	}
1089  
1090  	/*
1091  	 * We use this token as a relatively unique handle for this file on the
1092  	 * system in order to disambiguate potential conflicts between files of
1093  	 * the same name which contain identially named local symbols.
1094  	 */
1095  	if ((objkey = ftok(obj, 0)) == (key_t)-1) {
1096  		return (dt_link_error(dtp, elf, fd, bufs,
1097  		    "failed to generate unique key for object file: %s", obj));
1098  	}
1099  
1100  	scn_rel = NULL;
1101  	while ((scn_rel = elf_nextscn(elf, scn_rel)) != NULL) {
1102  		if (gelf_getshdr(scn_rel, &shdr_rel) == NULL)
1103  			goto err;
1104  
1105  		/*
1106  		 * Skip any non-relocation sections.
1107  		 */
1108  		if (shdr_rel.sh_type != SHT_RELA && shdr_rel.sh_type != SHT_REL)
1109  			continue;
1110  
1111  		if ((data_rel = elf_getdata(scn_rel, NULL)) == NULL)
1112  			goto err;
1113  
1114  		/*
1115  		 * Grab the section, section header and section data for the
1116  		 * symbol table that this relocation section references.
1117  		 */
1118  		if ((scn_sym = elf_getscn(elf, shdr_rel.sh_link)) == NULL ||
1119  		    gelf_getshdr(scn_sym, &shdr_sym) == NULL ||
1120  		    (data_sym = elf_getdata(scn_sym, NULL)) == NULL)
1121  			goto err;
1122  
1123  		/*
1124  		 * Ditto for that symbol table's string table.
1125  		 */
1126  		if ((scn_str = elf_getscn(elf, shdr_sym.sh_link)) == NULL ||
1127  		    gelf_getshdr(scn_str, &shdr_str) == NULL ||
1128  		    (data_str = elf_getdata(scn_str, NULL)) == NULL)
1129  			goto err;
1130  
1131  		/*
1132  		 * Grab the section, section header and section data for the
1133  		 * target section for the relocations. For the relocations
1134  		 * we're looking for -- this will typically be the text of the
1135  		 * object file.
1136  		 */
1137  		if ((scn_tgt = elf_getscn(elf, shdr_rel.sh_info)) == NULL ||
1138  		    gelf_getshdr(scn_tgt, &shdr_tgt) == NULL ||
1139  		    (data_tgt = elf_getdata(scn_tgt, NULL)) == NULL)
1140  			goto err;
1141  
1142  		/*
1143  		 * We're looking for relocations to symbols matching this form:
1144  		 *
1145  		 *   __dtrace[enabled]_<prov>___<probe>
1146  		 *
1147  		 * For the generated object, we need to record the location
1148  		 * identified by the relocation, and create a new relocation
1149  		 * in the generated object that will be resolved at link time
1150  		 * to the location of the function in which the probe is
1151  		 * embedded. In the target object, we change the matched symbol
1152  		 * so that it will be ignored at link time, and we modify the
1153  		 * target (text) section to replace the call instruction with
1154  		 * one or more nops.
1155  		 *
1156  		 * If the function containing the probe is locally scoped
1157  		 * (static), we create an alias used by the relocation in the
1158  		 * generated object. The alias, a new symbol, will be global
1159  		 * (so that the relocation from the generated object can be
1160  		 * resolved), and hidden (so that it is converted to a local
1161  		 * symbol at link time). Such aliases have this form:
1162  		 *
1163  		 *   $dtrace<key>.<function>
1164  		 *
1165  		 * We take a first pass through all the relocations to
1166  		 * populate our string table and count the number of extra
1167  		 * symbols we'll require.
1168  		 */
1169  		strtab = dt_strtab_create(1);
1170  		nsym = 0;
1171  		isym = data_sym->d_size / symsize;
1172  		istr = data_str->d_size;
1173  
1174  		for (i = 0; i < shdr_rel.sh_size / shdr_rel.sh_entsize; i++) {
1175  
1176  			if (shdr_rel.sh_type == SHT_RELA) {
1177  				if (gelf_getrela(data_rel, i, &rela) == NULL)
1178  					continue;
1179  			} else {
1180  				GElf_Rel rel;
1181  				if (gelf_getrel(data_rel, i, &rel) == NULL)
1182  					continue;
1183  				rela.r_offset = rel.r_offset;
1184  				rela.r_info = rel.r_info;
1185  				rela.r_addend = 0;
1186  			}
1187  
1188  			if (gelf_getsym(data_sym, GELF_R_SYM(rela.r_info),
1189  			    &rsym) == NULL) {
1190  				dt_strtab_destroy(strtab);
1191  				goto err;
1192  			}
1193  
1194  			s = (char *)data_str->d_buf + rsym.st_name;
1195  
1196  			if (strncmp(s, dt_prefix, sizeof (dt_prefix) - 1) != 0)
1197  				continue;
1198  
1199  			if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
1200  			    shdr_rel.sh_info, &fsym) != 0) {
1201  				dt_strtab_destroy(strtab);
1202  				goto err;
1203  			}
1204  
1205  			if (GELF_ST_BIND(fsym.st_info) != STB_LOCAL)
1206  				continue;
1207  
1208  			if (fsym.st_name > data_str->d_size) {
1209  				dt_strtab_destroy(strtab);
1210  				goto err;
1211  			}
1212  
1213  			s = (char *)data_str->d_buf + fsym.st_name;
1214  
1215  			/*
1216  			 * If this symbol isn't of type function, we've really
1217  			 * driven off the rails or the object file is corrupt.
1218  			 */
1219  			if (GELF_ST_TYPE(fsym.st_info) != STT_FUNC) {
1220  				dt_strtab_destroy(strtab);
1221  				return (dt_link_error(dtp, elf, fd, bufs,
1222  				    "expected %s to be of type function", s));
1223  			}
1224  
1225  			len = snprintf(NULL, 0, dt_symfmt, dt_symprefix,
1226  			    objkey, s) + 1;
1227  			if ((p = dt_alloc(dtp, len)) == NULL) {
1228  				dt_strtab_destroy(strtab);
1229  				goto err;
1230  			}
1231  			(void) snprintf(p, len, dt_symfmt, dt_symprefix,
1232  			    objkey, s);
1233  
1234  			if (dt_strtab_index(strtab, p) == -1) {
1235  				nsym++;
1236  				(void) dt_strtab_insert(strtab, p);
1237  			}
1238  
1239  			dt_free(dtp, p);
1240  		}
1241  
1242  		/*
1243  		 * If needed, allocate the additional space for the symbol
1244  		 * table and string table copying the old data into the new
1245  		 * buffers, and marking the buffers as dirty. We inject those
1246  		 * newly allocated buffers into the libelf data structures, but
1247  		 * are still responsible for freeing them once we're done with
1248  		 * the elf handle.
1249  		 */
1250  		if (nsym > 0) {
1251  			/*
1252  			 * The first byte of the string table is reserved for
1253  			 * the \0 entry.
1254  			 */
1255  			len = dt_strtab_size(strtab) - 1;
1256  
1257  			assert(len > 0);
1258  			assert(dt_strtab_index(strtab, "") == 0);
1259  
1260  			dt_strtab_destroy(strtab);
1261  
1262  			if ((pair = dt_alloc(dtp, sizeof (*pair))) == NULL)
1263  				goto err;
1264  
1265  			if ((pair->dlp_str = dt_alloc(dtp, data_str->d_size +
1266  			    len)) == NULL) {
1267  				dt_free(dtp, pair);
1268  				goto err;
1269  			}
1270  
1271  			if ((pair->dlp_sym = dt_alloc(dtp, data_sym->d_size +
1272  			    nsym * symsize)) == NULL) {
1273  				dt_free(dtp, pair->dlp_str);
1274  				dt_free(dtp, pair);
1275  				goto err;
1276  			}
1277  
1278  			pair->dlp_next = bufs;
1279  			bufs = pair;
1280  
1281  			bcopy(data_str->d_buf, pair->dlp_str, data_str->d_size);
1282  			data_str->d_buf = pair->dlp_str;
1283  			data_str->d_size += len;
1284  			(void) elf_flagdata(data_str, ELF_C_SET, ELF_F_DIRTY);
1285  
1286  			shdr_str.sh_size += len;
1287  			(void) gelf_update_shdr(scn_str, &shdr_str);
1288  
1289  			bcopy(data_sym->d_buf, pair->dlp_sym, data_sym->d_size);
1290  			data_sym->d_buf = pair->dlp_sym;
1291  			data_sym->d_size += nsym * symsize;
1292  			(void) elf_flagdata(data_sym, ELF_C_SET, ELF_F_DIRTY);
1293  
1294  			shdr_sym.sh_size += nsym * symsize;
1295  			(void) gelf_update_shdr(scn_sym, &shdr_sym);
1296  
1297  			nsym += isym;
1298  		} else {
1299  			dt_strtab_destroy(strtab);
1300  		}
1301  
1302  		/*
1303  		 * Now that the tables have been allocated, perform the
1304  		 * modifications described above.
1305  		 */
1306  		for (i = 0; i < shdr_rel.sh_size / shdr_rel.sh_entsize; i++) {
1307  
1308  			if (shdr_rel.sh_type == SHT_RELA) {
1309  				if (gelf_getrela(data_rel, i, &rela) == NULL)
1310  					continue;
1311  			} else {
1312  				GElf_Rel rel;
1313  				if (gelf_getrel(data_rel, i, &rel) == NULL)
1314  					continue;
1315  				rela.r_offset = rel.r_offset;
1316  				rela.r_info = rel.r_info;
1317  				rela.r_addend = 0;
1318  			}
1319  
1320  			ndx = GELF_R_SYM(rela.r_info);
1321  
1322  			if (gelf_getsym(data_sym, ndx, &rsym) == NULL ||
1323  			    rsym.st_name > data_str->d_size)
1324  				goto err;
1325  
1326  			s = (char *)data_str->d_buf + rsym.st_name;
1327  
1328  			if (strncmp(s, dt_prefix, sizeof (dt_prefix) - 1) != 0)
1329  				continue;
1330  
1331  			s += sizeof (dt_prefix) - 1;
1332  
1333  			/*
1334  			 * Check to see if this is an 'is-enabled' check as
1335  			 * opposed to a normal probe.
1336  			 */
1337  			if (strncmp(s, dt_enabled,
1338  			    sizeof (dt_enabled) - 1) == 0) {
1339  				s += sizeof (dt_enabled) - 1;
1340  				eprobe = 1;
1341  				*eprobesp = 1;
1342  				dt_dprintf("is-enabled probe\n");
1343  			} else {
1344  				eprobe = 0;
1345  				dt_dprintf("normal probe\n");
1346  			}
1347  
1348  			if (*s++ != '_')
1349  				goto err;
1350  
1351  			if ((p = strstr(s, "___")) == NULL ||
1352  			    p - s >= sizeof (pname))
1353  				goto err;
1354  
1355  			bcopy(s, pname, p - s);
1356  			pname[p - s] = '\0';
1357  
1358  			if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
1359  			    shdr_rel.sh_info, &fsym) != 0)
1360  				goto err;
1361  
1362  			if (fsym.st_name > data_str->d_size)
1363  				goto err;
1364  
1365  			assert(GELF_ST_TYPE(fsym.st_info) == STT_FUNC);
1366  
1367  			/*
1368  			 * If a NULL relocation name is passed to
1369  			 * dt_probe_define(), the function name is used for the
1370  			 * relocation. The relocation needs to use a mangled
1371  			 * name if the symbol is locally scoped; the function
1372  			 * name may need to change if we've found the global
1373  			 * alias for the locally scoped symbol (we prefer
1374  			 * global symbols to locals in dt_symtab_lookup()).
1375  			 */
1376  			s = (char *)data_str->d_buf + fsym.st_name;
1377  			r = NULL;
1378  
1379  			if (GELF_ST_BIND(fsym.st_info) == STB_LOCAL) {
1380  				dsym = fsym;
1381  				dsym.st_name = istr;
1382  				dsym.st_info = GELF_ST_INFO(STB_GLOBAL,
1383  				    STT_FUNC);
1384  				dsym.st_other =
1385  				    ELF64_ST_VISIBILITY(STV_ELIMINATE);
1386  				(void) gelf_update_sym(data_sym, isym, &dsym);
1387  
1388  				r = (char *)data_str->d_buf + istr;
1389  				istr += 1 + sprintf(r, dt_symfmt,
1390  				    dt_symprefix, objkey, s);
1391  				isym++;
1392  				assert(isym <= nsym);
1393  
1394  			} else if (strncmp(s, dt_symprefix,
1395  			    strlen(dt_symprefix)) == 0) {
1396  				r = s;
1397  				if ((s = strchr(s, '.')) == NULL)
1398  					goto err;
1399  				s++;
1400  			}
1401  
1402  			if ((pvp = dt_provider_lookup(dtp, pname)) == NULL) {
1403  				return (dt_link_error(dtp, elf, fd, bufs,
1404  				    "no such provider %s", pname));
1405  			}
1406  
1407  			/* strlen("___") */
1408  			if (strlcpy(probename, p + 3, sizeof (probename)) >=
1409  			    sizeof (probename))
1410  				return (dt_link_error(dtp, elf, fd, bufs,
1411  				    "probe name too long %s", probename));
1412  
1413  			(void) strhyphenate(probename);
1414  
1415  			if ((prp = dt_probe_lookup(pvp, probename)) == NULL) {
1416  				return (dt_link_error(dtp, elf, fd, bufs,
1417  				    "no such probe %s", probename));
1418  			}
1419  
1420  			assert(fsym.st_value <= rela.r_offset);
1421  
1422  			off = rela.r_offset - fsym.st_value;
1423  			if (dt_modtext(dtp, data_tgt->d_buf, eprobe,
1424  			    &rela, &off) != 0) {
1425  				goto err;
1426  			}
1427  
1428  			if (dt_probe_define(pvp, prp, s, r, off, eprobe) != 0) {
1429  				return (dt_link_error(dtp, elf, fd, bufs,
1430  				    "failed to allocate space for probe"));
1431  			}
1432  
1433  			mod = 1;
1434  			(void) elf_flagdata(data_tgt, ELF_C_SET, ELF_F_DIRTY);
1435  
1436  			/*
1437  			 * This symbol may already have been marked to
1438  			 * be ignored by another relocation referencing
1439  			 * the same symbol or if this object file has
1440  			 * already been processed by an earlier link
1441  			 * invocation.
1442  			 */
1443  			if (rsym.st_shndx != SHN_SUNW_IGNORE) {
1444  				rsym.st_shndx = SHN_SUNW_IGNORE;
1445  				(void) gelf_update_sym(data_sym, ndx, &rsym);
1446  			}
1447  		}
1448  	}
1449  
1450  	if (mod && elf_update(elf, ELF_C_WRITE) == -1)
1451  		goto err;
1452  
1453  	(void) elf_end(elf);
1454  	(void) close(fd);
1455  
1456  	while ((pair = bufs) != NULL) {
1457  		bufs = pair->dlp_next;
1458  		dt_free(dtp, pair->dlp_str);
1459  		dt_free(dtp, pair->dlp_sym);
1460  		dt_free(dtp, pair);
1461  	}
1462  
1463  	return (0);
1464  
1465  err:
1466  	return (dt_link_error(dtp, elf, fd, bufs,
1467  	    "an error was encountered while processing %s", obj));
1468  }
1469  
1470  int
dtrace_program_link(dtrace_hdl_t * dtp,dtrace_prog_t * pgp,uint_t dflags,const char * file,int objc,char * const objv[])1471  dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
1472      const char *file, int objc, char *const objv[])
1473  {
1474  	char drti[PATH_MAX];
1475  	dof_hdr_t *dof;
1476  	int fd, status, i, cur;
1477  	char *cmd, tmp;
1478  	size_t len;
1479  	int eprobes = 0, ret = 0;
1480  
1481  	/*
1482  	 * A NULL program indicates a special use in which we just link
1483  	 * together a bunch of object files specified in objv and then
1484  	 * unlink(2) those object files.
1485  	 */
1486  	if (pgp == NULL) {
1487  		const char *fmt = "%s -o %s -r";
1488  
1489  		len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file) + 1;
1490  
1491  		for (i = 0; i < objc; i++)
1492  			len += strlen(objv[i]) + 1;
1493  
1494  		cmd = alloca(len);
1495  
1496  		cur = snprintf(cmd, len, fmt, dtp->dt_ld_path, file);
1497  
1498  		for (i = 0; i < objc; i++)
1499  			cur += snprintf(cmd + cur, len - cur, " %s", objv[i]);
1500  
1501  		if ((status = system(cmd)) == -1) {
1502  			return (dt_link_error(dtp, NULL, -1, NULL,
1503  			    "failed to run %s: %s", dtp->dt_ld_path,
1504  			    strerror(errno)));
1505  		}
1506  
1507  		if (WIFSIGNALED(status)) {
1508  			return (dt_link_error(dtp, NULL, -1, NULL,
1509  			    "failed to link %s: %s failed due to signal %d",
1510  			    file, dtp->dt_ld_path, WTERMSIG(status)));
1511  		}
1512  
1513  		if (WEXITSTATUS(status) != 0) {
1514  			return (dt_link_error(dtp, NULL, -1, NULL,
1515  			    "failed to link %s: %s exited with status %d\n",
1516  			    file, dtp->dt_ld_path, WEXITSTATUS(status)));
1517  		}
1518  
1519  		for (i = 0; i < objc; i++) {
1520  			if (strcmp(objv[i], file) != 0)
1521  				(void) unlink(objv[i]);
1522  		}
1523  
1524  		return (0);
1525  	}
1526  
1527  	for (i = 0; i < objc; i++) {
1528  		if (process_obj(dtp, objv[i], &eprobes) != 0)
1529  			return (-1); /* errno is set for us */
1530  	}
1531  
1532  	/*
1533  	 * If there are is-enabled probes then we need to force use of DOF
1534  	 * version 2.
1535  	 */
1536  	if (eprobes && pgp->dp_dofversion < DOF_VERSION_2)
1537  		pgp->dp_dofversion = DOF_VERSION_2;
1538  
1539  	if ((dof = dtrace_dof_create(dtp, pgp, dflags)) == NULL)
1540  		return (-1); /* errno is set for us */
1541  
1542  	/*
1543  	 * Create a temporary file and then unlink it if we're going to
1544  	 * combine it with drti.o later.  We can still refer to it in child
1545  	 * processes as /dev/fd/<fd>.
1546  	 */
1547  	if ((fd = open64(file, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1) {
1548  		return (dt_link_error(dtp, NULL, -1, NULL,
1549  		    "failed to open %s: %s", file, strerror(errno)));
1550  	}
1551  
1552  	/*
1553  	 * If -xlinktype=DOF has been selected, just write out the DOF.
1554  	 * Otherwise proceed to the default of generating and linking ELF.
1555  	 */
1556  	switch (dtp->dt_linktype) {
1557  	case DT_LTYP_DOF:
1558  		if (dt_write(dtp, fd, dof, dof->dofh_filesz) < dof->dofh_filesz)
1559  			ret = errno;
1560  
1561  		if (close(fd) != 0 && ret == 0)
1562  			ret = errno;
1563  
1564  		if (ret != 0) {
1565  			return (dt_link_error(dtp, NULL, -1, NULL,
1566  			    "failed to write %s: %s", file, strerror(ret)));
1567  		}
1568  
1569  		return (0);
1570  
1571  	case DT_LTYP_ELF:
1572  		break; /* fall through to the rest of dtrace_program_link() */
1573  
1574  	default:
1575  		return (dt_link_error(dtp, NULL, -1, NULL,
1576  		    "invalid link type %u\n", dtp->dt_linktype));
1577  	}
1578  
1579  
1580  	if (!dtp->dt_lazyload)
1581  		(void) unlink(file);
1582  
1583  	if (dtp->dt_oflags & DTRACE_O_LP64)
1584  		status = dump_elf64(dtp, dof, fd);
1585  	else
1586  		status = dump_elf32(dtp, dof, fd);
1587  
1588  	if (status != 0 || lseek(fd, 0, SEEK_SET) != 0) {
1589  		return (dt_link_error(dtp, NULL, -1, NULL,
1590  		    "failed to write %s: %s", file, strerror(errno)));
1591  	}
1592  
1593  	if (!dtp->dt_lazyload) {
1594  		const char *fmt = "%s -o %s -r -Blocal -Breduce /dev/fd/%d %s";
1595  
1596  		if (dtp->dt_oflags & DTRACE_O_LP64) {
1597  			(void) snprintf(drti, sizeof (drti),
1598  			    "%s/64/drti.o", _dtrace_libdir);
1599  		} else {
1600  			(void) snprintf(drti, sizeof (drti),
1601  			    "%s/drti.o", _dtrace_libdir);
1602  		}
1603  
1604  		len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, fd,
1605  		    drti) + 1;
1606  
1607  		cmd = alloca(len);
1608  
1609  		(void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, fd, drti);
1610  
1611  		if ((status = system(cmd)) == -1) {
1612  			ret = dt_link_error(dtp, NULL, -1, NULL,
1613  			    "failed to run %s: %s", dtp->dt_ld_path,
1614  			    strerror(errno));
1615  			goto done;
1616  		}
1617  
1618  		(void) close(fd); /* release temporary file */
1619  
1620  		if (WIFSIGNALED(status)) {
1621  			ret = dt_link_error(dtp, NULL, -1, NULL,
1622  			    "failed to link %s: %s failed due to signal %d",
1623  			    file, dtp->dt_ld_path, WTERMSIG(status));
1624  			goto done;
1625  		}
1626  
1627  		if (WEXITSTATUS(status) != 0) {
1628  			ret = dt_link_error(dtp, NULL, -1, NULL,
1629  			    "failed to link %s: %s exited with status %d\n",
1630  			    file, dtp->dt_ld_path, WEXITSTATUS(status));
1631  			goto done;
1632  		}
1633  	} else {
1634  		(void) close(fd);
1635  	}
1636  
1637  done:
1638  	dtrace_dof_destroy(dtp, dof);
1639  	return (ret);
1640  }
1641