static void r_binfmt_macho64_load_segment(r_binfmt_s *bin, r_binfmt_macho64_segment_s *s) { r_binfmt_segment_s *seg; u64 vaddr, filesz, fileoff; u32 flags, initprot; seg = r_binfmt_segment_new(); R_BINFMT_GET_INT(vaddr, s->vm_addr, bin->endian); R_BINFMT_GET_INT(filesz, s->file_size, bin->endian); R_BINFMT_GET_INT(fileoff, s->file_off, bin->endian); R_BINFMT_GET_INT(initprot, s->init_prot, bin->endian); flags = 0; if(initprot & R_BINFMT_MACHO_PROT_R) flags |= R_BINFMT_SEGMENT_FLAG_PROT_R; if(initprot & R_BINFMT_MACHO_PROT_W) flags |= R_BINFMT_SEGMENT_FLAG_PROT_W; if(initprot & R_BINFMT_MACHO_PROT_X) flags |= R_BINFMT_SEGMENT_FLAG_PROT_X; seg->addr = vaddr; seg->length = filesz; seg->start = bin->mapped + fileoff; seg->flags = flags; r_utils_list_push(&bin->segments, seg); }
r_binfmt_err_e r_binfmt_raw_load(r_binfmt_s *bin, r_binfmt_arch_e arch) { r_binfmt_segment_s *seg; seg = r_binfmt_segment_new(); seg->flags = R_BINFMT_SEGMENT_FLAG_PROT_X | R_BINFMT_SEGMENT_FLAG_PROT_R | R_BINFMT_SEGMENT_FLAG_PROT_W; seg->addr = 0; seg->start = bin->mapped; seg->length = bin->mapped_size; r_utils_list_push(&bin->segments, seg); bin->type = R_BINFMT_TYPE_RAW; bin->arch = arch; bin->endian = R_BINFMT_ENDIAN_LITTLE; return R_BINFMT_ERR_OK; }
/* Fill bin->segments structure */ static void r_binfmt_elf64_load_segments(r_binfmt_s *bin, r_binfmt_elf64_s *elf) { r_binfmt_segment_s *seg; Elf64_Word i, p_type, p_flags, p_filesz; Elf64_Off p_offset; Elf64_Addr p_vaddr; Elf64_Half e_phnum; R_BINFMT_ASSERT(elf->ehdr != NULL); R_BINFMT_ASSERT(elf->phdr != NULL); R_BINFMT_GET_INT(e_phnum, elf->ehdr->e_phnum, bin->endian); for(i = 0; i < e_phnum; i++) { R_BINFMT_GET_INT(p_type, elf->phdr[i].p_type, bin->endian); R_BINFMT_GET_INT(p_flags, elf->phdr[i].p_flags, bin->endian); R_BINFMT_GET_INT(p_vaddr, elf->phdr[i].p_vaddr, bin->endian); R_BINFMT_GET_INT(p_offset, elf->phdr[i].p_offset, bin->endian); R_BINFMT_GET_INT(p_filesz, elf->phdr[i].p_filesz, bin->endian); R_BINFMT_ASSERT(r_utils_add64(NULL, p_offset, p_filesz) && p_offset + p_filesz <= bin->mapped_size); if(p_type == PT_LOAD) { seg = r_binfmt_segment_new(); seg->flags = 0; if(p_flags & PF_X) seg->flags |= R_BINFMT_SEGMENT_FLAG_PROT_X; if(p_flags & PF_R) seg->flags |= R_BINFMT_SEGMENT_FLAG_PROT_R; if(p_flags & PF_W) seg->flags |= R_BINFMT_SEGMENT_FLAG_PROT_W; seg->addr = p_vaddr; seg->length = p_filesz; seg->start = bin->mapped + p_offset; r_utils_linklist_push(&bin->segments, seg); } } }