Changeset View
Changeset View
Standalone View
Standalone View
head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
Show First 20 Lines • Show All 275 Lines • ▼ Show 20 Lines | #endif | ||||
/* | /* | ||||
* Add a symbol for the DOF itself. We use a different symbol for | * Add a symbol for the DOF itself. We use a different symbol for | ||||
* lazily and actively loaded DOF to make them easy to distinguish. | * lazily and actively loaded DOF to make them easy to distinguish. | ||||
*/ | */ | ||||
sym->st_name = strtabsz; | sym->st_name = strtabsz; | ||||
sym->st_value = 0; | sym->st_value = 0; | ||||
sym->st_size = dof->dofh_filesz; | sym->st_size = dof->dofh_filesz; | ||||
sym->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT); | sym->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT); | ||||
#ifdef illumos | |||||
sym->st_other = 0; | sym->st_other = 0; | ||||
#else | |||||
sym->st_other = ELF32_ST_VISIBILITY(STV_HIDDEN); | |||||
#endif | |||||
sym->st_shndx = ESHDR_DOF; | sym->st_shndx = ESHDR_DOF; | ||||
sym++; | sym++; | ||||
if (dtp->dt_lazyload) { | if (dtp->dt_lazyload) { | ||||
bcopy(DOFLAZYSTR, dep->de_strtab + strtabsz, | bcopy(DOFLAZYSTR, dep->de_strtab + strtabsz, | ||||
sizeof (DOFLAZYSTR)); | sizeof (DOFLAZYSTR)); | ||||
strtabsz += sizeof (DOFLAZYSTR); | strtabsz += sizeof (DOFLAZYSTR); | ||||
} else { | } else { | ||||
▲ Show 20 Lines • Show All 173 Lines • ▼ Show 20 Lines | #endif | ||||
/* | /* | ||||
* Add a symbol for the DOF itself. We use a different symbol for | * Add a symbol for the DOF itself. We use a different symbol for | ||||
* lazily and actively loaded DOF to make them easy to distinguish. | * lazily and actively loaded DOF to make them easy to distinguish. | ||||
*/ | */ | ||||
sym->st_name = strtabsz; | sym->st_name = strtabsz; | ||||
sym->st_value = 0; | sym->st_value = 0; | ||||
sym->st_size = dof->dofh_filesz; | sym->st_size = dof->dofh_filesz; | ||||
sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_OBJECT); | sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_OBJECT); | ||||
#ifdef illumos | |||||
sym->st_other = 0; | sym->st_other = 0; | ||||
#else | |||||
sym->st_other = ELF64_ST_VISIBILITY(STV_HIDDEN); | |||||
#endif | |||||
sym->st_shndx = ESHDR_DOF; | sym->st_shndx = ESHDR_DOF; | ||||
sym++; | sym++; | ||||
if (dtp->dt_lazyload) { | if (dtp->dt_lazyload) { | ||||
bcopy(DOFLAZYSTR, dep->de_strtab + strtabsz, | bcopy(DOFLAZYSTR, dep->de_strtab + strtabsz, | ||||
sizeof (DOFLAZYSTR)); | sizeof (DOFLAZYSTR)); | ||||
strtabsz += sizeof (DOFLAZYSTR); | strtabsz += sizeof (DOFLAZYSTR); | ||||
} else { | } else { | ||||
▲ Show 20 Lines • Show All 223 Lines • ▼ Show 20 Lines | #endif | ||||
shp->sh_type = SHT_STRTAB; | shp->sh_type = SHT_STRTAB; | ||||
shp->sh_offset = off; | shp->sh_offset = off; | ||||
shp->sh_size = sizeof (DTRACE_SHSTRTAB64); | shp->sh_size = sizeof (DTRACE_SHSTRTAB64); | ||||
shp->sh_addralign = sizeof (char); | shp->sh_addralign = sizeof (char); | ||||
off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8); | off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8); | ||||
shp = &elf_file.shdr[ESHDR_DOF]; | shp = &elf_file.shdr[ESHDR_DOF]; | ||||
shp->sh_name = 11; /* DTRACE_SHSTRTAB64[11] = ".SUNW_dof" */ | shp->sh_name = 11; /* DTRACE_SHSTRTAB64[11] = ".SUNW_dof" */ | ||||
#ifdef illumos | |||||
shp->sh_flags = SHF_ALLOC; | shp->sh_flags = SHF_ALLOC; | ||||
#else | |||||
shp->sh_flags = SHF_WRITE | SHF_ALLOC; | |||||
#endif | |||||
shp->sh_type = SHT_SUNW_dof; | shp->sh_type = SHT_SUNW_dof; | ||||
shp->sh_offset = off; | shp->sh_offset = off; | ||||
shp->sh_size = dof->dofh_filesz; | shp->sh_size = dof->dofh_filesz; | ||||
shp->sh_addralign = 8; | shp->sh_addralign = 8; | ||||
off = shp->sh_offset + shp->sh_size; | off = shp->sh_offset + shp->sh_size; | ||||
shp = &elf_file.shdr[ESHDR_STRTAB]; | shp = &elf_file.shdr[ESHDR_STRTAB]; | ||||
shp->sh_name = 21; /* DTRACE_SHSTRTAB64[21] = ".strtab" */ | shp->sh_name = 21; /* DTRACE_SHSTRTAB64[21] = ".strtab" */ | ||||
▲ Show 20 Lines • Show All 1,142 Lines • ▼ Show 20 Lines | #else | ||||
/* | /* | ||||
* Arches which are 32-bit only just use the normal | * Arches which are 32-bit only just use the normal | ||||
* library path. | * library path. | ||||
*/ | */ | ||||
int use_32 = 0; | int use_32 = 0; | ||||
#endif | #endif | ||||
(void) snprintf(drti, sizeof (drti), "/usr/lib%s/dtrace/drti.o", | (void) snprintf(drti, sizeof (drti), "/usr/lib%s/dtrace/drti.o", | ||||
use_32 ? "32":""); | use_32 ? "32" : ""); | ||||
len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, tfile, | len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, tfile, | ||||
drti) + 1; | drti) + 1; | ||||
cmd = alloca(len); | cmd = alloca(len); | ||||
(void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, tfile, | (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, tfile, | ||||
drti); | drti); | ||||
#endif | #endif | ||||
if ((status = system(cmd)) == -1) { | if ((status = system(cmd)) == -1) { | ||||
ret = dt_link_error(dtp, NULL, -1, NULL, | ret = dt_link_error(dtp, NULL, fd, NULL, | ||||
"failed to run %s: %s", dtp->dt_ld_path, | "failed to run %s: %s", dtp->dt_ld_path, | ||||
strerror(errno)); | strerror(errno)); | ||||
goto done; | goto done; | ||||
} | } | ||||
if (WIFSIGNALED(status)) { | if (WIFSIGNALED(status)) { | ||||
ret = dt_link_error(dtp, NULL, -1, NULL, | ret = dt_link_error(dtp, NULL, fd, NULL, | ||||
"failed to link %s: %s failed due to signal %d", | "failed to link %s: %s failed due to signal %d", | ||||
file, dtp->dt_ld_path, WTERMSIG(status)); | file, dtp->dt_ld_path, WTERMSIG(status)); | ||||
goto done; | goto done; | ||||
} | } | ||||
if (WEXITSTATUS(status) != 0) { | if (WEXITSTATUS(status) != 0) { | ||||
ret = dt_link_error(dtp, NULL, -1, NULL, | ret = dt_link_error(dtp, NULL, fd, NULL, | ||||
"failed to link %s: %s exited with status %d\n", | "failed to link %s: %s exited with status %d\n", | ||||
file, dtp->dt_ld_path, WEXITSTATUS(status)); | file, dtp->dt_ld_path, WEXITSTATUS(status)); | ||||
goto done; | goto done; | ||||
} | } | ||||
(void) close(fd); /* release temporary file */ | (void) close(fd); /* release temporary file */ | ||||
#ifdef __FreeBSD__ | |||||
/* | |||||
* Now that we've linked drti.o, reduce the global __SUNW_dof | |||||
* symbol to a local symbol. This is needed to so that multiple | |||||
* generated object files (for different providers, for | |||||
* instance) can be linked together. This is accomplished using | |||||
* the -Blocal flag with Sun's linker, but GNU ld doesn't appear | |||||
* to have an equivalent option. | |||||
*/ | |||||
asprintf(&cmd, "%s --localize-hidden %s", dtp->dt_objcopy_path, | |||||
file); | |||||
if ((status = system(cmd)) == -1) { | |||||
ret = dt_link_error(dtp, NULL, -1, NULL, | |||||
"failed to run %s: %s", dtp->dt_objcopy_path, | |||||
strerror(errno)); | |||||
free(cmd); | |||||
goto done; | |||||
} | |||||
free(cmd); | |||||
if (WIFSIGNALED(status)) { | |||||
ret = dt_link_error(dtp, NULL, -1, NULL, | |||||
"failed to link %s: %s failed due to signal %d", | |||||
file, dtp->dt_objcopy_path, WTERMSIG(status)); | |||||
goto done; | |||||
} | |||||
if (WEXITSTATUS(status) != 0) { | |||||
ret = dt_link_error(dtp, NULL, -1, NULL, | |||||
"failed to link %s: %s exited with status %d\n", | |||||
file, dtp->dt_objcopy_path, WEXITSTATUS(status)); | |||||
goto done; | |||||
} | |||||
#endif | |||||
} else { | } else { | ||||
(void) close(fd); | (void) close(fd); | ||||
} | } | ||||
done: | done: | ||||
dtrace_dof_destroy(dtp, dof); | dtrace_dof_destroy(dtp, dof); | ||||
#ifndef illumos | #ifndef illumos | ||||
unlink(tfile); | unlink(tfile); | ||||
#endif | #endif | ||||
return (ret); | return (ret); | ||||
} | } |