Пример #1
0
int 
main(int argc, char **argv)
{

    Dwarf_Debug dbg = 0;
    int fd = -1;
    const char *filepath = "<stdin>";
    int res = DW_DLV_ERROR;
    Dwarf_Error error;
    Dwarf_Handler errhand = 0;
    Dwarf_Ptr errarg = 0;

    if(argc < 2) {
        fd = 0; /* stdin */
    } else {
        filepath = argv[1];
        fd = open(filepath,O_RDONLY);
    }
    if(fd < 0) {
        printf("Failure attempting to open %s\n",filepath);
    }
    res = dwarf_init(fd,DW_DLC_READ,errhand,errarg, &dbg,&error);
    if(res != DW_DLV_OK) {
        printf("Giving up, cannot do DWARF processing\n");
        exit(1);
    }

    read_cu_list(dbg);
    res = dwarf_finish(dbg,&error);
    if(res != DW_DLV_OK) {
        printf("dwarf_finish failed!\n");
    }
    close(fd);
    return 0;
}
Пример #2
0
bool codegen(ast_t* program, pass_opt_t* opt)
{
  printf("Generating\n");
  pony_mkdir(opt->output);

  compile_t c;
  memset(&c, 0, sizeof(compile_t));

  init_module(&c, program, opt);
  init_runtime(&c);
  genprim_builtins(&c);

  // Emit debug info for this compile unit.
  dwarf_init(&c.dwarf, c.opt, c.builder, c.target_data, c.module);
  dwarf_compileunit(&c.dwarf, program);

  bool ok;

  if(c.opt->library)
    ok = genlib(&c, program);
  else
    ok = genexe(&c, program);

  codegen_cleanup(&c);
  return ok;
}
Пример #3
0
int main(int argc, char** argv)
{
    Dwarf_Debug dbg = 0;
    Dwarf_Error err;
    const char* progname;
    int fd = -1;

    if (argc < 2) {
        fprintf(stderr, "Expected a program name as argument\n");
        return 1;
    }

    progname = argv[1];
    if ((fd = open(progname, O_RDONLY)) < 0) {
        perror("open");
        return 1;
    }
    
    if (dwarf_init(fd, DW_DLC_READ, 0, 0, &dbg, &err) != DW_DLV_OK) {
        fprintf(stderr, "Failed DWARF initialization\n");
        return 1;
    }

    list_funcs_in_file(dbg);

    if (dwarf_finish(dbg, &err) != DW_DLV_OK) {
        fprintf(stderr, "Failed DWARF finalization\n");
        return 1;
    }

    close(fd);
    return 0;
}
Пример #4
0
HIDDEN void
tdep_init (void)
{
  intrmask_t saved_mask;

  sigfillset (&unwi_full_mask);

  sigprocmask (SIG_SETMASK, &unwi_full_mask, &saved_mask);
  mutex_lock (&arm_lock);
  {
    if (!tdep_needs_initialization)
      /* another thread else beat us to it... */
      goto out;

    mi_init ();

    dwarf_init ();

#ifndef UNW_REMOTE_ONLY
    arm_local_addr_space_init ();
#endif
    tdep_needs_initialization = 0;	/* signal that we're initialized... */
  }
 out:
  mutex_unlock (&arm_lock);
  sigprocmask (SIG_SETMASK, &saved_mask, NULL);
}
Пример #5
0
HIDDEN void
tdep_init (void)
{
  intrmask_t saved_mask;

  sigfillset (&unwi_full_mask);

  lock_acquire (&x86_64_lock, saved_mask);
  {
    if (tdep_init_done)
      /* another thread else beat us to it... */
      goto out;

    mi_init ();

    dwarf_init ();

    tdep_init_mem_validate ();

#ifndef UNW_REMOTE_ONLY
    x86_64_local_addr_space_init ();
#endif
    tdep_init_done = 1; /* signal that we're initialized... */
  }
 out:
  lock_release (&x86_64_lock, saved_mask);
}
Пример #6
0
HIDDEN void
tdep_init (void)
{
  intrmask_t saved_mask;

  Debug(1, "called\n");

  sigfillset (&unwi_full_mask);

  lock_acquire (&x86_64_lock, saved_mask);
  {
    if (tdep_init_done)
      /* another thread else beat us to it... */
      goto out;

    mi_init ();

    dwarf_init ();

    tdep_init_mem_validate ();

    x86_64_local_addr_space_init ();

    tdep_init_done = 1; /* signal that we're initialized... */
  }
 out:
  lock_release (&x86_64_lock, saved_mask);

  Debug(1, "done\n");
}
HIDDEN void
tdep_init (void)
{
  intrmask_t saved_mask;

  sigfillset (&unwi_full_mask);

  lock_acquire (&arm_lock, saved_mask);
  {
    if (tdep_init_done)
      /* another thread else beat us to it... */
      goto out;

    /* read ARM unwind method setting */
    const char* str = getenv ("UNW_ARM_UNWIND_METHOD");
    if (str)
      {
        unwi_unwind_method = atoi (str);
      }

    mi_init ();

    dwarf_init ();

#ifndef UNW_REMOTE_ONLY
    arm_local_addr_space_init ();
#endif
    tdep_init_done = 1;	/* signal that we're initialized... */
  }
 out:
  lock_release (&arm_lock, saved_mask);
}
struct dwarf_compilation_unit * dwarf_get_compilation_unit(char * program)
{

