1178481Sjb/* 2178481Sjb * CDDL HEADER START 3178481Sjb * 4178481Sjb * The contents of this file are subject to the terms of the 5178481Sjb * Common Development and Distribution License (the "License"). 6178481Sjb * You may not use this file except in compliance with the License. 7178481Sjb * 8178481Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9178481Sjb * or http://www.opensolaris.org/os/licensing. 10178481Sjb * See the License for the specific language governing permissions 11178481Sjb * and limitations under the License. 12178481Sjb * 13178481Sjb * When distributing Covered Code, include this CDDL HEADER in each 14178481Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15178481Sjb * If applicable, add the following below this CDDL HEADER, with the 16178481Sjb * fields enclosed by brackets "[]" replaced with your own identifying 17178481Sjb * information: Portions Copyright [yyyy] [name of copyright owner] 18178481Sjb * 19178481Sjb * CDDL HEADER END 20178481Sjb */ 21178481Sjb/* 22178481Sjb * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23178481Sjb * Use is subject to license terms. 24178481Sjb */ 25178481Sjb 26178481Sjb#pragma ident "%Z%%M% %I% %E% SMI" 27178481Sjb 28178481Sjb/* 29178481Sjb * Routines used to read stabs data from a file, and to build a tdata structure 30178481Sjb * based on the interesting parts of that data. 31178481Sjb */ 32178481Sjb 33178481Sjb#include <stdio.h> 34178481Sjb#include <stdlib.h> 35178481Sjb#include <fcntl.h> 36178481Sjb#include <unistd.h> 37178481Sjb#include <assert.h> 38178481Sjb#include <string.h> 39178481Sjb#include <libgen.h> 40178481Sjb#include <errno.h> 41178481Sjb#include <sys/types.h> 42178481Sjb#include <sys/param.h> 43178481Sjb 44178481Sjb#include "ctftools.h" 45178481Sjb#include "list.h" 46178481Sjb#include "stack.h" 47178481Sjb#include "memory.h" 48178481Sjb#include "traverse.h" 49178481Sjb 50178546Sjbchar *curhdr; 51178481Sjb 52178481Sjb/* 53178481Sjb * The stabs generator will sometimes reference types before they've been 54178481Sjb * defined. If this is the case, a TYPEDEF_UNRES tdesc will be generated. 55178481Sjb * Note that this is different from a forward declaration, in which the 56178481Sjb * stab is defined, but is defined as something that doesn't exist yet. 57178481Sjb * When we have read all of the stabs from the file, we can go back and 58178481Sjb * fix up all of the unresolved types. We should be able to fix all of them. 59178481Sjb */ 60178481Sjb/*ARGSUSED2*/ 61178481Sjbstatic int 62178546Sjbresolve_tou_node(tdesc_t *node, tdesc_t **nodep, void *private __unused) 63178481Sjb{ 64178481Sjb tdesc_t *new; 65178481Sjb 66178481Sjb debug(3, "Trying to resolve %s (%d)\n", tdesc_name(node), node->t_id); 67178481Sjb new = lookup(node->t_id); 68178481Sjb 69178481Sjb if (new == NULL) { 70178481Sjb terminate("Couldn't resolve type %d\n", node->t_id); 71178481Sjb } 72178481Sjb 73178481Sjb debug(3, " Resolving to %d\n", new->t_id); 74178481Sjb 75178481Sjb *nodep = new; 76178481Sjb 77178481Sjb return (1); 78178481Sjb} 79178481Sjb 80178481Sjb/*ARGSUSED*/ 81178481Sjbstatic int 82178546Sjbresolve_fwd_node(tdesc_t *node, tdesc_t **nodep, void *private __unused) 83178481Sjb{ 84178481Sjb tdesc_t *new = lookupname(node->t_name); 85178481Sjb 86178481Sjb debug(3, "Trying to unforward %s (%d)\n", tdesc_name(node), node->t_id); 87178481Sjb 88178481Sjb if (!new || (new->t_type != STRUCT && new->t_type != UNION)) 89178481Sjb return (0); 90178481Sjb 91178481Sjb debug(3, " Unforwarded to %d\n", new->t_id); 92178481Sjb 93178481Sjb *nodep = new; 94178481Sjb 95178481Sjb return (1); 96178481Sjb} 97178481Sjb 98178481Sjbstatic tdtrav_cb_f resolve_cbs[] = { 99178481Sjb NULL, 100178481Sjb NULL, /* intrinsic */ 101178481Sjb NULL, /* pointer */ 102178481Sjb NULL, /* array */ 103178481Sjb NULL, /* function */ 104178481Sjb NULL, /* struct */ 105178481Sjb NULL, /* union */ 106178481Sjb NULL, /* enum */ 107178481Sjb resolve_fwd_node, /* forward */ 108178481Sjb NULL, /* typedef */ 109178481Sjb resolve_tou_node, /* typedef unres */ 110178481Sjb NULL, /* volatile */ 111178481Sjb NULL, /* const */ 112178481Sjb NULL, /* restrict */ 113178481Sjb}; 114178481Sjb 115178481Sjbstatic void 116178481Sjbresolve_nodes(tdata_t *td) 117178481Sjb{ 118178481Sjb debug(2, "Resolving unresolved stabs\n"); 119178481Sjb 120178481Sjb (void) iitraverse_hash(td->td_iihash, &td->td_curvgen, resolve_cbs, 121178481Sjb NULL, NULL, td); 122178481Sjb} 123178481Sjb 124178481Sjbstatic char * 125178481Sjbconcat(char *s1, char *s2, int s2strip) 126178481Sjb{ 127178481Sjb int savelen = strlen(s2) - s2strip; 128178481Sjb int newlen = (s1 ? strlen(s1) : 0) + savelen + 1; 129178481Sjb char *out; 130178481Sjb 131178481Sjb out = xrealloc(s1, newlen); 132178481Sjb if (s1) 133178481Sjb strncpy(out + strlen(out), s2, savelen); 134178481Sjb else 135178481Sjb strncpy(out, s2, savelen); 136178481Sjb 137178481Sjb out[newlen - 1] = '\0'; 138178481Sjb 139178481Sjb return (out); 140178481Sjb} 141178481Sjb 142178481Sjb/* 143178481Sjb * N_FUN stabs come with their arguments in promoted form. In order to get the 144178481Sjb * actual arguments, we need to wait for the N_PSYM stabs that will come towards 145178481Sjb * the end of the function. These routines free the arguments (fnarg_free) we 146178481Sjb * got from the N_FUN stab and add (fnarg_add) the ones from the N_PSYM stabs. 147178481Sjb */ 148178481Sjbstatic void 149178481Sjbfnarg_add(iidesc_t *curfun, iidesc_t *arg) 150178481Sjb{ 151178481Sjb curfun->ii_nargs++; 152178481Sjb 153178481Sjb if (curfun->ii_nargs == 1) 154178481Sjb curfun->ii_args = xmalloc(sizeof (tdesc_t *) * FUNCARG_DEF); 155178481Sjb else if (curfun->ii_nargs > FUNCARG_DEF) { 156178481Sjb curfun->ii_args = xrealloc(curfun->ii_args, 157178481Sjb sizeof (tdesc_t *) * curfun->ii_nargs); 158178481Sjb } 159178481Sjb 160178481Sjb curfun->ii_args[curfun->ii_nargs - 1] = arg->ii_dtype; 161178481Sjb arg->ii_dtype = NULL; 162178481Sjb} 163178481Sjb 164178481Sjbstatic void 165178481Sjbfnarg_free(iidesc_t *ii) 166178481Sjb{ 167178481Sjb ii->ii_nargs = 0; 168178481Sjb free(ii->ii_args); 169178481Sjb ii->ii_args = NULL; 170178481Sjb} 171178481Sjb 172178481Sjb/* 173178481Sjb * Read the stabs from the stab ELF section, and turn them into a tdesc tree, 174178481Sjb * assembled under an iidesc list. 175178481Sjb */ 176178481Sjbint 177178546Sjbstabs_read(tdata_t *td, Elf *elf, char *file) 178178481Sjb{ 179178481Sjb Elf_Scn *scn; 180178481Sjb Elf_Data *data; 181178481Sjb stab_t *stab; 182178481Sjb stk_t *file_stack; 183178481Sjb iidesc_t *iidescp; 184178481Sjb iidesc_t *curfun = NULL; 185178481Sjb char curpath[MAXPATHLEN]; 186178481Sjb char *curfile = NULL; 187178481Sjb char *str; 188178481Sjb char *fstr = NULL, *ofstr = NULL; 189178481Sjb int stabidx, stabstridx; 190178481Sjb int nstabs, rc, i; 191178481Sjb int scope = 0; 192178481Sjb 193178481Sjb if (!((stabidx = findelfsecidx(elf, file, ".stab.excl")) >= 0 && 194178481Sjb (stabstridx = findelfsecidx(elf, file, ".stab.exclstr")) >= 0) && 195178481Sjb !((stabidx = findelfsecidx(elf, file, ".stab")) >= 0 && 196178481Sjb (stabstridx = findelfsecidx(elf, file, ".stabstr")) >= 0)) { 197178481Sjb errno = ENOENT; 198178481Sjb return (-1); 199178481Sjb } 200178481Sjb 201178481Sjb file_stack = stack_new(free); 202178481Sjb 203178546Sjb stack_push(file_stack, file); 204178481Sjb curhdr = file; 205178481Sjb 206178481Sjb debug(3, "Found stabs in %d, strings in %d\n", stabidx, stabstridx); 207178481Sjb 208178481Sjb scn = elf_getscn(elf, stabidx); 209178481Sjb data = elf_rawdata(scn, NULL); 210178481Sjb nstabs = data->d_size / sizeof (stab_t); 211178481Sjb 212178481Sjb parse_init(td); 213178481Sjb for (i = 0; i < nstabs; i++) { 214178481Sjb stab = &((stab_t *)data->d_buf)[i]; 215178481Sjb 216178481Sjb /* We don't want any local definitions */ 217178481Sjb if (stab->n_type == N_LBRAC) { 218178481Sjb scope++; 219178481Sjb debug(3, "stab %d: opening scope (%d)\n", i + 1, scope); 220178481Sjb continue; 221178481Sjb } else if (stab->n_type == N_RBRAC) { 222178481Sjb scope--; 223178481Sjb debug(3, "stab %d: closing scope (%d)\n", i + 1, scope); 224178481Sjb continue; 225178481Sjb } else if (stab->n_type == N_EINCL) { 226178481Sjb /* 227178481Sjb * There's a bug in the 5.2 (Taz) compilers that causes 228178481Sjb * them to emit an extra N_EINCL if there's no actual 229178481Sjb * text in the file being compiled. To work around this 230178481Sjb * bug, we explicitly check to make sure we're not 231178481Sjb * trying to pop a stack that only has the outer scope 232178481Sjb * on it. 233178481Sjb */ 234178481Sjb if (stack_level(file_stack) != 1) { 235178481Sjb str = (char *)stack_pop(file_stack); 236178481Sjb free(str); 237178481Sjb curhdr = (char *)stack_peek(file_stack); 238178481Sjb } 239178481Sjb } 240178481Sjb 241178481Sjb /* We only care about a subset of the stabs */ 242178481Sjb if (!(stab->n_type == N_FUN || stab->n_type == N_GSYM || 243178481Sjb stab->n_type == N_LCSYM || stab->n_type == N_LSYM || 244178481Sjb stab->n_type == N_PSYM || stab->n_type == N_ROSYM || 245178481Sjb stab->n_type == N_RSYM || 246178481Sjb stab->n_type == N_STSYM || stab->n_type == N_BINCL || 247178481Sjb stab->n_type == N_SO || stab->n_type == N_OPT)) 248178481Sjb continue; 249178481Sjb 250178481Sjb if ((str = elf_strptr(elf, stabstridx, 251178481Sjb (size_t)stab->n_strx)) == NULL) { 252178481Sjb terminate("%s: Can't find string at %u for stab %d\n", 253178481Sjb file, stab->n_strx, i); 254178481Sjb } 255178481Sjb 256178481Sjb if (stab->n_type == N_BINCL) { 257178481Sjb curhdr = xstrdup(str); 258178546Sjb stack_push(file_stack, curhdr); 259178481Sjb continue; 260178481Sjb } else if (stab->n_type == N_SO) { 261178481Sjb if (str[strlen(str) - 1] != '/') { 262178481Sjb strcpy(curpath, str); 263178481Sjb curfile = basename(curpath); 264178481Sjb } 265178481Sjb continue; 266178481Sjb } else if (stab->n_type == N_OPT) { 267178481Sjb if (strcmp(str, "gcc2_compiled.") == 0) { 268178481Sjb terminate("%s: GCC-generated stabs are " 269178481Sjb "unsupported. Use DWARF instead.\n", file); 270178481Sjb } 271178481Sjb continue; 272178481Sjb } 273178481Sjb 274178481Sjb if (str[strlen(str) - 1] == '\\') { 275178481Sjb int offset = 1; 276178481Sjb /* 277178481Sjb * There's a bug in the compilers that causes them to 278178481Sjb * generate \ for continuations with just -g (this is 279178481Sjb * ok), and \\ for continuations with -g -O (this is 280178481Sjb * broken). This bug is "fixed" in the 6.2 compilers 281178481Sjb * via the elimination of continuation stabs. 282178481Sjb */ 283178481Sjb if (str[strlen(str) - 2] == '\\') 284178481Sjb offset = 2; 285178481Sjb fstr = concat(fstr, str, offset); 286178481Sjb continue; 287178481Sjb } else 288178481Sjb fstr = concat(fstr, str, 0); 289178481Sjb 290178481Sjb debug(3, "%4d: .stabs \"%s\", %#x, %d, %hd, %d (from %s)\n", i, 291178481Sjb fstr, stab->n_type, 0, stab->n_desc, 292178481Sjb stab->n_value, curhdr); 293178481Sjb 294178481Sjb if (debug_level >= 3) 295178481Sjb check_hash(); 296178481Sjb 297178481Sjb /* 298178481Sjb * Sometimes the compiler stutters, and emits the same stab 299178481Sjb * twice. This is bad for the parser, which will attempt to 300178481Sjb * redefine the type IDs indicated in the stabs. This is 301178481Sjb * compiler bug 4433511. 302178481Sjb */ 303178481Sjb if (ofstr && strcmp(fstr, ofstr) == 0) { 304178481Sjb debug(3, "Stutter stab\n"); 305178481Sjb free(fstr); 306178481Sjb fstr = NULL; 307178481Sjb continue; 308178481Sjb } 309178481Sjb 310178481Sjb if (ofstr) 311178481Sjb free(ofstr); 312178481Sjb ofstr = fstr; 313178481Sjb 314178481Sjb iidescp = NULL; 315178481Sjb 316178481Sjb if ((rc = parse_stab(stab, fstr, &iidescp)) < 0) { 317178481Sjb terminate("%s: Couldn't parse stab \"%s\" " 318178481Sjb "(source file %s)\n", file, str, curhdr); 319178481Sjb } 320178481Sjb 321178481Sjb if (rc == 0) 322178481Sjb goto parse_loop_end; 323178481Sjb 324178481Sjb /* Make sure the scope tracking is working correctly */ 325178481Sjb assert(stab->n_type != N_FUN || (iidescp->ii_type != II_GFUN && 326178481Sjb iidescp->ii_type != II_SFUN) || scope == 0); 327178481Sjb 328178481Sjb /* 329178481Sjb * The only things we care about that are in local scope are 330178481Sjb * the N_PSYM stabs. 331178481Sjb */ 332178481Sjb if (scope && stab->n_type != N_PSYM) { 333178481Sjb if (iidescp) 334178481Sjb iidesc_free(iidescp, NULL); 335178481Sjb goto parse_loop_end; 336178481Sjb } 337178481Sjb 338178481Sjb switch (iidescp->ii_type) { 339178481Sjb case II_SFUN: 340178481Sjb iidescp->ii_owner = xstrdup(curfile); 341178481Sjb /*FALLTHROUGH*/ 342178481Sjb case II_GFUN: 343178481Sjb curfun = iidescp; 344178481Sjb fnarg_free(iidescp); 345178481Sjb iidesc_add(td->td_iihash, iidescp); 346178481Sjb break; 347178481Sjb 348178481Sjb case II_SVAR: 349178481Sjb iidescp->ii_owner = xstrdup(curfile); 350178481Sjb /*FALLTHROUGH*/ 351178481Sjb case II_GVAR: 352178481Sjb case II_TYPE: 353178481Sjb case II_SOU: 354178481Sjb iidesc_add(td->td_iihash, iidescp); 355178481Sjb break; 356178481Sjb 357178481Sjb case II_PSYM: 358178481Sjb fnarg_add(curfun, iidescp); 359178481Sjb iidesc_free(iidescp, NULL); 360178481Sjb break; 361178481Sjb default: 362178481Sjb aborterr("invalid ii_type %d for stab type %d", 363178481Sjb iidescp->ii_type, stab->n_type); 364178481Sjb } 365178481Sjb 366178481Sjbparse_loop_end: 367178481Sjb fstr = NULL; 368178481Sjb } 369178481Sjb 370178481Sjb if (ofstr) 371178481Sjb free(ofstr); 372178481Sjb 373178481Sjb resolve_nodes(td); 374178481Sjb resolve_typed_bitfields(); 375178481Sjb parse_finish(td); 376178481Sjb 377178481Sjb cvt_fixstabs(td); 378178481Sjb cvt_fixups(td, elf_ptrsz(elf)); 379178481Sjb 380178481Sjb return (0); 381178481Sjb} 382