📄 elf.c
字号:
yasm__error(entry->xsize->line, N_("size specifier not an integer expression")); } else size_intn = yasm_intnum_create_uint(entry->size); /* get EQU value for constants */ if (entry->sym) { const yasm_expr *equ_expr_c; equ_expr_c = yasm_symrec_get_equ(entry->sym); if (equ_expr_c != NULL) { const yasm_intnum *equ_intn; yasm_expr *equ_expr = yasm_expr_copy(equ_expr_c); equ_intn = yasm_expr_get_intnum(&equ_expr, yasm_common_calc_bc_dist); if (equ_intn == NULL) { yasm__error(equ_expr->line, N_("EQU value not an integer expression")); } value_intn = yasm_intnum_copy(equ_intn); entry->index = SHN_ABS; yasm_expr_destroy(equ_expr); } } if (value_intn == NULL) value_intn = yasm_intnum_create_uint(entry->value); if (!elf_march->write_symtab_entry || !elf_march->symtab_entry_size) yasm_internal_error(N_("Unsupported machine for ELF output")); elf_march->write_symtab_entry(bufp, entry, value_intn, size_intn); fwrite(buf, elf_march->symtab_entry_size, 1, f); size += elf_march->symtab_entry_size; yasm_intnum_destroy(size_intn); yasm_intnum_destroy(value_intn); prev = entry; } return size;}void elf_symtab_set_nonzero(elf_symtab_entry *entry, yasm_section *sect, elf_section_index sectidx, elf_symbol_binding bind, elf_symbol_type type, yasm_expr *xsize, elf_address value){ if (!entry) yasm_internal_error("NULL entry"); if (sect) entry->sect = sect; if (sectidx) entry->index = sectidx; if (bind) entry->bind = bind; if (type) entry->type = type; if (xsize) entry->xsize = xsize; if (value) entry->value = value;}elf_secthead *elf_secthead_create(elf_strtab_entry *name, elf_section_type type, elf_section_flags flags, elf_section_index idx, elf_address offset, elf_size size){ elf_secthead *esd = yasm_xmalloc(sizeof(elf_secthead)); esd->type = type; esd->flags = flags; esd->offset = offset; esd->size = yasm_intnum_create_uint(size); esd->link = 0; esd->info = 0; esd->align = NULL; esd->entsize = 0; esd->index = idx; esd->sym = NULL; esd->name = name; esd->index = 0; esd->rel_name = NULL; esd->rel_index = idx; esd->rel_offset = 0; esd->nreloc = 0; if (name && (strcmp(name->str, ".symtab") == 0)) { if (!elf_march->symtab_entry_size || !elf_march->symtab_entry_align) yasm_internal_error(N_("unsupported ELF format")); esd->entsize = elf_march->symtab_entry_size; esd->align = yasm_intnum_create_uint(elf_march->symtab_entry_align); } return esd;}voidelf_secthead_destroy(elf_secthead *shead){ if (shead == NULL) yasm_internal_error(N_("shead is null")); if (shead->align) yasm_intnum_destroy(shead->align); yasm_xfree(shead);}static voidelf_section_data_destroy(void *data){ elf_secthead_destroy((elf_secthead *)data);}static voidelf_secthead_print(void *data, FILE *f, int indent_level){ elf_secthead *sect = data; fprintf(f, "%*sname=%s\n", indent_level, "", sect->name ? sect->name->str : "<undef>"); fprintf(f, "%*ssym=\n", indent_level, ""); yasm_symrec_print(sect->sym, f, indent_level+1); fprintf(f, "%*sindex=0x%x\n", indent_level, "", sect->index); fprintf(f, "%*sflags=", indent_level, ""); if (sect->flags & SHF_WRITE) fprintf(f, "WRITE "); if (sect->flags & SHF_ALLOC) fprintf(f, "ALLOC "); if (sect->flags & SHF_EXECINSTR) fprintf(f, "EXEC "); /*if (sect->flags & SHF_MASKPROC) fprintf(f, "PROC-SPECIFIC"); */ fprintf(f, "%*soffset=0x%lx\n", indent_level, "", sect->offset); fprintf(f, "%*ssize=0x%lx\n", indent_level, "", yasm_intnum_get_uint(sect->size)); fprintf(f, "%*slink=0x%x\n", indent_level, "", sect->link); fprintf(f, "%*salign=%ld\n", indent_level, "", yasm_intnum_get_uint(sect->align)); fprintf(f, "%*snreloc=%ld\n", indent_level, "", sect->nreloc);}unsigned longelf_secthead_write_to_file(FILE *f, elf_secthead *shead, elf_section_index sindex){ unsigned char buf[SHDR_MAXSIZE], *bufp = buf; shead->index = sindex; if (shead == NULL) yasm_internal_error("shead is null"); if (!elf_march->write_secthead || !elf_march->secthead_size) yasm_internal_error(N_("Unsupported machine for ELF output")); elf_march->write_secthead(bufp, shead); if (fwrite(buf, elf_march->secthead_size, 1, f)) return elf_march->secthead_size; yasm_internal_error(N_("Failed to write an elf section header")); return 0;}intelf_secthead_append_reloc(yasm_section *sect, elf_secthead *shead, elf_reloc_entry *reloc){ int new_sect = 0; if (sect == NULL) yasm_internal_error("sect is null"); if (shead == NULL) yasm_internal_error("shead is null"); if (reloc == NULL) yasm_internal_error("reloc is null"); shead->nreloc++; yasm_section_add_reloc(sect, (yasm_reloc *)reloc, elf_reloc_entry_destroy); return new_sect;}char *elf_secthead_name_reloc_section(const char *basesect){ if (!elf_march->reloc_section_prefix) { yasm_internal_error(N_("Unsupported machine for ELF output")); return NULL; } else { int prepend_length = strlen(elf_march->reloc_section_prefix); char *sectname = yasm_xmalloc(prepend_length + strlen(basesect) + 1); strcpy(sectname, elf_march->reloc_section_prefix); strcat(sectname, basesect); return sectname; }}voidelf_handle_reloc_addend(yasm_intnum *intn, elf_reloc_entry *reloc){ if (!elf_march->handle_reloc_addend) yasm_internal_error(N_("Unsupported machine for ELF output")); elf_march->handle_reloc_addend(intn, reloc);}unsigned longelf_secthead_write_rel_to_file(FILE *f, elf_section_index symtab_idx, yasm_section *sect, elf_secthead *shead, elf_section_index sindex){ unsigned char buf[SHDR_MAXSIZE], *bufp = buf; if (shead == NULL) yasm_internal_error("shead is null"); if (!yasm_section_relocs_first(sect)) return 0; /* no relocations, no .rel.* section header */ shead->rel_index = sindex; if (!elf_march->write_secthead_rel || !elf_march->secthead_size) yasm_internal_error(N_("Unsupported machine for ELF output")); elf_march->write_secthead_rel(bufp, shead, symtab_idx, sindex); if (fwrite(buf, elf_march->secthead_size, 1, f)) return elf_march->secthead_size; yasm_internal_error(N_("Failed to write an elf section header")); return 0;}unsigned longelf_secthead_write_relocs_to_file(FILE *f, yasm_section *sect, elf_secthead *shead){ elf_reloc_entry *reloc; unsigned char buf[RELOC_MAXSIZE], *bufp; unsigned long size = 0; long pos; if (shead == NULL) yasm_internal_error("shead is null"); reloc = (elf_reloc_entry *)yasm_section_relocs_first(sect); if (!reloc) return 0; /* first align section to multiple of 4 */ pos = ftell(f); if (pos == -1) yasm__error(0, N_("couldn't read position on output stream")); pos = (pos + 3) & ~3; if (fseek(f, pos, SEEK_SET) < 0) yasm__error(0, N_("couldn't seek on output stream")); shead->rel_offset = (unsigned long)pos; while (reloc) { yasm_sym_vis vis; unsigned int r_type=0, r_sym; elf_symtab_entry *esym; esym = yasm_symrec_get_data(reloc->reloc.sym, &elf_symrec_data); if (esym) r_sym = esym->symindex; else r_sym = STN_UNDEF; vis = yasm_symrec_get_visibility(reloc->reloc.sym); if (!elf_march->map_reloc_info_to_type) yasm_internal_error(N_("Unsupported arch/machine for elf output")); r_type = elf_march->map_reloc_info_to_type(reloc, elf_ssyms); bufp = buf; if (!elf_march->write_reloc || !elf_march->reloc_entry_size) yasm_internal_error(N_("Unsupported arch/machine for elf output")); elf_march->write_reloc(bufp, reloc, r_type, r_sym); fwrite(buf, elf_march->reloc_entry_size, 1, f); size += elf_march->reloc_entry_size; reloc = (elf_reloc_entry *) yasm_section_reloc_next((yasm_reloc *)reloc); } return size;}elf_section_typeelf_secthead_get_type(elf_secthead *shead){ return shead->type;}intelf_secthead_is_empty(elf_secthead *shead){ return yasm_intnum_is_zero(shead->size);}yasm_symrec *elf_secthead_get_sym(elf_secthead *shead){ return shead->sym;}elf_section_indexelf_secthead_get_index(elf_secthead *shead){ return shead->index;}const yasm_intnum *elf_secthead_set_align(elf_secthead *shead, yasm_intnum *align){ if (shead->align != NULL) yasm_intnum_destroy(shead->align); return shead->align = align;}elf_section_infoelf_secthead_set_info(elf_secthead *shead, elf_section_info info){ return shead->info = info;}elf_section_indexelf_secthead_set_index(elf_secthead *shead, elf_section_index sectidx){ return shead->index = sectidx;}elf_section_indexelf_secthead_set_link(elf_secthead *shead, elf_section_index link){ return shead->link = link;}elf_section_indexelf_secthead_set_rel_index(elf_secthead *shead, elf_section_index sectidx){ return shead->rel_index = sectidx;}elf_strtab_entry *elf_secthead_set_rel_name(elf_secthead *shead, elf_strtab_entry *entry){ return shead->rel_name = entry;}elf_sizeelf_secthead_set_entsize(elf_secthead *shead, elf_size size){ return shead->entsize = size;}yasm_symrec *elf_secthead_set_sym(elf_secthead *shead, yasm_symrec *sym){ return shead->sym = sym;}voidelf_secthead_add_size(elf_secthead *shead, yasm_intnum *size){ if (size) { yasm_intnum_calc(shead->size, YASM_EXPR_ADD, size, 0); }}longelf_secthead_set_file_offset(elf_secthead *shead, long pos){ unsigned long align = yasm_intnum_get_uint(shead->align); if (align == 0 || align == 1) { shead->offset = (unsigned long)pos; return pos; } else if (align & (align - 1)) yasm_internal_error( N_("alignment %d for section `%s' is not a power of 2")); /*, align, sect->name->str);*/ shead->offset = (unsigned long)((pos + align - 1) & ~(align - 1)); return (long)shead->offset;}unsigned longelf_proghead_get_size(void){ if (!elf_march->proghead_size) yasm_internal_error(N_("Unsupported ELF format for output")); return elf_march->proghead_size;}unsigned longelf_proghead_write_to_file(FILE *f, elf_offset secthead_addr, unsigned long secthead_count, elf_section_index shstrtab_index){ unsigned char buf[EHDR_MAXSIZE], *bufp = buf; YASM_WRITE_8(bufp, ELFMAG0); /* ELF magic number */ YASM_WRITE_8(bufp, ELFMAG1); YASM_WRITE_8(bufp, ELFMAG2); YASM_WRITE_8(bufp, ELFMAG3); if (!elf_march->write_proghead || !elf_march->proghead_size) yasm_internal_error(N_("Unsupported ELF format for output")); elf_march->write_proghead(&bufp, secthead_addr, secthead_count, shstrtab_index); if (((unsigned)(bufp - buf)) != elf_march->proghead_size) yasm_internal_error(N_("ELF program header is not proper length")); if (fwrite(buf, elf_march->proghead_size, 1, f)) return elf_march->proghead_size; yasm_internal_error(N_("Failed to write ELF program header")); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -