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.
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.
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]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #define ELF_TARGET_ALL
32 #include <sys/types.h>
33 #include <sys/sysmacros.h>
49 #include <dt_provider.h>
50 #include <dt_program.h>
51 #include <dt_string.h>
54 #define ESHDR_SHSTRTAB 1
56 #define ESHDR_STRTAB 3
57 #define ESHDR_SYMTAB 4
61 #define PWRITE_SCN(index, data) \
62 (lseek64(fd, (off64_t)elf_file.shdr[(index)].sh_offset, SEEK_SET) != \
63 (off64_t)elf_file.shdr[(index)].sh_offset || \
64 dt_write(dtp, fd, (data), elf_file.shdr[(index)].sh_size) != \
65 elf_file.shdr[(index)].sh_size)
67 static const char DTRACE_SHSTRTAB32
[] = "\0"
69 ".SUNW_dof\0" /* 11 */
73 ".rela.SUNW_dof"; /* 37 */
75 ".rel.SUNW_dof"; /* 37 */
78 static const char DTRACE_SHSTRTAB64
[] = "\0"
80 ".SUNW_dof\0" /* 11 */
83 ".rela.SUNW_dof"; /* 37 */
85 static const char DOFSTR
[] = "__SUNW_dof";
86 static const char DOFLAZYSTR
[] = "___SUNW_dof";
88 typedef struct dt_link_pair
{
89 struct dt_link_pair
*dlp_next
; /* next pair in linked list */
90 void *dlp_str
; /* buffer for string table */
91 void *dlp_sym
; /* buffer for symbol table */
94 typedef struct dof_elf32
{
95 uint32_t de_nrel
; /* relocation count */
97 Elf32_Rela
*de_rel
; /* array of relocations for sparc */
99 Elf32_Rel
*de_rel
; /* array of relocations for x86 */
101 uint32_t de_nsym
; /* symbol count */
102 Elf32_Sym
*de_sym
; /* array of symbols */
103 uint32_t de_strlen
; /* size of of string table */
104 char *de_strtab
; /* string table */
105 uint32_t de_global
; /* index of the first global symbol */
109 prepare_elf32(dtrace_hdl_t
*dtp
, const dof_hdr_t
*dof
, dof_elf32_t
*dep
)
112 dof_relohdr_t
*dofrh
;
113 dof_relodesc_t
*dofr
;
127 dofs
= (dof_sec_t
*)((char *)dof
+ dof
->dofh_secoff
);
130 * First compute the size of the string table and the number of
131 * relocations present in the DOF.
133 for (i
= 0; i
< dof
->dofh_secnum
; i
++) {
134 if (dofs
[i
].dofs_type
!= DOF_SECT_URELHDR
)
138 dofrh
= (dof_relohdr_t
*)((char *)dof
+ dofs
[i
].dofs_offset
);
140 s
= &dofs
[dofrh
->dofr_strtab
];
141 strtab
= (char *)dof
+ s
->dofs_offset
;
142 assert(strtab
[0] == '\0');
143 strtabsz
+= s
->dofs_size
- 1;
145 s
= &dofs
[dofrh
->dofr_relsec
];
147 dofr
= (dof_relodesc_t
*)((char *)dof
+ s
->dofs_offset
);
148 count
+= s
->dofs_size
/ s
->dofs_entsize
;
151 dep
->de_strlen
= strtabsz
;
152 dep
->de_nrel
= count
;
153 dep
->de_nsym
= count
+ 1; /* the first symbol is always null */
155 if (dtp
->dt_lazyload
) {
156 dep
->de_strlen
+= sizeof (DOFLAZYSTR
);
159 dep
->de_strlen
+= sizeof (DOFSTR
);
163 if ((dep
->de_rel
= calloc(dep
->de_nrel
,
164 sizeof (dep
->de_rel
[0]))) == NULL
) {
165 return (dt_set_errno(dtp
, EDT_NOMEM
));
168 if ((dep
->de_sym
= calloc(dep
->de_nsym
, sizeof (Elf32_Sym
))) == NULL
) {
170 return (dt_set_errno(dtp
, EDT_NOMEM
));
173 if ((dep
->de_strtab
= calloc(dep
->de_strlen
, 1)) == NULL
) {
176 return (dt_set_errno(dtp
, EDT_NOMEM
));
181 dep
->de_strtab
[0] = '\0';
187 * The first symbol table entry must be zeroed and is always ignored.
189 bzero(sym
, sizeof (Elf32_Sym
));
193 * Take a second pass through the DOF sections filling in the
194 * memory we allocated.
196 for (i
= 0; i
< dof
->dofh_secnum
; i
++) {
197 if (dofs
[i
].dofs_type
!= DOF_SECT_URELHDR
)
201 dofrh
= (dof_relohdr_t
*)((char *)dof
+ dofs
[i
].dofs_offset
);
203 s
= &dofs
[dofrh
->dofr_strtab
];
204 strtab
= (char *)dof
+ s
->dofs_offset
;
205 bcopy(strtab
+ 1, dep
->de_strtab
+ strtabsz
, s
->dofs_size
);
207 strtabsz
+= s
->dofs_size
- 1;
209 s
= &dofs
[dofrh
->dofr_relsec
];
211 dofr
= (dof_relodesc_t
*)((char *)dof
+ s
->dofs_offset
);
212 nrel
= s
->dofs_size
/ s
->dofs_entsize
;
214 s
= &dofs
[dofrh
->dofr_tgtsec
];
216 for (j
= 0; j
< nrel
; j
++) {
217 #if defined(__i386) || defined(__amd64)
218 rel
->r_offset
= s
->dofs_offset
+
220 rel
->r_info
= ELF32_R_INFO(count
+ dep
->de_global
,
222 #elif defined(__sparc)
224 * Add 4 bytes to hit the low half of this 64-bit
225 * big-endian address.
227 rel
->r_offset
= s
->dofs_offset
+
228 dofr
[j
].dofr_offset
+ 4;
229 rel
->r_info
= ELF32_R_INFO(count
+ dep
->de_global
,
235 sym
->st_name
= base
+ dofr
[j
].dofr_name
- 1;
238 sym
->st_info
= ELF32_ST_INFO(STB_GLOBAL
, STT_FUNC
);
240 sym
->st_shndx
= SHN_UNDEF
;
249 * Add a symbol for the DOF itself. We use a different symbol for
250 * lazily and actively loaded DOF to make them easy to distinguish.
252 sym
->st_name
= strtabsz
;
254 sym
->st_size
= dof
->dofh_filesz
;
255 sym
->st_info
= ELF32_ST_INFO(STB_GLOBAL
, STT_OBJECT
);
257 sym
->st_shndx
= ESHDR_DOF
;
260 if (dtp
->dt_lazyload
) {
261 bcopy(DOFLAZYSTR
, dep
->de_strtab
+ strtabsz
,
262 sizeof (DOFLAZYSTR
));
263 strtabsz
+= sizeof (DOFLAZYSTR
);
265 bcopy(DOFSTR
, dep
->de_strtab
+ strtabsz
, sizeof (DOFSTR
));
266 strtabsz
+= sizeof (DOFSTR
);
269 assert(count
== dep
->de_nrel
);
270 assert(strtabsz
== dep
->de_strlen
);
276 typedef struct dof_elf64
{
289 prepare_elf64(dtrace_hdl_t
*dtp
, const dof_hdr_t
*dof
, dof_elf64_t
*dep
)
292 dof_relohdr_t
*dofrh
;
293 dof_relodesc_t
*dofr
;
303 dofs
= (dof_sec_t
*)((char *)dof
+ dof
->dofh_secoff
);
306 * First compute the size of the string table and the number of
307 * relocations present in the DOF.
309 for (i
= 0; i
< dof
->dofh_secnum
; i
++) {
310 if (dofs
[i
].dofs_type
!= DOF_SECT_URELHDR
)
314 dofrh
= (dof_relohdr_t
*)((char *)dof
+ dofs
[i
].dofs_offset
);
316 s
= &dofs
[dofrh
->dofr_strtab
];
317 strtab
= (char *)dof
+ s
->dofs_offset
;
318 assert(strtab
[0] == '\0');
319 strtabsz
+= s
->dofs_size
- 1;
321 s
= &dofs
[dofrh
->dofr_relsec
];
323 dofr
= (dof_relodesc_t
*)((char *)dof
+ s
->dofs_offset
);
324 count
+= s
->dofs_size
/ s
->dofs_entsize
;
327 dep
->de_strlen
= strtabsz
;
328 dep
->de_nrel
= count
;
329 dep
->de_nsym
= count
+ 1; /* the first symbol is always null */
331 if (dtp
->dt_lazyload
) {
332 dep
->de_strlen
+= sizeof (DOFLAZYSTR
);
335 dep
->de_strlen
+= sizeof (DOFSTR
);
339 if ((dep
->de_rel
= calloc(dep
->de_nrel
,
340 sizeof (dep
->de_rel
[0]))) == NULL
) {
341 return (dt_set_errno(dtp
, EDT_NOMEM
));
344 if ((dep
->de_sym
= calloc(dep
->de_nsym
, sizeof (Elf64_Sym
))) == NULL
) {
346 return (dt_set_errno(dtp
, EDT_NOMEM
));
349 if ((dep
->de_strtab
= calloc(dep
->de_strlen
, 1)) == NULL
) {
352 return (dt_set_errno(dtp
, EDT_NOMEM
));
357 dep
->de_strtab
[0] = '\0';
363 * The first symbol table entry must be zeroed and is always ignored.
365 bzero(sym
, sizeof (Elf64_Sym
));
369 * Take a second pass through the DOF sections filling in the
370 * memory we allocated.
372 for (i
= 0; i
< dof
->dofh_secnum
; i
++) {
373 if (dofs
[i
].dofs_type
!= DOF_SECT_URELHDR
)
377 dofrh
= (dof_relohdr_t
*)((char *)dof
+ dofs
[i
].dofs_offset
);
379 s
= &dofs
[dofrh
->dofr_strtab
];
380 strtab
= (char *)dof
+ s
->dofs_offset
;
381 bcopy(strtab
+ 1, dep
->de_strtab
+ strtabsz
, s
->dofs_size
);
383 strtabsz
+= s
->dofs_size
- 1;
385 s
= &dofs
[dofrh
->dofr_relsec
];
387 dofr
= (dof_relodesc_t
*)((char *)dof
+ s
->dofs_offset
);
388 nrel
= s
->dofs_size
/ s
->dofs_entsize
;
390 s
= &dofs
[dofrh
->dofr_tgtsec
];
392 for (j
= 0; j
< nrel
; j
++) {
393 #if defined(__i386) || defined(__amd64)
394 rel
->r_offset
= s
->dofs_offset
+
396 rel
->r_info
= ELF64_R_INFO(count
+ dep
->de_global
,
398 #elif defined(__sparc)
399 rel
->r_offset
= s
->dofs_offset
+
401 rel
->r_info
= ELF64_R_INFO(count
+ dep
->de_global
,
407 sym
->st_name
= base
+ dofr
[j
].dofr_name
- 1;
410 sym
->st_info
= GELF_ST_INFO(STB_GLOBAL
, STT_FUNC
);
412 sym
->st_shndx
= SHN_UNDEF
;
421 * Add a symbol for the DOF itself. We use a different symbol for
422 * lazily and actively loaded DOF to make them easy to distinguish.
424 sym
->st_name
= strtabsz
;
426 sym
->st_size
= dof
->dofh_filesz
;
427 sym
->st_info
= GELF_ST_INFO(STB_GLOBAL
, STT_OBJECT
);
429 sym
->st_shndx
= ESHDR_DOF
;
432 if (dtp
->dt_lazyload
) {
433 bcopy(DOFLAZYSTR
, dep
->de_strtab
+ strtabsz
,
434 sizeof (DOFLAZYSTR
));
435 strtabsz
+= sizeof (DOFLAZYSTR
);
437 bcopy(DOFSTR
, dep
->de_strtab
+ strtabsz
, sizeof (DOFSTR
));
438 strtabsz
+= sizeof (DOFSTR
);
441 assert(count
== dep
->de_nrel
);
442 assert(strtabsz
== dep
->de_strlen
);
448 * Write out an ELF32 file prologue consisting of a header, section headers,
449 * and a section header string table. The DOF data will follow this prologue
450 * and complete the contents of the given ELF file.
453 dump_elf32(dtrace_hdl_t
*dtp
, const dof_hdr_t
*dof
, int fd
)
457 Elf32_Shdr shdr
[ESHDR_NUM
];
466 if (prepare_elf32(dtp
, dof
, &de
) != 0)
467 return (-1); /* errno is set for us */
470 * If there are no relocations, we only need enough sections for
471 * the shstrtab and the DOF.
473 nshdr
= de
.de_nrel
== 0 ? ESHDR_SYMTAB
+ 1 : ESHDR_NUM
;
475 bzero(&elf_file
, sizeof (elf_file
));
477 elf_file
.ehdr
.e_ident
[EI_MAG0
] = ELFMAG0
;
478 elf_file
.ehdr
.e_ident
[EI_MAG1
] = ELFMAG1
;
479 elf_file
.ehdr
.e_ident
[EI_MAG2
] = ELFMAG2
;
480 elf_file
.ehdr
.e_ident
[EI_MAG3
] = ELFMAG3
;
481 elf_file
.ehdr
.e_ident
[EI_VERSION
] = EV_CURRENT
;
482 elf_file
.ehdr
.e_ident
[EI_CLASS
] = ELFCLASS32
;
483 #if defined(_BIG_ENDIAN)
484 elf_file
.ehdr
.e_ident
[EI_DATA
] = ELFDATA2MSB
;
485 #elif defined(_LITTLE_ENDIAN)
486 elf_file
.ehdr
.e_ident
[EI_DATA
] = ELFDATA2LSB
;
488 elf_file
.ehdr
.e_type
= ET_REL
;
490 elf_file
.ehdr
.e_machine
= EM_SPARC
;
491 #elif defined(__i386) || defined(__amd64)
492 elf_file
.ehdr
.e_machine
= EM_386
;
494 elf_file
.ehdr
.e_version
= EV_CURRENT
;
495 elf_file
.ehdr
.e_shoff
= sizeof (Elf32_Ehdr
);
496 elf_file
.ehdr
.e_ehsize
= sizeof (Elf32_Ehdr
);
497 elf_file
.ehdr
.e_phentsize
= sizeof (Elf32_Phdr
);
498 elf_file
.ehdr
.e_shentsize
= sizeof (Elf32_Shdr
);
499 elf_file
.ehdr
.e_shnum
= nshdr
;
500 elf_file
.ehdr
.e_shstrndx
= ESHDR_SHSTRTAB
;
501 off
= sizeof (elf_file
) + nshdr
* sizeof (Elf32_Shdr
);
503 shp
= &elf_file
.shdr
[ESHDR_SHSTRTAB
];
504 shp
->sh_name
= 1; /* DTRACE_SHSTRTAB32[1] = ".shstrtab" */
505 shp
->sh_type
= SHT_STRTAB
;
506 shp
->sh_offset
= off
;
507 shp
->sh_size
= sizeof (DTRACE_SHSTRTAB32
);
508 shp
->sh_addralign
= sizeof (char);
509 off
= P2ROUNDUP(shp
->sh_offset
+ shp
->sh_size
, 8);
511 shp
= &elf_file
.shdr
[ESHDR_DOF
];
512 shp
->sh_name
= 11; /* DTRACE_SHSTRTAB32[11] = ".SUNW_dof" */
513 shp
->sh_flags
= SHF_ALLOC
;
514 shp
->sh_type
= SHT_SUNW_dof
;
515 shp
->sh_offset
= off
;
516 shp
->sh_size
= dof
->dofh_filesz
;
517 shp
->sh_addralign
= 8;
518 off
= shp
->sh_offset
+ shp
->sh_size
;
520 shp
= &elf_file
.shdr
[ESHDR_STRTAB
];
521 shp
->sh_name
= 21; /* DTRACE_SHSTRTAB32[21] = ".strtab" */
522 shp
->sh_flags
= SHF_ALLOC
;
523 shp
->sh_type
= SHT_STRTAB
;
524 shp
->sh_offset
= off
;
525 shp
->sh_size
= de
.de_strlen
;
526 shp
->sh_addralign
= sizeof (char);
527 off
= P2ROUNDUP(shp
->sh_offset
+ shp
->sh_size
, 4);
529 shp
= &elf_file
.shdr
[ESHDR_SYMTAB
];
530 shp
->sh_name
= 29; /* DTRACE_SHSTRTAB32[29] = ".symtab" */
531 shp
->sh_flags
= SHF_ALLOC
;
532 shp
->sh_type
= SHT_SYMTAB
;
533 shp
->sh_entsize
= sizeof (Elf32_Sym
);
534 shp
->sh_link
= ESHDR_STRTAB
;
535 shp
->sh_offset
= off
;
536 shp
->sh_info
= de
.de_global
;
537 shp
->sh_size
= de
.de_nsym
* sizeof (Elf32_Sym
);
538 shp
->sh_addralign
= 4;
539 off
= P2ROUNDUP(shp
->sh_offset
+ shp
->sh_size
, 4);
541 if (de
.de_nrel
== 0) {
542 if (dt_write(dtp
, fd
, &elf_file
,
543 sizeof (elf_file
)) != sizeof (elf_file
) ||
544 PWRITE_SCN(ESHDR_SHSTRTAB
, DTRACE_SHSTRTAB32
) ||
545 PWRITE_SCN(ESHDR_STRTAB
, de
.de_strtab
) ||
546 PWRITE_SCN(ESHDR_SYMTAB
, de
.de_sym
) ||
547 PWRITE_SCN(ESHDR_DOF
, dof
)) {
548 ret
= dt_set_errno(dtp
, errno
);
551 shp
= &elf_file
.shdr
[ESHDR_REL
];
552 shp
->sh_name
= 37; /* DTRACE_SHSTRTAB32[37] = ".rel.SUNW_dof" */
553 shp
->sh_flags
= SHF_ALLOC
;
555 shp
->sh_type
= SHT_RELA
;
557 shp
->sh_type
= SHT_REL
;
559 shp
->sh_entsize
= sizeof (de
.de_rel
[0]);
560 shp
->sh_link
= ESHDR_SYMTAB
;
561 shp
->sh_info
= ESHDR_DOF
;
562 shp
->sh_offset
= off
;
563 shp
->sh_size
= de
.de_nrel
* sizeof (de
.de_rel
[0]);
564 shp
->sh_addralign
= 4;
566 if (dt_write(dtp
, fd
, &elf_file
,
567 sizeof (elf_file
)) != sizeof (elf_file
) ||
568 PWRITE_SCN(ESHDR_SHSTRTAB
, DTRACE_SHSTRTAB32
) ||
569 PWRITE_SCN(ESHDR_STRTAB
, de
.de_strtab
) ||
570 PWRITE_SCN(ESHDR_SYMTAB
, de
.de_sym
) ||
571 PWRITE_SCN(ESHDR_REL
, de
.de_rel
) ||
572 PWRITE_SCN(ESHDR_DOF
, dof
)) {
573 ret
= dt_set_errno(dtp
, errno
);
585 * Write out an ELF64 file prologue consisting of a header, section headers,
586 * and a section header string table. The DOF data will follow this prologue
587 * and complete the contents of the given ELF file.
590 dump_elf64(dtrace_hdl_t
*dtp
, const dof_hdr_t
*dof
, int fd
)
594 Elf64_Shdr shdr
[ESHDR_NUM
];
603 if (prepare_elf64(dtp
, dof
, &de
) != 0)
604 return (-1); /* errno is set for us */
607 * If there are no relocations, we only need enough sections for
608 * the shstrtab and the DOF.
610 nshdr
= de
.de_nrel
== 0 ? ESHDR_SYMTAB
+ 1 : ESHDR_NUM
;
612 bzero(&elf_file
, sizeof (elf_file
));
614 elf_file
.ehdr
.e_ident
[EI_MAG0
] = ELFMAG0
;
615 elf_file
.ehdr
.e_ident
[EI_MAG1
] = ELFMAG1
;
616 elf_file
.ehdr
.e_ident
[EI_MAG2
] = ELFMAG2
;
617 elf_file
.ehdr
.e_ident
[EI_MAG3
] = ELFMAG3
;
618 elf_file
.ehdr
.e_ident
[EI_VERSION
] = EV_CURRENT
;
619 elf_file
.ehdr
.e_ident
[EI_CLASS
] = ELFCLASS64
;
620 #if defined(_BIG_ENDIAN)
621 elf_file
.ehdr
.e_ident
[EI_DATA
] = ELFDATA2MSB
;
622 #elif defined(_LITTLE_ENDIAN)
623 elf_file
.ehdr
.e_ident
[EI_DATA
] = ELFDATA2LSB
;
625 elf_file
.ehdr
.e_type
= ET_REL
;
627 elf_file
.ehdr
.e_machine
= EM_SPARCV9
;
628 #elif defined(__i386) || defined(__amd64)
629 elf_file
.ehdr
.e_machine
= EM_AMD64
;
631 elf_file
.ehdr
.e_version
= EV_CURRENT
;
632 elf_file
.ehdr
.e_shoff
= sizeof (Elf64_Ehdr
);
633 elf_file
.ehdr
.e_ehsize
= sizeof (Elf64_Ehdr
);
634 elf_file
.ehdr
.e_phentsize
= sizeof (Elf64_Phdr
);
635 elf_file
.ehdr
.e_shentsize
= sizeof (Elf64_Shdr
);
636 elf_file
.ehdr
.e_shnum
= nshdr
;
637 elf_file
.ehdr
.e_shstrndx
= ESHDR_SHSTRTAB
;
638 off
= sizeof (elf_file
) + nshdr
* sizeof (Elf64_Shdr
);
640 shp
= &elf_file
.shdr
[ESHDR_SHSTRTAB
];
641 shp
->sh_name
= 1; /* DTRACE_SHSTRTAB64[1] = ".shstrtab" */
642 shp
->sh_type
= SHT_STRTAB
;
643 shp
->sh_offset
= off
;
644 shp
->sh_size
= sizeof (DTRACE_SHSTRTAB64
);
645 shp
->sh_addralign
= sizeof (char);
646 off
= P2ROUNDUP(shp
->sh_offset
+ shp
->sh_size
, 8);
648 shp
= &elf_file
.shdr
[ESHDR_DOF
];
649 shp
->sh_name
= 11; /* DTRACE_SHSTRTAB64[11] = ".SUNW_dof" */
650 shp
->sh_flags
= SHF_ALLOC
;
651 shp
->sh_type
= SHT_SUNW_dof
;
652 shp
->sh_offset
= off
;
653 shp
->sh_size
= dof
->dofh_filesz
;
654 shp
->sh_addralign
= 8;
655 off
= shp
->sh_offset
+ shp
->sh_size
;
657 shp
= &elf_file
.shdr
[ESHDR_STRTAB
];
658 shp
->sh_name
= 21; /* DTRACE_SHSTRTAB64[21] = ".strtab" */
659 shp
->sh_flags
= SHF_ALLOC
;
660 shp
->sh_type
= SHT_STRTAB
;
661 shp
->sh_offset
= off
;
662 shp
->sh_size
= de
.de_strlen
;
663 shp
->sh_addralign
= sizeof (char);
664 off
= P2ROUNDUP(shp
->sh_offset
+ shp
->sh_size
, 8);
666 shp
= &elf_file
.shdr
[ESHDR_SYMTAB
];
667 shp
->sh_name
= 29; /* DTRACE_SHSTRTAB64[29] = ".symtab" */
668 shp
->sh_flags
= SHF_ALLOC
;
669 shp
->sh_type
= SHT_SYMTAB
;
670 shp
->sh_entsize
= sizeof (Elf64_Sym
);
671 shp
->sh_link
= ESHDR_STRTAB
;
672 shp
->sh_offset
= off
;
673 shp
->sh_info
= de
.de_global
;
674 shp
->sh_size
= de
.de_nsym
* sizeof (Elf64_Sym
);
675 shp
->sh_addralign
= 8;
676 off
= P2ROUNDUP(shp
->sh_offset
+ shp
->sh_size
, 8);
678 if (de
.de_nrel
== 0) {
679 if (dt_write(dtp
, fd
, &elf_file
,
680 sizeof (elf_file
)) != sizeof (elf_file
) ||
681 PWRITE_SCN(ESHDR_SHSTRTAB
, DTRACE_SHSTRTAB64
) ||
682 PWRITE_SCN(ESHDR_STRTAB
, de
.de_strtab
) ||
683 PWRITE_SCN(ESHDR_SYMTAB
, de
.de_sym
) ||
684 PWRITE_SCN(ESHDR_DOF
, dof
)) {
685 ret
= dt_set_errno(dtp
, errno
);
688 shp
= &elf_file
.shdr
[ESHDR_REL
];
689 shp
->sh_name
= 37; /* DTRACE_SHSTRTAB64[37] = ".rel.SUNW_dof" */
690 shp
->sh_flags
= SHF_ALLOC
;
691 shp
->sh_type
= SHT_RELA
;
692 shp
->sh_entsize
= sizeof (de
.de_rel
[0]);
693 shp
->sh_link
= ESHDR_SYMTAB
;
694 shp
->sh_info
= ESHDR_DOF
;
695 shp
->sh_offset
= off
;
696 shp
->sh_size
= de
.de_nrel
* sizeof (de
.de_rel
[0]);
697 shp
->sh_addralign
= 8;
699 if (dt_write(dtp
, fd
, &elf_file
,
700 sizeof (elf_file
)) != sizeof (elf_file
) ||
701 PWRITE_SCN(ESHDR_SHSTRTAB
, DTRACE_SHSTRTAB64
) ||
702 PWRITE_SCN(ESHDR_STRTAB
, de
.de_strtab
) ||
703 PWRITE_SCN(ESHDR_SYMTAB
, de
.de_sym
) ||
704 PWRITE_SCN(ESHDR_REL
, de
.de_rel
) ||
705 PWRITE_SCN(ESHDR_DOF
, dof
)) {
706 ret
= dt_set_errno(dtp
, errno
);
718 dt_symtab_lookup(Elf_Data
*data_sym
, int nsym
, uintptr_t addr
, uint_t shn
,
724 for (i
= 0; i
< nsym
&& gelf_getsym(data_sym
, i
, sym
) != NULL
; i
++) {
725 if (GELF_ST_TYPE(sym
->st_info
) == STT_FUNC
&&
726 shn
== sym
->st_shndx
&&
727 sym
->st_value
<= addr
&&
728 addr
< sym
->st_value
+ sym
->st_size
) {
729 if (GELF_ST_BIND(sym
->st_info
) == STB_GLOBAL
)
744 #define DT_OP_RET 0x81c7e008
745 #define DT_OP_NOP 0x01000000
746 #define DT_OP_CALL 0x40000000
747 #define DT_OP_CLR_O0 0x90102000
749 #define DT_IS_MOV_O7(inst) (((inst) & 0xffffe000) == 0x9e100000)
750 #define DT_IS_RESTORE(inst) (((inst) & 0xc1f80000) == 0x81e80000)
751 #define DT_IS_RETL(inst) (((inst) & 0xfff83fff) == 0x81c02008)
753 #define DT_RS2(inst) ((inst) & 0x1f)
754 #define DT_MAKE_RETL(reg) (0x81c02008 | ((reg) << 14))
758 dt_modtext(dtrace_hdl_t
*dtp
, char *p
, int isenabled
, GElf_Rela
*rela
,
763 if ((rela
->r_offset
& (sizeof (uint32_t) - 1)) != 0)
767 ip
= (uint32_t *)(p
+ rela
->r_offset
);
770 * We only know about some specific relocation types.
772 if (GELF_R_TYPE(rela
->r_info
) != R_SPARC_WDISP30
&&
773 GELF_R_TYPE(rela
->r_info
) != R_SPARC_WPLT30
)
777 * We may have already processed this object file in an earlier linker
778 * invocation. Check to see if the present instruction sequence matches
779 * the one we would install below.
782 if (ip
[0] == DT_OP_NOP
) {
783 (*off
) += sizeof (ip
[0]);
787 if (DT_IS_RESTORE(ip
[1])) {
788 if (ip
[0] == DT_OP_RET
) {
789 (*off
) += sizeof (ip
[0]);
792 } else if (DT_IS_MOV_O7(ip
[1])) {
793 if (DT_IS_RETL(ip
[0]))
796 if (ip
[0] == DT_OP_NOP
) {
797 (*off
) += sizeof (ip
[0]);
804 * We only expect call instructions with a displacement of 0.
806 if (ip
[0] != DT_OP_CALL
) {
807 dt_dprintf("found %x instead of a call instruction at %llx\n",
808 ip
[0], (u_longlong_t
)rela
->r_offset
);
814 * It would necessarily indicate incorrect usage if an is-
815 * enabled probe were tail-called so flag that as an error.
816 * It's also potentially (very) tricky to handle gracefully,
817 * but could be done if this were a desired use scenario.
819 if (DT_IS_RESTORE(ip
[1]) || DT_IS_MOV_O7(ip
[1])) {
820 dt_dprintf("tail call to is-enabled probe at %llx\n",
821 (u_longlong_t
)rela
->r_offset
);
827 * On SPARC, we take advantage of the fact that the first
828 * argument shares the same register as for the return value.
829 * The macro handles the work of zeroing that register so we
830 * don't need to do anything special here. We instrument the
831 * instruction in the delay slot as we'll need to modify the
832 * return register after that instruction has been emulated.
835 (*off
) += sizeof (ip
[0]);
838 * If the call is followed by a restore, it's a tail call so
839 * change the call to a ret. If the call if followed by a mov
840 * of a register into %o7, it's a tail call in leaf context
841 * so change the call to a retl-like instruction that returns
842 * to that register value + 8 (rather than the typical %o7 +
843 * 8); the delay slot instruction is left, but should have no
844 * effect. Otherwise we change the call to be a nop. We
845 * identify the subsequent instruction as the probe point in
846 * all but the leaf tail-call case to ensure that arguments to
847 * the probe are complete and consistent. An astute, though
848 * largely hypothetical, observer would note that there is the
849 * possibility of a false-positive probe firing if the function
850 * contained a branch to the instruction in the delay slot of
851 * the call. Fixing this would require significant in-kernel
852 * modifications, and isn't worth doing until we see it in the
855 if (DT_IS_RESTORE(ip
[1])) {
857 (*off
) += sizeof (ip
[0]);
858 } else if (DT_IS_MOV_O7(ip
[1])) {
859 ip
[0] = DT_MAKE_RETL(DT_RS2(ip
[1]));
862 (*off
) += sizeof (ip
[0]);
869 #elif defined(__i386) || defined(__amd64)
871 #define DT_OP_NOP 0x90
872 #define DT_OP_RET 0xc3
873 #define DT_OP_CALL 0xe8
874 #define DT_OP_JMP32 0xe9
875 #define DT_OP_REX_RAX 0x48
876 #define DT_OP_XOR_EAX_0 0x33
877 #define DT_OP_XOR_EAX_1 0xc0
880 dt_modtext(dtrace_hdl_t
*dtp
, char *p
, int isenabled
, GElf_Rela
*rela
,
883 uint8_t *ip
= (uint8_t *)(p
+ rela
->r_offset
- 1);
887 * On x86, the first byte of the instruction is the call opcode and
888 * the next four bytes are the 32-bit address; the relocation is for
889 * the address operand. We back up the offset to the first byte of
890 * the instruction. For is-enabled probes, we later advance the offset
891 * so that it hits the first nop in the instruction sequence.
896 * We only know about some specific relocation types. Luckily
897 * these types have the same values on both 32-bit and 64-bit
900 if (GELF_R_TYPE(rela
->r_info
) != R_386_PC32
&&
901 GELF_R_TYPE(rela
->r_info
) != R_386_PLT32
)
905 * We may have already processed this object file in an earlier linker
906 * invocation. Check to see if the present instruction sequence matches
907 * the one we would install. For is-enabled probes, we advance the
908 * offset to the first nop instruction in the sequence to match the
909 * text modification code below.
912 if ((ip
[0] == DT_OP_NOP
|| ip
[0] == DT_OP_RET
) &&
913 ip
[1] == DT_OP_NOP
&& ip
[2] == DT_OP_NOP
&&
914 ip
[3] == DT_OP_NOP
&& ip
[4] == DT_OP_NOP
)
916 } else if (dtp
->dt_oflags
& DTRACE_O_LP64
) {
917 if (ip
[0] == DT_OP_REX_RAX
&&
918 ip
[1] == DT_OP_XOR_EAX_0
&& ip
[2] == DT_OP_XOR_EAX_1
&&
919 (ip
[3] == DT_OP_NOP
|| ip
[3] == DT_OP_RET
) &&
920 ip
[4] == DT_OP_NOP
) {
925 if (ip
[0] == DT_OP_XOR_EAX_0
&& ip
[1] == DT_OP_XOR_EAX_1
&&
926 (ip
[2] == DT_OP_NOP
|| ip
[2] == DT_OP_RET
) &&
927 ip
[3] == DT_OP_NOP
&& ip
[4] == DT_OP_NOP
) {
934 * We expect either a call instrution with a 32-bit displacement or a
935 * jmp instruction with a 32-bit displacement acting as a tail-call.
937 if (ip
[0] != DT_OP_CALL
&& ip
[0] != DT_OP_JMP32
) {
938 dt_dprintf("found %x instead of a call or jmp instruction at "
939 "%llx\n", ip
[0], (u_longlong_t
)rela
->r_offset
);
943 ret
= (ip
[0] == DT_OP_JMP32
) ? DT_OP_RET
: DT_OP_NOP
;
946 * Establish the instruction sequence -- all nops for probes, and an
947 * instruction to clear the return value register (%eax/%rax) followed
948 * by nops for is-enabled probes. For is-enabled probes, we advance
949 * the offset to the first nop. This isn't stricly necessary but makes
950 * for more readable disassembly when the probe is enabled.
958 } else if (dtp
->dt_oflags
& DTRACE_O_LP64
) {
959 ip
[0] = DT_OP_REX_RAX
;
960 ip
[1] = DT_OP_XOR_EAX_0
;
961 ip
[2] = DT_OP_XOR_EAX_1
;
966 ip
[0] = DT_OP_XOR_EAX_0
;
967 ip
[1] = DT_OP_XOR_EAX_1
;
983 dt_link_error(dtrace_hdl_t
*dtp
, Elf
*elf
, int fd
, dt_link_pair_t
*bufs
,
984 const char *format
, ...)
987 dt_link_pair_t
*pair
;
989 va_start(ap
, format
);
990 dt_set_errmsg(dtp
, NULL
, NULL
, NULL
, 0, format
, ap
);
999 while ((pair
= bufs
) != NULL
) {
1000 bufs
= pair
->dlp_next
;
1001 dt_free(dtp
, pair
->dlp_str
);
1002 dt_free(dtp
, pair
->dlp_sym
);
1006 return (dt_set_errno(dtp
, EDT_COMPILER
));
1010 process_obj(dtrace_hdl_t
*dtp
, const char *obj
, int *eprobesp
)
1012 static const char dt_prefix
[] = "__dtrace";
1013 static const char dt_enabled
[] = "enabled";
1014 static const char dt_symprefix
[] = "$dtrace";
1015 static const char dt_symfmt
[] = "%s%d.%s";
1016 int fd
, i
, ndx
, eprobe
, mod
= 0;
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
;
1025 char pname
[DTRACE_PROVNAMELEN
];
1028 uint32_t off
, eclass
, emachine1
, emachine2
;
1029 size_t symsize
, nsym
, isym
, istr
, len
;
1031 dt_link_pair_t
*pair
, *bufs
= NULL
;
1032 dt_strtab_t
*strtab
;
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
)));
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())));
1044 switch (elf_kind(elf
)) {
1048 return (dt_link_error(dtp
, elf
, fd
, bufs
, "archives are not "
1049 "permitted; use the contents of the archive instead: %s",
1052 return (dt_link_error(dtp
, elf
, fd
, bufs
,
1053 "invalid file type: %s", obj
));
1056 if (gelf_getehdr(elf
, &ehdr
) == NULL
) {
1057 return (dt_link_error(dtp
, elf
, fd
, bufs
, "corrupt file: %s",
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
;
1068 symsize
= sizeof (Elf64_Sym
);
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
;
1077 symsize
= sizeof (Elf32_Sym
);
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
));
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
));
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.
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
));
1101 while ((scn_rel
= elf_nextscn(elf
, scn_rel
)) != NULL
) {
1102 if (gelf_getshdr(scn_rel
, &shdr_rel
) == NULL
)
1106 * Skip any non-relocation sections.
1108 if (shdr_rel
.sh_type
!= SHT_RELA
&& shdr_rel
.sh_type
!= SHT_REL
)
1111 if ((data_rel
= elf_getdata(scn_rel
, NULL
)) == NULL
)
1115 * Grab the section, section header and section data for the
1116 * symbol table that this relocation section references.
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
)
1124 * Ditto for that symbol table's string table.
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
)
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
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
)
1143 * We're looking for relocations to symbols matching this form:
1145 * __dtrace[enabled]_<prov>___<probe>
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
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:
1163 * $dtrace<key>.<function>
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.
1169 strtab
= dt_strtab_create(1);
1171 isym
= data_sym
->d_size
/ symsize
;
1172 istr
= data_str
->d_size
;
1174 for (i
= 0; i
< shdr_rel
.sh_size
/ shdr_rel
.sh_entsize
; i
++) {
1176 if (shdr_rel
.sh_type
== SHT_RELA
) {
1177 if (gelf_getrela(data_rel
, i
, &rela
) == NULL
)
1181 if (gelf_getrel(data_rel
, i
, &rel
) == NULL
)
1183 rela
.r_offset
= rel
.r_offset
;
1184 rela
.r_info
= rel
.r_info
;
1188 if (gelf_getsym(data_sym
, GELF_R_SYM(rela
.r_info
),
1190 dt_strtab_destroy(strtab
);
1194 s
= (char *)data_str
->d_buf
+ rsym
.st_name
;
1196 if (strncmp(s
, dt_prefix
, sizeof (dt_prefix
) - 1) != 0)
1199 if (dt_symtab_lookup(data_sym
, isym
, rela
.r_offset
,
1200 shdr_rel
.sh_info
, &fsym
) != 0) {
1201 dt_strtab_destroy(strtab
);
1205 if (GELF_ST_BIND(fsym
.st_info
) != STB_LOCAL
)
1208 if (fsym
.st_name
> data_str
->d_size
) {
1209 dt_strtab_destroy(strtab
);
1213 s
= (char *)data_str
->d_buf
+ fsym
.st_name
;
1216 * If this symbol isn't of type function, we've really
1217 * driven off the rails or the object file is corrupt.
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
));
1225 len
= snprintf(NULL
, 0, dt_symfmt
, dt_symprefix
,
1227 if ((p
= dt_alloc(dtp
, len
)) == NULL
) {
1228 dt_strtab_destroy(strtab
);
1231 (void) snprintf(p
, len
, dt_symfmt
, dt_symprefix
,
1234 if (dt_strtab_index(strtab
, p
) == -1) {
1236 (void) dt_strtab_insert(strtab
, p
);
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
1252 * The first byte of the string table is reserved for
1255 len
= dt_strtab_size(strtab
) - 1;
1258 assert(dt_strtab_index(strtab
, "") == 0);
1260 dt_strtab_destroy(strtab
);
1262 if ((pair
= dt_alloc(dtp
, sizeof (*pair
))) == NULL
)
1265 if ((pair
->dlp_str
= dt_alloc(dtp
, data_str
->d_size
+
1271 if ((pair
->dlp_sym
= dt_alloc(dtp
, data_sym
->d_size
+
1272 nsym
* symsize
)) == NULL
) {
1273 dt_free(dtp
, pair
->dlp_str
);
1278 pair
->dlp_next
= bufs
;
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
);
1286 shdr_str
.sh_size
+= len
;
1287 (void) gelf_update_shdr(scn_str
, &shdr_str
);
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
);
1294 shdr_sym
.sh_size
+= nsym
* symsize
;
1295 (void) gelf_update_shdr(scn_sym
, &shdr_sym
);
1299 dt_strtab_destroy(strtab
);
1303 * Now that the tables have been allocated, perform the
1304 * modifications described above.
1306 for (i
= 0; i
< shdr_rel
.sh_size
/ shdr_rel
.sh_entsize
; i
++) {
1308 if (shdr_rel
.sh_type
== SHT_RELA
) {
1309 if (gelf_getrela(data_rel
, i
, &rela
) == NULL
)
1313 if (gelf_getrel(data_rel
, i
, &rel
) == NULL
)
1315 rela
.r_offset
= rel
.r_offset
;
1316 rela
.r_info
= rel
.r_info
;
1320 ndx
= GELF_R_SYM(rela
.r_info
);
1322 if (gelf_getsym(data_sym
, ndx
, &rsym
) == NULL
||
1323 rsym
.st_name
> data_str
->d_size
)
1326 s
= (char *)data_str
->d_buf
+ rsym
.st_name
;
1328 if (strncmp(s
, dt_prefix
, sizeof (dt_prefix
) - 1) != 0)
1331 s
+= sizeof (dt_prefix
) - 1;
1334 * Check to see if this is an 'is-enabled' check as
1335 * opposed to a normal probe.
1337 if (strncmp(s
, dt_enabled
,
1338 sizeof (dt_enabled
) - 1) == 0) {
1339 s
+= sizeof (dt_enabled
) - 1;
1342 dt_dprintf("is-enabled probe\n");
1345 dt_dprintf("normal probe\n");
1351 if ((p
= strstr(s
, "___")) == NULL
||
1352 p
- s
>= sizeof (pname
))
1355 bcopy(s
, pname
, p
- s
);
1356 pname
[p
- s
] = '\0';
1358 p
= strhyphenate(p
+ 3); /* strlen("___") */
1360 if (dt_symtab_lookup(data_sym
, isym
, rela
.r_offset
,
1361 shdr_rel
.sh_info
, &fsym
) != 0)
1364 if (fsym
.st_name
> data_str
->d_size
)
1367 assert(GELF_ST_TYPE(fsym
.st_info
) == STT_FUNC
);
1370 * If a NULL relocation name is passed to
1371 * dt_probe_define(), the function name is used for the
1372 * relocation. The relocation needs to use a mangled
1373 * name if the symbol is locally scoped; the function
1374 * name may need to change if we've found the global
1375 * alias for the locally scoped symbol (we prefer
1376 * global symbols to locals in dt_symtab_lookup()).
1378 s
= (char *)data_str
->d_buf
+ fsym
.st_name
;
1381 if (GELF_ST_BIND(fsym
.st_info
) == STB_LOCAL
) {
1383 dsym
.st_name
= istr
;
1384 dsym
.st_info
= GELF_ST_INFO(STB_GLOBAL
,
1387 ELF64_ST_VISIBILITY(STV_ELIMINATE
);
1388 (void) gelf_update_sym(data_sym
, isym
, &dsym
);
1390 r
= (char *)data_str
->d_buf
+ istr
;
1391 istr
+= 1 + sprintf(r
, dt_symfmt
,
1392 dt_symprefix
, objkey
, s
);
1394 assert(isym
<= nsym
);
1396 } else if (strncmp(s
, dt_symprefix
,
1397 strlen(dt_symprefix
)) == 0) {
1399 if ((s
= strchr(s
, '.')) == NULL
)
1404 if ((pvp
= dt_provider_lookup(dtp
, pname
)) == NULL
) {
1405 return (dt_link_error(dtp
, elf
, fd
, bufs
,
1406 "no such provider %s", pname
));
1409 if ((prp
= dt_probe_lookup(pvp
, p
)) == NULL
) {
1410 return (dt_link_error(dtp
, elf
, fd
, bufs
,
1411 "no such probe %s", p
));
1414 assert(fsym
.st_value
<= rela
.r_offset
);
1416 off
= rela
.r_offset
- fsym
.st_value
;
1417 if (dt_modtext(dtp
, data_tgt
->d_buf
, eprobe
,
1418 &rela
, &off
) != 0) {
1422 if (dt_probe_define(pvp
, prp
, s
, r
, off
, eprobe
) != 0) {
1423 return (dt_link_error(dtp
, elf
, fd
, bufs
,
1424 "failed to allocate space for probe"));
1428 (void) elf_flagdata(data_tgt
, ELF_C_SET
, ELF_F_DIRTY
);
1431 * This symbol may already have been marked to
1432 * be ignored by another relocation referencing
1433 * the same symbol or if this object file has
1434 * already been processed by an earlier link
1437 if (rsym
.st_shndx
!= SHN_SUNW_IGNORE
) {
1438 rsym
.st_shndx
= SHN_SUNW_IGNORE
;
1439 (void) gelf_update_sym(data_sym
, ndx
, &rsym
);
1444 if (mod
&& elf_update(elf
, ELF_C_WRITE
) == -1)
1447 (void) elf_end(elf
);
1450 while ((pair
= bufs
) != NULL
) {
1451 bufs
= pair
->dlp_next
;
1452 dt_free(dtp
, pair
->dlp_str
);
1453 dt_free(dtp
, pair
->dlp_sym
);
1460 return (dt_link_error(dtp
, elf
, fd
, bufs
,
1461 "an error was encountered while processing %s", obj
));
1465 dtrace_program_link(dtrace_hdl_t
*dtp
, dtrace_prog_t
*pgp
, uint_t dflags
,
1466 const char *file
, int objc
, char *const objv
[])
1468 char drti
[PATH_MAX
];
1470 int fd
, status
, i
, cur
;
1473 int eprobes
= 0, ret
= 0;
1476 * A NULL program indicates a special use in which we just link
1477 * together a bunch of object files specified in objv and then
1478 * unlink(2) those object files.
1481 const char *fmt
= "%s -o %s -r";
1483 len
= snprintf(&tmp
, 1, fmt
, dtp
->dt_ld_path
, file
) + 1;
1485 for (i
= 0; i
< objc
; i
++)
1486 len
+= strlen(objv
[i
]) + 1;
1490 cur
= snprintf(cmd
, len
, fmt
, dtp
->dt_ld_path
, file
);
1492 for (i
= 0; i
< objc
; i
++)
1493 cur
+= snprintf(cmd
+ cur
, len
- cur
, " %s", objv
[i
]);
1495 if ((status
= system(cmd
)) == -1) {
1496 return (dt_link_error(dtp
, NULL
, -1, NULL
,
1497 "failed to run %s: %s", dtp
->dt_ld_path
,
1501 if (WIFSIGNALED(status
)) {
1502 return (dt_link_error(dtp
, NULL
, -1, NULL
,
1503 "failed to link %s: %s failed due to signal %d",
1504 file
, dtp
->dt_ld_path
, WTERMSIG(status
)));
1507 if (WEXITSTATUS(status
) != 0) {
1508 return (dt_link_error(dtp
, NULL
, -1, NULL
,
1509 "failed to link %s: %s exited with status %d\n",
1510 file
, dtp
->dt_ld_path
, WEXITSTATUS(status
)));
1513 for (i
= 0; i
< objc
; i
++) {
1514 if (strcmp(objv
[i
], file
) != 0)
1515 (void) unlink(objv
[i
]);
1521 for (i
= 0; i
< objc
; i
++) {
1522 if (process_obj(dtp
, objv
[i
], &eprobes
) != 0)
1523 return (-1); /* errno is set for us */
1527 * If there are is-enabled probes then we need to force use of DOF
1530 if (eprobes
&& pgp
->dp_dofversion
< DOF_VERSION_2
)
1531 pgp
->dp_dofversion
= DOF_VERSION_2
;
1533 if ((dof
= dtrace_dof_create(dtp
, pgp
, dflags
)) == NULL
)
1534 return (-1); /* errno is set for us */
1537 * Create a temporary file and then unlink it if we're going to
1538 * combine it with drti.o later. We can still refer to it in child
1539 * processes as /dev/fd/<fd>.
1541 if ((fd
= open64(file
, O_RDWR
| O_CREAT
| O_TRUNC
, 0666)) == -1) {
1542 return (dt_link_error(dtp
, NULL
, -1, NULL
,
1543 "failed to open %s: %s", file
, strerror(errno
)));
1547 * If -xlinktype=DOF has been selected, just write out the DOF.
1548 * Otherwise proceed to the default of generating and linking ELF.
1550 switch (dtp
->dt_linktype
) {
1552 if (dt_write(dtp
, fd
, dof
, dof
->dofh_filesz
) < dof
->dofh_filesz
)
1555 if (close(fd
) != 0 && ret
== 0)
1559 return (dt_link_error(dtp
, NULL
, -1, NULL
,
1560 "failed to write %s: %s", file
, strerror(ret
)));
1566 break; /* fall through to the rest of dtrace_program_link() */
1569 return (dt_link_error(dtp
, NULL
, -1, NULL
,
1570 "invalid link type %u\n", dtp
->dt_linktype
));
1574 if (!dtp
->dt_lazyload
)
1575 (void) unlink(file
);
1577 if (dtp
->dt_oflags
& DTRACE_O_LP64
)
1578 status
= dump_elf64(dtp
, dof
, fd
);
1580 status
= dump_elf32(dtp
, dof
, fd
);
1582 if (status
!= 0 || lseek(fd
, 0, SEEK_SET
) != 0) {
1583 return (dt_link_error(dtp
, NULL
, -1, NULL
,
1584 "failed to write %s: %s", file
, strerror(errno
)));
1587 if (!dtp
->dt_lazyload
) {
1588 const char *fmt
= "%s -o %s -r -Blocal -Breduce /dev/fd/%d %s";
1590 if (dtp
->dt_oflags
& DTRACE_O_LP64
) {
1591 (void) snprintf(drti
, sizeof (drti
),
1592 "%s/64/drti.o", _dtrace_libdir
);
1594 (void) snprintf(drti
, sizeof (drti
),
1595 "%s/drti.o", _dtrace_libdir
);
1598 len
= snprintf(&tmp
, 1, fmt
, dtp
->dt_ld_path
, file
, fd
,
1603 (void) snprintf(cmd
, len
, fmt
, dtp
->dt_ld_path
, file
, fd
, drti
);
1605 if ((status
= system(cmd
)) == -1) {
1606 ret
= dt_link_error(dtp
, NULL
, -1, NULL
,
1607 "failed to run %s: %s", dtp
->dt_ld_path
,
1612 (void) close(fd
); /* release temporary file */
1614 if (WIFSIGNALED(status
)) {
1615 ret
= dt_link_error(dtp
, NULL
, -1, NULL
,
1616 "failed to link %s: %s failed due to signal %d",
1617 file
, dtp
->dt_ld_path
, WTERMSIG(status
));
1621 if (WEXITSTATUS(status
) != 0) {
1622 ret
= dt_link_error(dtp
, NULL
, -1, NULL
,
1623 "failed to link %s: %s exited with status %d\n",
1624 file
, dtp
->dt_ld_path
, WEXITSTATUS(status
));
1632 dtrace_dof_destroy(dtp
, dof
);