Patchwork [3/4] Blackfin: add linux-user support

login
register
mail settings
Submitter Mike Frysinger
Date Jan. 24, 2011, 10:26 a.m.
Message ID <1295864800-13617-1-git-send-email-vapier@gentoo.org>
Download mbox | patch
Permalink /patch/80160/
State New
Headers show

Comments

Mike Frysinger - Jan. 24, 2011, 10:26 a.m.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 configure                           |    1 +
 default-configs/bfin-linux-user.mak |    1 +
 linux-user/bfin/syscall.h           |   59 ++++++
 linux-user/bfin/syscall_nr.h        |  388 +++++++++++++++++++++++++++++++++++
 linux-user/bfin/target_flat.h       |   91 ++++++++
 linux-user/bfin/target_signal.h     |   29 +++
 linux-user/bfin/termbits.h          |  227 ++++++++++++++++++++
 linux-user/elfload.c                |   39 ++++
 linux-user/main.c                   |   95 +++++++++
 linux-user/qemu.h                   |    4 +
 linux-user/syscall_defs.h           |   65 ++++++-
 11 files changed, 997 insertions(+), 2 deletions(-)
 create mode 100644 default-configs/bfin-linux-user.mak
 create mode 100644 linux-user/bfin/syscall.h
 create mode 100644 linux-user/bfin/syscall_nr.h
 create mode 100644 linux-user/bfin/target_flat.h
 create mode 100644 linux-user/bfin/target_signal.h
 create mode 100644 linux-user/bfin/termbits.h

Patch

diff --git a/configure b/configure
index 730039f..ca9e1ba 100755
--- a/configure
+++ b/configure
@@ -1004,6 +1004,7 @@  x86_64-linux-user \
 alpha-linux-user \
 arm-linux-user \
 armeb-linux-user \
+bfin-linux-user \
 cris-linux-user \
 m68k-linux-user \
 microblaze-linux-user \