    Dwarf_Debug dbg = 0;
    int fd = -1;
    const char *filepath = "<stdin>";
    int res = DW_DLV_ERROR;
    Dwarf_Error error;
    Dwarf_Handler errhand = 0;
    Dwarf_Ptr errarg = 0;

    fd = open(program,O_RDONLY);

    if(fd < 0) {
        printf("Failure attempting to open \"%s\"\n",filepath);
    }
    res = dwarf_init(fd,DW_DLC_READ,errhand,errarg, &dbg,&error);
    if(res != DW_DLV_OK) {
        printf("Giving up, cannot do DWARF processing\n");
        exit(1);
    }

    struct dwarf_compilation_unit * cu = read_cu_list(dbg);
    cu->dbg = dbg;
    
    return cu;

}
Пример #9
0
HIDDEN void
tdep_init (void)
{
  intrmask_t saved_mask;

  sigfillset (&unwi_full_mask);

  lock_acquire (&hppa_lock, saved_mask);
  {
    if (!tdep_needs_initialization)
      /* another thread else beat us to it... */
      goto out;

    mi_init ();

    dwarf_init ();

#ifndef UNW_REMOTE_ONLY
    hppa_local_addr_space_init ();
#endif
    tdep_needs_initialization = 0;	/* signal that we're initialized... */
  }
 out:
  lock_release (&hppa_lock, saved_mask);
}
Пример #10
0
//file_cmd helper funcs
//DBG init and exit functions
error_t load_dbg(mygdb_info_t* gdb_info){
	Dwarf_Error err;
	Dwarf_Die no_die = 0;
	Dwarf_Unsigned cu_header_length;
	Dwarf_Half version_stamp;
	Dwarf_Unsigned abbrev_offset;
	Dwarf_Half addr_size;
	Dwarf_Unsigned nxt_cu_hdr;


	gdb_info->dbg_fd = open(gdb_info->src_file, O_RDONLY);

	if( dwarf_init(gdb_info->dbg_fd,DW_DLC_READ,0,0, &gdb_info->dbg, &err) != DW_DLV_OK )
		return E_FATAL;

	printf("Succesfully loaded symbol info\n");
	int res;
	if( (res = dwarf_next_cu_header(gdb_info->dbg, &cu_header_length, &version_stamp, &abbrev_offset, &addr_size, &nxt_cu_hdr, &err)) == DW_DLV_ERROR ){
		printf("failed to get next header\n");		
		return E_FATAL;
	}

	if( dwarf_siblingof(gdb_info->dbg, no_die, &gdb_info->cu_die, &err) == DW_DLV_ERROR){
		printf("siblingof() failed\n");
		return E_FATAL;
	}

	
	return E_NONE;
}
int main( int argc, char ** argv ) {
	int status = 0;

	int fid = -1;
	Elf * elfp = NULL;
	
	Dwarf_Error error = (Dwarf_Error) NULL;
	Dwarf_Debug dbg;
	
	Dwarf_Cie * cie_data = NULL;
	Dwarf_Fde * fde_data = NULL;
	Dwarf_Signed cie_count, fde_count;

	if( argc != 2 ) {
		fprintf( stderr, "usage: %s <binary>\n", argv[0] );
		return 1;
		}
		
	fid = open( argv[1], O_RDONLY );
	if( fid == -1 ) {
		fprintf( stderr, "failed to open( %s ).\n", argv[1] );
		return 4;
		}
		
	if( elf_version( EV_CURRENT ) == EV_NONE ) {
		fprintf( stderr, "elf version check failed.\n" );
		return 6;
		}

#if defined( USE_ELF_POINTER )			
	elfp = elf_begin( fid, ELF_C_READ, (Elf *)NULL );
	if( elfp == NULL ) {
		fprintf( stderr, "failed to elf_begin().\n" );	
		return 5;
		}
		
	status = dwarf_elf_init( elfp, DW_DLC_READ, NULL, NULL, & dbg, & error );
	if( status != DW_DLV_OK ) {
		fprintf( stderr, "failed to dwarf_elf_init().\n" );
		return 2;
		}
#else
	status = dwarf_init( fid, DW_DLC_READ, NULL, NULL, & dbg, NULL );
	if( status != DW_DLV_OK ) {
		fprintf( stderr, "failed to dwarf_init().\n" );
		return 2;
		}
#endif
	
	status = dwarf_get_fde_list_eh( dbg, & cie_data, & cie_count, & fde_data, & fde_count, & error );
	if( status != DW_DLV_OK ) {
		fprintf( stderr, "failed to dwarf_get_fde_list_eh().\n" );
		return 3;
		}
	
	return 0;
	} /* end main() */
