static int bin_sections(RCore *r, int mode, ut64 laddr, int va, ut64 at, const char *name, const char *chksum) {
	char str[R_FLAG_NAME_SIZE];
	RBinSection *section;
	RBinInfo *info = NULL;
	RList *sections;
	RListIter *iter;
	int i = 0;
	int fd = -1;
	sections = r_bin_get_sections (r->bin);
	bool inDebugger = r_config_get_i (r->config, "cfg.debug");

	if (IS_MODE_JSON (mode)) r_cons_printf ("[");
	else if (IS_MODE_RAD (mode) && !at) r_cons_printf ("fs sections\n");
	else if (IS_MODE_NORMAL (mode) && !at) r_cons_printf ("[Sections]\n");
	else if (IS_MODE_SET (mode)) {
		fd = r_core_file_cur_fd (r);
		r_flag_space_set (r->flags, "sections");
	}
	r_list_foreach (sections, iter, section) {
		char perms[] = "-----";
		int va_sect = va;
		ut64 addr;

		if (va && !(section->srwx & R_BIN_SCN_READABLE)) {
			va_sect = VA_NOREBASE;
		}
		addr = rva (r->bin, section->paddr, section->vaddr, va_sect);

		if (name && strcmp (section->name, name)) {
			continue;
		}
		r_name_filter (section->name, sizeof (section->name));
		if (at && (!section->size || !is_in_range (at, addr, section->size))) {
			continue;
		}

		if (section->srwx & R_BIN_SCN_MAP) perms[0] = 'm';
		if (section->srwx & R_BIN_SCN_SHAREABLE) perms[1] = 's';
		if (section->srwx & R_BIN_SCN_READABLE) perms[2] = 'r';
		if (section->srwx & R_BIN_SCN_WRITABLE) perms[3] = 'w';
		if (section->srwx & R_BIN_SCN_EXECUTABLE) perms[4] = 'x';

		if (IS_MODE_SET (mode)) {
#if LOAD_BSS_MALLOC
			if (!strcmp (section->name, ".bss")) {
				// check if there's already a file opened there
				int loaded = 0;
				RListIter *iter;
				RIOMap *m;
				r_list_foreach (r->io->maps, iter, m) {
					if (m->from == addr) {
						loaded = 1;
					}
				}
				if (!loaded && !inDebugger) {
					r_core_cmdf (r, "on malloc://%d 0x%"PFMT64x" # bss\n",
						section->vsize, addr);
				}
			}
#endif
			r_name_filter (section->name, 128);
			if (section->format) {
				// This is damn slow if section vsize is HUGE
				if (section->vsize < 1024 * 1024 * 2) {
					r_core_cmdf (r, "%s @ 0x%"PFMT64x, section->format, section->vaddr);
				}
			}
			if (r->bin->prefix) {
				snprintf (str, sizeof(str)-1, "%s.section.%s",
					r->bin->prefix, section->name);
			} else {
				snprintf (str, sizeof(str)-1, "section.%s", section->name);

			}
			r_flag_set (r->flags, str, addr, section->size);
			if (r->bin->prefix) {
				snprintf (str, sizeof(str) - 1, "%s.section_end.%s",
					r->bin->prefix, section->name);
			} else {
				snprintf (str, sizeof(str) - 1, "section_end.%s", section->name);
			}

			r_flag_set (r->flags, str, addr + section->size, 0);
			if (section->arch || section->bits) {
				const char *arch = section->arch;
				int bits = section->bits;
				if (info) {
					if (!arch) {
						arch = info->arch;
					}
					if (!bits) {
						bits = info->bits;
					}
				}
				//r_io_section_set_archbits (r->io, addr, arch, bits);
			}
			if (r->bin->prefix) {
				snprintf (str, sizeof (str)-1, "section %i va=0x%08"PFMT64x" pa=0x%08"
					PFMT64x" sz=%" PFMT64d" vsz=%"PFMT64d" rwx=%s %s.%s",
					i, addr, section->paddr, section->size, section->vsize,
					perms, r->bin->prefix, section->name);
			} else {
				snprintf (str, sizeof (str)-1, "section %i va=0x%08"PFMT64x" pa=0x%08"
					PFMT64x" sz=%" PFMT64d" vsz=%"PFMT64d" rwx=%s %s",
					i, addr, section->paddr, section->size, section->vsize,
					perms, section->name);

			}
			r_meta_add (r->anal, R_META_TYPE_COMMENT, addr, addr, str);
			if (section->add) {
				r_io_section_add (r->io, section->paddr, addr,
						  section->size, section->vsize,
						  section->srwx, section->name,
						  0, fd);
			}
		} else if (IS_MODE_SIMPLE (mode)) {
			char *hashstr = NULL;
			if (chksum) {
				ut8 *data = malloc (section->size);
				if (!data) {
					return false;
				}
				ut32 datalen = section->size;
				r_io_pread (r->io, section->paddr, data, datalen);
				hashstr = build_hash_string (mode, chksum,
							data, datalen);
				free (data);
			}
			r_cons_printf ("0x%"PFMT64x" 0x%"PFMT64x" %s %s%s%s\n",
				addr, addr + section->size,
				perms,
				hashstr ? hashstr : "", hashstr ? " " : "",
				section->name
			);
			free (hashstr);
		} else if (IS_MODE_JSON (mode)) {
			char *hashstr = NULL;
			if (chksum) {
				ut8 *data = malloc (section->size);
				if (!data) {
					return false;
				}
				ut32 datalen = section->size;
				r_io_pread (r->io, section->paddr, data, datalen);
				hashstr = build_hash_string (mode, chksum,
							data, datalen);
				free (data);

			}
			r_cons_printf ("%s{\"name\":\"%s\","
				"\"size\":%"PFMT64d","
				"\"vsize\":%"PFMT64d","
				"\"flags\":\"%s\","
				"%s"
				"\"paddr\":%"PFMT64d","
				"\"vaddr\":%"PFMT64d"}",
				iter->p?",":"",
				section->name,
				section->size,
				section->vsize,
				perms,
				hashstr ? hashstr : "",
				section->paddr,
				addr);
			free (hashstr);
		} else if (IS_MODE_RAD (mode)) {
			if (!strcmp (section->name, ".bss") && !inDebugger) {
#if LOAD_BSS_MALLOC
				r_cons_printf ("on malloc://%d 0x%"PFMT64x" # bss\n",
						section->vsize, addr);
#endif
			}
			if (r->bin->prefix) {
				r_cons_printf ("S 0x%08"PFMT64x" 0x%08"PFMT64x" 0x%08"PFMT64x" 0x%08"PFMT64x" %s.%s %d\n",
					section->paddr, addr, section->size, section->vsize,
					r->bin->prefix, section->name, (int)section->srwx);
			} else {
				r_cons_printf ("S 0x%08"PFMT64x" 0x%08"PFMT64x" 0x%08"PFMT64x" 0x%08"PFMT64x" %s %d\n",
					section->paddr, addr, section->size, section->vsize,
					section->name, (int)section->srwx);

			}
			if (section->arch || section->bits) {
				const char *arch = section->arch;
				int bits = section->bits;
				if (info) {
					if (!arch) arch = info->arch;
					if (!bits) bits = info->bits;
				}
				if (!arch) {
					arch = r_config_get (r->config, "asm.arch");
				}
				r_cons_printf ("Sa %s %d @ 0x%08"
					PFMT64x"\n", arch, bits, addr);
			}
			if (r->bin->prefix) {
				r_cons_printf ("f %s.section.%s %"PFMT64d" 0x%08"PFMT64x"\n",
						r->bin->prefix, section->name, section->size, addr);
				r_cons_printf ("f %s.section_end.%s 1 0x%08"PFMT64x"\n",
						r->bin->prefix, section->name, addr + section->size);
				r_cons_printf ("CC section %i va=0x%08"PFMT64x" pa=0x%08"PFMT64x" sz=%"PFMT64d" vsz=%"PFMT64d" "
						"rwx=%s %s.%s @ 0x%08"PFMT64x"\n",
						i, addr, section->paddr, section->size, section->vsize,
						perms, r->bin->prefix, section->name, addr);

			} else {
				r_cons_printf ("f section.%s %"PFMT64d" 0x%08"PFMT64x"\n",
						section->name, section->size, addr);
				r_cons_printf ("f section_end.%s 1 0x%08"PFMT64x"\n",
						section->name, addr + section->size);
				r_cons_printf ("CC section %i va=0x%08"PFMT64x" pa=0x%08"PFMT64x" sz=%"PFMT64d" vsz=%"PFMT64d" "
						"rwx=%s %s @ 0x%08"PFMT64x"\n",
						i, addr, section->paddr, section->size, section->vsize,
						perms, section->name, addr);
			}
		} else {
			char *hashstr = NULL, str[128];
			if (chksum) {
				ut8 *data = malloc (section->size);
				if (!data) return false;
				ut32 datalen = section->size;
				// VA READ IS BROKEN?
				r_io_pread (r->io, section->paddr, data, datalen);
				hashstr = build_hash_string (mode, chksum,
							data, datalen);
				free (data);
			}
			if (section->arch || section->bits) {
				const char *arch = section->arch;
				int bits = section->bits;
				if (!arch && info) {
					arch = info->arch;
					if (!arch) {
						arch = r_config_get (r->config, "asm.arch");
					}
				}
				if (!bits) {
					bits = info? info->bits: R_SYS_BITS;
				}
				snprintf (str, sizeof (str), "arch=%s bits=%d ",
					r_str_get2 (arch), bits);
			} else {
				str[0] = 0;
			}
			if (r->bin->prefix) {
				r_cons_printf ("idx=%02i vaddr=0x%08"PFMT64x" paddr=0x%08"PFMT64x" sz=%"PFMT64d" vsz=%"PFMT64d" "
					"perm=%s %s%sname=%s.%s\n",
					i, addr, section->paddr, section->size, section->vsize,
					perms, str, hashstr ?hashstr : "", r->bin->prefix, section->name);
			} else {
				r_cons_printf ("idx=%02i vaddr=0x%08"PFMT64x" paddr=0x%08"PFMT64x" sz=%"PFMT64d" vsz=%"PFMT64d" "
					"perm=%s %s%sname=%s\n",
					i, addr, section->paddr, section->size, section->vsize,
					perms, str, hashstr ?hashstr : "", section->name);
			}
			free (hashstr);
		}
		i++;
	}
	if (IS_MODE_JSON (mode)) {
		r_cons_println ("]");
	} else if (IS_MODE_NORMAL (mode) && !at) {
		r_cons_printf ("\n%i sections\n", i);
	}
	return true;
}