36 #define CTF_HDR_SIZE 36
37 #define CTF_HDR_STRTAB_U32 7
38 #define CTF_HDR_STRLEN_U32 8
42 z_alloc(
void *nil, u_int items, u_int size)
46 ptr =
malloc(items * size, M_TEMP, M_NOWAIT);
51 z_free(
void *nil,
void *ptr)
63 Elf_Shdr *shdr = NULL;
64 caddr_t ctftab = NULL;
66 caddr_t shstrtab = NULL;
75 struct thread *td = curthread;
80 if (lf == NULL || lc == NULL)
84 bzero(lc,
sizeof(*lc));
104 lc->ctfoffp = (uint32_t **) &ef->
ctfoff;
105 lc->typoffp = (uint32_t **) &ef->
typoff;
106 lc->typlenp = &ef->
typlen;
117 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, lf->pathname, td);
119 error =
vn_open(&nd, &flags, 0, NULL);
122 vfslocked = NDHASGIANT(&nd);
123 NDFREE(&nd, NDF_ONLY_PNBUF);
126 if ((hdr =
malloc(
sizeof(*hdr), M_LINKER, M_WAITOK)) == NULL) {
132 if ((error =
vn_rdwr(UIO_READ, nd.ni_vp, hdr,
sizeof(*hdr),
133 0, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid,
143 nbytes = hdr->e_shnum * hdr->e_shentsize;
144 if (nbytes == 0 || hdr->e_shoff == 0 ||
145 hdr->e_shentsize !=
sizeof(Elf_Shdr)) {
151 if ((shdr =
malloc(nbytes, M_LINKER, M_WAITOK)) == NULL) {
157 if ((error =
vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)shdr, nbytes,
158 hdr->e_shoff, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
167 if (hdr->e_shstrndx == 0 || shdr[hdr->e_shstrndx].sh_type != SHT_STRTAB) {
168 printf(
"%s(%d): module %s e_shstrndx is %d, sh_type is %d\n",
169 __func__, __LINE__, lf->pathname, hdr->e_shstrndx,
170 shdr[hdr->e_shstrndx].sh_type);
176 if ((shstrtab =
malloc(shdr[hdr->e_shstrndx].sh_size, M_LINKER,
177 M_WAITOK)) == NULL) {
183 if ((error =
vn_rdwr(UIO_READ, nd.ni_vp, shstrtab,
184 shdr[hdr->e_shstrndx].sh_size, shdr[hdr->e_shstrndx].sh_offset,
185 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid,
190 for (i = 0; i < hdr->e_shnum; i++)
191 if (strcmp(
".SUNW_ctf", shstrtab + shdr[i].sh_name) == 0)
195 if (i >= hdr->e_shnum) {
196 printf(
"%s(%d): module %s has no .SUNW_ctf section\n",
197 __func__, __LINE__, lf->pathname);
203 if ((error =
vn_rdwr(UIO_READ, nd.ni_vp, ctf_hdr,
sizeof(ctf_hdr),
204 shdr[i].sh_offset, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
205 NOCRED, &resid, td)) != 0)
209 if (ctf_hdr[0] != 0xf1 || ctf_hdr[1] != 0xcf) {
210 printf(
"%s(%d): module %s has invalid format\n",
211 __func__, __LINE__, lf->pathname);
217 if (ctf_hdr[2] != 2) {
218 printf(
"%s(%d): module %s CTF format version is %d "
220 __func__, __LINE__, lf->pathname, ctf_hdr[2]);
226 if ((ctf_hdr[3] & 0x1) != 0) {
227 uint32_t *u32 = (uint32_t *) ctf_hdr;
243 if ((raw =
malloc(shdr[i].sh_size, M_LINKER, M_WAITOK)) == NULL) {
252 sz = shdr[i].sh_size;
259 if ((ctftab =
malloc(sz, M_LINKER, M_WAITOK)) == NULL) {
268 if ((error =
vn_rdwr(UIO_READ, nd.ni_vp, raw == NULL ? ctftab : raw,
269 shdr[i].sh_size, shdr[i].sh_offset, UIO_SYSSPACE, IO_NODELOCKED,
270 td->td_ucred, NOCRED, &resid, td)) != 0)
282 bcopy(ctf_hdr, ctftab,
sizeof(ctf_hdr));
285 bzero(&zs,
sizeof(zs));
289 if (inflateInit(&zs) != Z_OK) {
294 zs.avail_in = shdr[i].sh_size -
sizeof(ctf_hdr);
295 zs.next_in = ((uint8_t *) raw) +
sizeof(ctf_hdr);
296 zs.avail_out = sz -
sizeof(ctf_hdr);
297 zs.next_out = ((uint8_t *) ctftab) +
sizeof(ctf_hdr);
298 if ((ret =
inflate(&zs, Z_FINISH)) != Z_STREAM_END) {
299 printf(
"%s(%d): zlib inflate returned %d\n", __func__, __LINE__, ret);
307 ef->
ctfcnt = shdr[i].sh_size;
319 lc->ctfoffp = (uint32_t **) &ef->
ctfoff;
320 lc->typoffp = (uint32_t **) &ef->
typoff;
321 lc->typlenp = &ef->
typlen;
324 VOP_UNLOCK(nd.ni_vp, 0);
325 vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
326 VFS_UNLOCK_GIANT(vfslocked);
331 free(shdr, M_LINKER);
332 if (shstrtab != NULL)
333 free(shstrtab, M_LINKER);
335 free(ctftab, M_LINKER);
void NDFREE(struct nameidata *ndp, const u_int flags)
void * malloc(unsigned long size, struct malloc_type *mtp, int flags)
static int link_elf_ctf_get(linker_file_t lf, linker_ctf_t *lc)
#define CTF_HDR_STRLEN_U32
int inflate(struct inflate *glbl)
const Elf_Sym * ddbsymtab
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)
void free(void *addr, struct malloc_type *mtp)
int vn_close(struct vnode *vp, int flags, struct ucred *file_cred, struct thread *td)
int printf(const char *fmt,...)
#define CTF_HDR_STRTAB_U32
int vn_open(struct nameidata *ndp, int *flagp, int cmode, struct file *fp)
struct elf_file * elf_file_t