Merge pull request #77 from WinterMute/mingw

Changes to allow compiling for windows using mingw toolchains
pull/79/merge
texane 2012-05-14 08:18:46 -07:00
commit d2c78b96e0
18 zmienionych plików z 679 dodań i 106 usunięć

45
.gitignore vendored
Wyświetl plik

@ -1,18 +1,29 @@
nbproject
.project
COPYING
INSTALL
Makefile.in
aclocal.m4
autom4te.cache
config.guess
config.sub
configure
depcomp
install-sh
ltmain.sh
missing
*.bz2
*.lo
*.o
*.elf
doc/tutorial/*.log
doc/tutorial/*.aux
libstlink.a
test_usb
test_sg
gdbserver/st-util
flash/flash
*.log
example/*/*.bin
example/*/*.elf
example/*/*/*.bin
example/*/*/*/*.bin
example/*/*/*.a
example/*/*/*/*.a
.libs
libtool
*.la
config.log
config.status
compile
st-flash
st-util
*.deps*
*.dirstamp
*.a
Makefile
*.exe
example/blink/*.elf

0
ChangeLog 100644
Wyświetl plik

Wyświetl plik

@ -1,58 +0,0 @@
# make ... for both stlink v1 and stlink v2 support
##
VPATH=src
SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c uglylogging.c
OBJS_LIB=$(SOURCES_LIB:.c=.o)
TEST_PROGRAMS=test_usb test_sg
LDFLAGS=-L. -lstlink
# libusb location
LDFLAGS+=`pkg-config --libs libusb-1.0`
CFLAGS+=`pkg-config --cflags libusb-1.0`
CFLAGS+=-g
CFLAGS+=-DDEBUG=1
CFLAGS+=-std=gnu99
CFLAGS+=-Wall -Wextra
LIBRARY=libstlink.a
all: $(LIBRARY) flash gdbserver $(TEST_PROGRAMS)
$(LIBRARY): $(OBJS_LIB)
@echo "objs are $(OBJS_LIB)"
$(AR) -cr $@ $^
@echo "done making library"
test_sg: test_sg.o $(LIBRARY)
@echo "building test_sg"
$(CC) test_sg.o $(LDFLAGS) -o $@
test_usb: test_usb.o $(LIBRARY)
@echo "building test_usb"
$(CC) test_usb.o $(LDFLAGS) -o $@
@echo "done linking"
%.o: %.c
@echo "building $^ into $@"
$(CC) $(CFLAGS) -c $^ -o $@
@echo "done compiling"
clean:
rm -rf $(OBJS_LIB)
rm -rf $(LIBRARY)
rm -rf test_usb*
rm -rf test_sg*
$(MAKE) -C flash clean
$(MAKE) -C gdbserver clean
flash:
$(MAKE) -C flash
gdbserver:
$(MAKE) -C gdbserver CONFIG_USE_LIBSG="$(CONFIG_USE_LIBSG)"
.PHONY: clean all flash gdbserver

37
Makefile.am 100644
Wyświetl plik

@ -0,0 +1,37 @@
# Makefile.am -- Process this file with automake to produce Makefile.in
AUTOMAKE_OPTIONS = subdir-objects
bin_PROGRAMS = st-flash st-util
noinst_LIBRARIES = libstlink.a
st_flash_SOURCES = flash/main.c
st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c mingw/mingw.c mingw/mingw.h
CFILES = \
src/stlink-common.c \
src/stlink-usb.c \
src/stlink-sg.c \
src/uglylogging.c
HFILES = \
src/stlink-common.h \
src/stlink-usb.h \
src/stlink-sg.h \
src/uglylogging.h \
src/mmap.h
libstlink_a_SOURCES = $(CFILES) $(HFILES)
libstlink_a_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2
libstlink_a_LIBADD = $(LIBOBJS)
st_flash_LDADD = libstlink.a
st_flash_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw
st_util_LDADD = libstlink.a
st_util_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw
EXTRA_DIST = autogen.sh

0
NEWS 100644
Wyświetl plik

2
autogen.sh 100755
Wyświetl plik

@ -0,0 +1,2 @@
#!/bin/sh
autoreconf --install --force --verbose

40
configure.ac 100644
Wyświetl plik

@ -0,0 +1,40 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
AC_INIT([stlink],[0.5.2],[davem@devkitpro.org])
AC_CONFIG_SRCDIR([src/stlink-common.c])
AC_CONFIG_LIBOBJ_DIR([src])
AM_INIT_AUTOMAKE([1.10])
# Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
AC_CANONICAL_HOST
AC_CANONICAL_BUILD
AC_PROG_RANLIB
AM_PROG_CC_C_O
AC_CHECK_HEADERS(sys/mman.h)
AC_CHECK_HEADERS(sys/poll.h)
AC_CHECK_FUNCS(mmap)
AC_REPLACE_FUNCS(mmap pread)
# Checks for libraries.
PKG_CHECK_MODULES(USB, libusb-1.0 >= 1.0.0,,
AC_MSG_ERROR([*** Required libusb-1.0 >= 1.0.0 not installed ***]))
AC_CHECK_LIB([usbpath],[usb_path2devnum],,,-lusb)
LIBS="$LIBS $USB_LIBS"
CFLAGS="$CFLAGS $USB_CFLAGS"
case "${host}" in
*-mingw32*)
LIBS="$LIBS -lws2_32"
CPPFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CPPFLAGS"
;;
esac
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

Wyświetl plik

@ -1,7 +1,7 @@
/* missing type */
typedef unsigned int uint32_t;
void main(void);
/* hardware configuration */

