struct r_bin_pe_section_t* PE_(r_bin_pe_get_sections)(struct PE_(r_bin_pe_obj_t)* bin) {
	struct r_bin_pe_section_t* sections = NULL;
	PE_(image_section_header) * shdr;
	int i, j, section_count = 0;

	if (!bin || !bin->nt_headers) {
		return NULL;
	}
	shdr = bin->section_header;
	for (i = 0; i < bin->num_sections; i++) {
		//just allocate the needed
		if (shdr[i].SizeOfRawData || shdr[i].Misc.VirtualSize) {
			section_count++;
		}
	}
	sections = calloc (section_count + 1, sizeof(struct r_bin_pe_section_t));
	if (!sections) {
		r_sys_perror ("malloc (sections)");
		return NULL;
	}
	for (i = 0, j = 0; i < bin->num_sections; i++) {
		//if sz = 0 r_io_section_add will not add it so just skeep
		if (!shdr[i].SizeOfRawData && !shdr[i].Misc.VirtualSize) {
			continue;
		}
		if (shdr[i].Name[0] == '\0') {
			char* new_name = r_str_newf ("sect_%d", j);
			strncpy ((char*) sections[j].name, new_name, R_ARRAY_SIZE (sections[j].name) - 1);
			free (new_name);
		} else if (shdr[i].Name[0] == '/') {
			//long name is something deprecated but still used
			int idx = atoi ((const char *)shdr[i].Name + 1);
			ut64 sym_tbl_off = bin->nt_headers->file_header.PointerToSymbolTable;
			int num_symbols = bin->nt_headers->file_header.NumberOfSymbols;
			int off = num_symbols * COFF_SYMBOL_SIZE;
			if (sym_tbl_off &&
			    sym_tbl_off + off + idx < bin->size &&
			    sym_tbl_off + off + idx > off) {
				int sz = PE_IMAGE_SIZEOF_SHORT_NAME * 3;
				char* buf[64] = {0};
				if (r_buf_read_at (bin->b,
						   sym_tbl_off + off + idx,
						   (ut8*)buf, 64)) {
					memcpy (sections[j].name, buf, sz);
					sections[j].name[sz - 1] = '\0';
				}
			}
		} else {
			memcpy (sections[j].name, shdr[i].Name, PE_IMAGE_SIZEOF_SHORT_NAME);
			sections[j].name[PE_IMAGE_SIZEOF_SHORT_NAME] = '\0';
		}
		sections[j].vaddr = shdr[i].VirtualAddress;
		sections[j].size = shdr[i].SizeOfRawData;
		sections[j].vsize = shdr[i].Misc.VirtualSize;
		if (bin->optional_header) {
			int sa = R_MAX (bin->optional_header->SectionAlignment, 0x1000);
			ut64 diff = sections[j].vsize % sa;
			if (diff) {
				sections[j].vsize += sa - diff;
			}
		}
		sections[j].paddr = shdr[i].PointerToRawData;
		sections[j].flags = shdr[i].Characteristics;
		sections[j].last = 0;
		j++;
	}
	sections[j].last = 1;
	bin->num_sections = section_count;
	return sections;
}
struct r_bin_pe_section_t* PE_(r_bin_pe_get_sections)(struct PE_(r_bin_pe_obj_t)* bin) {
	struct r_bin_pe_section_t* sections = NULL;
	PE_(image_section_header) * shdr;
	int i, j, section_count = 0;

	if (!bin || !bin->nt_headers) {
		return NULL;
	}
	shdr = bin->section_header;
	for (i = 0; i < bin->num_sections; i++) {
		 
		if (shdr[i].SizeOfRawData || shdr[i].Misc.VirtualSize) {
			section_count++;
		}
	}
	sections = calloc (section_count + 1, sizeof(struct r_bin_pe_section_t));
	if (!sections) {
		r_sys_perror ("malloc (sections)");
		return NULL;
	}
	for (i = 0, j = 0; i < bin->num_sections; i++) {
		 
		if (!shdr[i].SizeOfRawData && !shdr[i].Misc.VirtualSize) {
			continue;
		}
		if (shdr[i].Name[0] == '\0') {
			char* new_name = r_str_newf ("sect_%d", j);
			strncpy ((char*) sections[j].name, new_name, R_ARRAY_SIZE (sections[j].name) - 1);
			free (new_name);
		} else if (shdr[i].Name[0] == '/') {
			 
			int idx = atoi ((const char *)shdr[i].Name + 1);
			ut64 sym_tbl_off = bin->nt_headers->file_header.PointerToSymbolTable;
			int num_symbols = bin->nt_headers->file_header.NumberOfSymbols;
			int off = num_symbols * COFF_SYMBOL_SIZE;
			if (sym_tbl_off &&
			    sym_tbl_off + off + idx < bin->size &&
			    sym_tbl_off + off + idx > off) {
				int sz = PE_IMAGE_SIZEOF_SHORT_NAME * 3;
				char* buf[64] = {0};
				if (r_buf_read_at (bin->b,
						   sym_tbl_off + off + idx,
						   (ut8*)buf, 64)) {
					memcpy (sections[j].name, buf, sz);
					sections[j].name[sz - 1] = '\0';
				}
			}
		} else {
			memcpy (sections[j].name, shdr[i].Name, PE_IMAGE_SIZEOF_SHORT_NAME);
			sections[j].name[PE_IMAGE_SIZEOF_SHORT_NAME] = '\0';
		}
		sections[j].vaddr = shdr[i].VirtualAddress;
		sections[j].size = shdr[i].SizeOfRawData;
		sections[j].vsize = shdr[i].Misc.VirtualSize;
		if (bin->optional_header) {
			int sa = R_MAX (bin->optional_header->SectionAlignment, 0x1000);
			ut64 diff = sections[j].vsize % sa;
			if (diff) {
				sections[j].vsize += sa - diff;
			}
		}
		sections[j].paddr = shdr[i].PointerToRawData;
		sections[j].flags = shdr[i].Characteristics;
		sections[j].last = 0;
		j++;
	}
	sections[j].last = 1;
	bin->num_sections = section_count;
	return sections;
}