int 
main(int argc, char **argv)
{

    Dwarf_Debug dbg = 0;
    int fd = -1;
    const char *filepath = "<stdin>";
    int res = DW_DLV_ERROR;
    Dwarf_Error error;
    Dwarf_Handler errhand = 0;
    Dwarf_Ptr errarg = 0;
    
    
    /**/

    if(argc < 2) {
        fd = 0; /* stdin */
    } else {
        int i = 0;
        for(i = 1; i < (argc-1) ; ++i) {
            if(strcmp(argv[i],"--names") == 0) {
                namesoptionon=1;
            } else {
                printf("Unknown argument \"%s\" ignored\n",argv[i]);
            }
        }
        filepath = argv[i];
        fd = open(filepath,O_RDONLY);
    }
    if(argc > 2) {
    }

    /**/

    if(fd < 0) {
        printf("Failure attempting to open \"%s\"\n",filepath);
    }
    res = dwarf_init(fd,DW_DLC_READ,errhand,errarg, &dbg,&error);
    if(res != DW_DLV_OK) {
        printf("Giving up, cannot do DWARF processing\n");
        exit(1);
    }

    read_cu_list(dbg);
    res = dwarf_finish(dbg,&error);
    if(res != DW_DLV_OK) {
        printf("dwarf_finish failed!\n");
    }
    close(fd);
    return 0;
}
Пример #13
0
static void
tp_dwarf_init(void)
{
	Dwarf_Debug dbg;
	Dwarf_Error de;
	int fd, result;

	result = TET_UNRESOLVED;

	assert(_cur_file != NULL);
	dbg = NULL;
	if ((fd = open(_cur_file, O_RDONLY)) < 0) {
		tet_printf("open %s failed: %s", _cur_file, strerror(errno));
		result = TET_FAIL;
		goto done;
	}

	if (dwarf_init(fd, DW_DLC_READ, NULL, NULL, &dbg, &de) != DW_DLV_OK) {
		tet_printf("dwarf_init failed: %s", dwarf_errmsg(de));
		result = TET_FAIL;
		goto done;
	}

	if (dwarf_init(-1, DW_DLC_READ, NULL, NULL, &dbg, &de) != DW_DLV_ERROR) {
		tet_infoline("dwarf_init didn't return DW_DLV_ERROR when"
		    " called with fd(-1)");
		result = TET_FAIL;
		goto done;
	}

	if (result == TET_UNRESOLVED)
		result = TET_PASS;

done:
	TS_DWARF_FINISH(dbg, de);
	TS_RESULT(result);
}
Пример #14
0
int dwarf(int argc, char** argv)
{
    Dwarf_Debug dbg = 0;
    Dwarf_Error err;
    const char* progname;
    char filename[TARGET_NAME_LEN];
    int fd = -1;
    FILE *fp = NULL;

    if (argc < 2) {
        fprintf(stderr, "Expected a program name as argument\n");
        return 1;
    }

    progname = argv[1];
    if ((fd = open(progname, O_RDONLY)) < 0) {
        perror("open");
        return 1;
    }

    strncpy(filename, progname, TARGET_NAME_LEN - strlen(suffix) - 1);
    strncat(filename, suffix, strlen(suffix));
    if ((fp = fopen(filename, "w")) < 0){
        perror("open");
        return 1;
    }
    
    if (dwarf_init(fd, DW_DLC_READ, 0, 0, &dbg, &err) != DW_DLV_OK) {
        fprintf(stderr, "Failed DWARF initialization\n");
        return 1;
    }

    list_funcs_in_file(dbg, fp);
    fclose(fp);

    if (dwarf_finish(dbg, &err) != DW_DLV_OK) {
        fprintf(stderr, "Failed DWARF finalization\n");
        return 1;
    }

    close(fd);
    return 0;
}
Пример #15
0
HIDDEN void
tdep_init (void)
{
  lock_init (&x86_64_lock, "tdep_init");

  lock_acquire (&x86_64_lock);
  {
    if (tdep_init_done)
      /* another thread else beat us to it... */
      goto out;

  
    mi_init ();
    dwarf_init ();
    tdep_init_mem_validate ();
    x86_64_local_addr_space_init ();

    tdep_init_done = 1;	/* signal that we're initialized... */
  }
 out:
  lock_release (&x86_64_lock);
}
Пример #16
0
static VALUE rdwarf_initialize(VALUE self, VALUE filename)
{
    rdwarf_t *rd = GetRDwarf(self);
    Dwarf_Debug dbg;
    Dwarf_Error err;
    int fd;
    int ret;

    SafeStringValue(filename);
    filename = rb_str_export_to_enc(filename, rb_filesystem_encoding());

    fd = rb_cloexec_open(StringValueCStr(filename), O_RDONLY, 0);
    if (fd < 0) {
        rb_sys_fail("open");
    }
    ret = dwarf_init(fd, DW_DLC_READ, NULL, NULL, &dbg, &err);
    if (ret != DW_DLV_OK) {
        rb_raise(rd_eError, "%s", dwarf_errmsg(err));
    }
    rd->shared_data = rd_shared_data_alloc(dbg, fd, self);
    return self;
}
Пример #17
0
void FLinuxCrashContext::InitFromSignal(int32 InSignal, siginfo_t* InInfo, void* InContext)
{
	Signal = InSignal;
	Info = InInfo;
	Context = reinterpret_cast< ucontext_t* >( InContext );

	// open ourselves for examination
	if (!FParse::Param( FCommandLine::Get(), TEXT(CMDARG_SUPPRESS_DWARF_PARSING)))
	{
		ExeFd = open("/proc/self/exe", O_RDONLY);
		if (ExeFd >= 0)
		{
			Dwarf_Error ErrorInfo;
			// allocate DWARF debug descriptor
			if (dwarf_init(ExeFd, DW_DLC_READ, NULL, NULL, &DebugInfo, &ErrorInfo) == DW_DLV_OK)
			{
				// get ELF descritor
				if (dwarf_get_elf(DebugInfo, &ElfHdr, &ErrorInfo) != DW_DLV_OK)
				{
					dwarf_finish(DebugInfo, &ErrorInfo);
					DebugInfo = NULL;

					close(ExeFd);
					ExeFd = -1;
				}
			}
			else
			{
				DebugInfo = NULL;
				close(ExeFd);
				ExeFd = -1;
			}
		}
	}

	FCString::Strcat(SignalDescription, ARRAY_COUNT( SignalDescription ) - 1, *DescribeSignal(Signal, Info));
}
Пример #18
0
int
main(int argc, char **argv)
{
	Elf *e;
	Dwarf_Debug dbg;
	Dwarf_Error de;
	const char *exe, *section;
	char line[1024];
	int fd, i, opt;

	exe = NULL;
	section = NULL;
	while ((opt = getopt_long(argc, argv, "b:Ce:fj:sHV", longopts, NULL)) !=
	    -1) {
		switch (opt) {
		case 'b':
			/* ignored */
			break;
		case 'C':
			demangle = 1;
			break;
		case 'e':
			exe = optarg;
			break;
		case 'f':
			func = 1;
			break;
		case 'j':
			section = optarg;
			break;
		case 's':
			base = 1;
			break;
		case 'H':
			usage();
		case 'V':
			version();
		default:
			usage();
		}
	}

	argv += optind;
	argc -= optind;

	if (exe == NULL)
		exe = "a.out";

	if ((fd = open(exe, O_RDONLY)) < 0)
		err(EXIT_FAILURE, "%s", exe);

	if (dwarf_init(fd, DW_DLC_READ, NULL, NULL, &dbg, &de))
		errx(EXIT_FAILURE, "dwarf_init: %s", dwarf_errmsg(de));

	if (dwarf_get_elf(dbg, &e, &de) != DW_DLV_OK)
		errx(EXIT_FAILURE, "dwarf_get_elf: %s", dwarf_errmsg(de));

	if (section)
		find_section_base(exe, e, section);
	else
		section_base = 0;

	if (argc > 0)
		for (i = 0; i < argc; i++)
			translate(dbg, argv[i]);
	else
		while (fgets(line, sizeof(line), stdin) != NULL) {
			translate(dbg, line);
			fflush(stdout);
		}

	dwarf_finish(dbg, &de);

	(void) elf_end(e);

	exit(0);
}
Пример #19
0
void mapped_module::parseFileLineInfo() {
	/* Determine if we've parsed this file already. */
	image * moduleImage = obj()->parse_img();
	assert( moduleImage != NULL );
	const Object & moduleObject = moduleImage->getObject();	
	const char * fileName = moduleObject.getFileName();

	/* We have not parsed this file already, so wind up libdwarf. */
	int fd = open( fileName, O_RDONLY );
   if (fd == -1)
      return;
	
	Dwarf_Debug dbg;
	int status = dwarf_init(	fd, DW_DLC_READ, & pd_dwarf_handler,
								moduleObject.getErrFunc(),
								& dbg, NULL );
	if( status != DW_DLV_OK ) { P_close( fd ); return; }
	
	/* Itereate over the CU headers. */
	Dwarf_Unsigned header;
	while( dwarf_next_cu_header( dbg, NULL, NULL, NULL, NULL, & header, NULL ) == DW_DLV_OK ) {
		/* Acquire the CU DIE. */
		Dwarf_Die cuDIE;
		status = dwarf_siblingof( dbg, NULL, & cuDIE, NULL);
		if( status != DW_DLV_OK ) { 
			/* If we can get no (more) CUs, we're done. */
			break;
			}
		
		/* Acquire this CU's source lines. */
		Dwarf_Line * lineBuffer;
		Dwarf_Signed lineCount;
		status = dwarf_srclines( cuDIE, & lineBuffer, & lineCount, NULL );
		
		/* See if we can get anything useful out of the next CU
		   if this one is corrupt. */
		if( status == DW_DLV_ERROR ) {
			dwarf_printf( "%s[%d]: dwarf_srclines() error.\n" );
			}
		
		/* It's OK for a CU not to have line information. */
		if( status != DW_DLV_OK ) {
			/* Free this CU's DIE. */
			dwarf_dealloc( dbg, cuDIE, DW_DLA_DIE );
			continue;
			}
		assert( status == DW_DLV_OK );
		
		/* The 'lines' returned are actually interval markers; the code
		   generated from lineNo runs from lineAddr up to but not including
		   the lineAddr of the next line. */			   
		bool isPreviousValid = false;
		Dwarf_Unsigned previousLineNo = 0;
		Dwarf_Addr previousLineAddr = 0x0;
		char * previousLineSource = NULL;
		
		Address baseAddr = obj()->codeBase();
		
		/* Iterate over this CU's source lines. */
		for( int i = 0; i < lineCount; i++ ) {
			/* Acquire the line number, address, source, and end of sequence flag. */
			Dwarf_Unsigned lineNo;
			status = dwarf_lineno( lineBuffer[i], & lineNo, NULL );
			if( status != DW_DLV_OK ) { continue; }
				
			Dwarf_Addr lineAddr;
			status = dwarf_lineaddr( lineBuffer[i], & lineAddr, NULL );
			if( status != DW_DLV_OK ) { continue; }
			lineAddr += baseAddr;
			
			char * lineSource;
			status = dwarf_linesrc( lineBuffer[i], & lineSource, NULL );
			if( status != DW_DLV_OK ) { continue; }
						
			Dwarf_Bool isEndOfSequence;
			status = dwarf_lineendsequence( lineBuffer[i], & isEndOfSequence, NULL );
			if( status != DW_DLV_OK ) { continue; }
			
			if( isPreviousValid ) {
				/* If we're talking about the same (source file, line number) tuple,
				   and it isn't the end of the sequence, we can coalesce the range.
				   (The end of sequence marker marks discontinuities in the ranges.) */
				if( lineNo == previousLineNo && strcmp( lineSource, previousLineSource ) == 0 && ! isEndOfSequence ) {
					/* Don't update the prev* values; just keep going until we hit the end of a sequence or
					   a new sourcefile. */
					continue;
					} /* end if we can coalesce this range */
                                
				/* Determine into which mapped_module this line information should be inserted. */
				int_function * currentFunction = obj()->findFuncByAddr( previousLineAddr );
				if( currentFunction == NULL ) {
					// /* DEBUG */ fprintf( stderr, "%s[%d]: failed to find function containing address 0x%lx; line number information will be lost.\n", __FILE__, __LINE__, lineAddr );
					}
				else {
					mapped_module * currentModule = currentFunction->mod();
					assert( currentModule != NULL );
					
					char * canonicalLineSource = strrchr( previousLineSource, '/' );
					if( canonicalLineSource == NULL ) { canonicalLineSource = previousLineSource; }
					else { ++canonicalLineSource; }
					
					/* The line 'canonicalLineSource:previousLineNo' has an address range of [previousLineAddr, lineAddr). */
					currentModule->lineInfo_.addLine( canonicalLineSource, previousLineNo, previousLineAddr, lineAddr );
				
					// /* DEBUG */ fprintf( stderr, "%s[%d]: inserted address range [0x%lx, 0x%lx) for source '%s:%u' into module '%s'.\n", __FILE__, __LINE__, previousLineAddr, lineAddr, canonicalLineSource, previousLineNo, currentModule->fileName().c_str() );
					} /* end if we found the function by its address */
				} /* end if the previous* variables are valid */
				
			/* If the current line ends the sequence, invalidate previous; otherwise, update. */
			if( isEndOfSequence ) {
				dwarf_dealloc( dbg, lineSource, DW_DLA_STRING );
				
				isPreviousValid = false;
				}
			else {
				if( isPreviousValid ) { dwarf_dealloc( dbg, previousLineSource, DW_DLA_STRING ); }

				previousLineNo = lineNo;
				previousLineSource = lineSource;
				previousLineAddr = lineAddr;
							
				isPreviousValid = true;
				} /* end if line was not the end of a sequence */
			} /* end iteration over source line entries. */
		
		/* Free this CU's source lines. */
		for( int i = 0; i < lineCount; i++ ) {
			dwarf_dealloc( dbg, lineBuffer[i], DW_DLA_LINE );
			}
		dwarf_dealloc( dbg, lineBuffer, DW_DLA_LIST );
		
		/* Free this CU's DIE. */
		dwarf_dealloc( dbg, cuDIE, DW_DLA_DIE );
		} /* end CU header iteration */

	/* Wind down libdwarf. */
	status = dwarf_finish( dbg, NULL );
	if( status != DW_DLV_OK ) {
		dwarf_printf( "%s[%d]: failed to dwarf_finish()\n" );
		}
	P_close( fd );
	
	/* Note that we've parsed this file. */
	} /* end parseFileLineInfo() */