diff --git a/default-configs/bfin-linux-user.mak b/default-configs/bfin-linux-user.mak
new file mode 100644
index 0000000..5f7aefb
--- /dev/null
+++ b/default-configs/bfin-linux-user.mak
@@ -0,0 +1 @@ 
+# Default configuration for bfin-linux-user
diff --git a/linux-user/bfin/syscall.h b/linux-user/bfin/syscall.h
new file mode 100644
index 0000000..892ee75
--- /dev/null
+++ b/linux-user/bfin/syscall.h
@@ -0,0 +1,59 @@ 
+struct target_pt_regs {
+	abi_ulong orig_pc;
+	abi_ulong ipend;
+	abi_ulong seqstat;
+	abi_ulong rete;
+	abi_ulong retn;
+	abi_ulong retx;
+	abi_ulong pc;		/* PC == RETI */
+	abi_ulong rets;
+	abi_ulong reserved;		/* Used as scratch during system calls */
+	abi_ulong astat;
+	abi_ulong lb1;
+	abi_ulong lb0;
+	abi_ulong lt1;
+	abi_ulong lt0;
+	abi_ulong lc1;
+	abi_ulong lc0;
+	abi_ulong a1w;
+	abi_ulong a1x;
+	abi_ulong a0w;
+	abi_ulong a0x;
+	abi_ulong b3;
+	abi_ulong b2;
+	abi_ulong b1;
+	abi_ulong b0;
+	abi_ulong l3;
+	abi_ulong l2;
+	abi_ulong l1;
+	abi_ulong l0;
+	abi_ulong m3;
+	abi_ulong m2;
+	abi_ulong m1;
+	abi_ulong m0;
+	abi_ulong i3;
+	abi_ulong i2;
+	abi_ulong i1;
+	abi_ulong i0;
+	abi_ulong usp;
+	abi_ulong fp;
+	abi_ulong p5;
+	abi_ulong p4;
+	abi_ulong p3;
+	abi_ulong p2;
+	abi_ulong p1;
+	abi_ulong p0;
+	abi_ulong r7;
+	abi_ulong r6;
+	abi_ulong r5;
+	abi_ulong r4;
+	abi_ulong r3;
+	abi_ulong r2;
+	abi_ulong r1;
+	abi_ulong r0;
+	abi_ulong orig_r0;
+	abi_ulong orig_p0;
+	abi_ulong syscfg;
+};
+
+#define UNAME_MACHINE "blackfin"
diff --git a/linux-user/bfin/syscall_nr.h b/linux-user/bfin/syscall_nr.h
new file mode 100644
index 0000000..fd01c38
--- /dev/null
+++ b/linux-user/bfin/syscall_nr.h
@@ -0,0 +1,388 @@ 
+/*
+ * This file contains the system call numbers.
+ */
+#define TARGET_NR_restart_syscall	  0
+#define TARGET_NR_exit		  1
+#define TARGET_NR_fork		  2
+#define TARGET_NR_read		  3
+#define TARGET_NR_write		  4
+#define TARGET_NR_open		  5
+#define TARGET_NR_close		  6
+				/* 7 TARGET_NR_waitpid obsolete */
+#define TARGET_NR_creat		  8
+#define TARGET_NR_link		  9
+#define TARGET_NR_unlink		 10
+#define TARGET_NR_execve		 11
+#define TARGET_NR_chdir		 12
+#define TARGET_NR_time		 13
+#define TARGET_NR_mknod		 14
+#define TARGET_NR_chmod		 15
+#define TARGET_NR_chown		 16
+				/* 17 TARGET_NR_break obsolete */
+				/* 18 TARGET_NR_oldstat obsolete */
+#define TARGET_NR_lseek		 19
+#define TARGET_NR_getpid		 20
+#define TARGET_NR_mount		 21
+				/* 22 TARGET_NR_umount obsolete */
+#define TARGET_NR_setuid		 23
+#define TARGET_NR_getuid		 24
+#define TARGET_NR_stime		 25
+#define TARGET_NR_ptrace		 26
+#define TARGET_NR_alarm		 27
+				/* 28 TARGET_NR_oldfstat obsolete */
+#define TARGET_NR_pause		 29
+				/* 30 TARGET_NR_utime obsolete */
+				/* 31 TARGET_NR_stty obsolete */
+				/* 32 TARGET_NR_gtty obsolete */
+#define TARGET_NR_access		 33
+#define TARGET_NR_nice		 34
+				/* 35 TARGET_NR_ftime obsolete */
+#define TARGET_NR_sync		 36
+#define TARGET_NR_kill		 37
+#define TARGET_NR_rename		 38
+#define TARGET_NR_mkdir		 39
+#define TARGET_NR_rmdir		 40
+#define TARGET_NR_dup		 41
+#define TARGET_NR_pipe		 42
+#define TARGET_NR_times		 43
+				/* 44 TARGET_NR_prof obsolete */
+#define TARGET_NR_brk		 45
+#define TARGET_NR_setgid		 46
+#define TARGET_NR_getgid		 47
+				/* 48 TARGET_NR_signal obsolete */
+#define TARGET_NR_geteuid		 49
+#define TARGET_NR_getegid		 50
+#define TARGET_NR_acct		 51
+#define TARGET_NR_umount2		 52
+				/* 53 TARGET_NR_lock obsolete */
+#define TARGET_NR_ioctl		 54
+#define TARGET_NR_fcntl		 55
+				/* 56 TARGET_NR_mpx obsolete */
+#define TARGET_NR_setpgid		 57
+				/* 58 TARGET_NR_ulimit obsolete */
+				/* 59 TARGET_NR_oldolduname obsolete */
+#define TARGET_NR_umask		 60
+#define TARGET_NR_chroot		 61
+#define TARGET_NR_ustat		 62
+#define TARGET_NR_dup2		 63
+#define TARGET_NR_getppid		 64
+#define TARGET_NR_getpgrp		 65
+#define TARGET_NR_setsid		 66
+				/* 67 TARGET_NR_sigaction obsolete */
+#define TARGET_NR_sgetmask		 68
+#define TARGET_NR_ssetmask		 69
+#define TARGET_NR_setreuid		 70
+#define TARGET_NR_setregid		 71
+				/* 72 TARGET_NR_sigsuspend obsolete */
+				/* 73 TARGET_NR_sigpending obsolete */
+#define TARGET_NR_sethostname	 74
+#define TARGET_NR_setrlimit		 75
+				/* 76 TARGET_NR_old_getrlimit obsolete */
+#define TARGET_NR_getrusage		 77
+#define TARGET_NR_gettimeofday	 78
+#define TARGET_NR_settimeofday	 79
+#define TARGET_NR_getgroups		 80
+#define TARGET_NR_setgroups		 81
+				/* 82 TARGET_NR_select obsolete */
+#define TARGET_NR_symlink		 83
+				/* 84 TARGET_NR_oldlstat obsolete */
+#define TARGET_NR_readlink		 85
+				/* 86 TARGET_NR_uselib obsolete */
+				/* 87 TARGET_NR_swapon obsolete */
+#define TARGET_NR_reboot		 88
+				/* 89 TARGET_NR_readdir obsolete */
+				/* 90 TARGET_NR_mmap obsolete */
+#define TARGET_NR_munmap		 91
+#define TARGET_NR_truncate		 92
+#define TARGET_NR_ftruncate		 93
+#define TARGET_NR_fchmod		 94
+#define TARGET_NR_fchown		 95
+#define TARGET_NR_getpriority	 96
+#define TARGET_NR_setpriority	 97
+				/* 98 TARGET_NR_profil obsolete */
+#define TARGET_NR_statfs		 99
+#define TARGET_NR_fstatfs		100
+				/* 101 TARGET_NR_ioperm */
+				/* 102 TARGET_NR_socketcall obsolete */
+#define TARGET_NR_syslog		103
+#define TARGET_NR_setitimer		104
+#define TARGET_NR_getitimer		105
+#define TARGET_NR_stat		106
+#define TARGET_NR_lstat		107
+#define TARGET_NR_fstat		108
+				/* 109 TARGET_NR_olduname obsolete */
+				/* 110 TARGET_NR_iopl obsolete */
+#define TARGET_NR_vhangup		111
+				/* 112 TARGET_NR_idle obsolete */
+				/* 113 TARGET_NR_vm86old */
+#define TARGET_NR_wait4		114
+				/* 115 TARGET_NR_swapoff obsolete */
+#define TARGET_NR_sysinfo		116
+				/* 117 TARGET_NR_ipc oboslete */
+#define TARGET_NR_fsync		118
+				/* 119 TARGET_NR_sigreturn obsolete */
+#define TARGET_NR_clone		120
+#define TARGET_NR_setdomainname	121
+#define TARGET_NR_uname		122
+				/* 123 TARGET_NR_modify_ldt obsolete */
+#define TARGET_NR_adjtimex		124
+#define TARGET_NR_mprotect		125
+				/* 126 TARGET_NR_sigprocmask obsolete */
+				/* 127 TARGET_NR_create_module obsolete */
+#define TARGET_NR_init_module	128
+#define TARGET_NR_delete_module	129
+				/* 130 TARGET_NR_get_kernel_syms obsolete */
+#define TARGET_NR_quotactl		131
+#define TARGET_NR_getpgid		132
+#define TARGET_NR_fchdir		133
+#define TARGET_NR_bdflush		134
+				/* 135 was sysfs */
+#define TARGET_NR_personality	136
+				/* 137 TARGET_NR_afs_syscall */
+#define TARGET_NR_setfsuid		138
+#define TARGET_NR_setfsgid		139
+#define TARGET_NR__llseek		140
+#define TARGET_NR_getdents		141
+				/* 142 TARGET_NR__newselect obsolete */
+#define TARGET_NR_flock		143
+				/* 144 TARGET_NR_msync obsolete */
+#define TARGET_NR_readv		145
+#define TARGET_NR_writev		146
+#define TARGET_NR_getsid		147
+#define TARGET_NR_fdatasync		148
+#define TARGET_NR__sysctl		149
+				/* 150 TARGET_NR_mlock */
+				/* 151 TARGET_NR_munlock */
+				/* 152 TARGET_NR_mlockall */
+				/* 153 TARGET_NR_munlockall */
+#define TARGET_NR_sched_setparam		154
+#define TARGET_NR_sched_getparam		155
+#define TARGET_NR_sched_setscheduler		156
+#define TARGET_NR_sched_getscheduler		157
+#define TARGET_NR_sched_yield		158
+#define TARGET_NR_sched_get_priority_max	159
+#define TARGET_NR_sched_get_priority_min	160
+#define TARGET_NR_sched_rr_get_interval	161
+#define TARGET_NR_nanosleep		162
+#define TARGET_NR_mremap		163
+#define TARGET_NR_setresuid		164
+#define TARGET_NR_getresuid		165
+				/* 166 TARGET_NR_vm86 */
+				/* 167 TARGET_NR_query_module */
+				/* 168 TARGET_NR_poll */
+#define TARGET_NR_nfsservctl		169
+#define TARGET_NR_setresgid		170
+#define TARGET_NR_getresgid		171
+#define TARGET_NR_prctl		172
+#define TARGET_NR_rt_sigreturn	173
+#define TARGET_NR_rt_sigaction	174
+#define TARGET_NR_rt_sigprocmask	175
+#define TARGET_NR_rt_sigpending	176
+#define TARGET_NR_rt_sigtimedwait	177
+#define TARGET_NR_rt_sigqueueinfo	178
+#define TARGET_NR_rt_sigsuspend	179
+#define TARGET_NR_pread		180
+#define TARGET_NR_pwrite		181
+#define TARGET_NR_lchown		182
+#define TARGET_NR_getcwd		183
+#define TARGET_NR_capget		184
+#define TARGET_NR_capset		185
+#define TARGET_NR_sigaltstack	186
+#define TARGET_NR_sendfile		187
+				/* 188 TARGET_NR_getpmsg */
+				/* 189 TARGET_NR_putpmsg */
+#define TARGET_NR_vfork		190
+#define TARGET_NR_getrlimit		191
+#define TARGET_NR_mmap		192	/* xxx: this is mmap2 !? */
+#define TARGET_NR_truncate64		193
+#define TARGET_NR_ftruncate64	194
+#define TARGET_NR_stat64		195
+#define TARGET_NR_lstat64		196
+#define TARGET_NR_fstat64		197
+#define TARGET_NR_chown32		198
+#define TARGET_NR_getuid32		199
+#define TARGET_NR_getgid32		200
+#define TARGET_NR_geteuid32		201
+#define TARGET_NR_getegid32		202
+#define TARGET_NR_setreuid32		203
+#define TARGET_NR_setregid32		204
+#define TARGET_NR_getgroups32	205
+#define TARGET_NR_setgroups32	206
+#define TARGET_NR_fchown32		207
+#define TARGET_NR_setresuid32	208
+#define TARGET_NR_getresuid32	209
+#define TARGET_NR_setresgid32	210
+#define TARGET_NR_getresgid32	211
+#define TARGET_NR_lchown32		212
+#define TARGET_NR_setuid32		213
+#define TARGET_NR_setgid32		214
+#define TARGET_NR_setfsuid32		215
+#define TARGET_NR_setfsgid32		216
+#define TARGET_NR_pivot_root		217
+				/* 218 TARGET_NR_mincore */
+				/* 219 TARGET_NR_madvise */
+#define TARGET_NR_getdents64		220
+#define TARGET_NR_fcntl64		221
+				/* 222 reserved for TUX */
+				/* 223 reserved for TUX */
+#define TARGET_NR_gettid		224
+#define TARGET_NR_readahead		225
+#define TARGET_NR_setxattr		226
+#define TARGET_NR_lsetxattr		227
+#define TARGET_NR_fsetxattr		228
+#define TARGET_NR_getxattr		229
+#define TARGET_NR_lgetxattr		230
+#define TARGET_NR_fgetxattr		231
+#define TARGET_NR_listxattr		232
+#define TARGET_NR_llistxattr		233
+#define TARGET_NR_flistxattr		234
+#define TARGET_NR_removexattr	235
+#define TARGET_NR_lremovexattr	236
+#define TARGET_NR_fremovexattr	237
+#define TARGET_NR_tkill		238
+#define TARGET_NR_sendfile64		239
+#define TARGET_NR_futex		240
+#define TARGET_NR_sched_setaffinity	241
+#define TARGET_NR_sched_getaffinity	242
+				/* 243 TARGET_NR_set_thread_area */
+				/* 244 TARGET_NR_get_thread_area */
+#define TARGET_NR_io_setup		245
+#define TARGET_NR_io_destroy		246
+#define TARGET_NR_io_getevents	247
+#define TARGET_NR_io_submit		248
+#define TARGET_NR_io_cancel		249
+				/* 250 TARGET_NR_alloc_hugepages */
+				/* 251 TARGET_NR_free_hugepages */
+#define TARGET_NR_exit_group		252
+#define TARGET_NR_lookup_dcookie     253
+#define TARGET_NR_bfin_spinlock      254
+
+#define TARGET_NR_epoll_create	255
+#define TARGET_NR_epoll_ctl		256
+#define TARGET_NR_epoll_wait		257
+				/* 258 TARGET_NR_remap_file_pages */
+#define TARGET_NR_set_tid_address	259
+#define TARGET_NR_timer_create	260
+#define TARGET_NR_timer_settime	261
+#define TARGET_NR_timer_gettime	262
+#define TARGET_NR_timer_getoverrun	263
+#define TARGET_NR_timer_delete	264
+#define TARGET_NR_clock_settime	265
+#define TARGET_NR_clock_gettime	266
+#define TARGET_NR_clock_getres	267
+#define TARGET_NR_clock_nanosleep	268
+#define TARGET_NR_statfs64		269
+#define TARGET_NR_fstatfs64		270
+#define TARGET_NR_tgkill		271
+#define TARGET_NR_utimes		272
+#define TARGET_NR_fadvise64_64	273
+				/* 274 TARGET_NR_vserver */
+				/* 275 TARGET_NR_mbind */
+				/* 276 TARGET_NR_get_mempolicy */
+				/* 277 TARGET_NR_set_mempolicy */
+#define TARGET_NR_mq_open 		278
+#define TARGET_NR_mq_unlink		279
+#define TARGET_NR_mq_timedsend	280
+#define TARGET_NR_mq_timedreceive	281
+#define TARGET_NR_mq_notify		282
+#define TARGET_NR_mq_getsetattr	283
+#define TARGET_NR_kexec_load		284
+#define TARGET_NR_waitid		285
+#define TARGET_NR_add_key		286
+#define TARGET_NR_request_key	287
+#define TARGET_NR_keyctl		288
+#define TARGET_NR_ioprio_set		289
+#define TARGET_NR_ioprio_get		290
+#define TARGET_NR_inotify_init	291
+#define TARGET_NR_inotify_add_watch	292
+#define TARGET_NR_inotify_rm_watch	293
+				/* 294 TARGET_NR_migrate_pages */
+#define TARGET_NR_openat		295
+#define TARGET_NR_mkdirat		296
+#define TARGET_NR_mknodat		297
+#define TARGET_NR_fchownat		298
+#define TARGET_NR_futimesat		299
+#define TARGET_NR_fstatat64		300
+#define TARGET_NR_unlinkat		301
+#define TARGET_NR_renameat		302
+#define TARGET_NR_linkat		303
+#define TARGET_NR_symlinkat		304
+#define TARGET_NR_readlinkat		305
+#define TARGET_NR_fchmodat		306
+#define TARGET_NR_faccessat		307
+#define TARGET_NR_pselect6		308
+#define TARGET_NR_ppoll		309
+#define TARGET_NR_unshare		310
+
+/* Blackfin private syscalls */
+#define TARGET_NR_sram_alloc		311
+#define TARGET_NR_sram_free		312
+#define TARGET_NR_dma_memcpy		313
+
+/* socket syscalls */
+#define TARGET_NR_accept		314
+#define TARGET_NR_bind		315
+#define TARGET_NR_connect		316
+#define TARGET_NR_getpeername	317
+#define TARGET_NR_getsockname	318
+#define TARGET_NR_getsockopt		319
+#define TARGET_NR_listen		320
+#define TARGET_NR_recv		321
+#define TARGET_NR_recvfrom		322
+#define TARGET_NR_recvmsg		323
+#define TARGET_NR_send		324
+#define TARGET_NR_sendmsg		325
+#define TARGET_NR_sendto		326
+#define TARGET_NR_setsockopt		327
+#define TARGET_NR_shutdown		328
+#define TARGET_NR_socket		329
+#define TARGET_NR_socketpair		330
+
+/* sysv ipc syscalls */
+#define TARGET_NR_semctl		331
+#define TARGET_NR_semget		332
+#define TARGET_NR_semop		333
+#define TARGET_NR_msgctl		334
+#define TARGET_NR_msgget		335
+#define TARGET_NR_msgrcv		336
+#define TARGET_NR_msgsnd		337
+#define TARGET_NR_shmat		338
+#define TARGET_NR_shmctl		339
+#define TARGET_NR_shmdt		340
+#define TARGET_NR_shmget		341
+
+#define TARGET_NR_splice		342
+#define TARGET_NR_sync_file_range	343
+#define TARGET_NR_tee		344
+#define TARGET_NR_vmsplice		345
+
+#define TARGET_NR_epoll_pwait	346
+#define TARGET_NR_utimensat		347
+#define TARGET_NR_signalfd		348
+#define TARGET_NR_timerfd_create	349
+#define TARGET_NR_eventfd		350
+#define TARGET_NR_pread64		351
+#define TARGET_NR_pwrite64		352
+#define TARGET_NR_fadvise64		353
+#define TARGET_NR_set_robust_list	354
+#define TARGET_NR_get_robust_list	355
+#define TARGET_NR_fallocate		356
+#define TARGET_NR_semtimedop		357
+#define TARGET_NR_timerfd_settime	358
+#define TARGET_NR_timerfd_gettime	359
+#define TARGET_NR_signalfd4		360
+#define TARGET_NR_eventfd2		361
+#define TARGET_NR_epoll_create1		362
+#define TARGET_NR_dup3			363
+#define TARGET_NR_pipe2			364
+#define TARGET_NR_inotify_init1		365
+#define TARGET_NR_preadv		366
+#define TARGET_NR_pwritev		367
+#define TARGET_NR_rt_tgsigqueueinfo	368
+#define TARGET_NR_perf_event_open	369
+#define TARGET_NR_recvmmsg		370
+#define TARGET_NR_fanotify_init	371
+#define TARGET_NR_fanotify_mark	372
+#define TARGET_NR_prlimit64		373
+
+#define TARGET_NR_syscall		374
diff --git a/linux-user/bfin/target_flat.h b/linux-user/bfin/target_flat.h
new file mode 100644
index 0000000..3ba18ac
--- /dev/null
+++ b/linux-user/bfin/target_flat.h
@@ -0,0 +1,91 @@ 
+/*
+ * uClinux flat-format executables
+ *
+ * Copyright 2003-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2
+ */
+
+#define FLAT_BFIN_RELOC_TYPE_16_BIT  0
+#define FLAT_BFIN_RELOC_TYPE_16H_BIT 1
+#define FLAT_BFIN_RELOC_TYPE_32_BIT  2
+
+#define flat_reloc_valid(reloc, size)             ((reloc) <= (size))
+#define flat_old_ram_flag(flag)                   (flag)
+#define flat_get_relocate_addr(relval)            ((relval) & 0x03ffffff)
+
+static inline int flat_set_persistent(abi_ulong relval, abi_ulong *persistent)
+{
+    int type = (relval >> 26) & 7;
+    if (type == 3) {
+        *persistent = relval << 16;
+        return 1;
+    }
+    return 0;
+}
+
+static abi_ulong
+flat_get_addr_from_rp(abi_ulong ul_ptr, abi_ulong relval, abi_ulong flags, abi_ulong *persistent)
+{
+    int type = (relval >> 26) & 7;
+    abi_ulong val;
+
+#ifdef DEBUG
+    printf("%s:%i: ptr:%8x relval:%8x type:%x flags:%x persistent:%x",
+           __func__, __LINE__, ul_ptr, relval, type, flags, *persistent);
+#endif
+
+    switch (type) {
+    case FLAT_BFIN_RELOC_TYPE_16_BIT:
+    case FLAT_BFIN_RELOC_TYPE_16H_BIT:
+        if (get_user_u16(val, ul_ptr)) {
+            fprintf(stderr, "BINFMT_FLAT: unable to read reloc at %#x\n", ul_ptr);
+            abort();
+        }
+        val += *persistent;
+        break;
+    case FLAT_BFIN_RELOC_TYPE_32_BIT:
+        if (get_user_u32(val, ul_ptr)) {
+            fprintf(stderr, "BINFMT_FLAT: unable to read reloc at %#x\n", ul_ptr);
+            abort();
+        }
+        break;
+    default:
+        fprintf(stderr, "BINFMT_FLAT: Unknown relocation type %x\n", type);
+        abort();
+        break;
+    }
+#ifdef DEBUG
+    printf(" val:%x\n", val);
+#endif
+
+    /*
+     * Stack-relative relocs contain the offset into the stack, we
+     * have to add the stack's start address here and return 1 from
+     * flat_addr_absolute to prevent the normal address calculations
+     */
+    if (relval & (1 << 29)) {
+        fprintf(stderr, "BINFMT_FLAT: stack relocs not supported\n");
+        abort();
+        /*return val + current->mm->context.end_brk;*/
+    }
+
+    if ((flags & FLAT_FLAG_GOTPIC) == 0)
+        val = ntohl(val);
+
+    return val;
+}
+
+static int
+flat_put_addr_at_rp(abi_ulong ptr, abi_ulong addr, abi_ulong relval)
+{
+    int type = (relval >> 26) & 7;
+
+    switch (type) {
+    case FLAT_BFIN_RELOC_TYPE_16_BIT:  return put_user_u16(addr, ptr);
+    case FLAT_BFIN_RELOC_TYPE_16H_BIT: return put_user_u16(addr >> 16, ptr);
+    case FLAT_BFIN_RELOC_TYPE_32_BIT:  return put_user_u32(addr, ptr);
+    }
+
+    abort();
+}
diff --git a/linux-user/bfin/target_signal.h b/linux-user/bfin/target_signal.h
new file mode 100644
index 0000000..ba931d5
--- /dev/null
+++ b/linux-user/bfin/target_signal.h
@@ -0,0 +1,29 @@ 
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+	abi_ulong ss_sp;
+	abi_long ss_flags;
+	abi_ulong ss_size;
+} target_stack_t;
+
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK	1
+#define TARGET_SS_DISABLE	2
+
+#define TARGET_MINSIGSTKSZ	2048
+#define TARGET_SIGSTKSZ		8192
+
+static inline abi_ulong get_sp_from_cpustate(CPUState *env)
+{
+	return env->fpreg;
+}
+
+#endif /* TARGET_SIGNAL_H */
diff --git a/linux-user/bfin/termbits.h b/linux-user/bfin/termbits.h
new file mode 100644
index 0000000..5c5fa01
--- /dev/null
+++ b/linux-user/bfin/termbits.h
@@ -0,0 +1,227 @@ 
+/* from asm/termbits.h */
+/* NOTE: exactly the same as i386 */
+
+#define TARGET_NCCS 19
+
+struct target_termios {
+    uint32_t c_iflag;               /* input mode flags */
+    uint32_t c_oflag;               /* output mode flags */
+    uint32_t c_cflag;               /* control mode flags */
+    uint32_t c_lflag;               /* local mode flags */
+    uint8_t c_line;                    /* line discipline */
+    uint8_t c_cc[TARGET_NCCS];                /* control characters */
+};
+
+/* c_iflag bits */
+#define TARGET_IGNBRK  0000001
+#define TARGET_BRKINT  0000002
+#define TARGET_IGNPAR  0000004
+#define TARGET_PARMRK  0000010
+#define TARGET_INPCK   0000020
+#define TARGET_ISTRIP  0000040
+#define TARGET_INLCR   0000100
+#define TARGET_IGNCR   0000200
+#define TARGET_ICRNL   0000400
+#define TARGET_IUCLC   0001000
+#define TARGET_IXON    0002000
+#define TARGET_IXANY   0004000
+#define TARGET_IXOFF   0010000
+#define TARGET_IMAXBEL 0020000
+#define TARGET_IUTF8   0040000
+
+/* c_oflag bits */
+#define TARGET_OPOST   0000001
+#define TARGET_OLCUC   0000002
+#define TARGET_ONLCR   0000004
+#define TARGET_OCRNL   0000010
+#define TARGET_ONOCR   0000020
+#define TARGET_ONLRET  0000040
+#define TARGET_OFILL   0000100
+#define TARGET_OFDEL   0000200
+#define TARGET_NLDLY   0000400
+#define   TARGET_NL0   0000000
+#define   TARGET_NL1   0000400
+#define TARGET_CRDLY   0003000
+#define   TARGET_CR0   0000000
+#define   TARGET_CR1   0001000
+#define   TARGET_CR2   0002000
+#define   TARGET_CR3   0003000
+#define TARGET_TABDLY  0014000
+#define   TARGET_TAB0  0000000
+#define   TARGET_TAB1  0004000
+#define   TARGET_TAB2  0010000
+#define   TARGET_TAB3  0014000
+#define   TARGET_XTABS 0014000
+#define TARGET_BSDLY   0020000
+#define   TARGET_BS0   0000000
+#define   TARGET_BS1   0020000
+#define TARGET_VTDLY   0040000
+#define   TARGET_VT0   0000000
+#define   TARGET_VT1   0040000
+#define TARGET_FFDLY   0100000
+#define   TARGET_FF0   0000000
+#define   TARGET_FF1   0100000
+
+/* c_cflag bit meaning */
+#define TARGET_CBAUD   0010017
+#define  TARGET_B0     0000000         /* hang up */
+#define  TARGET_B50    0000001
+#define  TARGET_B75    0000002
+#define  TARGET_B110   0000003
+#define  TARGET_B134   0000004
+#define  TARGET_B150   0000005
+#define  TARGET_B200   0000006
+#define  TARGET_B300   0000007
+#define  TARGET_B600   0000010
+#define  TARGET_B1200  0000011
+#define  TARGET_B1800  0000012
+#define  TARGET_B2400  0000013
+#define  TARGET_B4800  0000014
+#define  TARGET_B9600  0000015
+#define  TARGET_B19200 0000016
+#define  TARGET_B38400 0000017
+#define TARGET_EXTA B19200
+#define TARGET_EXTB B38400
+#define TARGET_CSIZE   0000060
+#define   TARGET_CS5   0000000
+#define   TARGET_CS6   0000020
+#define   TARGET_CS7   0000040
+#define   TARGET_CS8   0000060
+#define TARGET_CSTOPB  0000100
+#define TARGET_CREAD   0000200
+#define TARGET_PARENB  0000400
+#define TARGET_PARODD  0001000
+#define TARGET_HUPCL   0002000
+#define TARGET_CLOCAL  0004000
+#define TARGET_CBAUDEX 0010000
+#define  TARGET_B57600  0010001
+#define  TARGET_B115200 0010002
+#define  TARGET_B230400 0010003
+#define  TARGET_B460800 0010004
+#define  TARGET_B500000 0010005
+#define  TARGET_B576000 0010006
+#define  TARGET_B921600 0010007
+#define  TARGET_B1000000 0010010
+#define  TARGET_B1152000 0010011
+#define  TARGET_B1500000 0010012
+#define  TARGET_B2000000 0010013
+#define  TARGET_B2500000 0010014
+#define  TARGET_B3000000 0010015
+#define  TARGET_B3500000 0010016
+#define  TARGET_B4000000 0010017
+#define TARGET_CIBAUD    002003600000  /* input baud rate (not used) */
+#define TARGET_CMSPAR    010000000000  /* mark or space (stick) parity */
+#define TARGET_CRTSCTS   020000000000  /* flow control */
+
+/* c_lflag bits */
+#define TARGET_ISIG    0000001
+#define TARGET_ICANON  0000002
+#define TARGET_XCASE   0000004
+#define TARGET_ECHO    0000010
+#define TARGET_ECHOE   0000020
+#define TARGET_ECHOK   0000040
+#define TARGET_ECHONL  0000100
+#define TARGET_NOFLSH  0000200
+#define TARGET_TOSTOP  0000400
+#define TARGET_ECHOCTL 0001000
+#define TARGET_ECHOPRT 0002000
+#define TARGET_ECHOKE  0004000
+#define TARGET_FLUSHO  0010000
+#define TARGET_PENDIN  0040000
+#define TARGET_IEXTEN  0100000
+
+/* c_cc character offsets */
+#define TARGET_VINTR	0
+#define TARGET_VQUIT	1
+#define TARGET_VERASE	2
+#define TARGET_VKILL	3
+#define TARGET_VEOF	4
+#define TARGET_VTIME	5
+#define TARGET_VMIN	6
+#define TARGET_VSWTC	7
+#define TARGET_VSTART	8
+#define TARGET_VSTOP	9
+#define TARGET_VSUSP	10
+#define TARGET_VEOL	11
+#define TARGET_VREPRINT	12
+#define TARGET_VDISCARD	13
+#define TARGET_VWERASE	14
+#define TARGET_VLNEXT	15
+#define TARGET_VEOL2	16
+
+/* ioctls */
+
+#define TARGET_TCGETS		0x5401
+#define TARGET_TCSETS		0x5402
+#define TARGET_TCSETSW		0x5403
+#define TARGET_TCSETSF		0x5404
+#define TARGET_TCGETA		0x5405
+#define TARGET_TCSETA		0x5406
+#define TARGET_TCSETAW		0x5407
+#define TARGET_TCSETAF		0x5408
+#define TARGET_TCSBRK		0x5409
+#define TARGET_TCXONC		0x540A
+#define TARGET_TCFLSH		0x540B
+
+#define TARGET_TIOCEXCL	0x540C
+#define TARGET_TIOCNXCL	0x540D
+#define TARGET_TIOCSCTTY	0x540E
+#define TARGET_TIOCGPGRP	0x540F
+#define TARGET_TIOCSPGRP	0x5410
+#define TARGET_TIOCOUTQ	0x5411
+#define TARGET_TIOCSTI		0x5412
+#define TARGET_TIOCGWINSZ	0x5413
+#define TARGET_TIOCSWINSZ	0x5414
+#define TARGET_TIOCMGET	0x5415
+#define TARGET_TIOCMBIS	0x5416
+#define TARGET_TIOCMBIC	0x5417
+#define TARGET_TIOCMSET	0x5418
+#define TARGET_TIOCGSOFTCAR	0x5419
+#define TARGET_TIOCSSOFTCAR	0x541A
+#define TARGET_FIONREAD	0x541B
+#define TARGET_TIOCINQ		TARGET_FIONREAD
+#define TARGET_TIOCLINUX	0x541C
+#define TARGET_TIOCCONS	0x541D
+#define TARGET_TIOCGSERIAL	0x541E
+#define TARGET_TIOCSSERIAL	0x541F
+#define TARGET_TIOCPKT		0x5420
+#define TARGET_FIONBIO		0x5421
+#define TARGET_TIOCNOTTY	0x5422
+#define TARGET_TIOCSETD	0x5423
+#define TARGET_TIOCGETD	0x5424
+#define TARGET_TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TARGET_TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define TARGET_TIOCSBRK	0x5427  /* BSD compatibility */
+#define TARGET_TIOCCBRK	0x5428  /* BSD compatibility */
+#define TARGET_TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TARGET_TIOCGPTN	TARGET_IOR('T',0x30, uint32_t) /* Get Pty Number (of pty-mux device) */
+#define TARGET_TIOCSPTLCK	TARGET_IOW('T',0x31, int32_t)  /* Lock/unlock Pty */
+
+#define TARGET_FIONCLEX	0x5450  /* these numbers need to be adjusted. */
+#define TARGET_FIOCLEX		0x5451
+#define TARGET_FIOASYNC	0x5452
+#define TARGET_TIOCSERCONFIG	0x5453
+#define TARGET_TIOCSERGWILD	0x5454
+#define TARGET_TIOCSERSWILD	0x5455
+#define TARGET_TIOCGLCKTRMIOS	0x5456
+#define TARGET_TIOCSLCKTRMIOS	0x5457
+#define TARGET_TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TARGET_TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TARGET_TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TARGET_TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define TARGET_TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
+#define TARGET_TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
+
+/* Used for packet mode */
+#define TARGET_TIOCPKT_DATA		 0
+#define TARGET_TIOCPKT_FLUSHREAD	 1
+#define TARGET_TIOCPKT_FLUSHWRITE	 2
+#define TARGET_TIOCPKT_STOP		 4
+#define TARGET_TIOCPKT_START		 8
+#define TARGET_TIOCPKT_NOSTOP		16
+#define TARGET_TIOCPKT_DOSTOP		32
+
+#define TARGET_TIOCSER_TEMT    0x01	/* Transmitter physically empty */
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 8c6d448..b011345 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -772,6 +772,45 @@  static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
 
 #endif
 
