static int bin_relocs(RCore *r, int mode, int va) {
	int bin_demangle = r_config_get_i (r->config, "bin.demangle");
	RList *relocs;
	RListIter *iter;
	RBinReloc *reloc = NULL;
	Sdb *db = NULL;
	char *sdb_module = NULL;
	int i = 0;

	va = VA_TRUE; // XXX relocs always vaddr?
	//this has been created for reloc object files
	relocs = r_bin_patch_relocs (r->bin);
	if (!relocs) {
		relocs = r_bin_get_relocs (r->bin);
	}

	if (IS_MODE_RAD (mode)) {
		r_cons_println ("fs relocs");
	} else if (IS_MODE_NORMAL (mode)) {
		r_cons_println ("[Relocations]");
	} else if (IS_MODE_JSON (mode)) {
		r_cons_print ("[");
	} else if (IS_MODE_SET (mode)) {
		r_flag_space_set (r->flags, "relocs");
	}
	RBinFile * binfile = r->bin->cur;
	RBinObject *binobj = binfile ? binfile->o: NULL;
	RBinInfo *info = binobj ? binobj->info: NULL;
	int cdsz = info? (info->bits == 64? 8: info->bits == 32? 4: info->bits == 16 ? 4: 0): 0;
	r_list_foreach (relocs, iter, reloc) {
		ut64 addr = rva (r->bin, reloc->paddr, reloc->vaddr, va);
		if (IS_MODE_SET (mode)) {
			set_bin_relocs (r, reloc, addr, &db, &sdb_module);
			if (cdsz) {
				r_meta_add (r->anal, R_META_TYPE_DATA, reloc->vaddr, reloc->vaddr + cdsz, NULL);
			}
		} else if (IS_MODE_SIMPLE (mode)) {
			r_cons_printf ("0x%08"PFMT64x"  %s\n", addr, reloc->import ? reloc->import->name : "");
		} else if (IS_MODE_RAD (mode)) {
			char *name = reloc->import
				? strdup (reloc->import->name)
				: (reloc->symbol ? strdup (reloc->symbol->name) : NULL);
			if (name && bin_demangle) {
				char *mn = r_bin_demangle (r->bin->cur, NULL, name, addr);
				if (mn) {
					free (name);
					name = mn;
				}
			}
			if (name) {
				r_cons_printf ("f %s%s%s @ 0x%08"PFMT64x"\n",
					r->bin->prefix ? r->bin->prefix : "reloc.",
					r->bin->prefix ? "." : "", name, addr);
				if (cdsz) {
					r_cons_printf ("f Cd %d @ 0x%08"PFMT64x"\n", cdsz, addr);
				}
				free (name);
			}
		} else if (IS_MODE_JSON (mode)) {
			if (iter->p) {
				r_cons_printf (",{\"name\":");
			} else {
				r_cons_printf ("{\"name\":");
			}
			// take care with very long symbol names! do not use sdb_fmt or similar
			if (reloc->import) {
				r_cons_printf ("\"%s\"", reloc->import->name);
			} else if (reloc->symbol) {
				r_cons_printf ("\"%s\"", reloc->symbol->name);
			} else {
				r_cons_printf ("null");
			}

			r_cons_printf (","
				"\"type\":\"%s\","
				"\"vaddr\":%"PFMT64d","
				"\"paddr\":%"PFMT64d","
				"\"is_ifunc\":%s}",
				bin_reloc_type_name (reloc),
				reloc->vaddr, reloc->paddr,
				r_str_bool (reloc->is_ifunc));
		} else if (IS_MODE_NORMAL (mode)) {
			char *name = reloc->import
				? strdup (reloc->import->name)
				: reloc->symbol
				? strdup (reloc->symbol->name)
				: strdup ("null");
			if (bin_demangle) {
				char *mn = r_bin_demangle (r->bin->cur, NULL, name, addr);
				if (mn && *mn) {
					free (name);
					name = mn;
				}
			}
			r_cons_printf ("vaddr=0x%08"PFMT64x" paddr=0x%08"PFMT64x" type=%s",
				addr, reloc->paddr, bin_reloc_type_name (reloc));
			if (reloc->import && reloc->import->name[0]) {
				r_cons_printf (" %s", name);
			} else if (reloc->symbol && name && name[0]) {
				r_cons_printf (" %s", name);
			}
			free (name);
			if (reloc->addend) {
				if (reloc->import && reloc->addend > 0) {
					r_cons_printf (" +");
				}
				if (reloc->addend < 0) {
					r_cons_printf (" - 0x%08"PFMT64x, -reloc->addend);
				} else {
					r_cons_printf (" 0x%08"PFMT64x, reloc->addend);
				}
			}
			if (reloc->is_ifunc) {
				r_cons_print (" (ifunc)");
			}
			r_cons_newline ();
		}
		i++;
	}
	if (IS_MODE_JSON (mode)) {
		r_cons_print ("]");
	}
	if (IS_MODE_NORMAL (mode)) {
		r_cons_printf ("\n%i relocations\n", i);
	}
	return relocs != NULL;
}