Пример #20
0
int
open_dwarf_executable (char *fileName)
{
  int dwStatus = -1;


  mpiPi_msg_debug ("enter open_dwarf_executable\n");
  if (fileName == NULL)
    {
      mpiPi_msg_warn ("Executable file name is NULL!\n");
      mpiPi_msg_warn
	("If this is a Fortran application, you may be using the incorrect mpiP library.\n");
    }

  /* open the executable */
  assert (dwFd == -1);
  mpiPi_msg_debug ("opening file %s\n", fileName);
  dwFd = open (fileName, O_RDONLY);
  if (dwFd == -1)
    {
      mpiPi_msg_warn ("could not open file %s\n", fileName);
      return 0;
    }

  /* initialize the DWARF library */
  assert (dwHandle == NULL);
  dwStatus = dwarf_init (dwFd,	/* exe file descriptor */
			 DW_DLC_READ,	/* desired access */
			 NULL,	/* error handler */
			 NULL,	/* error argument */
			 &dwHandle,	/* session handle */
			 &dw_err);	/* error object */
  if (dwStatus == DW_DLV_ERROR)
    {
      close (dwFd);
      dwFd = -1;
      mpiPi_abort ("could not initialize DWARF library : %s\n", dwarf_errmsg(dw_err));
    }

  if (dwStatus == DW_DLV_NO_ENTRY)
    {
      mpiPi_msg_warn ("No symbols in the executable\n");
      return 0;
    }

  /* initialize our function and addr-to-source mappings */
  AddrToSourceMap_Init ();
  FunctionMap_Init ();

  /* access symbol info */
  while (1)
    {
      Dwarf_Unsigned nextCompilationUnitHeaderOffset = 0;
      Dwarf_Die currCompileUnitDIE = NULL;
      Dwarf_Line *lineEntries = NULL;
      Dwarf_Signed nLineEntries = 0;
      Dwarf_Half currDIETag;
      Dwarf_Die currChildDIE = NULL;
      Dwarf_Die nextChildDIE = NULL;
      Dwarf_Die oldChildDIE = NULL;


      /* access next compilation unit header */
      dwStatus = dwarf_next_cu_header (dwHandle, NULL,	/* cu_header_length */
				       NULL,	/* version_stamp */
				       NULL,	/* abbrev_offset */
				       NULL,	/* address_size */
				       &nextCompilationUnitHeaderOffset, &dw_err);	/* error object */
      if (dwStatus != DW_DLV_OK)
	{
	  if (dwStatus != DW_DLV_NO_ENTRY)
	    {
	      mpiPi_abort ("failed to access next DWARF cu header : %s\n", dwarf_errmsg(dw_err));
	    }
	  break;
	}

      /* access the first debug info entry (DIE) for this computation unit */
      dwStatus = dwarf_siblingof (dwHandle, NULL,	/* current DIE */
				  &currCompileUnitDIE,	/* sibling DIE */
				  &dw_err);	/* error object */
      if (dwStatus != DW_DLV_OK)
	{
	  mpiPi_abort ("failed to access first DWARF DIE : %s\n", dwarf_errmsg(dw_err));
	}

      /* get line number information for this compilation 
       * unit, if available 
       */
      dwStatus = dwarf_srclines (currCompileUnitDIE,
				 &lineEntries, &nLineEntries, &dw_err);
      if (dwStatus == DW_DLV_OK)
	{
	  unsigned int i;


	  /*
	   * Extract and save address-to-source line mapping.
	   * 
	   * NOTE: At least on the Cray X1, we see line number 
	   * information with the same address mapping to different lines.
	   * It seems like when there are multiple entries for a given
	   * address, the last one is the correct one.  (Needs verification.)
	   * If we see multiple entries for a given address, we only 
	   * save the last one.
	   */
	  for (i = 0; i < nLineEntries; i++)
	    {
	      Dwarf_Unsigned lineNumber = 0;
	      Dwarf_Addr lineAddress = 0;
	      char *lineSourceFile = NULL;


	      int lineNoStatus, lineAddrStatus, lineSrcFileStatus;

	      lineNoStatus = dwarf_lineno (lineEntries[i],
					   &lineNumber,
					   &dw_err);

              if (lineNoStatus != DW_DLV_OK)
                 mpiPi_msg_debug("Failed to get line number : %s\n", dwarf_errmsg(dw_err));

	      lineAddrStatus = dwarf_lineaddr (lineEntries[i],
						&lineAddress,
						&dw_err);

              if (lineAddrStatus != DW_DLV_OK)
                 mpiPi_msg_debug("Failed to get line address : %s\n", dwarf_errmsg(dw_err));

	      lineSrcFileStatus = dwarf_linesrc (lineEntries[i],
						 &lineSourceFile,
						 &dw_err);

              if (lineSrcFileStatus != DW_DLV_OK)
                 mpiPi_msg_debug("Failed to get source file status : %s\n", dwarf_errmsg(dw_err));

	      if ((lineNoStatus == DW_DLV_OK) &&
		  (lineAddrStatus == DW_DLV_OK)
		  && (lineSrcFileStatus == DW_DLV_OK))
		{
		  int saveCurrentEntry = 0;	/* bool */

		  if (i < (nLineEntries - 1))
		    {
		      /*
		       * We're not on the last line number entry -
		       * check the address associated with the next
		       * entry to see if it differs from this one.
		       * Only save the entry if it the next address
		       * differs.
		       */
		      Dwarf_Addr nextLineAddress = 0;
		      int nextLineAddrStatus =
			dwarf_lineaddr (lineEntries[i + 1],
					&nextLineAddress,
					&dw_err);
		      assert (nextLineAddrStatus == DW_DLV_OK);
		      if (nextLineAddress != lineAddress)
			{
			  saveCurrentEntry = 1;
			}
		    }
		  else
		    {
		      /* we're on the last line number entry */
		      saveCurrentEntry = 1;
		    }

		  if (saveCurrentEntry)
		    {
		      /* save the mapping entry */
		      AddrToSourceMap_Add (lineAddress, lineSourceFile,
					   lineNumber);
		    }
		}

	      if (lineSourceFile != NULL)
		{
		  dwarf_dealloc (dwHandle, lineSourceFile, DW_DLA_STRING);
		}
	    }

	  /* release the line number info */
	  for (i = 0; i < nLineEntries; i++)
	    {
	      dwarf_dealloc (dwHandle, lineEntries[i], DW_DLA_LINE);
	    }
	  dwarf_dealloc (dwHandle, lineEntries, DW_DLA_LIST);
	}
      else if (dwStatus != DW_DLV_ERROR)
	{
	  /*
	   * no line information for the current DIE - 
	   * not an error, just unfortunate
	   */
	}
      else
	{
	  mpiPi_abort ("failed to obtain line info for the current DIE : %s\n", dwarf_errmsg(dw_err));
	}

      /* discover function information for the current compilation unit */
      /* 
       * NOTE: DWARF debug information entries can be organized in 
       * a hierarchy.  However, we presume that the function entries are
       * all children of the compilation unit DIE.
       */
      dwStatus = dwarf_tag (currCompileUnitDIE, &currDIETag, &dw_err);
      assert ((dwStatus == DW_DLV_OK) && (currDIETag == DW_TAG_compile_unit));

      /* access the first child DIE of the compile unit DIE */
      dwStatus = dwarf_child (currCompileUnitDIE, &currChildDIE, &dw_err);
      if (dwStatus == DW_DLV_NO_ENTRY)
	{
          // On some Cray systems, executables are linked with assembly compile units
          // with no functions.
          // mpiPi_abort ("no child DIEs of compile unit DIE\n");
	}
      else if (dwStatus != DW_DLV_OK)
	{
	  mpiPi_abort
	    ("failed to access first child DIE of compile unit DIE\n");
	}

      while (dwStatus == DW_DLV_OK)
	{
	  /* determine the type of the child DIE */
	  dwStatus = dwarf_tag (currChildDIE, &currDIETag, &dw_err);
	  if (dwStatus == DW_DLV_OK)
	    {
	      if ((currDIETag == DW_TAG_subprogram) ||
		  (currDIETag == DW_TAG_entry_point))
		{
		  HandleFunctionDIE (dwHandle, currChildDIE);
		}
	    }
	  else
	    {
	      mpiPi_abort ("unable to determine tag of current child DIE : %s \n", dwarf_errmsg(dw_err));
	    }

	  /* advance to the next child DIE */
	  oldChildDIE = currChildDIE;
	  dwStatus = dwarf_siblingof (dwHandle,
				      currChildDIE, &nextChildDIE, &dw_err);
	  if (dwStatus == DW_DLV_OK)
	    {
	      currChildDIE = nextChildDIE;
	      nextChildDIE = NULL;
	    }
	  else if (dwStatus != DW_DLV_NO_ENTRY)
	    {
	      mpiPi_abort
		("unable to access next child DIE of current compilation unit : %s\n", dwarf_errmsg(dw_err));
	    }

	  if (oldChildDIE != NULL)
	    {
	      dwarf_dealloc (dwHandle, oldChildDIE, DW_DLA_DIE);
	    }
	}

      /* release the current compilation unit DIE */
      dwarf_dealloc (dwHandle, currCompileUnitDIE, DW_DLA_DIE);
    }

  /*
   * DWARF address-to-source line information does not give
   * address ranges, so we need to patch the address ranges
   * in our address-to-source map.
   */
  AddrToSourceMap_PatchRanges ();

  return 1;
}
Пример #21
0
int opendwarf(char *argv){
#else
int main(int argc, char **argv){
#endif

#ifdef DWARF_CLIENT_LIB
  char *fname = argv;
#else
  char *fname = argv[1];
#endif

#ifndef DWARF_CLIENT_LIB

  int getCU = 0;
  int getAddrOfFileLine = 0;
  const char *fileline_fn = NULL;
  int fileline_ln = 0;
  int dump = 0;
  char opt;
  const char *optString = "cgf:l:e:ph";
  while( (opt = getopt(argc,argv,optString) ) != -1 ){
    switch(opt){
      case 'c':
        getCU = 1;
        break;
      case 'g':
        getAddrOfFileLine = 1;
        break;
      case 'f':
        fileline_fn = strdup(optarg);
        break;
      case 'l':
        fileline_ln = atoi(optarg);
        break;
      case 'e':
        fname = strdup(optarg); 
        break;
      case 'p':
        dump = 1;
        break;
      case 'h':
        fprintf(stderr,"Usage: ./dwarfinfo -e <executable> [Option(s)]\n"); 
        fprintf(stderr,"\t-e Specify executable\n");
        fprintf(stderr,"\t-g Get instruction address of file and line (requires -f and -l)\n");
        fprintf(stderr,"\t-c Show enclosing scopes and variables in each for file and line (requires -f and -l)\n");
        fprintf(stderr,"\t-p Dump dwarf information for executable\n");
        fprintf(stderr,"\t-f Specify source file\n");
        fprintf(stderr,"\t-l Specify source line\n");
        fprintf(stderr,"\t-h Help\n");

      default:
        break;
    };
  }
#endif

  int fd = open(fname,O_RDONLY);
  if(fd == -1){exit(-1);} 
  dwarf_init(fd,DW_DLC_READ,NULL,NULL,&d,&e) ;

#ifndef DWARF_CLIENT_LIB
  unsigned long a;
  if(getAddrOfFileLine){
    a = get_iaddr_of_file_line(fileline_fn,fileline_ln);
    fprintf(stderr,"%x\n",a);
  }

  if(getCU && a != 0xffffffffffffffff){
    reset_cu_header_info();
    Dwarf_Die cu = get_cu_by_iaddr(a);
    reset_cu_header_info();
    DC_show_info_for_containing_pc_ranges(cu,0,a);
    fprintf(stderr,"\n");
  }

  if(dump){
    reset_cu_header_info();
    dump_dwarf_info();
  }

#endif

 
}
Пример #22
0
/* get_compiler_info */
int get_compiler_info(void) {
    Dwarf_Unsigned   cu_header_length, abbrev_offset, next_cu_header;
    Dwarf_Half       version, address_size;
    Dwarf_Signed     attrcount, i, language;
    Dwarf_Die        no_die = 0, cu_die;
    Dwarf_Attribute *attrs;
    Dwarf_Half       attrcode;
    Dwarf_Debug      dbg = 0;
    Dwarf_Error      err;
    char *compiler = NULL;
    int fd = -1;

    OUTPUT_VERBOSE((5, "%s", _BLUE("Extracting DWARF info")));

    /* Open the binary */
    if (0 > (fd = open(globals.program_full, O_RDONLY))) {
        OUTPUT(("%s [%s]", _ERROR("opening program binary"),
            globals.program_full));
        return PERFEXPERT_ERROR;
    }

    /* Initialize DWARF library  */
    if (DW_DLV_OK != dwarf_init(fd, DW_DLC_READ, 0, 0, &dbg, &err)) {
        OUTPUT(("%s", _ERROR("failed DWARF initialization")));
        return PERFEXPERT_ERROR;
    }

    /* Find compilation unit header */
    if (DW_DLV_ERROR == dwarf_next_cu_header(dbg, &cu_header_length,
        &version, &abbrev_offset, &address_size, &next_cu_header, &err)) {
        OUTPUT(("%s", _ERROR("reading DWARF CU header")));
        return PERFEXPERT_ERROR;
    }

    /* Expect the CU to have a single sibling, a DIE */
    if (DW_DLV_ERROR == dwarf_siblingof(dbg, no_die, &cu_die, &err)) {
        OUTPUT(("%s", _ERROR("getting sibling of CU")));
        return PERFEXPERT_ERROR;
    }

    /* Find the DIEs attributes */
    if (DW_DLV_OK != dwarf_attrlist(cu_die, &attrs, &attrcount, &err)) {
        OUTPUT(("%s", _ERROR("in dwarf_attlist")));
        return PERFEXPERT_ERROR;
    }

    /* For each attribute... */
    for (i = 0; i < attrcount; ++i) {
        if (DW_DLV_OK != dwarf_whatattr(attrs[i], &attrcode, &err)) {
            OUTPUT(("%s [%s]", _ERROR("in dwarf_whatattr")));
            return PERFEXPERT_ERROR;
        }
        if (DW_AT_producer == attrcode) {
            if (DW_DLV_OK != dwarf_formstring(attrs[i], &compiler, &err)) {
                OUTPUT(("%s [%s]", _ERROR("in dwarf_formstring")));
                return PERFEXPERT_ERROR;
            } else {
                OUTPUT_VERBOSE((5, "   Compiler: %s", _CYAN(compiler)));
            }
        }
        if (DW_AT_language == attrcode) {
            if (DW_DLV_OK != dwarf_formsdata(attrs[i], &language, &err)) {
                OUTPUT(("%s [%s]", _ERROR("in dwarf_formsdata")));
                return PERFEXPERT_ERROR;
            } else {
                OUTPUT_VERBOSE((5, "   Language: %d", language));
            }
        }
    }

    if (PERFEXPERT_SUCCESS != database_write(compiler, language)) {
        OUTPUT(("%s", _ERROR("writing to database")));
        return PERFEXPERT_ERROR;
    }

    /* Finalize DWARF library  */
    if (DW_DLV_OK != dwarf_finish(dbg, &err)) {
        OUTPUT(("%s", _ERROR("failed DWARF finalization")));
        return PERFEXPERT_ERROR;
    }

    close(fd);

    return PERFEXPERT_SUCCESS;
}