📄 elf.c
字号:
} /* Switch xvec to match the specified byte order. */ switch (x_ehdr.e_ident[EI_DATA]) { case ELFDATA2MSB: /* Big-endian */ abfd->xvec = &elf_big_vec; break; case ELFDATA2LSB: /* Little-endian */ abfd->xvec = &elf_little_vec; break; case ELFDATANONE: /* No data encoding specified */ default: /* Unknown data encoding specified */ goto wrong; } /* Allocate an instance of the elf_obj_tdata structure and hook it up to the tdata pointer in the bfd. */ elf_tdata (abfd) = (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata)); if (elf_tdata (abfd) == NULL) { bfd_error = no_memory; return (NULL); } /* FIXME, `wrong' returns from this point onward, leak memory. */ /* Now that we know the byte order, swap in the rest of the header */ i_ehdrp = elf_elfheader (abfd); elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp); /* If there is no program header, or the type is not a core file, then we are hosed. */ if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE) goto wrong; /* Allocate space for a copy of the program header table in internal form, seek to the program header table in the file, read it in, and convert it to internal form. As a simple sanity check, verify that the what BFD thinks is the size of each program header table entry actually matches the size recorded in the file. */ if (i_ehdrp->e_phentsize != sizeof (x_phdr)) goto wrong; i_phdrp = (Elf_Internal_Phdr *) bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum); if (! i_phdrp) { bfd_error = no_memory; return (NULL); } if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) == -1) { bfd_error = system_call_error; return (NULL); } for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++) { if (bfd_read ((PTR) &x_phdr, sizeof (x_phdr), 1, abfd) != sizeof (x_phdr)) { bfd_error = system_call_error; return (NULL); } elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex); } /* Once all of the program headers have been read and converted, we can start processing them. */ for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++) { bfd_section_from_phdr (abfd, i_phdrp + phindex, phindex); if ((i_phdrp + phindex) -> p_type == PT_NOTE) { elf_corefile_note (abfd, i_phdrp + phindex); } } /* Remember the entry point specified in the ELF file header. */ bfd_get_start_address (abfd) = i_ehdrp->e_entry; return (abfd->xvec);}static booleanDEFUN (elf_mkobject, (abfd), bfd *abfd){ /* this just does initialization */ /* coff_mkobject zalloc's space for tdata.coff_obj_data ... */ elf_tdata(abfd) = (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof(struct elf_obj_tdata)); if (elf_tdata(abfd) == 0) { bfd_error = no_memory; return false; } /* since everything is done at close time, do we need any initialization? */ return (true);}/* Create ELF output from BFD sections. Essentially, just create the section header and forget about the program header for now. *//* lacking nested functions and nested types, set up for mapping over BFD sections to produce ELF sections */typedef struct { Elf_Internal_Ehdr *i_ehdr; Elf_Internal_Shdr *i_shdrp; struct strtab *shstrtab; int symtab_section;} elf_sect_thunk;static voidDEFUN (elf_make_sections, (abfd, asect, obj), bfd *abfd AND asection *asect AND PTR obj){ elf_sect_thunk *thunk = (elf_sect_thunk*)obj; /* most of what is in bfd_shdr_from_section goes in here... */ /* and all of these sections generate at *least* one ELF section. */ int this_section; int idx; /* check if we're making a PROGBITS section... */ /* if ((asect->flags & SEC_ALLOC) && (asect->flags & SEC_LOAD)) */ /* this was too strict... what *do* we want to check here? */ if(1) { Elf_Internal_Shdr *this_hdr; this_section = elf_section_from_bfd_section (abfd, asect); this_hdr = &thunk->i_shdrp[this_section]; this_hdr->sh_addr = asect->vma; this_hdr->sh_size = asect->_raw_size; /* contents already set by elf_set_section_contents */ if (asect->flags & SEC_RELOC) { /* emit a reloc section, and thus strtab and symtab... */ Elf_Internal_Shdr *rela_hdr; Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Shdr *symstrtab_hdr; Elf_External_Rela *outbound_relocs; Elf_External_Sym *outbound_syms; int rela_section; int symstrtab_section; symtab_hdr = &thunk->i_shdrp[thunk->symtab_section]; if (thunk->symtab_section == this_section + 1) rela_section = thunk->symtab_section + 2; /* symtab + symstrtab */ else rela_section = this_section + 1; rela_hdr = &thunk->i_shdrp[rela_section]; rela_hdr->sh_type = SHT_RELA; rela_hdr->sh_link = thunk->symtab_section; rela_hdr->sh_info = this_section; rela_hdr->sh_entsize = sizeof (Elf_External_Rela); /* orelocation has the data, reloc_count has the count... */ rela_hdr->sh_size = rela_hdr->sh_entsize * asect->reloc_count; outbound_relocs = (Elf_External_Rela *) bfd_alloc(abfd, asect->reloc_count * sizeof(Elf_External_Rela)); for (idx = 0; idx < asect->reloc_count; idx++) { Elf_Internal_Rela dst; arelent *ptr; Elf_External_Rela *src; ptr = asect->orelocation[idx]; src = outbound_relocs + idx; if (asect->flags & SEC_RELOC) dst.r_offset = ptr->address - asect->vma; else dst.r_offset = ptr->address; dst.r_info = ELF_R_INFO(1 /*ptr->sym_ptr_ptr*/, /* needs index into symtab (FIXME) */ ptr->howto->type); dst.r_addend = ptr->addend; elf_swap_reloca_out(abfd, &dst, src); } rela_hdr->contents = (void*)outbound_relocs; } }}static voidDEFUN (elf_fake_sections, (abfd, asect, obj), bfd *abfd AND asection *asect AND PTR obj){ elf_sect_thunk *thunk = (elf_sect_thunk*)obj; /* most of what is in bfd_shdr_from_section goes in here... */ /* and all of these sections generate at *least* one ELF section. */ int this_section; int idx; /* check if we're making a PROGBITS section... */ /* if ((asect->flags & SEC_ALLOC) && (asect->flags & SEC_LOAD)) */ /* this was too strict... what *do* we want to check here? */ if(1) { Elf_Internal_Shdr *this_hdr; this_section = thunk->i_ehdr->e_shnum++; this_hdr = &thunk->i_shdrp[this_section]; this_hdr->sh_name = bfd_add_to_strtab (abfd, thunk->shstrtab, asect->name); /* we need to log the type *now* so that elf_section_from_bfd_section can find us... have to set rawdata too. */ this_hdr->rawdata = (void*)asect; if ((asect->flags & SEC_ALLOC) && (asect->flags & SEC_LOAD)) this_hdr->sh_type = SHT_PROGBITS; else /* what *do* we put here? */ this_hdr->sh_type = SHT_PROGBITS; if (asect->flags & SEC_RELOC) { /* emit a reloc section, and thus strtab and symtab... */ Elf_Internal_Shdr *rela_hdr; Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Shdr *symstrtab_hdr; Elf_External_Rela *outbound_relocs; Elf_External_Sym *outbound_syms; int rela_section; int symstrtab_section; /* note that only one symtab is used, so just remember it for now */ if (! thunk->symtab_section) { thunk->symtab_section = thunk->i_ehdr->e_shnum++; symtab_hdr = &thunk->i_shdrp[thunk->symtab_section]; symtab_hdr->sh_name = bfd_add_to_strtab (abfd, thunk->shstrtab, ".symtab"); symtab_hdr->sh_type = SHT_SYMTAB; symtab_hdr->sh_entsize = sizeof (Elf_External_Sym); symstrtab_section = thunk->i_ehdr->e_shnum++; BFD_ASSERT(symstrtab_section == thunk->symtab_section+1); symstrtab_hdr = &thunk->i_shdrp[symstrtab_section]; symtab_hdr->sh_link = symstrtab_section; symstrtab_hdr->sh_name = bfd_add_to_strtab (abfd, thunk->shstrtab, ".strtab"); symstrtab_hdr->sh_type = SHT_STRTAB; symtab_hdr->contents = 0; symstrtab_hdr->contents = 0; symstrtab_hdr->sh_size = 0; } else symtab_hdr = &thunk->i_shdrp[thunk->symtab_section]; rela_section = thunk->i_ehdr->e_shnum++; rela_hdr = &thunk->i_shdrp[rela_section]; rela_hdr->sh_name = bfd_add_2_to_strtab (abfd, thunk->shstrtab, ".rela", asect->name); rela_hdr->sh_type = SHT_RELA; rela_hdr->sh_link = thunk->symtab_section; rela_hdr->sh_info = this_section; rela_hdr->sh_entsize = sizeof (Elf_External_Rela); } }}static booleanDEFUN (elf_compute_section_file_positions, (abfd), bfd *abfd){ Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ Elf_Internal_Shdr *i_shdrp; /* Section header table, internal form */ struct strtab *shstrtab; int count, maxsections; int outbase; elf_sect_thunk est; if (! elf_shstrtab (abfd)) { i_ehdrp = elf_elfheader (abfd); /* build new header in tdata memory */ shstrtab = bfd_new_strtab(abfd); i_ehdrp->e_ident[EI_MAG0] = ELFMAG0; i_ehdrp->e_ident[EI_MAG1] = ELFMAG1; i_ehdrp->e_ident[EI_MAG2] = ELFMAG2; i_ehdrp->e_ident[EI_MAG3] = ELFMAG3; i_ehdrp->e_ident[EI_CLASS] = ELFCLASS32; /* FIXME: find out from bfd */ i_ehdrp->e_ident[EI_DATA] = abfd->xvec->byteorder_big_p ? ELFDATA2MSB : ELFDATA2LSB; i_ehdrp->e_ident[EI_VERSION] = EV_CURRENT; for(count = EI_PAD; count < EI_NIDENT; count ++) i_ehdrp->e_ident[count] = 0; i_ehdrp->e_type = (abfd->flags & EXEC_P)? ET_EXEC : ET_REL; switch(bfd_get_arch(abfd)) { case bfd_arch_unknown: i_ehdrp->e_machine = EM_NONE; break; case bfd_arch_sparc: i_ehdrp->e_machine = EM_SPARC; break; case bfd_arch_i386: i_ehdrp->e_machine = EM_386; break; case bfd_arch_m68k: i_ehdrp->e_machine = EM_68K; break; case bfd_arch_m88k: i_ehdrp->e_machine = EM_88K; break; case bfd_arch_i860: i_ehdrp->e_machine = EM_860; break; case bfd_arch_mips: /* MIPS Rxxxx */ i_ehdrp->e_machine = EM_MIPS; /* only MIPS R3000 */ break; /* also note that EM_M32, AT&T WE32100 is unknown to bfd */ default: i_ehdrp->e_machine = EM_NONE; } i_ehdrp->e_version = EV_CURRENT; i_ehdrp->e_ehsize = sizeof(Elf_External_Ehdr); /* no program header, for now. */ i_ehdrp->e_phoff = 0; i_ehdrp->e_phentsize = 0; i_ehdrp->e_phnum = 0; /* each bfd section is section header entry */ i_ehdrp->e_entry = bfd_get_start_address (abfd); i_ehdrp->e_shentsize = sizeof (Elf_External_Shdr); /* figure at most each section can have a rel, strtab, symtab */ maxsections = 4*bfd_count_sections(abfd)+2; i_ehdrp->e_shoff = i_ehdrp->e_ehsize; /* and we'll just have to fix up the offsets later. */ /* outbase += i_ehdr.e_shentsize * i_ehdr.e_shnum; */ i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, sizeof (*i_shdrp) * maxsections); if (! i_shdrp) { bfd_error = no_memory; return (false); } for (count=0; count < maxsections; count++) { i_shdrp[count].rawdata = 0; i_shdrp[count].contents = 0; } i_shdrp[0].sh_name = 0; i_shdrp[0].sh_type = SHT_NULL; i_shdrp[0].sh_flags = 0; i_shdrp[0].sh_addr = 0; i_shdrp[0].sh_offset = 0; i_shdrp[0].sh_size = 0; i_shdrp[0].sh_link = SHN_UNDEF; i_shdrp[0].sh_info = 0; i_shdrp[0].sh_addralign = 0; i_shdrp[0].sh_entsize = 0; i_ehdrp->e_shnum = 1; elf_elfsections (abfd) = i_shdrp; elf_shstrtab (abfd) = shstrtab; } est.i_ehdr = elf_elfheader(abfd); est.i_shdrp = elf_elfsections(abfd); est.shstrtab = elf_shstrtab(abfd); est.symtab_section = 0; /* elf_fake_sections fils it in */ bfd_map_over_sections(abfd, elf_fake_sections, &est); elf_onesymtab (abfd) = est.symtab_section; return (true);}static booleanDEFUN (elf_write_object_contents, (abfd), bfd *abfd){ Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ Elf_External_Phdr *x_phdrp; /* Program header table, external form */ Elf_Internal_Phdr *i_phdrp; /* Program header table, internal form */ Elf_External_Shdr *x_shdrp; /* Section header table, external form */ Elf_Internal_Shdr *i_shdrp; /* Section header table, internal form */ asection *nsect; int maxsections; elf_sect_thunk est; int outbase = 0; int count; struct strtab *shstrtab; if(abfd->output_has_begun == false) elf_compute_section_file_positions(abfd); i_ehdrp = elf_elfheader (abfd); i_shdrp = elf_elfsections (abfd); shstrtab = elf_shstrtab (abfd); est.i_ehdr = i_ehdrp; est.i_shdrp = i_shdrp; est.shstrtab = shstrtab; est.symtab_section = elf_onesymtab (abfd); /* filled in by elf_fake */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -