38#include <contrib/zlib/zlib.h>
46 Elf_Shdr *shdr = NULL;
47 caddr_t ctftab = NULL;
49 caddr_t shstrtab = NULL;
56 struct thread *td = curthread;
57 struct ctf_header cth;
61 if (lf == NULL ||
lc == NULL)
65 bzero(
lc,
sizeof(*
lc));
85 lc->ctfoffp = (uint32_t **) &ef->
ctfoff;
86 lc->typoffp = (uint32_t **) &ef->
typoff;
98 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, lf->pathname);
103 NDFREE(&nd, NDF_ONLY_PNBUF);
106 hdr =
malloc(
sizeof(*hdr), M_LINKER, M_WAITOK);
109 if ((error =
vn_rdwr(UIO_READ, nd.ni_vp, hdr,
sizeof(*hdr),
110 0, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, NULL,
120 nbytes = hdr->e_shnum * hdr->e_shentsize;
121 if (
nbytes == 0 || hdr->e_shoff == 0 ||
122 hdr->e_shentsize !=
sizeof(Elf_Shdr)) {
131 if ((error =
vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)shdr,
nbytes,
132 hdr->e_shoff, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
141 if (hdr->e_shstrndx == 0 || shdr[hdr->e_shstrndx].sh_type != SHT_STRTAB) {
142 printf(
"%s(%d): module %s e_shstrndx is %d, sh_type is %d\n",
143 __func__, __LINE__, lf->pathname, hdr->e_shstrndx,
144 shdr[hdr->e_shstrndx].sh_type);
150 shstrtab =
malloc(shdr[hdr->e_shstrndx].sh_size, M_LINKER, M_WAITOK);
153 if ((error =
vn_rdwr(UIO_READ, nd.ni_vp, shstrtab,
154 shdr[hdr->e_shstrndx].sh_size, shdr[hdr->e_shstrndx].sh_offset,
155 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, NULL, td)) != 0)
159 for (i = 0; i < hdr->e_shnum; i++)
160 if (strcmp(
".SUNW_ctf", shstrtab + shdr[i].sh_name) == 0)
164 if (i >= hdr->e_shnum) {
165 printf(
"%s(%d): module %s has no .SUNW_ctf section\n",
166 __func__, __LINE__, lf->pathname);
172 if ((error =
vn_rdwr(UIO_READ, nd.ni_vp, &cth,
sizeof(cth),
173 shdr[i].sh_offset, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
174 NOCRED, NULL, td)) != 0)
178 if (cth.cth_magic != CTF_MAGIC) {
179 printf(
"%s(%d): module %s has invalid format\n",
180 __func__, __LINE__, lf->pathname);
185 if (cth.cth_version != CTF_VERSION_2 &&
186 cth.cth_version != CTF_VERSION_3) {
188 "%s(%d): module %s CTF format has unsupported version %d\n",
189 __func__, __LINE__, lf->pathname, cth.cth_version);
195 if ((cth.cth_flags & CTF_F_COMPRESS) != 0) {
203 sz = cth.cth_stroff + cth.cth_strlen +
sizeof(cth);
209 raw =
malloc(shdr[i].sh_size, M_LINKER, M_WAITOK);
215 sz = shdr[i].sh_size;
222 ctftab =
malloc(sz, M_LINKER, M_WAITOK);
228 if ((error =
vn_rdwr(UIO_READ, nd.ni_vp, raw == NULL ? ctftab : raw,
229 shdr[i].sh_size, shdr[i].sh_offset, UIO_SYSSPACE, IO_NODELOCKED,
230 td->td_ucred, NOCRED, NULL, td)) != 0)
242 bcopy(&cth, ctftab,
sizeof(cth));
244 destlen = sz -
sizeof(cth);
245 ret = uncompress(ctftab +
sizeof(cth), &destlen,
246 raw +
sizeof(cth), shdr[i].sh_size -
sizeof(cth));
248 printf(
"%s(%d): zlib uncompress returned %d\n",
249 __func__, __LINE__, ret);
257 ef->
ctfcnt = shdr[i].sh_size;
269 lc->ctfoffp = (uint32_t **) &ef->
ctfoff;
270 lc->typoffp = (uint32_t **) &ef->
typoff;
274 VOP_UNLOCK(nd.ni_vp);
275 vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
280 free(shdr, M_LINKER);
281 if (shstrtab != NULL)
282 free(shstrtab, M_LINKER);
284 free(ctftab, M_LINKER);
static int link_elf_ctf_get(linker_file_t lf, linker_ctf_t *lc)
void *() malloc(size_t size, struct malloc_type *mtp, int flags)
void free(void *addr, struct malloc_type *mtp)
struct elf_file * elf_file_t
const Elf_Sym * ddbsymtab
int printf(const char *fmt,...)
void() NDFREE(struct nameidata *ndp, const u_int flags)
int vn_rdwr(enum uio_rw rw, struct vnode *vp, void *base, int len, off_t offset, enum uio_seg segflg, int ioflg, struct ucred *active_cred, struct ucred *file_cred, ssize_t *aresid, struct thread *td)
int vn_open(struct nameidata *ndp, int *flagp, int cmode, struct file *fp)
int vn_close(struct vnode *vp, int flags, struct ucred *file_cred, struct thread *td)