+#ifdef TARGET_BFIN
+
+#define ELF_START_MMAP 0x00000000
+
+#define elf_check_arch(x) ( (x) == EM_BLACKFIN )
+#define elf_is_fdpic(e)   ( (e)->e_flags & EF_BFIN_FDPIC )
+
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2LSB
+#define ELF_ARCH	EM_BLACKFIN
+
+static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
+{
+	if (infop->personality == PER_LINUX_FDPIC) {
+		if (infop->other_info) {
+			/* dynamic */
+			regs->p0 = tswapl(infop->loadmap_addr);
+			regs->p1 = tswapl(infop->other_info->loadmap_addr);
+			regs->p2 = tswapl(infop->other_info->pt_dynamic_addr);
+		} else {
+			/* static */
+			regs->p0 = tswapl(infop->loadmap_addr);
+			regs->p1 = 0;
+			regs->p2 = tswapl(infop->pt_dynamic_addr);
+		}
+		regs->r7 = 0;
+	}
+	regs->pc = tswapl(infop->entry);
+	regs->usp = tswapl(infop->start_stack);
+}
+
+#define ELF_EXEC_PAGESIZE	4096
+
+/* See linux kernel: arch/blackfin/include/asm/elf.h.  */
+#define ELF_NREG 40
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
+
+#endif
+
 #ifdef TARGET_ALPHA
 
 #define ELF_START_MMAP (0x30000000000ULL)
diff --git a/linux-user/main.c b/linux-user/main.c
index 0d627d6..b075791 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2380,6 +2380,79 @@  void cpu_loop(CPUM68KState *env)
 }
 #endif /* TARGET_M68K */
 
+#ifdef TARGET_BFIN
+
+void cpu_loop(CPUState *env)
+{
+    int trapnr;
+    target_siginfo_t info;
+
+    for (;;) {
+        trapnr = cpu_exec(env);
+
+        switch (trapnr) {
+        case EXCP_SYSCALL:
+            env->pc += 2;
+            env->dreg[0] = do_syscall(env,
+                                      env->preg[0],
+                                      env->dreg[0],
+                                      env->dreg[1],
+                                      env->dreg[2],
+                                      env->dreg[3],
+                                      env->dreg[4],
+                                      env->dreg[5]);
+            break;
+        case EXCP_INTERRUPT:
+            /* just indicate that signals should be handled asap */
+            break;
+        case EXCP_DEBUG:
+            {
+                int sig;
+
+                sig = gdb_handlesig(env, TARGET_SIGTRAP);
+                if (sig)
+                  {
+                    info.si_signo = sig;
+                    info.si_errno = 0;
+                    info.si_code = TARGET_TRAP_BRKPT;
+                    queue_signal(env, info.si_signo, &info);
+                  }
+            }
+            break;
+        case EXCP_HLT:
+            do_syscall(env, TARGET_NR_exit, 0, 0, 0, 0, 0, 0);
+            break;
+        case EXCP_ABORT:
+            do_syscall(env, TARGET_NR_exit, 1, 0, 0, 0, 0, 0);
+            break;
+        case EXCP_DBGA:
+            fprintf(stderr, "qemu: DBGA failed\n");
+            cpu_dump_state(env, stderr, fprintf, 0);
+            abort();
+        case EXCP_UNDEF_INST:
+            fprintf(stderr, "qemu: unhandled insn @ %#x\n", env->pc);
+            log_target_disas(env->pc, 8, 0);
+            exit(1);
+        case EXCP_DCPLB_VIOLATE:
+            fprintf(stderr, "qemu: memory violation @ %#x\n", env->pc);
+            log_target_disas(env->pc, 8, 0);
+            exit(1);
+        case EXCP_ILL_SUPV:
+            fprintf(stderr, "qemu: supervisor mode required @ %#x\n", env->pc);
+            log_target_disas(env->pc, 8, 0);
+            exit(1);
+        default:
+            fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
+                    trapnr);
+            cpu_dump_state(env, stderr, fprintf, 0);
+            abort();
+        }
+        process_pending_signals(env);
+    }
+}
+
+#endif
+
 #ifdef TARGET_ALPHA
 static void do_store_exclusive(CPUAlphaState *env, int reg, int quad)
 {
@@ -3324,6 +3397,28 @@  int main(int argc, char **argv, char **envp)
         }
         env->pc = regs->pc;
     }
+#elif defined(TARGET_BFIN)
+    {
+#warning show restore all the regs i think
+        env->dreg[0] = regs->r0;
+        env->dreg[1] = regs->r1;
+        env->dreg[2] = regs->r2;
+        env->dreg[3] = regs->r3;
+        env->dreg[4] = regs->r4;
+        env->dreg[5] = regs->r5;
+        env->dreg[6] = regs->r6;
+        env->dreg[7] = regs->r7;
+        env->preg[0] = regs->p0;
+        env->preg[1] = regs->p1;
+        env->preg[2] = regs->p2;
+        env->preg[3] = regs->p3;
+        env->preg[4] = regs->p4;
+        env->preg[5] = regs->p5;
+        env->spreg = regs->usp;
+        env->fpreg = regs->fp;
+        env->uspreg = regs->usp;
+        env->pc = regs->pc;
+    }
 #elif defined(TARGET_ALPHA)
     {
         int i;
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 250814d..d825f9c 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -26,6 +26,10 @@ 
 #define THREAD
 #endif
 
+#ifdef TARGET_BFIN
+#define CONFIG_USE_FDPIC
+#endif
+
 /* This struct is used to hold certain information about the image.
  * Basically, it replicates in user space what would be certain
  * task_struct fields in the kernel
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 4742ac0..e5e2262 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -55,7 +55,7 @@ 
 #endif
 
 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \
-    || defined(TARGET_M68K) || defined(TARGET_CRIS)
+    || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_BFIN)
 
 #define TARGET_IOC_SIZEBITS	14
 #define TARGET_IOC_DIRBITS	2
@@ -315,7 +315,7 @@  struct target_sigaction;
 int do_sigaction(int sig, const struct target_sigaction *act,
                  struct target_sigaction *oact);
 
-#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) || defined(TARGET_BFIN)
 
 #if defined(TARGET_SPARC)
 #define TARGET_SA_NOCLDSTOP    8u
@@ -1552,6 +1552,67 @@  struct target_stat64 {
 	int64_t  	st_blocks;
 };
 
+#elif defined(TARGET_BFIN)
+
+struct target_stat {
+	unsigned short st_dev;
+	unsigned short __pad1;
+	abi_ulong st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned short __pad2;
+	abi_ulong st_size;
+	abi_ulong st_blksize;
+	abi_ulong st_blocks;
+	abi_ulong target_st_atime;
+	abi_ulong __unused1;
+	abi_ulong target_st_mtime;
+	abi_ulong __unused2;
+	abi_ulong target_st_ctime;
+	abi_ulong __unused3;
+	abi_ulong __unused4;
+	abi_ulong __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct target_stat64 {
+	uint64_t st_dev;
+	unsigned char __pad1[4];
+
+#define STAT64_HAS_BROKEN_ST_INO	1
+	abi_ulong __st_ino;
+
+	unsigned int st_mode;
+	unsigned int st_nlink;
+
+	abi_ulong st_uid;
+	abi_ulong st_gid;
+
+	uint64_t st_rdev;
+	unsigned char __pad2[4];
+
+	int64_t st_size;
+	abi_ulong st_blksize;
+
+	int64_t st_blocks;	/* Number 512-byte blocks allocated. */
+
+	abi_ulong target_st_atime;
+	abi_ulong target_st_atime_nsec;
+
+	abi_ulong target_st_mtime;
+	abi_ulong target_st_mtime_nsec;
+
+	abi_ulong target_st_ctime;
+	abi_ulong target_st_ctime_nsec;
+
+	uint64_t st_ino;
+};
+
 #elif defined(TARGET_ALPHA)
 
 struct target_stat {