Wyświetl plik

@ -11,12 +11,16 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#ifdef __MINGW32__
#include "mingw.h"
#else
#include <sys/poll.h>
#endif
static const char hex[] = "0123456789abcdef";
int gdb_send_packet(int fd, char* data) {
unsigned length = strlen(data) + 5;
int length = strlen(data) + 5;
char* packet = malloc(length); /* '$' data (hex) '#' cksum (hex) */
memset(packet, 0, length);
@ -24,7 +28,7 @@ int gdb_send_packet(int fd, char* data) {
packet[0] = '$';
uint8_t cksum = 0;
for(int i = 0; i < strlen(data); i++) {
for(unsigned int i = 0; i < strlen(data); i++) {
packet[i + 1] = data[i];
cksum += data[i];
}

Wyświetl plik

@ -12,10 +12,14 @@
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#ifdef __MINGW32__
#include "mingw.h"
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#endif
#include <stlink-common.h>
@ -166,8 +170,20 @@ int main(int argc, char** argv) {
current_memory_map = make_memory_map(sl);
#ifdef __MINGW32__
WSADATA wsadata;
if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0 ) {
goto winsock_error;
}
#endif
while(serve(sl, state.listen_port) == 0);
#ifdef __MINGW32__
winsock_error:
WSACleanup();
#endif
/* Switch back to mass storage mode before closing. */
stlink_run(sl);
stlink_exit_debug_mode(sl);
@ -204,15 +220,15 @@ static const char* const memory_map_template =
"<!DOCTYPE memory-map PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\""
" \"http://sourceware.org/gdb/gdb-memory-map.dtd\">"
"<memory-map>"
" <memory type=\"rom\" start=\"0x00000000\" length=\"0x%x\"/>" // code = sram, bootrom or flash; flash is bigger
" <memory type=\"ram\" start=\"0x20000000\" length=\"0x%x\"/>" // sram 8k
" <memory type=\"flash\" start=\"0x08000000\" length=\"0x%x\">"
" <property name=\"blocksize\">0x%x</property>"
" <memory type=\"rom\" start=\"0x00000000\" length=\"0x%zx\"/>" // code = sram, bootrom or flash; flash is bigger
" <memory type=\"ram\" start=\"0x20000000\" length=\"0x%zx\"/>" // sram 8k
" <memory type=\"flash\" start=\"0x08000000\" length=\"0x%zx\">"
" <property name=\"blocksize\">0x%zx</property>"
" </memory>"
" <memory type=\"ram\" start=\"0x40000000\" length=\"0x1fffffff\"/>" // peripheral regs
" <memory type=\"ram\" start=\"0xe0000000\" length=\"0x1fffffff\"/>" // cortex regs
" <memory type=\"rom\" start=\"0x%08x\" length=\"0x%x\"/>" // bootrom
" <memory type=\"rom\" start=\"0x1ffff800\" length=\"0x8\"/>" // option byte area
" <memory type=\"rom\" start=\"0x%08x\" length=\"0x%zx\"/>" // bootrom
" <memory type=\"rom\" start=\"0x1ffff800\" length=\"0x8x\"/>" // option byte area
"</memory-map>";
char* make_memory_map(stlink_t *sl) {
@ -292,7 +308,7 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr
mask++;
}
if((mask != -1) && (mask < 16)) {
if((mask != (uint32_t)-1) && (mask < 16)) {
for(i = 0; i < DATA_WATCH_NUM; i++) {
// is this an empty slot ?
if(data_watches[i].fun == WATCHDISABLED) {
@ -462,7 +478,7 @@ static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) {
}
static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) {
int fit_blocks = 0, fit_length = 0;
unsigned int fit_blocks = 0, fit_length = 0;
for(struct flash_block* fb = flash_root; fb; fb = fb->next) {
/* Block: ------X------Y--------
@ -552,9 +568,10 @@ int serve(stlink_t *sl, int port) {
}
unsigned int val = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
struct sockaddr_in serv_addr = {0};
struct sockaddr_in serv_addr;
memset(&serv_addr,0,sizeof(struct sockaddr_in));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv_addr.sin_port = htons(port);
@ -577,7 +594,7 @@ int serve(stlink_t *sl, int port) {
printf("Listening at *:%d...\n", port);
int client = accept(sock, NULL, NULL);
signal (SIGINT, SIG_DFL);
//signal (SIGINT, SIG_DFL);
if(client < 0) {
perror("accept");
return 1;
@ -634,17 +651,17 @@ int serve(stlink_t *sl, int port) {
if(!strcmp(queryName, "Supported")) {
reply = strdup("PacketSize=3fff;qXfer:memory-map:read+");
} else if(!strcmp(queryName, "Xfer")) {
char *type, *op, *s_addr, *s_length;
char *type, *op, *__s_addr, *s_length;
char *tok = params;
char *annex __attribute__((unused));
type = strsep(&tok, ":");
op = strsep(&tok, ":");
annex = strsep(&tok, ":");
s_addr = strsep(&tok, ",");
__s_addr = strsep(&tok, ",");
s_length = tok;
unsigned addr = strtoul(s_addr, NULL, 16),
unsigned addr = strtoul(__s_addr, NULL, 16),
length = strtoul(s_length, NULL, 16);
#ifdef DEBUG
@ -730,13 +747,13 @@ int serve(stlink_t *sl, int port) {
cmdName++; // vCommand -> Command
if(!strcmp(cmdName, "FlashErase")) {
char *s_addr, *s_length;
char *__s_addr, *s_length;
char *tok = params;
s_addr = strsep(&tok, ",");
__s_addr = strsep(&tok, ",");
s_length = tok;
unsigned addr = strtoul(s_addr, NULL, 16),
unsigned addr = strtoul(__s_addr, NULL, 16),
length = strtoul(s_length, NULL, 16);
#ifdef DEBUG
@ -750,13 +767,13 @@ int serve(stlink_t *sl, int port) {
reply = strdup("OK");
}
} else if(!strcmp(cmdName, "FlashWrite")) {
char *s_addr, *data;
char *__s_addr, *data;
char *tok = params;
s_addr = strsep(&tok, ":");
__s_addr = strsep(&tok, ":");
data = tok;
unsigned addr = strtoul(s_addr, NULL, 16);
unsigned addr = strtoul(__s_addr, NULL, 16);
unsigned data_length = status - (data - packet);
// Length of decoded data cannot be more than
@ -764,7 +781,7 @@ int serve(stlink_t *sl, int port) {
// Additional byte is reserved for alignment fix.
uint8_t *decoded = calloc(data_length + 1, 1);
unsigned dec_index = 0;
for(int i = 0; i < data_length; i++) {
for(unsigned int i = 0; i < data_length; i++) {
if(data[i] == 0x7d) {
i++;
decoded[dec_index++] = data[i] ^ 0x20;
@ -920,7 +937,7 @@ int serve(stlink_t *sl, int port) {
count : count + 4 - (count % 4));
reply = calloc(count * 2 + 1, 1);
for(int i = 0; i < count; i++) {
for(unsigned int i = 0; i < count; i++) {
reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4];
reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf];
}
@ -936,7 +953,7 @@ int serve(stlink_t *sl, int port) {
stm32_addr_t start = strtoul(s_start, NULL, 16);
unsigned count = strtoul(s_count, NULL, 16);
for(int i = 0; i < count; i ++) {
for(unsigned int i = 0; i < count; i ++) {
char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 };
uint8_t byte = strtoul(hex, NULL, 16);
sl->q_buf[i] = byte;

268
mingw/mingw.c 100644
Wyświetl plik

@ -0,0 +1,268 @@
#ifdef __MINGW32__
#include "mingw.h"
#undef socket
#undef connect
#undef accept
#undef shutdown
#include <string.h>
#include <errno.h>
#include <assert.h>
int win32_poll(struct pollfd *fds, unsigned int nfds, int timo)
{
struct timeval timeout, *toptr;
fd_set ifds, ofds, efds, *ip, *op;
unsigned int i, rc;
/* Set up the file-descriptor sets in ifds, ofds and efds. */
FD_ZERO(&ifds);
FD_ZERO(&ofds);
FD_ZERO(&efds);
for (i = 0, op = ip = 0; i < nfds; ++i) {
fds[i].revents = 0;
if(fds[i].events & (POLLIN|POLLPRI)) {
ip = &ifds;
FD_SET(fds[i].fd, ip);
}
if(fds[i].events & POLLOUT) {
op = &ofds;
FD_SET(fds[i].fd, op);
}
FD_SET(fds[i].fd, &efds);
}
/* Set up the timeval structure for the timeout parameter */
if(timo < 0) {
toptr = 0;
} else {
toptr = &timeout;
timeout.tv_sec = timo / 1000;
timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000;
}
#ifdef DEBUG_POLL
printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n",
(long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op);
#endif
rc = select(0, ip, op, &efds, toptr);
#ifdef DEBUG_POLL
printf("Exiting select rc=%d\n", rc);
#endif
if(rc <= 0)
return rc;
if(rc > 0) {
for ( i = 0; i < nfds; ++i) {
int fd = fds[i].fd;
if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds))
fds[i].revents |= POLLIN;
if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds))
fds[i].revents |= POLLOUT;
if(FD_ISSET(fd, &efds))
/* Some error was detected ... should be some way to know. */
fds[i].revents |= POLLHUP;
#ifdef DEBUG_POLL
printf("%d %d %d revent = %x\n",
FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds),
fds[i].revents
);
#endif
}
}
return rc;
}
static void
set_connect_errno(int winsock_err)
{
switch(winsock_err) {
case WSAEINVAL:
case WSAEALREADY:
case WSAEWOULDBLOCK:
errno = EINPROGRESS;
break;
default:
errno = winsock_err;
break;
}
}
static void
set_socket_errno(int winsock_err)
{
switch(winsock_err) {
case WSAEWOULDBLOCK:
errno = EAGAIN;
break;
default:
errno = winsock_err;
break;
}
}
/*
* A wrapper around the socket() function. The purpose of this wrapper
* is to ensure that the global errno symbol is set if an error occurs,
* even if we are using winsock.
*/
SOCKET
win32_socket(int domain, int type, int protocol)
{
SOCKET fd = socket(domain, type, protocol);
if(fd == INVALID_SOCKET) {
set_socket_errno(WSAGetLastError());
}
return fd;
}
/*
* A wrapper around the connect() function. The purpose of this wrapper
* is to ensure that the global errno symbol is set if an error occurs,
* even if we are using winsock.
*/
int
win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len)
{
int rc = connect(fd, addr, addr_len);
assert(rc == 0 || rc == SOCKET_ERROR);
if(rc == SOCKET_ERROR) {
set_connect_errno(WSAGetLastError());
}
return rc;
}
/*
* A wrapper around the accept() function. The purpose of this wrapper
* is to ensure that the global errno symbol is set if an error occurs,
* even if we are using winsock.
*/
SOCKET
win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len)
{
SOCKET newfd = accept(fd, addr, addr_len);
if(newfd == INVALID_SOCKET) {
set_socket_errno(WSAGetLastError());
newfd = -1;
}
return newfd;
}
/*
* A wrapper around the shutdown() function. The purpose of this wrapper
* is to ensure that the global errno symbol is set if an error occurs,
* even if we are using winsock.
*/
int
win32_shutdown(SOCKET fd, int mode)
{
int rc = shutdown(fd, mode);
assert(rc == 0 || rc == SOCKET_ERROR);
if(rc == SOCKET_ERROR) {
set_socket_errno(WSAGetLastError());
}
return rc;
}
int win32_close_socket(SOCKET fd) {
int rc;
rc = closesocket(fd);
return rc;
}
ssize_t win32_write_socket(SOCKET fd, void *buf, int n)
{
int rc = send(fd, buf, n, 0);
if(rc == SOCKET_ERROR) {
set_socket_errno(WSAGetLastError());
}
return rc;
}
ssize_t win32_read_socket(SOCKET fd, void *buf, int n)
{
int rc = recv(fd, buf, n, 0);
if(rc == SOCKET_ERROR) {
set_socket_errno(WSAGetLastError());
}
return rc;
}
char * win32_strtok_r(char *s, const char *delim, char **lasts)
{
register char *spanp;
register int c, sc;
char *tok;
if (s == NULL && (s = *lasts) == NULL)
return (NULL);
/*
* Skip (span) leading delimiters (s += strspn(s, delim), sort of).
*/
cont:
c = *s++;
for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
if (c == sc)
goto cont;
}
if (c == 0) { /* no non-delimiter characters */
*lasts = NULL;
return (NULL);
}
tok = s - 1;
/*
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
* Note that delim must have one NUL; we stop if we see that, too.
*/
for (;;) {
c = *s++;
spanp = (char *)delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
*lasts = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
char *win32_strsep (char **stringp, const char *delim)
{
register char *s;
register const char *spanp;
register int c, sc;
char *tok;
if ((s = *stringp) == NULL)
return (NULL);
for (tok = s;;) {
c = *s++;
spanp = delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
*stringp = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
#endif

68
mingw/mingw.h 100644
Wyświetl plik

@ -0,0 +1,68 @@
#ifdef __MINGW32__
#include <io.h>
#define _USE_W32_SOCKETS 1
#include <windows.h>
#define ENOTCONN WSAENOTCONN
#define EWOULDBLOCK WSAEWOULDBLOCK
#define ENOBUFS WSAENOBUFS
#define ECONNRESET WSAECONNRESET
#define ESHUTDOWN WSAESHUTDOWN
#define EAFNOSUPPORT WSAEAFNOSUPPORT
#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
#define EINPROGRESS WSAEINPROGRESS
#define EISCONN WSAEISCONN
/* winsock doesn't feature poll(), so there is a version implemented
* in terms of select() in mingw.c. The following definitions
* are copied from linux man pages. A poll() macro is defined to
* call the version in mingw.c.
*/
#define POLLIN 0x0001 /* There is data to read */
#define POLLPRI 0x0002 /* There is urgent data to read */
#define POLLOUT 0x0004 /* Writing now will not block */
#define POLLERR 0x0008 /* Error condition */
#define POLLHUP 0x0010 /* Hung up */
#define POLLNVAL 0x0020 /* Invalid request: fd not open */
struct pollfd {
SOCKET fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};
#define poll(x, y, z) win32_poll(x, y, z)
/* These wrappers do nothing special except set the global errno variable if
* an error occurs (winsock doesn't do this by default). They set errno
* to unix-like values (i.e. WSAEWOULDBLOCK is mapped to EAGAIN), so code
* outside of this file "shouldn't" have to worry about winsock specific error
* handling.
*/
#define socket(x, y, z) win32_socket(x, y, z)
#define connect(x, y, z) win32_connect(x, y, z)
#define accept(x, y, z) win32_accept(x, y, z)
#define shutdown(x, y) win32_shutdown(x, y)
#define read(x, y, z) win32_read_socket(x, y, z)
#define write(x, y, z) win32_write_socket(x, y, z)
/* Winsock uses int instead of the usual socklen_t */
typedef int socklen_t;
int win32_poll(struct pollfd *, unsigned int, int);
SOCKET win32_socket(int, int, int);
int win32_connect(SOCKET, struct sockaddr*, socklen_t);
SOCKET win32_accept(SOCKET, struct sockaddr*, socklen_t *);
int win32_shutdown(SOCKET, int);
#define strtok_r(x, y, z) win32_strtok_r(x, y, z)
#define strsep(x,y) win32_strsep(x,y)
char *win32_strtok_r(char *s, const char *delim, char **lasts);
char *win32_strsep(char **stringp, const char *delim);
ssize_t win32_read_socket(SOCKET fd, void *buf, int n);
ssize_t win32_write_socket(SOCKET fd, void *buf, int n);
#endif

69
src/mmap.c 100644
Wyświetl plik

@ -0,0 +1,69 @@
/* mmap.c -- version of mmap for gold. */
/* Copyright 2009 Free Software Foundation, Inc.
Written by Vladimir Simonov <sv@sw.ru>.
This file is part of gold.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
//#include "config.h"
//#include "ansidecl.h"
#include <string.h>
#include <sys/types.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "mmap.h"
extern ssize_t pread (int, void *, size_t, off_t);
void *
mmap (void *__addr, size_t __len, int __prot,
int __flags, int __fd, long long __offset)
{
void *ret;
ssize_t count;
if (__addr || (__fd != -1 && (__prot & PROT_WRITE))
|| (__flags & MAP_SHARED))
return MAP_FAILED;
ret = malloc (__len);
if (!ret)
return MAP_FAILED;
if (__fd == -1)
return ret;
count = pread (__fd, ret, __len, __offset);
if ((size_t) count != __len)
{
free (ret);
return MAP_FAILED;
}
return ret;
}
int
munmap (void *__addr, size_t __len)
{
free (__addr);
return 0;
}

62
src/mmap.h 100644
Wyświetl plik

@ -0,0 +1,62 @@
/* mmap.h -- mmap family functions prototypes for gold. */
/* Copyright 2009 Free Software Foundation, Inc.
Written by Vladimir Simonov <sv@sw.ru>
This file is part of gold.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
#ifndef GOLD_MMAP_H
#define GOLD_MMAP_H
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
/* Some BSD systems still use MAP_ANON instead of MAP_ANONYMOUS. */
#ifndef MAP_ANONYMOUS
# define MAP_ANONYMOUS MAP_ANON
#endif
#else
#define PROT_READ 0x1
#define PROT_WRITE 0x2
#define MAP_SHARED 0x01
#define MAP_PRIVATE 0x02
#define MAP_ANONYMOUS 0x20
#define MAP_FAILED ((void *) -1)
#endif /* HAVE_SYS_MMAN_H */
#ifndef HAVE_MMAP
#ifdef __cplusplus
extern "C" {
#endif
extern void *mmap (void *__addr, size_t __len, int __prot,
int __flags, int __fd, long long __offset);
extern int munmap (void *__addr, size_t __len);
#ifdef __cplusplus
}
#endif
#endif /* HAVE_MMAP */
#endif /* GOLD_MMAP_H */

42
src/pread.c 100644
Wyświetl plik

@ -0,0 +1,42 @@
/* pread.c -- version of pread for gold. */
/* Copyright 2006, 2007, 2009 Free Software Foundation, Inc.
Written by Ian Lance Taylor <iant@google.com>.
This file is part of gold.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
/* This file implements pread for systems which don't have it. This
file is only compiled if pread is not present on the system. This
is not an exact version of pread, as it does not preserve the
current file offset. */
//#include "config.h"
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
extern ssize_t pread (int, void *, size_t, off_t);
ssize_t
pread (int fd, void *buf, size_t count, off_t offset)
{
if (lseek(fd, offset, SEEK_SET) != offset)
return -1;
return read(fd, buf, count);
}

Wyświetl plik

@ -9,8 +9,7 @@
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include "mmap.h"
#include "stlink-common.h"
#include "uglylogging.h"

Wyświetl plik

@ -85,7 +85,7 @@
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include "mmap.h"
#include "stlink-common.h"
#include "stlink-sg.h"

Wyświetl plik

@ -2,7 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <libusb.h>
@ -16,6 +16,18 @@
#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args)
#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args)
#ifndef timersub
/* This is a copy from GNU C Library (GNU LGPL 2.1), sys/time.h. */
# define timersub(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
if ((result)->tv_usec < 0) { \
--(result)->tv_sec; \
(result)->tv_usec += 1000000; \
} \
} while (0)
#endif
enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80};
@ -45,7 +57,7 @@ struct trans_ctx {
volatile unsigned long flags;
};
static void on_trans_done(struct libusb_transfer * trans) {
static void LIBUSB_CALL on_trans_done(struct libusb_transfer * trans) {
struct trans_ctx * const ctx = trans->user_data;
if (trans->status != LIBUSB_TRANSFER_COMPLETED)