⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dyngen.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
struct symtab_command 	*symtabcmd = 0;/* section */struct section 	*section_hdr;struct section *text_sec_hdr;uint8_t 	**sdata;/* relocs */struct relocation_info *relocs;/* symbols */EXE_SYM			*symtab;struct nlist 	*symtab_std;char			*strtab;/* indirect symbols */uint32_t 	*tocdylib;/* Utility functions */static inline char *find_str_by_index(int index){    return strtab+index;}/* Used by dyngen common code */static char *get_sym_name(EXE_SYM *sym){	char *name = find_str_by_index(sym->n_un.n_strx);	if ( sym->n_type & N_STAB ) /* Debug symbols are ignored */		return "debug";	if(!name)		return name;	if(name[0]=='_')		return name + 1;	else		return name;}/* find a section index given its segname, sectname */static int find_mach_sec_index(struct section *section_hdr, int shnum, const char *segname,                                  const char *sectname){    int i;    struct section *sec = section_hdr;    for(i = 0; i < shnum; i++, sec++) {        if (!sec->segname || !sec->sectname)            continue;        if (!strcmp(sec->sectname, sectname) && !strcmp(sec->segname, segname))            return i;    }    return -1;}/* find a section header given its segname, sectname */struct section *find_mach_sec_hdr(struct section *section_hdr, int shnum, const char *segname,                                  const char *sectname){    int index = find_mach_sec_index(section_hdr, shnum, segname, sectname);	if(index == -1)		return NULL;	return section_hdr+index;}static inline void fetch_next_pair_value(struct relocation_info * rel, unsigned int *value){    struct scattered_relocation_info * scarel;    if(R_SCATTERED & rel->r_address) {        scarel = (struct scattered_relocation_info*)rel;        if(scarel->r_type != PPC_RELOC_PAIR)            error("fetch_next_pair_value: looking for a pair which was not found (1)");        *value = scarel->r_value;    } else {		if(rel->r_type != PPC_RELOC_PAIR)			error("fetch_next_pair_value: looking for a pair which was not found (2)");		*value = rel->r_address;	}}/* find a sym name given its value, in a section number */static const char * find_sym_with_value_and_sec_number( int value, int sectnum, int * offset ){	int i, ret = -1;	for( i = 0 ; i < nb_syms; i++ )	{	    if( !(symtab[i].n_type & N_STAB) && (symtab[i].n_type & N_SECT) &&			 (symtab[i].n_sect ==  sectnum) && (symtab[i].st_value <= value) )		{			if( (ret<0) || (symtab[i].st_value >= symtab[ret].st_value) )				ret = i;		}	}	if( ret < 0 ) {		*offset = 0;		return 0;	} else {		*offset = value - symtab[ret].st_value;		return get_sym_name(&symtab[ret]);	}}/* *  Find symbol name given a (virtual) address, and a section which is of type *  S_NON_LAZY_SYMBOL_POINTERS or S_LAZY_SYMBOL_POINTERS or S_SYMBOL_STUBS */static const char * find_reloc_name_in_sec_ptr(int address, struct section * sec_hdr){    unsigned int tocindex, symindex, size;    const char *name = 0;    /* Sanity check */    if(!( address >= sec_hdr->addr && address < (sec_hdr->addr + sec_hdr->size) ) )        return (char*)0;	if( sec_hdr->flags & S_SYMBOL_STUBS ){		size = sec_hdr->reserved2;		if(size == 0)		    error("size = 0");	}	else if( sec_hdr->flags & S_LAZY_SYMBOL_POINTERS ||	            sec_hdr->flags & S_NON_LAZY_SYMBOL_POINTERS)		size = sizeof(unsigned long);	else		return 0;    /* Compute our index in toc */	tocindex = (address - sec_hdr->addr)/size;	symindex = tocdylib[sec_hdr->reserved1 + tocindex];	name = get_sym_name(&symtab[symindex]);    return name;}static const char * find_reloc_name_given_its_address(int address){    unsigned int i;    for(i = 0; i < segment->nsects ; i++)    {        const char * name = find_reloc_name_in_sec_ptr(address, &section_hdr[i]);        if((long)name != -1)            return name;    }    return 0;}static const char * get_reloc_name(EXE_RELOC * rel, int * sslide){	char * name = 0;	struct scattered_relocation_info * sca_rel = (struct scattered_relocation_info*)rel;	int sectnum = rel->r_symbolnum;	int sectoffset;	int other_half=0;	/* init the slide value */	*sslide = 0;	if(R_SCATTERED & rel->r_address)		return (char *)find_reloc_name_given_its_address(sca_rel->r_value);	if(rel->r_extern)	{		/* ignore debug sym */		if ( symtab[rel->r_symbolnum].n_type & N_STAB )			return 0;		return get_sym_name(&symtab[rel->r_symbolnum]);	}	/* Intruction contains an offset to the symbols pointed to, in the rel->r_symbolnum section */	sectoffset = *(uint32_t *)(text + rel->r_address) & 0xffff;	if(sectnum==0xffffff)		return 0;	/* Sanity Check */	if(sectnum > segment->nsects)		error("sectnum > segment->nsects");	switch(rel->r_type)	{		case PPC_RELOC_LO16: fetch_next_pair_value(rel+1, &other_half); sectoffset |= (other_half << 16);			break;		case PPC_RELOC_HI16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset << 16) | (uint16_t)(other_half & 0xffff);			break;		case PPC_RELOC_HA16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset << 16) + (int16_t)(other_half & 0xffff);			break;		case PPC_RELOC_BR24:			sectoffset = ( *(uint32_t *)(text + rel->r_address) & 0x03fffffc );			if (sectoffset & 0x02000000) sectoffset |= 0xfc000000;			break;		default:			error("switch(rel->type) not found");	}	if(rel->r_pcrel)		sectoffset += rel->r_address;	if (rel->r_type == PPC_RELOC_BR24)		name = (char *)find_reloc_name_in_sec_ptr((int)sectoffset, &section_hdr[sectnum-1]);	/* search it in the full symbol list, if not found */	if(!name)		name = (char *)find_sym_with_value_and_sec_number(sectoffset, sectnum, sslide);	return name;}/* Used by dyngen common code */static const char * get_rel_sym_name(EXE_RELOC * rel){	int sslide;	return get_reloc_name( rel, &sslide);}/* Used by dyngen common code */static host_ulong get_rel_offset(EXE_RELOC *rel){	struct scattered_relocation_info * sca_rel = (struct scattered_relocation_info*)rel;    if(R_SCATTERED & rel->r_address)		return sca_rel->r_address;	else		return rel->r_address;}/* load a mach-o object file */int load_object(const char *filename){	int fd;	unsigned int offset_to_segment = 0;    unsigned int offset_to_dysymtab = 0;    unsigned int offset_to_symtab = 0;    struct load_command lc;    unsigned int i, j;	EXE_SYM *sym;	struct nlist *syment;	fd = open(filename, O_RDONLY);    if (fd < 0)        error("can't open file '%s'", filename);    /* Read Mach header.  */    if (read(fd, &mach_hdr, sizeof (mach_hdr)) != sizeof (mach_hdr))        error("unable to read file header");    /* Check Mach identification.  */    if (!check_mach_header(mach_hdr)) {        error("bad Mach header");    }    if (mach_hdr.cputype != CPU_TYPE_POWERPC)        error("Unsupported CPU");    if (mach_hdr.filetype != MH_OBJECT)        error("Unsupported Mach Object");    /* read segment headers */    for(i=0, j=sizeof(mach_hdr); i<mach_hdr.ncmds ; i++)    {        if(read(fd, &lc, sizeof(struct load_command)) != sizeof(struct load_command))            error("unable to read load_command");        if(lc.cmd == LC_SEGMENT)        {            offset_to_segment = j;            lseek(fd, offset_to_segment, SEEK_SET);            segment = malloc(sizeof(struct segment_command));            if(read(fd, segment, sizeof(struct segment_command)) != sizeof(struct segment_command))                error("unable to read LC_SEGMENT");        }        if(lc.cmd == LC_DYSYMTAB)        {            offset_to_dysymtab = j;            lseek(fd, offset_to_dysymtab, SEEK_SET);            dysymtabcmd = malloc(sizeof(struct dysymtab_command));            if(read(fd, dysymtabcmd, sizeof(struct dysymtab_command)) != sizeof(struct dysymtab_command))                error("unable to read LC_DYSYMTAB");        }        if(lc.cmd == LC_SYMTAB)        {            offset_to_symtab = j;            lseek(fd, offset_to_symtab, SEEK_SET);            symtabcmd = malloc(sizeof(struct symtab_command));            if(read(fd, symtabcmd, sizeof(struct symtab_command)) != sizeof(struct symtab_command))                error("unable to read LC_SYMTAB");        }        j+=lc.cmdsize;        lseek(fd, j, SEEK_SET);    }    if(!segment)        error("unable to find LC_SEGMENT");    /* read section headers */    section_hdr = load_data(fd, offset_to_segment + sizeof(struct segment_command), segment->nsects * sizeof(struct section));    /* read all section data */    sdata = (uint8_t **)malloc(sizeof(void *) * segment->nsects);    memset(sdata, 0, sizeof(void *) * segment->nsects);	/* Load the data in section data */	for(i = 0; i < segment->nsects; i++) {        sdata[i] = load_data(fd, section_hdr[i].offset, section_hdr[i].size);    }    /* text section */	text_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);	i = find_mach_sec_index(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);	if (i == -1 || !text_sec_hdr)        error("could not find __TEXT,__text section");    text = sdata[i];    /* Make sure dysym was loaded */    if(!(int)dysymtabcmd)        error("could not find __DYSYMTAB segment");    /* read the table of content of the indirect sym */    tocdylib = load_data( fd, dysymtabcmd->indirectsymoff, dysymtabcmd->nindirectsyms * sizeof(uint32_t) );    /* Make sure symtab was loaded  */    if(!(int)symtabcmd)        error("could not find __SYMTAB segment");    nb_syms = symtabcmd->nsyms;    symtab_std = load_data(fd, symtabcmd->symoff, symtabcmd->nsyms * sizeof(struct nlist));    strtab = load_data(fd, symtabcmd->stroff, symtabcmd->strsize);	symtab = malloc(sizeof(EXE_SYM) * nb_syms);	/* Now transform the symtab, to an extended version, with the sym size, and the C name */	for(i = 0, sym = symtab, syment = symtab_std; i < nb_syms; i++, sym++, syment++) {        struct nlist *sym_follow, *sym_next = 0;        unsigned int j;		memset(sym, 0, sizeof(*sym));		if ( syment->n_type & N_STAB ) /* Debug symbols are skipped */            continue;		memcpy(sym, syment, sizeof(*syment));		/* Find the following symbol in order to get the current symbol size */        for(j = 0, sym_follow = symtab_std; j < nb_syms; j++, sym_follow++) {            if ( sym_follow->n_sect != 1 || sym_follow->n_type & N_STAB || !(sym_follow->n_value > sym->st_value))                continue;            if(!sym_next) {                sym_next = sym_follow;                continue;            }            if(!(sym_next->n_value > sym_follow->n_value))                continue;            sym_next = sym_follow;        }		if(sym_next)            sym->st_size = sym_next->n_value - sym->st_value;		else            sym->st_size = text_sec_hdr->size - sym->st_value;	}    /* Find Reloc */    relocs = load_data(fd, text_sec_hdr->reloff, text_sec_hdr->nreloc * sizeof(struct relocation_info));    nb_relocs = text_sec_hdr->nreloc;	close(fd);	return 0;}#endif /* CONFIG_FORMAT_MACH */void get_reloc_expr(char *name, int name_size, const char *sym_name){    const char *p;    if (strstart(sym_name, "__op_param", &p)) {        snprintf(name, name_size, "param%s", p);    } else if (strstart(sym_name, "__op_gen_label", &p)) {        snprintf(name, name_size, "gen_labels[param%s]", p);    } else {#ifdef HOST_SPARC        if (sym_name[0] == '.')            snprintf(name, name_size,                     "(long)(&__dot_%s)",                     sym_name + 1);        else#endif            snprintf(name, name_size, "(long)(&%s)", sym_name);    }}#ifdef HOST_IA64#define PLT_ENTRY_SIZE	16	/* 1 bundle containing "brl" */struct plt_entry {    struct plt_entry *next;    const char *name;    unsigned long addend;} *plt_list;static intget_plt_index (const char *name, unsigned long addend){    struct plt_entry *plt, *prev= NULL;    int index = 0;    /* see if we already have an entry for this target: */    for (plt = plt_list; plt; ++index, prev = plt, plt = plt->next)	if (strcmp(plt->name, name) == 0 && plt->addend == addend)	    return index;    /* nope; create a new PLT entry: */    plt = malloc(sizeof(*plt));    if (!plt) {	perror("malloc");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -