eclair snapshot

This commit is contained in:
Jean-Baptiste Queru 2009-11-12 18:46:23 -08:00
parent 85b3fcc5de
commit 4b29fe640a
173 changed files with 17397 additions and 1603 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*~

View File

191
adb/NOTICE Normal file
View File

@ -0,0 +1,191 @@
Copyright (c) 2006-2009, The Android Open Source Project
Copyright 2006, Brian Swetland <swetland@frotz.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

View File

@ -832,6 +832,7 @@ int adb_main(int is_daemon)
{
#if !ADB_HOST
int secure = 0;
int port;
char value[PROPERTY_VALUE_MAX];
#endif
@ -850,7 +851,7 @@ int adb_main(int is_daemon)
HOST = 1;
usb_vendors_init();
usb_init();
local_init();
local_init(ADB_LOCAL_TRANSPORT_PORT);
if(install_listener("tcp:5037", "*smartsocket*", NULL)) {
exit(1);
@ -918,14 +919,19 @@ int adb_main(int is_daemon)
}
/* for the device, start the usb transport if the
** android usb device exists, otherwise start the
** network transport.
** android usb device exists and "service.adb.tcp"
** is not set, otherwise start the network transport.
*/
if(access("/dev/android_adb", F_OK) == 0 ||
access("/dev/android", F_OK) == 0) {
property_get("service.adb.tcp.port", value, "0");
if (sscanf(value, "%d", &port) == 1 && port > 0) {
// listen on TCP port specified by service.adb.tcp.port property
local_init(port);
} else if (access("/dev/android_adb", F_OK) == 0) {
// listen on USB
usb_init();
} else {
local_init();
// listen on default port
local_init(ADB_LOCAL_TRANSPORT_PORT);
}
init_jdwp();
#endif
@ -1006,6 +1012,66 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
return 0;
}
// add a new TCP transport
if (!strncmp(service, "connect:", 8)) {
char buffer[4096];
int port, fd;
char* host = service + 8;
char* portstr = strchr(host, ':');
if (!portstr) {
snprintf(buffer, sizeof(buffer), "unable to parse %s as <host>:<port>", host);
goto done;
}
if (find_transport(host)) {
snprintf(buffer, sizeof(buffer), "Already connected to %s", host);
goto done;
}
// zero terminate host by overwriting the ':'
*portstr++ = 0;
if (sscanf(portstr, "%d", &port) == 0) {
snprintf(buffer, sizeof(buffer), "bad port number %s", portstr);
goto done;
}
fd = socket_network_client(host, port, SOCK_STREAM);
if (fd < 0) {
snprintf(buffer, sizeof(buffer), "unable to connect to %s:%d", host, port);
goto done;
}
D("client: connected on remote on fd %d\n", fd);
close_on_exec(fd);
disable_tcp_nagle(fd);
snprintf(buf, sizeof buf, "%s:%d", host, port);
register_socket_transport(fd, buf, port, 0);
snprintf(buffer, sizeof(buffer), "connected to %s:%d", host, port);
done:
snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer);
writex(reply_fd, buf, strlen(buf));
return 0;
}
// remove TCP transport
if (!strncmp(service, "disconnect:", 11)) {
char buffer[4096];
memset(buffer, 0, sizeof(buffer));
char* serial = service + 11;
atransport *t = find_transport(serial);
if (t) {
unregister_transport(t);
} else {
snprintf(buffer, sizeof(buffer), "No such device %s", serial);
}
snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer);
writex(reply_fd, buf, strlen(buf));
return 0;
}
// returns our value for ADB_SERVER_VERSION
if (!strcmp(service, "version")) {
char version[12];

View File

@ -33,7 +33,7 @@
#define ADB_VERSION_MAJOR 1 // Used for help/version information
#define ADB_VERSION_MINOR 0 // Used for help/version information
#define ADB_SERVER_VERSION 22 // Increment this when we want to force users to start a new adb server
#define ADB_SERVER_VERSION 25 // Increment this when we want to force users to start a new adb server
typedef struct amessage amessage;
typedef struct apacket apacket;
@ -262,15 +262,24 @@ void run_transport_disconnects( atransport* t );
void kick_transport( atransport* t );
/* initialize a transport object's func pointers and state */
int init_socket_transport(atransport *t, int s, int port);
void init_usb_transport(atransport *t, usb_handle *usb);
int init_socket_transport(atransport *t, int s, int port, int local);
void init_usb_transport(atransport *t, usb_handle *usb, int state);
/* for MacOS X cleanup */
void close_usb_devices();
/* cause new transports to be init'd and added to the list */
void register_socket_transport(int s, const char *serial, int port);
void register_usb_transport(usb_handle *h, const char *serial);
void register_socket_transport(int s, const char *serial, int port, int local);
/* this should only be used for the "adb disconnect" command */
void unregister_transport(atransport *t);
void register_usb_transport(usb_handle *h, const char *serial, unsigned writeable);
/* this should only be used for transports with connection_state == CS_NOPERM */
void unregister_usb_transport(usb_handle *usb);
atransport *find_transport(const char *serial);
int service_to_fd(const char *name);
#if ADB_HOST
@ -357,7 +366,7 @@ typedef enum {
#define ADB_PROTOCOL 0x1
void local_init();
void local_init(int port);
int local_connect(int port);
/* usb host/client interface */
@ -384,7 +393,7 @@ int connection_state(atransport *t);
#define CS_DEVICE 2
#define CS_HOST 3
#define CS_RECOVERY 4
#define CS_ERROR 5
#define CS_NOPERM 5 /* Insufficient permissions to communicate with the device */
extern int HOST;

View File

@ -96,7 +96,8 @@ void help()
" -e - directs command to the only running emulator.\n"
" returns an error if more than one emulator is running.\n"
" -s <serial number> - directs command to the USB device or emulator with\n"
" the given serial number\n"
" the given serial number. Overrides ANDROID_SERIAL\n"
" envivornment variable.\n"
" -p <product name or path> - simple product name like 'sooner', or\n"
" a relative/absolute path to a product\n"
" out directory like 'out/target/product/sooner'.\n"
@ -104,6 +105,8 @@ void help()
" environment variable is used, which must\n"
" be an absolute path.\n"
" devices - list all connected devices\n"
" connect <host>:<port> - connect to a device via TCP/IP"
" disconnect <host>:<port> - disconnect from a TCP/IP device"
"\n"
"device commands:\n"
" adb push <local> <remote> - copy file/dir to device\n"
@ -148,7 +151,9 @@ void help()
" adb status-window - continuously print device status for a specified device\n"
" adb remount - remounts the /system partition on the device read-write\n"
" adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
" adb root - restarts adb with root permissions\n"
" adb root - restarts the adbd daemon with root permissions\n"
" adb usb - restarts the adbd daemon listening on USB"
" adb tcpip <port> - restarts the adbd daemon listening on TCP on the specified port"
"\n"
"networking:\n"
" adb ppp <tty> [parameters] - Run PPP over USB.\n"
@ -767,6 +772,8 @@ int adb_commandline(int argc, char **argv)
}
// TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
serial = getenv("ANDROID_SERIAL");
/* modifiers and flags */
while(argc > 0) {
if(!strcmp(argv[0],"nodaemon")) {
@ -847,6 +854,22 @@ top:
}
}
if(!strcmp(argv[0], "connect") || !strcmp(argv[0], "disconnect")) {
char *tmp;
if (argc != 2) {
fprintf(stderr, "Usage: adb %s <host>:<port>\n", argv[0]);
return 1;
}
snprintf(buf, sizeof buf, "host:%s:%s", argv[0], argv[1]);
tmp = adb_query(buf);
if(tmp) {
printf("%s\n", tmp);
return 0;
} else {
return 1;
}
}
if (!strcmp(argv[0], "emu")) {
return adb_send_emulator_command(argc, argv);
}
@ -905,35 +928,15 @@ top:
return 0;
}
if(!strcmp(argv[0], "remount")) {
int fd = adb_connect("remount:");
if(fd >= 0) {
read_and_dump(fd);
adb_close(fd);
return 0;
}
fprintf(stderr,"error: %s\n", adb_error());
return 1;
}
if(!strcmp(argv[0], "reboot")) {
int fd;
if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
|| !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
|| !strcmp(argv[0], "root")) {
char command[100];
if (argc > 1)
snprintf(buf, sizeof(buf), "reboot:%s", argv[1]);
snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
else
snprintf(buf, sizeof(buf), "reboot:");
fd = adb_connect(buf);
if(fd >= 0) {
read_and_dump(fd);
adb_close(fd);
return 0;
}
fprintf(stderr,"error: %s\n", adb_error());
return 1;
}
if(!strcmp(argv[0], "root")) {
int fd = adb_connect("root:");
snprintf(command, sizeof(command), "%s:", argv[0]);
int fd = adb_connect(command);
if(fd >= 0) {
read_and_dump(fd);
adb_close(fd);

View File

@ -28,18 +28,35 @@
#include <sys/mman.h>
/* TODO:
** - grab the current buffer, not the first buffer
** - sync with vsync to avoid tearing
*/
/* This version number defines the format of the fbinfo struct.
It must match versioning in ddms where this data is consumed. */
#define DDMS_RAWIMAGE_VERSION 1
struct fbinfo {
unsigned int version;
unsigned int bpp;
unsigned int size;
unsigned int width;
unsigned int height;
unsigned int red_offset;
unsigned int red_length;
unsigned int blue_offset;
unsigned int blue_length;
unsigned int green_offset;
unsigned int green_length;
unsigned int alpha_offset;
unsigned int alpha_length;
} __attribute__((packed));
void framebuffer_service(int fd, void *cookie)
{
struct fb_var_screeninfo vinfo;
int fb;
void *ptr = MAP_FAILED;
char x;
int fb, offset;
char x[256];
unsigned fbinfo[4];
struct fbinfo fbinfo;
unsigned i, bytespp;
fb = open("/dev/graphics/fb0", O_RDONLY);
if(fb < 0) goto done;
@ -47,24 +64,43 @@ void framebuffer_service(int fd, void *cookie)
if(ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) < 0) goto done;
fcntl(fb, F_SETFD, FD_CLOEXEC);
fbinfo[0] = 16;
fbinfo[1] = vinfo.xres * vinfo.yres * 2;
fbinfo[2] = vinfo.xres;
fbinfo[3] = vinfo.yres;
bytespp = vinfo.bits_per_pixel / 8;
ptr = mmap(0, fbinfo[1], PROT_READ, MAP_SHARED, fb, 0);
if(ptr == MAP_FAILED) goto done;
fbinfo.version = DDMS_RAWIMAGE_VERSION;
fbinfo.bpp = vinfo.bits_per_pixel;
fbinfo.size = vinfo.xres * vinfo.yres * bytespp;
fbinfo.width = vinfo.xres;
fbinfo.height = vinfo.yres;
fbinfo.red_offset = vinfo.red.offset;
fbinfo.red_length = vinfo.red.length;
fbinfo.green_offset = vinfo.green.offset;
fbinfo.green_length = vinfo.green.length;
fbinfo.blue_offset = vinfo.blue.offset;
fbinfo.blue_length = vinfo.blue.length;
fbinfo.alpha_offset = vinfo.transp.offset;
fbinfo.alpha_length = vinfo.transp.length;
if(writex(fd, fbinfo, sizeof(unsigned) * 4)) goto done;
/* HACK: for several of our 3d cores a specific alignment
* is required so the start of the fb may not be an integer number of lines
* from the base. As a result we are storing the additional offset in
* xoffset. This is not the correct usage for xoffset, it should be added
* to each line, not just once at the beginning */
offset = vinfo.xoffset * bytespp;
for(;;) {
if(readx(fd, &x, 1)) goto done;
if(writex(fd, ptr, fbinfo[1])) goto done;
offset += vinfo.xres * vinfo.yoffset * bytespp;
if(writex(fd, &fbinfo, sizeof(fbinfo))) goto done;
lseek(fb, offset, SEEK_SET);
for(i = 0; i < fbinfo.size; i += 256) {
if(readx(fb, &x, 256)) goto done;
if(writex(fd, &x, 256)) goto done;
}
if(readx(fb, &x, fbinfo.size % 256)) goto done;
if(writex(fd, &x, fbinfo.size % 256)) goto done;
done:
if(ptr != MAP_FAILED) munmap(ptr, fbinfo[1]);
if(fb >= 0) close(fb);
close(fd);
}

View File

@ -14,7 +14,6 @@
* limitations under the License.
*/
#include <utils/executablepath.h>
#import <Carbon/Carbon.h>
#include <unistd.h>

View File

@ -164,7 +164,7 @@ jdwp_process_free( JdwpProcess* proc )
proc->next->prev = proc->prev;
if (proc->socket >= 0) {
shutdown(proc->socket, SHUT_RDWR);
adb_shutdown(proc->socket);
adb_close(proc->socket);
proc->socket = -1;
}

View File

@ -32,8 +32,7 @@
# include <netdb.h>
# endif
#else
#include <sys/poll.h>
#include <sys/reboot.h>
# include <sys/reboot.h>
#endif
typedef struct stinfo stinfo;
@ -64,6 +63,7 @@ static void dns_service(int fd, void *cookie)
adb_mutex_lock(&dns_lock);
hp = gethostbyname(hostname);
free(cookie);
if(hp == 0) {
writex(fd, &zero, 4);
} else {
@ -120,6 +120,7 @@ void restart_root_service(int fd, void *cookie)
if (strcmp(value, "1") != 0) {
snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n");
writex(fd, buf, strlen(buf));
adb_close(fd);
return;
}
@ -134,17 +135,57 @@ void restart_root_service(int fd, void *cookie)
}
}
void reboot_service(int fd, char *arg)
void restart_tcp_service(int fd, void *cookie)
{
char buf[100];
char value[PROPERTY_VALUE_MAX];
int port = (int)cookie;
if (port <= 0) {
snprintf(buf, sizeof(buf), "invalid port\n");
writex(fd, buf, strlen(buf));
adb_close(fd);
return;
}
snprintf(value, sizeof(value), "%d", port);
property_set("service.adb.tcp.port", value);
snprintf(buf, sizeof(buf), "restarting in TCP mode port: %d\n", port);
writex(fd, buf, strlen(buf));
adb_close(fd);
// quit, and init will restart us in TCP mode
sleep(1);
exit(1);
}
void restart_usb_service(int fd, void *cookie)
{
char buf[100];
property_set("service.adb.tcp.port", "0");
snprintf(buf, sizeof(buf), "restarting in USB mode\n");
writex(fd, buf, strlen(buf));
adb_close(fd);
// quit, and init will restart us in USB mode
sleep(1);
exit(1);
}
void reboot_service(int fd, void *arg)
{
char buf[100];
int ret;
sync();
ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, arg);
ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
LINUX_REBOOT_CMD_RESTART2, (char *)arg);
if (ret < 0) {
snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno));
writex(fd, buf, strlen(buf));
}
free(arg);
adb_close(fd);
}
@ -213,9 +254,12 @@ static int create_service_thread(void (*func)(int, void *), void *cookie)
return s[0];
}
#if !ADB_HOST
static int create_subprocess(const char *cmd, const char *arg0, const char *arg1)
{
#ifdef HAVE_WIN32_PROC
fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
return -1;
#else /* !HAVE_WIN32_PROC */
char *devname;
int ptm;
pid_t pid;
@ -258,6 +302,7 @@ static int create_subprocess(const char *cmd, const char *arg0, const char *arg1
cmd, strerror(errno), errno);
exit(-1);
} else {
#if !ADB_HOST
// set child's OOM adjustment to zero
char text[64];
snprintf(text, sizeof text, "/proc/%d/oom_adj", pid);
@ -268,11 +313,11 @@ static int create_subprocess(const char *cmd, const char *arg0, const char *arg1
} else {
D("adb: unable to open %s\n", text);
}
#endif
return ptm;
}
#endif /* !HAVE_WIN32_PROC */
}
#endif /* !ADB_HOST */
#if ADB_HOST
#define SHELL_COMMAND "/bin/sh"
@ -280,76 +325,6 @@ static int create_subprocess(const char *cmd, const char *arg0, const char *arg1
#define SHELL_COMMAND "/system/bin/sh"
#endif
#if !ADB_HOST
static void shell_service(int s, void *command)
{
char buffer[MAX_PAYLOAD];
char buffer2[MAX_PAYLOAD];
struct pollfd ufds[2];
int fd, ret = 0;
unsigned count = 0;
char** args = (char **)command;
fd = create_subprocess(SHELL_COMMAND, args[0], args[1]);
while (1) {
while (count < sizeof(buffer)) {
ufds[0].fd = fd;
ufds[0].events = POLLIN | POLLHUP;
ufds[0].revents = 0;
ufds[1].fd = s;
ufds[1].events = POLLIN | POLLHUP;
ufds[1].revents = 0;
// use a 100ms timeout so we don't block indefinitely with our
// buffer partially filled.
ret = poll(ufds, 2, 100);
if (ret <= 0) {
D("poll returned %d\n", ret);
// file has closed or we timed out
// set ret to 1 so we don't exit the outer loop
ret = 1;
break;
}
if (ufds[0].revents & POLLIN) {
ret = adb_read(fd, buffer + count, sizeof(buffer) - count);
D("read fd ret: %d, count: %d\n", ret, count);
if (ret > 0)
count += ret;
else
break;
}
if (ufds[1].revents & POLLIN) {
ret = adb_read(s, buffer2, sizeof(buffer2));
D("read s ret: %d\n", ret);
if (ret > 0)
adb_write(fd, buffer2, ret);
else
break;
}
if ((ufds[0].revents & POLLHUP) || (ufds[1].revents & POLLHUP)) {
// set flag to exit after flushing the buffer
ret = -1;
break;
}
}
D("writing: %d\n", count);
if (count > 0) {
adb_write(s, buffer, count);
count = 0;
}
if (ret <= 0)
break;
}
D("shell_service done\n");
adb_close(fd);
adb_close(s);
}
#endif // !ADB_HOST
int service_to_fd(const char *name)
{
int ret = -1;
@ -400,27 +375,32 @@ int service_to_fd(const char *name)
ret = create_jdwp_connection_fd(atoi(name+5));
} else if (!strncmp(name, "log:", 4)) {
ret = create_service_thread(log_service, get_log_file_path(name + 4));
#endif
} else if(!HOST && !strncmp(name, "shell:", 6)) {
const char* args[2];
if(name[6]) {
args[0] = "-c";
args[1] = name + 6;
ret = create_subprocess(SHELL_COMMAND, "-c", name + 6);
} else {
args[0] = "-";
args[1] = 0;
ret = create_subprocess(SHELL_COMMAND, "-", 0);
}
ret = create_service_thread(shell_service, (void *)args);
#if !ADB_HOST
} else if(!strncmp(name, "sync:", 5)) {
ret = create_service_thread(file_sync_service, NULL);
} else if(!strncmp(name, "remount:", 8)) {
ret = create_service_thread(remount_service, NULL);
} else if(!strncmp(name, "reboot:", 7)) {
char* arg = name + 7;
if (*name == 0)
arg = NULL;
void* arg = strdup(name + 7);
if(arg == 0) return -1;
ret = create_service_thread(reboot_service, arg);
} else if(!strncmp(name, "root:", 5)) {
ret = create_service_thread(restart_root_service, NULL);
} else if(!strncmp(name, "tcpip:", 6)) {
int port;
if (sscanf(name + 6, "%d", &port) == 0) {
port = 0;
}
ret = create_service_thread(restart_tcp_service, (void *)port);
} else if(!strncmp(name, "usb:", 4)) {
ret = create_service_thread(restart_usb_service, NULL);
#endif
#if 0
} else if(!strncmp(name, "echo:", 5)){

View File

@ -113,6 +113,7 @@ extern int adb_creat(const char* path, int mode);
extern int adb_read(int fd, void* buf, int len);
extern int adb_write(int fd, const void* buf, int len);
extern int adb_lseek(int fd, int pos, int where);
extern int adb_shutdown(int fd);
extern int adb_close(int fd);
static __inline__ int unix_close(int fd)
@ -327,6 +328,13 @@ static __inline__ int adb_open( const char* pathname, int options )
#undef open
#define open ___xxx_open
static __inline__ int adb_shutdown(int fd)
{
return shutdown(fd, SHUT_RDWR);
}
#undef shutdown
#define shutdown ____xxx_shutdown
static __inline__ int adb_close(int fd)
{
return close(fd);

View File

@ -435,6 +435,20 @@ int adb_lseek(int fd, int pos, int where)
}
int adb_shutdown(int fd)
{
FH f = _fh_from_int(fd);
if (!f) {
return -1;
}
D( "adb_shutdown: %s\n", f->name);
shutdown( f->fh_socket, SD_BOTH );
return 0;
}
int adb_close(int fd)
{
FH f = _fh_from_int(fd);

View File

@ -584,18 +584,37 @@ static void transport_registration_func(int _fd, unsigned ev, void *data)
return;
}
/* don't create transport threads for inaccessible devices */
if (t->connection_state != CS_NOPERM) {
/* initial references are the two threads */
t->ref_count = 2;
t->ref_count = 2;
if(adb_socketpair(s)) {
fatal_errno("cannot open transport socketpair");
if(adb_socketpair(s)) {
fatal_errno("cannot open transport socketpair");
}
D("transport: %p (%d,%d) starting\n", t, s[0], s[1]);
t->transport_socket = s[0];
t->fd = s[1];
D("transport: %p install %d\n", t, t->transport_socket );
fdevent_install(&(t->transport_fde),
t->transport_socket,
transport_socket_events,
t);
fdevent_set(&(t->transport_fde), FDE_READ);
if(adb_thread_create(&input_thread_ptr, input_thread, t)){
fatal_errno("cannot create input thread");
}
if(adb_thread_create(&output_thread_ptr, output_thread, t)){
fatal_errno("cannot create output thread");
}
}
D("transport: %p (%d,%d) starting\n", t, s[0], s[1]);
t->transport_socket = s[0];
t->fd = s[1];
/* put us on the master device list */
adb_mutex_lock(&transport_lock);
t->next = &transport_list;
@ -604,22 +623,6 @@ static void transport_registration_func(int _fd, unsigned ev, void *data)
t->prev->next = t;
adb_mutex_unlock(&transport_lock);
D("transport: %p install %d\n", t, t->transport_socket );
fdevent_install(&(t->transport_fde),
t->transport_socket,
transport_socket_events,
t);
fdevent_set(&(t->transport_fde), FDE_READ);
if(adb_thread_create(&input_thread_ptr, input_thread, t)){
fatal_errno("cannot create input thread");
}
if(adb_thread_create(&output_thread_ptr, output_thread, t)){
fatal_errno("cannot create output thread");
}
t->disconnects.next = t->disconnects.prev = &t->disconnects;
update_transports();
@ -717,6 +720,12 @@ retry:
adb_mutex_lock(&transport_lock);
for (t = transport_list.next; t != &transport_list; t = t->next) {
if (t->connection_state == CS_NOPERM) {
if (error_out)
*error_out = "insufficient permissions for device";
continue;
}
/* check for matching serial number */
if (serial) {
if (t->serial && !strcmp(serial, t->serial)) {
@ -763,7 +772,6 @@ retry:
*error_out = "device offline";
result = NULL;
}
/* check for required connection state */
if (result && state != CS_ANY && result->connection_state != state) {
if (error_out)
@ -793,6 +801,7 @@ static const char *statename(atransport *t)
case CS_DEVICE: return "device";
case CS_HOST: return "host";
case CS_RECOVERY: return "recovery";
case CS_NOPERM: return "no permissions";
default: return "unknown";
}
}
@ -807,9 +816,10 @@ int list_transports(char *buf, size_t bufsize)
/* XXX OVERRUN PROBLEMS XXX */
adb_mutex_lock(&transport_lock);
for(t = transport_list.next; t != &transport_list; t = t->next) {
len = snprintf(p, end - p, "%s\t%s\n",
t->serial ? t->serial : "",
statename(t));
const char* serial = t->serial;
if (!serial || !serial[0])
serial = "????????????";
len = snprintf(p, end - p, "%s\t%s\n", serial, statename(t));
if (p + len >= end) {
/* discard last line if buffer is too short */
@ -839,11 +849,11 @@ void close_usb_devices()
}
#endif // ADB_HOST
void register_socket_transport(int s, const char *serial, int port)
void register_socket_transport(int s, const char *serial, int port, int local)
{
atransport *t = calloc(1, sizeof(atransport));
D("transport: %p init'ing for socket %d, on port %d\n", t, s, port);
if ( init_socket_transport(t, s, port) < 0 ) {
if ( init_socket_transport(t, s, port, local) < 0 ) {
adb_close(s);
free(t);
return;
@ -854,18 +864,64 @@ void register_socket_transport(int s, const char *serial, int port)
register_transport(t);
}
void register_usb_transport(usb_handle *usb, const char *serial)
#if ADB_HOST
atransport *find_transport(const char *serial)
{
atransport *t;
adb_mutex_lock(&transport_lock);
for(t = transport_list.next; t != &transport_list; t = t->next) {
if (t->serial && !strcmp(serial, t->serial)) {
break;
}
}
adb_mutex_unlock(&transport_lock);
if (t != &transport_list)
return t;
else
return 0;
}
void unregister_transport(atransport *t)
{
adb_mutex_lock(&transport_lock);
t->next->prev = t->prev;
t->prev->next = t->next;
adb_mutex_unlock(&transport_lock);
kick_transport(t);
transport_unref(t);
}
#endif
void register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable)
{
atransport *t = calloc(1, sizeof(atransport));
D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
serial ? serial : "");
init_usb_transport(t, usb);
init_usb_transport(t, usb, (writeable ? CS_OFFLINE : CS_NOPERM));
if(serial) {
t->serial = strdup(serial);
}
register_transport(t);
}
/* this should only be used for transports with connection_state == CS_NOPERM */
void unregister_usb_transport(usb_handle *usb)
{
atransport *t;
adb_mutex_lock(&transport_lock);
for(t = transport_list.next; t != &transport_list; t = t->next) {
if (t->usb == usb && t->connection_state == CS_NOPERM) {
t->next->prev = t->prev;
t->prev->next = t->next;
break;
}
}
adb_mutex_unlock(&transport_lock);
}
#undef TRACE_TAG
#define TRACE_TAG TRACE_RWX

View File

@ -122,7 +122,7 @@ int local_connect(int port)
close_on_exec(fd);
disable_tcp_nagle(fd);
snprintf(buf, sizeof buf, "%s%d", LOCAL_CLIENT_PREFIX, port - 1);
register_socket_transport(fd, buf, port);
register_socket_transport(fd, buf, port, 1);
return 0;
}
return -1;
@ -147,17 +147,18 @@ static void *client_socket_thread(void *x)
return 0;
}
static void *server_socket_thread(void *x)
static void *server_socket_thread(void * arg)
{
int serverfd, fd;
struct sockaddr addr;
socklen_t alen;
int port = (int)arg;
D("transport: server_socket_thread() starting\n");
serverfd = -1;
for(;;) {
if(serverfd == -1) {
serverfd = socket_inaddr_any_server(ADB_LOCAL_TRANSPORT_PORT, SOCK_STREAM);
serverfd = socket_inaddr_any_server(port, SOCK_STREAM);
if(serverfd < 0) {
D("server: cannot bind socket yet\n");
adb_sleep_ms(1000);
@ -167,20 +168,20 @@ static void *server_socket_thread(void *x)
}
alen = sizeof(addr);
D("server: trying to get new connection from %d\n", ADB_LOCAL_TRANSPORT_PORT);
D("server: trying to get new connection from %d\n", port);
fd = adb_socket_accept(serverfd, &addr, &alen);
if(fd >= 0) {
D("server: new connection on fd %d\n", fd);
close_on_exec(fd);
disable_tcp_nagle(fd);
register_socket_transport(fd,"host",ADB_LOCAL_TRANSPORT_PORT);
register_socket_transport(fd, "host", port, 1);
}
}
D("transport: server_socket_thread() exiting\n");
return 0;
}
void local_init(void)
void local_init(int port)
{
adb_thread_t thr;
void* (*func)(void *);
@ -193,7 +194,7 @@ void local_init(void)
D("transport: local %s init\n", HOST ? "client" : "server");
if(adb_thread_create(&thr, func, 0)) {
if(adb_thread_create(&thr, func, (void *)port)) {
fatal_errno("cannot create local socket %s thread",
HOST ? "client" : "server");
}
@ -203,6 +204,7 @@ static void remote_kick(atransport *t)
{
int fd = t->sfd;
t->sfd = -1;
adb_shutdown(fd);
adb_close(fd);
#if ADB_HOST
@ -225,7 +227,7 @@ static void remote_close(atransport *t)
adb_close(t->fd);
}
int init_socket_transport(atransport *t, int s, int port)
int init_socket_transport(atransport *t, int s, int port, int local)
{
int fail = 0;
@ -239,7 +241,7 @@ int init_socket_transport(atransport *t, int s, int port)
t->type = kTransportLocal;
#if ADB_HOST
if (HOST) {
if (HOST && local) {
adb_mutex_lock( &local_transports_lock );
{
int index = (port - ADB_LOCAL_TRANSPORT_PORT)/2;

View File

@ -110,7 +110,7 @@ static void remote_kick(atransport *t)
usb_kick(t->usb);
}
void init_usb_transport(atransport *t, usb_handle *h)
void init_usb_transport(atransport *t, usb_handle *h, int state)
{
D("transport: usb\n");
t->close = remote_close;
@ -118,7 +118,7 @@ void init_usb_transport(atransport *t, usb_handle *h)
t->read_from_remote = remote_read;
t->write_to_remote = remote_write;
t->sync_token = 1;
t->connection_state = CS_OFFLINE;
t->connection_state = state;
t->type = kTransportUsb;
t->usb = h;

View File

@ -57,6 +57,7 @@ struct usb_handle
unsigned char ep_out;
unsigned zero_mask;
unsigned writeable;
struct usbdevfs_urb urb_in;
struct usbdevfs_urb urb_out;
@ -115,7 +116,7 @@ static void kick_disconnected_devices()
}
static void register_device(const char *dev_name, unsigned char ep_in, unsigned char ep_out,
int ifc, const char *serial, unsigned zero_mask);
int ifc, int serial_index, unsigned zero_mask);
static inline int badname(const char *name)
{
@ -125,19 +126,18 @@ static inline int badname(const char *name)
return 0;
}
static int find_usb_device(const char *base,
void (*register_device_callback) (const char *, unsigned char, unsigned char, int, const char *, unsigned))
static void find_usb_device(const char *base,
void (*register_device_callback)
(const char *, unsigned char, unsigned char, int, int, unsigned))
{
char busname[32], devname[32];
unsigned char local_ep_in, local_ep_out;
DIR *busdir , *devdir ;
struct dirent *de;
int fd ;
int found_device = 0;
char serial[256];
busdir = opendir(base);
if(busdir == 0) return 0;
if(busdir == 0) return;
while((de = readdir(busdir)) != 0) {
if(badname(de->d_name)) continue;
@ -168,7 +168,7 @@ static int find_usb_device(const char *base,
}
// DBGX("[ scanning %s ]\n", devname);
if((fd = unix_open(devname, O_RDWR)) < 0) {
if((fd = unix_open(devname, O_RDONLY)) < 0) {
continue;
}
@ -263,67 +263,13 @@ static int find_usb_device(const char *base,
local_ep_out = ep1->bEndpointAddress;
}
// read the device's serial number
serial[0] = 0;
memset(serial, 0, sizeof(serial));
if (device->iSerialNumber) {
struct usbdevfs_ctrltransfer ctrl;
__u16 buffer[128];
__u16 languages[128];
int i, result;
int languageCount = 0;
memset(languages, 0, sizeof(languages));
memset(&ctrl, 0, sizeof(ctrl));
// read list of supported languages
ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE;
ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
ctrl.wValue = (USB_DT_STRING << 8) | 0;
ctrl.wIndex = 0;
ctrl.wLength = sizeof(languages);
ctrl.data = languages;
result = ioctl(fd, USBDEVFS_CONTROL, &ctrl);
if (result > 0)
languageCount = (result - 2) / 2;
for (i = 1; i <= languageCount; i++) {
memset(buffer, 0, sizeof(buffer));
memset(&ctrl, 0, sizeof(ctrl));
ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE;
ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
ctrl.wValue = (USB_DT_STRING << 8) | device->iSerialNumber;
ctrl.wIndex = languages[i];
ctrl.wLength = sizeof(buffer);
ctrl.data = buffer;
result = ioctl(fd, USBDEVFS_CONTROL, &ctrl);
if (result > 0) {
int i;
// skip first word, and copy the rest to the serial string, changing shorts to bytes.
result /= 2;
for (i = 1; i < result; i++)
serial[i - 1] = buffer[i];
serial[i - 1] = 0;
break;
}
}
}
register_device_callback(devname, local_ep_in, local_ep_out,
interface->bInterfaceNumber, serial, zero_mask);
interface->bInterfaceNumber, device->iSerialNumber, zero_mask);
found_device = 1;
break;
} else {
// seek next interface descriptor
if (i < interfaces - 1) {
while (bufptr[1] != USB_DT_INTERFACE) {
bufptr += bufptr[0];
}
}
bufptr += (USB_DT_ENDPOINT_SIZE * interface->bNumEndpoints);
}
} // end of for
@ -332,8 +278,6 @@ static int find_usb_device(const char *base,
closedir(devdir);
} //end of busdir while
closedir(busdir);
return found_device;
}
void usb_cleanup()
@ -537,26 +481,30 @@ void usb_kick(usb_handle *h)
if(h->dead == 0) {
h->dead = 1;
/* HACK ALERT!
** Sometimes we get stuck in ioctl(USBDEVFS_REAPURB).
** This is a workaround for that problem.
*/
if (h->reaper_thread) {
pthread_kill(h->reaper_thread, SIGALRM);
}
if (h->writeable) {
/* HACK ALERT!
** Sometimes we get stuck in ioctl(USBDEVFS_REAPURB).
** This is a workaround for that problem.
*/
if (h->reaper_thread) {
pthread_kill(h->reaper_thread, SIGALRM);
}
/* cancel any pending transactions
** these will quietly fail if the txns are not active,
** but this ensures that a reader blocked on REAPURB
** will get unblocked
*/
ioctl(h->desc, USBDEVFS_DISCARDURB, &h->urb_in);
ioctl(h->desc, USBDEVFS_DISCARDURB, &h->urb_out);
h->urb_in.status = -ENODEV;
h->urb_out.status = -ENODEV;
h->urb_in_busy = 0;
h->urb_out_busy = 0;
adb_cond_broadcast(&h->notify);
/* cancel any pending transactions
** these will quietly fail if the txns are not active,
** but this ensures that a reader blocked on REAPURB
** will get unblocked
*/
ioctl(h->desc, USBDEVFS_DISCARDURB, &h->urb_in);
ioctl(h->desc, USBDEVFS_DISCARDURB, &h->urb_out);
h->urb_in.status = -ENODEV;
h->urb_out.status = -ENODEV;
h->urb_in_busy = 0;
h->urb_out_busy = 0;
adb_cond_broadcast(&h->notify);
} else {
unregister_usb_transport(h);
}
}
adb_mutex_unlock(&h->lock);
}
@ -580,11 +528,11 @@ int usb_close(usb_handle *h)
static void register_device(const char *dev_name,
unsigned char ep_in, unsigned char ep_out,
int interface,
const char *serial, unsigned zero_mask)
int interface, int serial_index, unsigned zero_mask)
{
usb_handle* usb = 0;
int n = 0;
char serial[256];
/* Since Linux will not reassign the device ID (and dev_name)
** as long as the device is open, we can add to the list here
@ -610,6 +558,7 @@ static void register_device(const char *dev_name,
usb->ep_in = ep_in;
usb->ep_out = ep_out;
usb->zero_mask = zero_mask;
usb->writeable = 1;
adb_cond_init(&usb->notify, 0);
adb_mutex_init(&usb->lock, 0);
@ -618,10 +567,66 @@ static void register_device(const char *dev_name,
usb->reaper_thread = 0;
usb->desc = unix_open(usb->fname, O_RDWR);
if(usb->desc < 0) goto fail;
D("[ usb open %s fd = %d]\n", usb->fname, usb->desc);
n = ioctl(usb->desc, USBDEVFS_CLAIMINTERFACE, &interface);
if(n != 0) goto fail;
if(usb->desc < 0) {
/* if we fail, see if have read-only access */
usb->desc = unix_open(usb->fname, O_RDONLY);
if(usb->desc < 0) goto fail;
usb->writeable = 0;
D("[ usb open read-only %s fd = %d]\n", usb->fname, usb->desc);
} else {
D("[ usb open %s fd = %d]\n", usb->fname, usb->desc);
n = ioctl(usb->desc, USBDEVFS_CLAIMINTERFACE, &interface);
if(n != 0) goto fail;
}
/* read the device's serial number */
serial[0] = 0;
memset(serial, 0, sizeof(serial));
if (serial_index) {
struct usbdevfs_ctrltransfer ctrl;
__u16 buffer[128];
__u16 languages[128];
int i, result;
int languageCount = 0;
memset(languages, 0, sizeof(languages));
memset(&ctrl, 0, sizeof(ctrl));
// read list of supported languages
ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE;
ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
ctrl.wValue = (USB_DT_STRING << 8) | 0;
ctrl.wIndex = 0;
ctrl.wLength = sizeof(languages);
ctrl.data = languages;
result = ioctl(usb->desc, USBDEVFS_CONTROL, &ctrl);
if (result > 0)
languageCount = (result - 2) / 2;
for (i = 1; i <= languageCount; i++) {
memset(buffer, 0, sizeof(buffer));
memset(&ctrl, 0, sizeof(ctrl));
ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE;
ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
ctrl.wValue = (USB_DT_STRING << 8) | serial_index;
ctrl.wIndex = languages[i];
ctrl.wLength = sizeof(buffer);
ctrl.data = buffer;
result = ioctl(usb->desc, USBDEVFS_CONTROL, &ctrl);
if (result > 0) {
int i;
// skip first word, and copy the rest to the serial string, changing shorts to bytes.
result /= 2;
for (i = 1; i < result; i++)
serial[i - 1] = buffer[i];
serial[i - 1] = 0;
break;
}
}
}
/* add to the end of the active handles */
adb_mutex_lock(&usb_lock);
@ -631,7 +636,7 @@ static void register_device(const char *dev_name,
usb->next->prev = usb;
adb_mutex_unlock(&usb_lock);
register_usb_transport(usb, serial);
register_usb_transport(usb, serial, usb->writeable);
return;
fail:

View File

@ -72,7 +72,7 @@ static void *usb_open_thread(void *x)
usb->fd = fd;
D("[ usb_thread - registering device ]\n");
register_usb_transport(usb, 0);
register_usb_transport(usb, 0, 1);
}
// never gets here

View File

@ -194,30 +194,54 @@ AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
kr = (*dev)->GetDeviceProduct(dev, &product);
kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex);
if (serialIndex > 0) {
IOUSBDevRequest req;
UInt16 buffer[256];
if (serialIndex > 0) {
IOUSBDevRequest req;
UInt16 buffer[256];
UInt16 languages[128];
req.bmRequestType =
USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
req.bRequest = kUSBRqGetDescriptor;
req.wValue = (kUSBStringDesc << 8) | serialIndex;
req.wIndex = 0;
req.pData = buffer;
req.wLength = sizeof(buffer);
kr = (*dev)->DeviceRequest(dev, &req);
memset(languages, 0, sizeof(languages));
if (kr == kIOReturnSuccess && req.wLenDone > 0) {
int i, count;
req.bmRequestType =
USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
req.bRequest = kUSBRqGetDescriptor;
req.wValue = (kUSBStringDesc << 8) | 0;
req.wIndex = 0;
req.pData = languages;
req.wLength = sizeof(languages);
kr = (*dev)->DeviceRequest(dev, &req);
// skip first word, and copy the rest to the serial string,
// changing shorts to bytes.
count = (req.wLenDone - 1) / 2;
for (i = 0; i < count; i++)
serial[i] = buffer[i + 1];
serial[i] = 0;
}
}
if (kr == kIOReturnSuccess && req.wLenDone > 0) {
int langCount = (req.wLenDone - 2) / 2, lang;
for (lang = 1; lang <= langCount; lang++) {
memset(buffer, 0, sizeof(buffer));
memset(&req, 0, sizeof(req));
req.bmRequestType =
USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
req.bRequest = kUSBRqGetDescriptor;
req.wValue = (kUSBStringDesc << 8) | serialIndex;
req.wIndex = languages[lang];
req.pData = buffer;
req.wLength = sizeof(buffer);
kr = (*dev)->DeviceRequest(dev, &req);
if (kr == kIOReturnSuccess && req.wLenDone > 0) {
int i, count;
// skip first word, and copy the rest to the serial string,
// changing shorts to bytes.
count = (req.wLenDone - 1) / 2;
for (i = 0; i < count; i++)
serial[i] = buffer[i + 1];
serial[i] = 0;
break;
}
}
}
}
(*dev)->Release(dev);
DBG("INFO: Found vid=%04x pid=%04x serial=%s\n", vendor, product,
@ -232,7 +256,7 @@ AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
}
DBG("AndroidDeviceAdded calling register_usb_transport\n");
register_usb_transport(handle, (serial[0] ? serial : NULL));
register_usb_transport(handle, (serial[0] ? serial : NULL), 1);
// Register for an interest notification of this device being removed.
// Pass the reference to our private data as the refCon for the

View File

@ -43,6 +43,14 @@
#define VENDOR_ID_SAMSUNG 0x04e8
// Motorola's USB Vendor ID
#define VENDOR_ID_MOTOROLA 0x22b8
// LG's USB Vendor ID
#define VENDOR_ID_LGE 0x1004
// Huawei's USB Vendor ID
#define VENDOR_ID_HUAWEI 0x12D1
// Acer's USB Vendor ID
#define VENDOR_ID_ACER 0x0502
// Sony Ericsson's USB Vendor ID
#define VENDOR_ID_SONY_ERICSSON 0x0FCE
/** built-in vendor list */
int builtInVendorIds[] = {
@ -50,6 +58,10 @@ int builtInVendorIds[] = {
VENDOR_ID_HTC,
VENDOR_ID_SAMSUNG,
VENDOR_ID_MOTOROLA,
VENDOR_ID_LGE,
VENDOR_ID_HUAWEI,
VENDOR_ID_ACER,
VENDOR_ID_SONY_ERICSSON,
};
#define BUILT_IN_VENDOR_COUNT (sizeof(builtInVendorIds)/sizeof(builtInVendorIds[0]))

View File

@ -488,7 +488,7 @@ void find_devices() {
true)) {
// Lets make sure that we don't duplicate this device
if (register_new_device(handle)) {
register_usb_transport(handle, serial_number);
register_usb_transport(handle, serial_number, 1);
} else {
D("register_new_device failed for %s\n", interf_name);
usb_cleanup_handle(handle);

View File

@ -2,16 +2,16 @@
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
@ -48,8 +48,6 @@ extern int unwind_backtrace_with_ptrace(int tfd, pid_t pid, mapinfo *map,
int *frame0_pc_sane,
bool at_fault);
static char **process_name_ptr;
static int logsocket = -1;
#define ANDROID_LOG_INFO 4
@ -58,7 +56,7 @@ static int logsocket = -1;
void _LOG(int tfd, bool in_tombstone_only, const char *fmt, ...)
{
char buf[128];
va_list ap;
va_start(ap, fmt);
@ -91,16 +89,16 @@ mapinfo *parse_maps_line(char *line)
if(len < 1) return 0;
line[--len] = 0;
if(len < 50) return 0;
if(line[20] != 'x') return 0;
mi = malloc(sizeof(mapinfo) + (len - 47));
if(mi == 0) return 0;
mi->start = strtoul(line, 0, 16);
mi->end = strtoul(line + 9, 0, 16);
/* To be filled in parse_exidx_info if the mapped section starts with
/* To be filled in parse_exidx_info if the mapped section starts with
* elf_header
*/
mi->exidx_start = mi->exidx_end = 0;
@ -120,7 +118,7 @@ void dump_build_info(int tfd)
}
void dump_stack_and_code(int tfd, int pid, mapinfo *map,
void dump_stack_and_code(int tfd, int pid, mapinfo *map,
int unwind_depth, unsigned int sp_list[],
int frame0_pc_sane, bool at_fault)
{
@ -128,6 +126,7 @@ void dump_stack_and_code(int tfd, int pid, mapinfo *map,
struct pt_regs r;
int sp_depth;
bool only_in_tombstone = !at_fault;
char code_buffer[80];
if(ptrace(PTRACE_GETREGS, pid, 0, &r)) return;
sp = r.ARM_sp;
@ -140,26 +139,53 @@ void dump_stack_and_code(int tfd, int pid, mapinfo *map,
pc = r.ARM_lr;
}
_LOG(tfd, true, "code%s:\n", frame0_pc_sane ? "" : " (around frame #01)");
_LOG(tfd, only_in_tombstone,
"\ncode around %s:\n", frame0_pc_sane ? "pc" : "lr");
end = p = pc & ~3;
p -= 16;
end += 16;
/* Dump the code as:
* PC contents
/* Dump the code around PC as:
* addr contents
* 00008d34 fffffcd0 4c0eb530 b0934a0e 1c05447c
* 00008d44 f7ff18a0 490ced94 68035860 d0012b00
*/
while (p <= end) {
int i;
_LOG(tfd, true, " %08x ", p);
sprintf(code_buffer, "%08x ", p);
for (i = 0; i < 4; i++) {
data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL);
_LOG(tfd, true, " %08x", data);
sprintf(code_buffer + strlen(code_buffer), "%08x ", data);
p += 4;
}
_LOG(tfd, true, "\n", p);
_LOG(tfd, only_in_tombstone, "%s\n", code_buffer);
}
if (frame0_pc_sane) {
_LOG(tfd, only_in_tombstone, "\ncode around lr:\n");
end = p = r.ARM_lr & ~3;
p -= 16;
end += 16;
/* Dump the code around LR as:
* addr contents
* 00008d34 fffffcd0 4c0eb530 b0934a0e 1c05447c
* 00008d44 f7ff18a0 490ced94 68035860 d0012b00
*/
while (p <= end) {
int i;
sprintf(code_buffer, "%08x ", p);
for (i = 0; i < 4; i++) {
data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL);
sprintf(code_buffer + strlen(code_buffer), "%08x ", data);
p += 4;
}
_LOG(tfd, only_in_tombstone, "%s\n", code_buffer);
}
}
p = sp - 64;
@ -177,7 +203,7 @@ void dump_stack_and_code(int tfd, int pid, mapinfo *map,
end += 0xff;
}
_LOG(tfd, only_in_tombstone, "stack:\n");
_LOG(tfd, only_in_tombstone, "\nstack:\n");
/* If the crash is due to PC == 0, there will be two frames that
* have identical SP value.
@ -190,7 +216,7 @@ void dump_stack_and_code(int tfd, int pid, mapinfo *map,
}
while (p <= end) {
char *prompt;
char *prompt;
char level[16];
data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL);
if (p == sp_list[sp_depth]) {
@ -200,12 +226,12 @@ void dump_stack_and_code(int tfd, int pid, mapinfo *map,
else {
prompt = " ";
}
/* Print the stack content in the log for the first 3 frames. For the
* rest only print them in the tombstone file.
*/
_LOG(tfd, (sp_depth > 2) || only_in_tombstone,
"%s %08x %08x %s\n", prompt, p, data,
_LOG(tfd, (sp_depth > 2) || only_in_tombstone,
"%s %08x %08x %s\n", prompt, p, data,
map_to_name(map, data, ""));
p += 4;
}
@ -214,14 +240,14 @@ void dump_stack_and_code(int tfd, int pid, mapinfo *map,
end = p+64;
while (p <= end) {
data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL);
_LOG(tfd, (sp_depth > 2) || only_in_tombstone,
" %08x %08x %s\n", p, data,
_LOG(tfd, (sp_depth > 2) || only_in_tombstone,
" %08x %08x %s\n", p, data,
map_to_name(map, data, ""));
p += 4;
}
}
void dump_pc_and_lr(int tfd, int pid, mapinfo *map, int unwound_level,
void dump_pc_and_lr(int tfd, int pid, mapinfo *map, int unwound_level,
bool at_fault)
{
struct pt_regs r;
@ -239,26 +265,26 @@ void dump_pc_and_lr(int tfd, int pid, mapinfo *map, int unwound_level,
map_to_name(map, r.ARM_lr, "<unknown>"));
}
void dump_registers(int tfd, int pid, bool at_fault)
void dump_registers(int tfd, int pid, bool at_fault)
{
struct pt_regs r;
bool only_in_tombstone = !at_fault;
if(ptrace(PTRACE_GETREGS, pid, 0, &r)) {
_LOG(tfd, only_in_tombstone,
_LOG(tfd, only_in_tombstone,
"cannot get registers: %s\n", strerror(errno));
return;
}
_LOG(tfd, only_in_tombstone, " r0 %08x r1 %08x r2 %08x r3 %08x\n",
r.ARM_r0, r.ARM_r1, r.ARM_r2, r.ARM_r3);
_LOG(tfd, only_in_tombstone, " r4 %08x r5 %08x r6 %08x r7 %08x\n",
r.ARM_r4, r.ARM_r5, r.ARM_r6, r.ARM_r7);
_LOG(tfd, only_in_tombstone, " r8 %08x r9 %08x 10 %08x fp %08x\n",
r.ARM_r8, r.ARM_r9, r.ARM_r10, r.ARM_fp);
_LOG(tfd, only_in_tombstone,
_LOG(tfd, only_in_tombstone,
" ip %08x sp %08x lr %08x pc %08x cpsr %08x\n",
r.ARM_ip, r.ARM_sp, r.ARM_lr, r.ARM_pc, r.ARM_cpsr);
r.ARM_ip, r.ARM_sp, r.ARM_lr, r.ARM_pc, r.ARM_cpsr);
}
const char *get_signame(int sig)
@ -277,7 +303,7 @@ const char *get_signame(int sig)
void dump_fault_addr(int tfd, int pid, int sig)
{
siginfo_t si;
memset(&si, 0, sizeof(si));
if(ptrace(PTRACE_GETSIGINFO, pid, 0, &si)){
_LOG(tfd, false, "cannot get siginfo: %s\n", strerror(errno));
@ -292,20 +318,20 @@ void dump_crash_banner(int tfd, unsigned pid, unsigned tid, int sig)
char data[1024];
char *x = 0;
FILE *fp;
sprintf(data, "/proc/%d/cmdline", pid);
fp = fopen(data, "r");
if(fp) {
x = fgets(data, 1024, fp);
fclose(fp);
}
_LOG(tfd, false,
"*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
dump_build_info(tfd);
_LOG(tfd, false, "pid: %d, tid: %d >>> %s <<<\n",
pid, tid, x ? x : "UNKNOWN");
if(sig) dump_fault_addr(tfd, tid, sig);
}
@ -316,10 +342,10 @@ static void parse_exidx_info(mapinfo *milist, pid_t pid)
Elf32_Ehdr ehdr;
memset(&ehdr, 0, sizeof(Elf32_Ehdr));
/* Read in sizeof(Elf32_Ehdr) worth of data from the beginning of
/* Read in sizeof(Elf32_Ehdr) worth of data from the beginning of
* mapped section.
*/
get_remote_struct(pid, (void *) (mi->start), &ehdr,
get_remote_struct(pid, (void *) (mi->start), &ehdr,
sizeof(Elf32_Ehdr));
/* Check if it has the matching magic words */
if (IS_ELF(ehdr)) {
@ -330,7 +356,7 @@ static void parse_exidx_info(mapinfo *milist, pid_t pid)
ptr = (Elf32_Phdr *) (mi->start + ehdr.e_phoff);
for (i = 0; i < ehdr.e_phnum; i++) {
/* Parse the program header */
get_remote_struct(pid, (void *) ptr+i, &phdr,
get_remote_struct(pid, (char *) ptr+i, &phdr,
sizeof(Elf32_Phdr));
/* Found a EXIDX segment? */
if (phdr.p_type == PT_ARM_EXIDX) {
@ -351,7 +377,7 @@ void dump_crash_report(int tfd, unsigned pid, unsigned tid, bool at_fault)
unsigned int sp_list[STACK_CONTENT_DEPTH];
int stack_depth;
int frame0_pc_sane = 1;
if (!at_fault) {
_LOG(tfd, true,
"--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n");
@ -359,7 +385,7 @@ void dump_crash_report(int tfd, unsigned pid, unsigned tid, bool at_fault)
}
dump_registers(tfd, tid, at_fault);
/* Clear stack pointer records */
memset(sp_list, 0, sizeof(sp_list));
@ -401,40 +427,6 @@ void dump_crash_report(int tfd, unsigned pid, unsigned tid, bool at_fault)
}
}
/* FIXME: unused: use it or lose it*/
#if 0
static
void start_gdbserver_vs(int pid, int port)
{
pid_t p;
char *args[5];
char commspec[16];
char pidspec[16];
p = fork();
if(p < 0) {
LOG("could not fork()\n");
return;
}
if(p == 0) {
sprintf(commspec, ":%d", port);
sprintf(pidspec, "%d", pid);
args[0] = "/system/bin/gdbserver";
args[1] = commspec;
args[2] = "--attach";
args[3] = pidspec;
args[4] = 0;
exit(execv(args[0], args));
} else {
LOG("gdbserver pid=%d port=%d targetpid=%d\n",
p, port, pid);
sleep(5);
}
}
#endif
#define MAX_TOMBSTONES 10
#define typecheck(x,y) { \
@ -514,7 +506,7 @@ static bool dump_sibling_thread_report(int tfd, unsigned pid, unsigned tid)
while ((de = readdir(d)) != NULL) {
unsigned new_tid;
/* Ignore "." and ".." */
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
continue;
new_tid = atoi(de->d_name);
/* The main thread at fault has been handled individually */
@ -533,7 +525,7 @@ static bool dump_sibling_thread_report(int tfd, unsigned pid, unsigned tid)
}
/* Return true if some thread is not detached cleanly */
static bool engrave_tombstone(unsigned pid, unsigned tid, int debug_uid,
static bool engrave_tombstone(unsigned pid, unsigned tid, int debug_uid,
int signal)
{
int fd;
@ -548,7 +540,7 @@ static bool engrave_tombstone(unsigned pid, unsigned tid, int debug_uid,
dump_crash_banner(fd, pid, tid, signal);
dump_crash_report(fd, pid, tid, true);
/*
/*
* If the user has requested to attach gdb, don't collect the per-thread
* information as it increases the chance to lose track of the process.
*/
@ -619,7 +611,7 @@ static void wait_for_user_action(unsigned tid, struct ucred* cr)
"* adb shell gdbserver :port --attach %d & \n"
"* \n"
"* and press the HOME key. \n"
"********************************************************\n",
"********************************************************\n",
cr->pid, cr->pid);
/* wait for HOME key */
@ -653,13 +645,13 @@ static void wait_for_user_action(unsigned tid, struct ucred* cr)
disable_debug_led();
}
}
} while (!home);
} while (!home);
uninit_getevent();
}
/* don't forget to turn debug led off */
disable_debug_led();
/* close filedescriptor */
LOG("debuggerd resuming process %d", cr->pid);
}
@ -670,7 +662,7 @@ static void handle_crashing_process(int fd)
struct stat s;
unsigned tid;
struct ucred cr;
int n, len, status;
int n, len, status;
int tid_attach_status = -1;
unsigned retry = 30;
bool need_cleanup = false;
@ -678,9 +670,9 @@ static void handle_crashing_process(int fd)
char value[PROPERTY_VALUE_MAX];
property_get("debug.db.uid", value, "-1");
int debug_uid = atoi(value);
XLOG("handle_crashing_process(%d)\n", fd);
len = sizeof(cr);
n = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
if(n != 0) {
@ -688,7 +680,7 @@ static void handle_crashing_process(int fd)
goto done;
}
XLOG("reading tid\n");
XLOG("reading tid\n");
fcntl(fd, F_SETFL, O_NONBLOCK);
while((n = read(fd, &tid, sizeof(unsigned))) != sizeof(unsigned)) {
if(errno == EINTR) continue;
@ -711,7 +703,7 @@ static void handle_crashing_process(int fd)
close(fd);
return;
}
XLOG("BOOM: pid=%d uid=%d gid=%d tid=%d\n", cr.pid, cr.uid, cr.gid, tid);
tid_attach_status = ptrace(PTRACE_ATTACH, tid, 0, 0);
@ -725,7 +717,7 @@ static void handle_crashing_process(int fd)
for(;;) {
n = waitpid(tid, &status, __WALL);
if(n < 0) {
if(errno == EAGAIN) continue;
LOG("waitpid failed: %s\n", strerror(errno));
@ -745,7 +737,7 @@ static void handle_crashing_process(int fd)
goto done;
}
continue;
case SIGILL:
case SIGABRT:
case SIGBUS:
@ -767,17 +759,17 @@ static void handle_crashing_process(int fd)
goto done;
}
}
done:
XLOG("detaching\n");
/* stop the process so we can debug */
kill(cr.pid, SIGSTOP);
/*
* If a thread has been attached by ptrace, make sure it is detached
/*
* If a thread has been attached by ptrace, make sure it is detached
* successfully otherwise we will get a zombie.
*/
*/
if (tid_attach_status == 0) {
int detach_status;
/* detach so we can attach gdbserver */
@ -807,14 +799,12 @@ done:
if(fd != -1) close(fd);
}
int main(int argc, char **argv)
int main()
{
int s;
struct sigaction act;
process_name_ptr = argv;
logsocket = socket_local_client("logd",
logsocket = socket_local_client("logd",
ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_DGRAM);
if(logsocket < 0) {
logsocket = -1;
@ -827,23 +817,23 @@ int main(int argc, char **argv)
sigaddset(&act.sa_mask,SIGCHLD);
act.sa_flags = SA_NOCLDWAIT;
sigaction(SIGCHLD, &act, 0);
s = socket_local_server("android:debuggerd",
s = socket_local_server("android:debuggerd",
ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
if(s < 0) return -1;
fcntl(s, F_SETFD, FD_CLOEXEC);
LOG("debuggerd: " __DATE__ " " __TIME__ "\n");
for(;;) {
struct sockaddr addr;
socklen_t alen;
int fd;
alen = sizeof(addr);
fd = accept(s, &addr, &alen);
if(fd < 0) continue;
fcntl(fd, F_SETFD, FD_CLOEXEC);
handle_crashing_process(fd);

View File

@ -147,9 +147,11 @@ oops:
int match_fastboot(usb_ifc_info *info)
{
if(!(vendor_id && (info->dev_vendor == vendor_id)) &&
(info->dev_vendor != 0x18d1) &&
(info->dev_vendor != 0x18d1) && // Google
(info->dev_vendor != 0x0451) &&
(info->dev_vendor != 0x0bb4)) return -1;
(info->dev_vendor != 0x22b8) && // Motorola
(info->dev_vendor != 0x0bb4)) // HTC
return -1;
if(info->ifc_class != 0xff) return -1;
if(info->ifc_subclass != 0x42) return -1;
if(info->ifc_protocol != 0x03) return -1;

View File

@ -51,7 +51,9 @@
#include "usb.h"
#if TRACE_USB
#define MAX_RETRIES 5
#ifdef TRACE_USB
#define DBG1(x...) fprintf(stderr, x)
#define DBG(x...) fprintf(stderr, x)
#else
@ -303,7 +305,7 @@ int usb_read(usb_handle *h, void *_data, int len)
unsigned char *data = (unsigned char*) _data;
unsigned count = 0;
struct usbdevfs_bulktransfer bulk;
int n;
int n, retry;
if(h->ep_in == 0) {
return -1;
@ -316,16 +318,20 @@ int usb_read(usb_handle *h, void *_data, int len)
bulk.len = xfer;
bulk.data = data;
bulk.timeout = 0;
DBG("[ usb read %d fd = %d], fname=%s\n", xfer, h->desc, h->fname);
n = ioctl(h->desc, USBDEVFS_BULK, &bulk);
DBG("[ usb read %d ] = %d, fname=%s\n", xfer, n, h->fname);
retry = 0;
if(n < 0) {
DBG1("ERROR: n = %d, errno = %d (%s)\n",
n, errno, strerror(errno));
return -1;
do{
DBG("[ usb read %d fd = %d], fname=%s\n", xfer, h->desc, h->fname);
n = ioctl(h->desc, USBDEVFS_BULK, &bulk);
DBG("[ usb read %d ] = %d, fname=%s, Retry %d \n", xfer, n, h->fname, retry);
if( n < 0 ) {
DBG1("ERROR: n = %d, errno = %d (%s)\n",n, errno, strerror(errno));
if ( ++retry > MAX_RETRIES ) return -1;
sleep( 1 );
}
}
while( n < 0 );
count += n;
len -= n;

View File

@ -26,7 +26,6 @@
* SUCH DAMAGE.
*/
#include <utils/executablepath.h>
#import <Carbon/Carbon.h>
#include <unistd.h>

92
include/acc/acc.h Normal file
View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_ACC_ACC_H
#define ANDROID_ACC_ACC_H
#include <stdint.h>
#include <sys/types.h>
typedef char ACCchar;
typedef int32_t ACCint;
typedef uint32_t ACCuint;
typedef ssize_t ACCsizei;
typedef unsigned int ACCenum;
typedef void ACCvoid;
typedef struct ACCscript ACCscript;
#define ACC_NO_ERROR 0x0000
#define ACC_INVALID_ENUM 0x0500
#define ACC_INVALID_OPERATION 0x0502
#define ACC_INVALID_VALUE 0x0501
#define ACC_OUT_OF_MEMORY 0x0505
#define ACC_COMPILE_STATUS 0x8B81
#define ACC_INFO_LOG_LENGTH 0x8B84
// ----------------------------------------------------------------------------
#ifdef __cplusplus
extern "C" {
#endif
ACCscript* accCreateScript();
void accDeleteScript(ACCscript* script);
typedef ACCvoid* (*ACCSymbolLookupFn)(ACCvoid* pContext, const ACCchar * name);
void accRegisterSymbolCallback(ACCscript* script, ACCSymbolLookupFn pFn,
ACCvoid* pContext);
ACCenum accGetError( ACCscript* script );
void accScriptSource(ACCscript* script,
ACCsizei count,
const ACCchar** string,
const ACCint* length);
void accCompileScript(ACCscript* script);
void accGetScriptiv(ACCscript* script,
ACCenum pname,
ACCint* params);
void accGetScriptInfoLog(ACCscript* script,
ACCsizei maxLength,
ACCsizei* length,
ACCchar* infoLog);
void accGetScriptLabel(ACCscript* script, const ACCchar * name,
ACCvoid** address);
void accGetPragmas(ACCscript* script, ACCsizei* actualStringCount,
ACCsizei maxStringCount, ACCchar** strings);
/* Used to implement disassembly */
void accGetProgramBinary(ACCscript* script,
ACCvoid** base,
ACCsizei* length);
#ifdef __cplusplus
};
#endif
// ----------------------------------------------------------------------------
#endif

View File

@ -15,9 +15,7 @@
*/
/*
* Android config -- "Darwin". Used for PPC Mac OS X.
*
* TODO: split this into "x86" and "ppc" versions
* Android config -- "Darwin". Used for X86 Mac OS X.
*/
#ifndef _ANDROID_CONFIG_H
#define _ANDROID_CONFIG_H
@ -257,4 +255,19 @@
*/
#define HAVE_WRITEV 1
/*
* Define if <stdint.h> exists.
*/
#define HAVE_STDINT_H 1
/*
* Define if <stdbool.h> exists.
*/
#define HAVE_STDBOOL_H 1
/*
* Define if <sched.h> exists.
*/
#define HAVE_SCHED_H 1
#endif /*_ANDROID_CONFIG_H*/

View File

@ -0,0 +1,332 @@
/*
* Copyright (C) 2005 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Android config -- "FreeBSD". Used for desktop x86 FreeBSD.
*/
#ifndef _ANDROID_CONFIG_H
#define _ANDROID_CONFIG_H
/*
* make sure we are building for FreeBSD
*/
#ifndef OS_FREEBSD
#define OS_FREEBSD
#endif
/*
* ===========================================================================
* !!! IMPORTANT !!!
* ===========================================================================
*
* This file is included by ALL C/C++ source files. Don't put anything in
* here unless you are absolutely certain it can't go anywhere else.
*
* Any C++ stuff must be wrapped with "#ifdef __cplusplus". Do not use "//"
* comments.
*/
/*
* Threading model. Choose one:
*
* HAVE_PTHREADS - use the pthreads library.
* HAVE_WIN32_THREADS - use Win32 thread primitives.
* -- combine HAVE_CREATETHREAD, HAVE_CREATEMUTEX, and HAVE__BEGINTHREADEX
*/
#define HAVE_PTHREADS
/*
* Do we have the futex syscall?
*/
/* #define HAVE_FUTEX */
/*
* Process creation model. Choose one:
*
* HAVE_FORKEXEC - use fork() and exec()
* HAVE_WIN32_PROC - use CreateProcess()
*/
#define HAVE_FORKEXEC
/*
* Process out-of-memory adjustment. Set if running on Linux,
* where we can write to /proc/<pid>/oom_adj to modify the out-of-memory
* badness adjustment.
*/
/* #define HAVE_OOM_ADJ */
/*
* IPC model. Choose one:
*
* HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget).
* HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap).
* HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping).
* HAVE_ANDROID_IPC - use Android versions (?, mmap).
*/
#define HAVE_SYSV_IPC
/*
* Memory-mapping model. Choose one:
*
* HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h
* HAVE_WIN32_FILEMAP - use Win32 filemaps
*/
#define HAVE_POSIX_FILEMAP
/*
* Define this if you have <termio.h>
*/
/* #define HAVE_TERMIO_H */
/*
* Define this if you build against MSVCRT.DLL
*/
/* #define HAVE_MS_C_RUNTIME */
/*
* Define this if you have sys/uio.h
*/
#define HAVE_SYS_UIO_H
/*
* Define this if your platforms implements symbolic links
* in its filesystems
*/
#define HAVE_SYMLINKS
/*
* Define this if we have localtime_r().
*/
#define HAVE_LOCALTIME_R
/*
* Define this if we have gethostbyname_r().
*/
/* #define HAVE_GETHOSTBYNAME_R */
/*
* Define this if we have ioctl().
*/
#define HAVE_IOCTL
/*
* Define this if we want to use WinSock.
*/
/* #define HAVE_WINSOCK */
/*
* Define this if have clock_gettime() and friends
*
* Desktop Linux has this in librt, but it's broken in goobuntu, yielding
* mildly or wildly inaccurate results.
*/
#define HAVE_POSIX_CLOCKS
/*
* Define this if we have pthread_cond_timedwait_monotonic() and
* clock_gettime(CLOCK_MONOTONIC).
*/
/* #define HAVE_TIMEDWAIT_MONOTONIC */
/*
* Define this if we have linux style epoll()
*/
/* #define HAVE_EPOLL */
/*
* Endianness of the target machine. Choose one:
*
* HAVE_ENDIAN_H -- have endian.h header we can include.
* HAVE_LITTLE_ENDIAN -- we are little endian.
* HAVE_BIG_ENDIAN -- we are big endian.
*/
/* #define HAVE_ENDIAN_H */
#define HAVE_LITTLE_ENDIAN
/*
* Define this if you have sys/endian.h
* NOTE: mutually exclusive with HAVE_ENDIAN_H
*/
#define HAVE_SYS_ENDIAN_H
/*
* We need to choose between 32-bit and 64-bit off_t. All of our code should
* agree on the same size. For desktop systems, use 64-bit values,
* because some of our libraries (e.g. wxWidgets) expect to be built that way.
*/
#define _FILE_OFFSET_BITS 64
#define _LARGEFILE_SOURCE 1
/*
* Defined if we have the backtrace() call for retrieving a stack trace.
* Needed for CallStack to operate; if not defined, CallStack is
* non-functional.
*/
#define HAVE_BACKTRACE 0
/*
* Defined if we have the dladdr() call for retrieving the symbol associated
* with a memory address. If not defined, stack crawls will not have symbolic
* information.
*/
#define HAVE_DLADDR 1
/*
* Defined if we have the cxxabi.h header for demangling C++ symbols. If
* not defined, stack crawls will be displayed with raw mangled symbols
*/
#define HAVE_CXXABI 0
/*
* Defined if we have the gettid() system call.
*/
/* #define HAVE_GETTID */
/*
* Defined if we have the sched_setscheduler() call
*/
#define HAVE_SCHED_SETSCHEDULER
/*
* Add any extra platform-specific defines here.
*/
/*
* Define if we have <malloc.h> header
*/
#define HAVE_MALLOC_H
/*
* Define if we have Linux-style non-filesystem Unix Domain Sockets
*/
/*
* What CPU architecture does this platform use?
*/
#define ARCH_X86
/*
* Define if we have Linux's inotify in <sys/inotify.h>.
*/
/*#define HAVE_INOTIFY 1*/
/*
* Define if we have madvise() in <sys/mman.h>
*/
#define HAVE_MADVISE 1
/*
* Define if tm struct has tm_gmtoff field
*/
#define HAVE_TM_GMTOFF 1
/*
* Define if dirent struct has d_type field
*/
#define HAVE_DIRENT_D_TYPE 1
/*
* Define if libc includes Android system properties implementation.
*/
/* #define HAVE_LIBC_SYSTEM_PROPERTIES */
/*
* Define if system provides a system property server (should be
* mutually exclusive with HAVE_LIBC_SYSTEM_PROPERTIES).
*/
#define HAVE_SYSTEM_PROPERTY_SERVER
/*
* sprintf() format string for shared library naming.
*/
#define OS_SHARED_LIB_FORMAT_STR "lib%s.so"
/*
* type for the third argument to mincore().
*/
#define MINCORE_POINTER_TYPE char *
/*
* Do we have the sigaction flag SA_NOCLDWAIT?
*/
#define HAVE_SA_NOCLDWAIT
/*
* Define if we include <sys/mount.h> for statfs()
*/
#define INCLUDE_SYS_MOUNT_FOR_STATFS 1
/*
* The default path separator for the platform
*/
#define OS_PATH_SEPARATOR '/'
/*
* Is the filesystem case sensitive?
*/
#define OS_CASE_SENSITIVE
/*
* Define if <sys/socket.h> exists.
*/
#define HAVE_SYS_SOCKET_H 1
/*
* Define if the strlcpy() function exists on the system.
*/
#define HAVE_STRLCPY 1
/*
* Define if prctl() exists
*/
/* #define HAVE_PRCTL 1 */
/*
* Define if writev() exists
*/
#define HAVE_WRITEV 1
/*
* Define if <alloca.h> does not exist
* NOTE: <alloca.h> defines alloca() which
* on FreeBSD is defined in <stdlib.h>
*/
#define HAVE_NO_ALLOCA_H
/*
* Defines CLOCK_PROCESS_CPUTIME_ID for clock_gettime()
* XXX: CLOCK_PROF seems to be commonly used replacement
*/
#ifndef CLOCK_PROCESS_CPUTIME_ID
#define CLOCK_PROCESS_CPUTIME_ID CLOCK_PROF
#endif
/*
* Define if <stdint.h> exists.
*/
/* #define HAVE_STDINT_H */
/*
* Define if <stdbool.h> exists.
*/
/* #define HAVE_STDBOOL_H */
/*
* Define if <sched.h> exists.
*/
#define HAVE_SCHED_H 1
#endif /*_ANDROID_CONFIG_H*/

View File

@ -302,4 +302,19 @@
*/
#define HAVE_WRITEV 1
/*
* Define if <stdint.h> exists.
*/
#define HAVE_STDINT_H 1
/*
* Define if <stdbool.h> exists.
*/
#define HAVE_STDBOOL_H 1
/*
* Define if <sched.h> exists.
*/
#define HAVE_SCHED_H 1
#endif /* _ANDROID_CONFIG_H */

View File

@ -283,4 +283,19 @@
*/
#define HAVE_WRITEV 1
/*
* Define if <stdint.h> exists.
*/
#define HAVE_STDINT_H 1
/*
* Define if <stdbool.h> exists.
*/
#define HAVE_STDBOOL_H 1
/*
* Define if <sched.h> exists.
*/
#define HAVE_SCHED_H 1
#endif /*_ANDROID_CONFIG_H*/

View File

@ -293,4 +293,19 @@
*/
#define HAVE_UNWIND_CONTEXT_STRUCT
/*
* Define if <stdint.h> exists.
*/
#define HAVE_STDINT_H 1
/*
* Define if <stdbool.h> exists.
*/
#define HAVE_STDBOOL_H 1
/*
* Define if <sched.h> exists.
*/
#define HAVE_SCHED_H 1
#endif /* _ANDROID_CONFIG_H */

View File

@ -287,4 +287,19 @@
*/
/* #define HAVE_WRITEV */
/*
* Define if <stdint.h> exists.
*/
/* #define HAVE_STDINT_H */
/*
* Define if <stdbool.h> exists.
*/
/* #define HAVE_STDBOOL_H */
/*
* Define if <sched.h> exists.
*/
/* #define HAVE_SCHED_H */
#endif /*_ANDROID_CONFIG_H*/

View File

@ -0,0 +1,103 @@
/*
* Copyright 2009, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Helper to perform abortable blocking operations on a socket:
* asocket_connect()
* asocket_accept()
* asocket_read()
* asocket_write()
* These calls are similar to the regular syscalls, but can be aborted with:
* asocket_abort()
*
* Calling close() on a regular POSIX socket does not abort blocked syscalls on
* that socket in other threads.
*
* After calling asocket_abort() the socket cannot be reused.
*
* Call asocket_destory() *after* all threads have finished with the socket to
* finish closing the socket and free the asocket structure.
*
* The helper is implemented by setting the socket non-blocking to initiate
* syscalls connect(), accept(), read(), write(), then using a blocking poll()
* on both the primary socket and a local pipe. This makes the poll() abortable
* by writing a byte to the local pipe in asocket_abort().
*
* asocket_create() sets the fd to non-blocking mode. It must not be changed to
* blocking mode.
*
* Using asocket will triple the number of file descriptors required per
* socket, due to the local pipe. It may be possible to use a global pipe per
* process rather than per socket, but we have not been able to come up with a
* race-free implementation yet.
*
* All functions except asocket_init() and asocket_destroy() are thread safe.
*/
#include <stdlib.h>
#include <sys/socket.h>
#ifndef __CUTILS_ABORT_SOCKET_H__
#define __CUTILS_ABORT_SOCKET_H__
#ifdef __cplusplus
extern "C" {
#endif
struct asocket {
int fd; /* primary socket fd */
int abort_fd[2]; /* pipe used to abort */
};
/* Create an asocket from fd.
* Sets the socket to non-blocking mode.
* Returns NULL on error with errno set.
*/
struct asocket *asocket_init(int fd);
/* Blocking socket I/O with timeout.
* Calling asocket_abort() from another thread will cause each of these
* functions to immediately return with value -1 and errno ECANCELED.
* timeout is in ms, use -1 to indicate no timeout. On timeout -1 is returned
* with errno ETIMEDOUT.
* EINTR is handled in-call.
* Other semantics are identical to the regular syscalls.
*/
int asocket_connect(struct asocket *s, const struct sockaddr *addr,
socklen_t addrlen, int timeout);
int asocket_accept(struct asocket *s, struct sockaddr *addr,
socklen_t *addrlen, int timeout);
int asocket_read(struct asocket *s, void *buf, size_t count, int timeout);
int asocket_write(struct asocket *s, const void *buf, size_t count,
int timeout);
/* Abort above calls and shutdown socket.
* Further I/O operations on this socket will immediately fail after this call.
* asocket_destroy() should be used to release resources once all threads
* have returned from blocking calls on the socket.
*/
void asocket_abort(struct asocket *s);
/* Close socket and free asocket structure.
* Must not be called until all calls on this structure have completed.
*/
void asocket_destroy(struct asocket *s);
#ifdef __cplusplus
}
#endif
#endif //__CUTILS_ABORT_SOCKET__H__

View File

@ -10,6 +10,8 @@
#ifndef _CUTILS_ASHMEM_H
#define _CUTILS_ASHMEM_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif

32
include/cutils/compiler.h Normal file
View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_CUTILS_COMPILER_H
#define ANDROID_CUTILS_COMPILER_H
/*
* helps the compiler's optimizer predicting branches
*/
#ifdef __cplusplus
# define CC_LIKELY( exp ) (__builtin_expect( !!(exp), true ))
# define CC_UNLIKELY( exp ) (__builtin_expect( !!(exp), false ))
#else
# define CC_LIKELY( exp ) (__builtin_expect( !!(exp), 1 ))
# define CC_UNLIKELY( exp ) (__builtin_expect( !!(exp), 0 ))
#endif
#endif // ANDROID_CUTILS_COMPILER_H

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CUTILS_SCHED_POLICY_H
#define __CUTILS_SCHED_POLICY_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
SP_BACKGROUND = 0,
SP_FOREGROUND = 1,
} SchedPolicy;
extern int set_sched_policy(int tid, SchedPolicy policy);
extern int get_sched_policy(int tid, SchedPolicy *policy);
#ifdef __cplusplus
}
#endif
#endif /* __CUTILS_SCHED_POLICY_H */

View File

@ -17,6 +17,8 @@
#ifndef _CUTILS_TZTIME_H
#define _CUTILS_TZTIME_H
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -24,6 +26,9 @@ extern "C" {
time_t mktime_tz(struct tm * const tmp, char const * tz);
void localtime_tz(const time_t * const timep, struct tm * tmp, const char* tz);
#ifndef HAVE_ANDROID_OS
/* the following is defined in <time.h> in Bionic */
struct strftime_locale {
const char *mon[12]; /* short names */
const char *month[12]; /* long names */
@ -40,6 +45,8 @@ struct strftime_locale {
size_t strftime_tz(char *s, size_t max, const char *format, const struct tm *tm, const struct strftime_locale *locale);
#endif /* !HAVE_ANDROID_OS */
#ifdef __cplusplus
}
#endif

View File

@ -13,14 +13,14 @@
** be used to endorse or promote products derived from this software
** without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@ -36,16 +36,23 @@ extern "C" {
typedef struct SHA_CTX {
uint64_t count;
uint8_t buf[64];
uint32_t state[5];
#if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
union {
uint8_t b[64];
uint32_t w[16];
} buf;
#else
uint8_t buf[64];
#endif
} SHA_CTX;
void SHA_init(SHA_CTX *ctx);
void SHA_update(SHA_CTX *ctx, const void* data, int len);
const uint8_t* SHA_final(SHA_CTX *ctx);
void SHA_init(SHA_CTX* ctx);
void SHA_update(SHA_CTX* ctx, const void* data, int len);
const uint8_t* SHA_final(SHA_CTX* ctx);
/* Convenience method. Returns digest parameter value. */
const uint8_t* SHA(const void *data, int len, uint8_t *digest);
const uint8_t* SHA(const void* data, int len, uint8_t* digest);
#define SHA_DIGEST_SIZE 20

View File

@ -156,10 +156,10 @@ static struct fs_path_config android_files[] = {
{ 00550, AID_ROOT, AID_SHELL, "system/etc/init.testmenu" },
{ 00550, AID_DHCP, AID_SHELL, "system/etc/dhcpcd/dhcpcd-run-hooks" },
{ 00440, AID_BLUETOOTH, AID_BLUETOOTH, "system/etc/dbus.conf" },
{ 00440, AID_BLUETOOTH, AID_BLUETOOTH, "system/etc/bluez/hcid.conf" },
{ 00440, AID_BLUETOOTH, AID_BLUETOOTH, "system/etc/bluez/main.conf" },
{ 00440, AID_BLUETOOTH, AID_BLUETOOTH, "system/etc/bluez/input.conf" },
{ 00440, AID_BLUETOOTH, AID_BLUETOOTH, "system/etc/bluez/audio.conf" },
{ 00440, AID_RADIO, AID_AUDIO, "system/etc/AudioPara4.csv" },
{ 00444, AID_RADIO, AID_AUDIO, "system/etc/AudioPara4.csv" },
{ 00555, AID_ROOT, AID_ROOT, "system/etc/ppp/*" },
{ 00644, AID_SYSTEM, AID_SYSTEM, "data/app/*" },
{ 00644, AID_SYSTEM, AID_SYSTEM, "data/app-private/*" },

View File

@ -21,8 +21,8 @@
#include <stddef.h>
#include <string.h>
#include <sys/types.h>
#include <endian.h>
#include <utils/Endian.h>
#include <pixelflinger/pixelflinger.h>
#include <private/pixelflinger/ggl_fixed.h>

View File

@ -33,7 +33,7 @@ public:
SocketListener(const char *socketNames, bool listen);
SocketListener(int socketFd, bool listen);
virtual ~SocketListener() {}
virtual ~SocketListener();
int startListener();
int stopListener();

View File

@ -29,6 +29,7 @@
#include <stdlib.h>
#include <sys/mount.h>
#include <sys/resource.h>
#include <linux/loop.h>
#include "init.h"
#include "keywords.h"
@ -48,7 +49,7 @@ static int write_file(const char *path, const char *value)
fd = open(path, O_WRONLY|O_CREAT, 0622);
if (fd < 0)
return -1;
return -errno;
len = strlen(value);
@ -58,7 +59,7 @@ static int write_file(const char *path, const char *value)
close(fd);
if (ret < 0) {
return -1;
return -errno;
} else {
return 0;
}
@ -257,7 +258,7 @@ static struct {
int do_mount(int nargs, char **args)
{
char tmp[64];
char *source;
char *source, *target, *system;
char *options = NULL;
unsigned flags = 0;
int n, i;
@ -275,15 +276,70 @@ int do_mount(int nargs, char **args)
options = args[n];
}
system = args[1];
source = args[2];
target = args[3];
if (!strncmp(source, "mtd@", 4)) {
n = mtd_name_to_number(source + 4);
if (n >= 0) {
sprintf(tmp, "/dev/block/mtdblock%d", n);
source = tmp;
if (n < 0) {
return -1;
}
sprintf(tmp, "/dev/block/mtdblock%d", n);
if (mount(tmp, target, system, flags, options) < 0) {
return -1;
}
return 0;
} else if (!strncmp(source, "loop@", 5)) {
int mode, loop, fd;
struct loop_info info;
mode = (flags & MS_RDONLY) ? O_RDONLY : O_RDWR;
fd = open(source + 5, mode);
if (fd < 0) {
return -1;
}
for (n = 0; ; n++) {
sprintf(tmp, "/dev/block/loop%d", n);
loop = open(tmp, mode);
if (loop < 0) {
return -1;
}
/* if it is a blank loop device */
if (ioctl(loop, LOOP_GET_STATUS, &info) < 0 && errno == ENXIO) {
/* if it becomes our loop device */
if (ioctl(loop, LOOP_SET_FD, fd) >= 0) {
close(fd);
if (mount(tmp, target, system, flags, options) < 0) {
ioctl(loop, LOOP_CLR_FD, 0);
close(loop);
return -1;
}
close(loop);
return 0;
}
}
close(loop);
}
close(fd);
ERROR("out of loopback devices");
return -1;
} else {
if (mount(source, target, system, flags, options) < 0) {
return -1;
}
return 0;
}
return mount(source, args[3], args[1], flags, options);
}
int do_setkey(int nargs, char **args)
@ -371,6 +427,68 @@ int do_write(int nargs, char **args)
return write_file(args[1], args[2]);
}
int do_copy(int nargs, char **args)
{
char *buffer = NULL;
int rc = 0;
int fd1 = -1, fd2 = -1;
struct stat info;
int brtw, brtr;
char *p;
if (nargs != 3)
return -1;
if (stat(args[1], &info) < 0)
return -1;
if ((fd1 = open(args[1], O_RDONLY)) < 0)
goto out_err;
if ((fd2 = open(args[2], O_WRONLY|O_CREAT|O_TRUNC, 0660)) < 0)
goto out_err;
if (!(buffer = malloc(info.st_size)))
goto out_err;
p = buffer;
brtr = info.st_size;
while(brtr) {
rc = read(fd1, p, brtr);
if (rc < 0)
goto out_err;
if (rc == 0)
break;
p += rc;
brtr -= rc;
}
p = buffer;
brtw = info.st_size;
while(brtw) {
rc = write(fd2, p, brtw);
if (rc < 0)
goto out_err;
if (rc == 0)
break;
p += rc;
brtw -= rc;
}
rc = 0;
goto out;
out_err:
rc = -1;
out:
if (buffer)
free(buffer);
if (fd1 >= 0)
close(fd1);
if (fd2 >= 0)
close(fd2);
return rc;
}
int do_chown(int nargs, char **args) {
/* GID is optional. */
if (nargs == 3) {

View File

@ -95,21 +95,28 @@ static struct perms_ devperms[] = {
/* logger should be world writable (for logging) but not readable */
{ "/dev/log/", 0662, AID_ROOT, AID_LOG, 1 },
/* the msm hw3d client device node is world writable/readable. */
{ "/dev/msm_hw3dc", 0666, AID_ROOT, AID_ROOT, 0 },
/* gpu driver for adreno200 is globally accessible */
{ "/dev/kgsl", 0666, AID_ROOT, AID_ROOT, 0 },
/* these should not be world writable */
{ "/dev/diag", 0660, AID_RADIO, AID_RADIO, 0 },
{ "/dev/diag_arm9", 0660, AID_RADIO, AID_RADIO, 0 },
{ "/dev/android_adb", 0660, AID_ADB, AID_ADB, 0 },
{ "/dev/android_adb_enable", 0660, AID_ADB, AID_ADB, 0 },
{ "/dev/ttyMSM0", 0600, AID_BLUETOOTH, AID_BLUETOOTH, 0 },
{ "/dev/ttyHS0", 0600, AID_BLUETOOTH, AID_BLUETOOTH, 0 },
{ "/dev/uinput", 0600, AID_BLUETOOTH, AID_BLUETOOTH, 0 },
{ "/dev/uinput", 0660, AID_SYSTEM, AID_BLUETOOTH, 0 },
{ "/dev/alarm", 0664, AID_SYSTEM, AID_RADIO, 0 },
{ "/dev/tty0", 0660, AID_ROOT, AID_SYSTEM, 0 },
{ "/dev/graphics/", 0660, AID_ROOT, AID_GRAPHICS, 1 },
{ "/dev/hw3d", 0660, AID_SYSTEM, AID_GRAPHICS, 0 },
{ "/dev/msm_hw3dm", 0660, AID_SYSTEM, AID_GRAPHICS, 0 },
{ "/dev/input/", 0660, AID_ROOT, AID_INPUT, 1 },
{ "/dev/eac", 0660, AID_ROOT, AID_AUDIO, 0 },
{ "/dev/cam", 0660, AID_ROOT, AID_CAMERA, 0 },
{ "/dev/pmem", 0660, AID_SYSTEM, AID_GRAPHICS, 0 },
{ "/dev/pmem_gpu", 0660, AID_SYSTEM, AID_GRAPHICS, 1 },
{ "/dev/pmem_adsp", 0660, AID_SYSTEM, AID_AUDIO, 1 },
{ "/dev/pmem_camera", 0660, AID_SYSTEM, AID_CAMERA, 1 },
{ "/dev/oncrpc/", 0660, AID_ROOT, AID_SYSTEM, 1 },
@ -118,20 +125,34 @@ static struct perms_ devperms[] = {
{ "/dev/msm_camera/", 0660, AID_SYSTEM, AID_SYSTEM, 1 },
{ "/dev/akm8976_daemon",0640, AID_COMPASS, AID_SYSTEM, 0 },
{ "/dev/akm8976_aot", 0640, AID_COMPASS, AID_SYSTEM, 0 },
{ "/dev/akm8973_daemon",0640, AID_COMPASS, AID_SYSTEM, 0 },
{ "/dev/akm8973_aot", 0640, AID_COMPASS, AID_SYSTEM, 0 },
{ "/dev/bma150", 0640, AID_COMPASS, AID_SYSTEM, 0 },
{ "/dev/cm3602", 0640, AID_COMPASS, AID_SYSTEM, 0 },
{ "/dev/akm8976_pffd", 0640, AID_COMPASS, AID_SYSTEM, 0 },
{ "/dev/lightsensor", 0640, AID_SYSTEM, AID_SYSTEM, 0 },
{ "/dev/msm_pcm_out", 0660, AID_SYSTEM, AID_AUDIO, 1 },
{ "/dev/msm_pcm_in", 0660, AID_SYSTEM, AID_AUDIO, 1 },
{ "/dev/msm_pcm_ctl", 0660, AID_SYSTEM, AID_AUDIO, 1 },
{ "/dev/msm_snd", 0660, AID_SYSTEM, AID_AUDIO, 1 },
{ "/dev/msm_mp3", 0660, AID_SYSTEM, AID_AUDIO, 1 },
{ "/dev/audience_a1026", 0660, AID_SYSTEM, AID_AUDIO, 1 },
{ "/dev/msm_audpre", 0660, AID_SYSTEM, AID_AUDIO, 0 },
{ "/dev/msm_audio_ctl", 0660, AID_SYSTEM, AID_AUDIO, 0 },
{ "/dev/htc-acoustic", 0660, AID_SYSTEM, AID_AUDIO, 0 },
{ "/dev/vdec", 0660, AID_SYSTEM, AID_AUDIO, 0 },
{ "/dev/q6venc", 0660, AID_SYSTEM, AID_AUDIO, 0 },
{ "/dev/snd/dsp", 0660, AID_SYSTEM, AID_AUDIO, 0 },
{ "/dev/snd/dsp1", 0660, AID_SYSTEM, AID_AUDIO, 0 },
{ "/dev/snd/mixer", 0660, AID_SYSTEM, AID_AUDIO, 0 },
{ "/dev/smd0", 0640, AID_RADIO, AID_RADIO, 0 },
{ "/dev/qemu_trace", 0666, AID_SYSTEM, AID_SYSTEM, 0 },
{ "/dev/qmi", 0640, AID_RADIO, AID_RADIO, 0 },
{ "/dev/qmi0", 0640, AID_RADIO, AID_RADIO, 0 },
{ "/dev/qmi1", 0640, AID_RADIO, AID_RADIO, 0 },
{ "/dev/qmi2", 0640, AID_RADIO, AID_RADIO, 0 },
/* CDMA radio interface MUX */
{ "/dev/ts0710mux", 0640, AID_RADIO, AID_RADIO, 1 },
{ "/dev/ppp", 0660, AID_RADIO, AID_VPN, 0 },
{ "/dev/tun", 0640, AID_VPN, AID_VPN, 0 },
{ NULL, 0, 0, 0, 0 },
@ -393,6 +414,9 @@ static void handle_device_event(struct uevent *uevent)
} else if(!strncmp(uevent->subsystem, "mtd", 3)) {
base = "/dev/mtd/";
mkdir(base, 0755);
} else if(!strncmp(uevent->subsystem, "sound", 5)) {
base = "/dev/snd/";
mkdir(base, 0755);
} else if(!strncmp(uevent->subsystem, "misc", 4) &&
!strncmp(name, "log_", 4)) {
base = "/dev/log/";

View File

@ -255,9 +255,11 @@ void service_start(struct service *svc, const char *dynamic_args)
setuid(svc->uid);
}
if (!dynamic_args)
execve(svc->args[0], (char**) svc->args, (char**) ENV);
else {
if (!dynamic_args) {
if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0) {
ERROR("cannot execve('%s'): %s\n", svc->args[0], strerror(errno));
}
} else {
char *arg_ptrs[SVC_MAXARGS+1];
int arg_idx = svc->nargs;
char *tmp = strdup(dynamic_args);

View File

@ -21,6 +21,7 @@ int do_trigger(int nargs, char **args);
int do_symlink(int nargs, char **args);
int do_sysclktz(int nargs, char **args);
int do_write(int nargs, char **args);
int do_copy(int nargs, char **args);
int do_chown(int nargs, char **args);
int do_chmod(int nargs, char **args);
int do_loglevel(int nargs, char **args);
@ -65,6 +66,7 @@ enum {
KEYWORD(sysclktz, COMMAND, 1, do_sysclktz)
KEYWORD(user, OPTION, 0, 0)
KEYWORD(write, COMMAND, 2, do_write)
KEYWORD(copy, COMMAND, 2, do_copy)
KEYWORD(chown, COMMAND, 2, do_chown)
KEYWORD(chmod, COMMAND, 2, do_chmod)
KEYWORD(loglevel, COMMAND, 1, do_loglevel)

View File

@ -127,6 +127,7 @@ int lookup_keyword(const char *s)
{
switch (*s++) {
case 'c':
if (!strcmp(s, "opy")) return K_copy;
if (!strcmp(s, "apability")) return K_capability;
if (!strcmp(s, "lass")) return K_class;
if (!strcmp(s, "lass_start")) return K_class_start;

View File

@ -52,29 +52,32 @@ static int persistent_properties_loaded = 0;
struct {
const char *prefix;
unsigned int uid;
unsigned int gid;
} property_perms[] = {
{ "net.rmnet0.", AID_RADIO },
{ "net.gprs.", AID_RADIO },
{ "ril.", AID_RADIO },
{ "gsm.", AID_RADIO },
{ "net.dns", AID_RADIO },
{ "net.", AID_SYSTEM },
{ "dev.", AID_SYSTEM },
{ "runtime.", AID_SYSTEM },
{ "hw.", AID_SYSTEM },
{ "sys.", AID_SYSTEM },
{ "service.", AID_SYSTEM },
{ "wlan.", AID_SYSTEM },
{ "dhcp.", AID_SYSTEM },
{ "dhcp.", AID_DHCP },
{ "vpn.", AID_SYSTEM },
{ "vpn.", AID_VPN },
{ "debug.", AID_SHELL },
{ "log.", AID_SHELL },
{ "service.adb.root", AID_SHELL },
{ "persist.sys.", AID_SYSTEM },
{ "persist.service.", AID_SYSTEM },
{ NULL, 0 }
{ "net.rmnet0.", AID_RADIO, 0 },
{ "net.gprs.", AID_RADIO, 0 },
{ "net.ppp", AID_RADIO, 0 },
{ "ril.", AID_RADIO, 0 },
{ "gsm.", AID_RADIO, 0 },
{ "persist.radio", AID_RADIO, 0 },
{ "net.dns", AID_RADIO, 0 },
{ "net.", AID_SYSTEM, 0 },
{ "dev.", AID_SYSTEM, 0 },
{ "runtime.", AID_SYSTEM, 0 },
{ "hw.", AID_SYSTEM, 0 },
{ "sys.", AID_SYSTEM, 0 },
{ "service.", AID_SYSTEM, 0 },
{ "wlan.", AID_SYSTEM, 0 },
{ "dhcp.", AID_SYSTEM, 0 },
{ "dhcp.", AID_DHCP, 0 },
{ "vpn.", AID_SYSTEM, 0 },
{ "vpn.", AID_VPN, 0 },
{ "debug.", AID_SHELL, 0 },
{ "log.", AID_SHELL, 0 },
{ "service.adb.root", AID_SHELL, 0 },
{ "persist.sys.", AID_SYSTEM, 0 },
{ "persist.service.", AID_SYSTEM, 0 },
{ NULL, 0, 0 }
};
/*
@ -84,8 +87,10 @@ struct {
struct {
const char *service;
unsigned int uid;
unsigned int gid;
} control_perms[] = {
{NULL, 0 }
{ "dumpstate",AID_SHELL, AID_LOG },
{NULL, 0, 0 }
};
typedef struct {
@ -181,7 +186,7 @@ static int property_write(prop_info *pi, const char *value)
*
* Returns 1 if uid allowed, 0 otherwise.
*/
static int check_control_perms(const char *name, int uid) {
static int check_control_perms(const char *name, int uid, int gid) {
int i;
if (uid == AID_SYSTEM || uid == AID_ROOT)
return 1;
@ -189,8 +194,10 @@ static int check_control_perms(const char *name, int uid) {
/* Search the ACL */
for (i = 0; control_perms[i].service; i++) {
if (strcmp(control_perms[i].service, name) == 0) {
if (control_perms[i].uid == uid)
if ((uid && control_perms[i].uid == uid) ||
(gid && control_perms[i].gid == gid)) {
return 1;
}
}
}
return 0;
@ -200,7 +207,7 @@ static int check_control_perms(const char *name, int uid) {
* Checks permissions for setting system properties.
* Returns 1 if uid allowed, 0 otherwise.
*/
static int check_perms(const char *name, unsigned int uid)
static int check_perms(const char *name, unsigned int uid, int gid)
{
int i;
if (uid == 0)
@ -213,7 +220,8 @@ static int check_perms(const char *name, unsigned int uid)
int tmp;
if (strncmp(property_perms[i].prefix, name,
strlen(property_perms[i].prefix)) == 0) {
if (property_perms[i].uid == uid) {
if ((uid && property_perms[i].uid == uid) ||
(gid && property_perms[i].gid == gid)) {
return 1;
}
}
@ -237,7 +245,7 @@ const char* property_get(const char *name)
}
}
static void write_peristent_property(const char *name, const char *value)
static void write_persistent_property(const char *name, const char *value)
{
const char *tempPath = PERSISTENT_PROPERTY_DIR "/.temp";
char path[PATH_MAX];
@ -248,7 +256,7 @@ static void write_peristent_property(const char *name, const char *value)
fd = open(tempPath, O_WRONLY|O_CREAT|O_TRUNC, 0600);
if (fd < 0) {
ERROR("Unable to write persistent property to temp file %s errno: %d\n", tempPath, errno);
return;
return;
}
write(fd, value, strlen(value));
close(fd);
@ -302,7 +310,7 @@ int property_set(const char *name, const char *value)
if (strcmp("net.change", name) == 0) {
return 0;
}
/*
/*
* The 'net.change' property is a special property used track when any
* 'net.*' property name is updated. It is _ONLY_ updated here. Its value
* contains the last updated 'net.*' property.
@ -310,11 +318,11 @@ int property_set(const char *name, const char *value)
property_set("net.change", name);
} else if (persistent_properties_loaded &&
strncmp("persist.", name, strlen("persist.")) == 0) {
/*
/*
* Don't write properties to disk until after we have read all default properties
* to prevent them from being overwritten by default values.
*/
write_peristent_property(name, value);
write_persistent_property(name, value);
}
property_changed(name, value);
return 0;
@ -371,14 +379,14 @@ void handle_property_set_fd(int fd)
msg.value[PROP_VALUE_MAX-1] = 0;
if(memcmp(msg.name,"ctl.",4) == 0) {
if (check_control_perms(msg.value, cr.uid)) {
if (check_control_perms(msg.value, cr.uid, cr.gid)) {
handle_control_message((char*) msg.name + 4, (char*) msg.value);
} else {
ERROR("sys_prop: Unable to %s service ctl [%s] uid: %d pid:%d\n",
msg.name + 4, msg.value, cr.uid, cr.pid);
}
} else {
if (check_perms(msg.name, cr.uid)) {
if (check_perms(msg.name, cr.uid, cr.gid)) {
property_set((char*) msg.name, (char*) msg.value);
} else {
ERROR("sys_prop: permission denied uid:%d name:%s\n",
@ -474,7 +482,7 @@ static void load_persistent_properties()
} else {
ERROR("Unable to open persistent property directory %s errno: %d\n", PERSISTENT_PROPERTY_DIR, errno);
}
persistent_properties_loaded = 1;
}

31
libacc/Android.mk Normal file
View File

@ -0,0 +1,31 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
# Shared library for target
# ========================================================
LOCAL_MODULE:= libacc
LOCAL_SRC_FILES := acc.cpp
LOCAL_SHARED_LIBRARIES := libdl libcutils
include $(BUILD_SHARED_LIBRARY)
# Shared library for host
# ========================================================
include $(CLEAR_VARS)
LOCAL_MODULE:= libacc
LOCAL_SRC_FILES := acc.cpp
LOCAL_CFLAGS := -O0 -g
LOCAL_STATIC_LIBRARIES := libcutils
LOCAL_LDLIBS := -ldl
include $(BUILD_HOST_SHARED_LIBRARY)
# Build children
# ========================================================
include $(call all-makefiles-under,$(LOCAL_PATH))

83
libacc/FEATURES Normal file
View File

@ -0,0 +1,83 @@
Supported C language subset:
- Expressions:
* binary operators, by decreasing priority order: '*' '/' '%',
'+' '-', '>>' '<<', '<' '<=' '>' '>=', '==' '!=', '&',
'^', '|', '=', '&&', '||'.
* '&&' and '||' have the same semantics as C : left to right
evaluation and early exit.
* Parenthesis are supported.
* Comma operator is supported.
* Trinary operator (?:) is not supported.
* Unary operators: '&', '*' (pointer indirection), '-'
(negation), '+', '!', '~', '++' and '--'.
* Pointer indirection ('*') is supported.
* Square brackets can be used for pointer arithmetic.
* '=' and <op>= are supported.
* Function calls are supported with standard Linux calling
convention. Function pointers are supported.
Functions can be used before being declared.
- sizeof() is not supported.
- Types:
+ int, short, char, float, double
+ pointers
+ variables can be initialized in declarations.
+ Only ANSI-style function declarations are supported.
- "..." is not supported.
- short is not supported
- const is not supported
- arrays are not supported
- long doubles are not supported
- structs are not supported
- Unknown functions and variables are bound at compile time by calling
back to the caller. For the 'acc' command-line tool unknown functions
and variables are looked up using dlsym, to allow using many libc
functions and variables.
- Instructions: blocks ('{' '}') are supported as in C. 'if' and
'else' can be used for tests. The 'while' and 'for' C constructs
are supported for loops. 'break' can be used to exit
loops. 'return' is used for the return value of a function.
- switch / case is not supported.
- goto and labels are not supported.
- continue is not supported.
- Identifiers are parsed the same way as C. Local variables are
handled, but there is no local name space (not a problem if
different names are used for local and global variables).
- Numbers can be entered in decimal, hexadecimal ('0x' or '0X'
prefix), or octal ('0' prefix).
- Float and double constants are supported.
- '#define' is supported without function like arguments. No macro
recursion is tolerated. Other preprocessor directives are
ignored.
- C Strings and C character constants are supported. All ANSI C
character escapes are supported.
- Both C comments ( /* */ ) and C++ comments ( // ... end-of-line ) are
supported.
- Some syntax errors are reported, others may cause a crash.
- Memory: the code, data, and symbol sizes are limited to 100KB
(it can be changed in the source code).

21
libacc/LICENSE Normal file
View File

@ -0,0 +1,21 @@
Obfuscated Tiny C Compiler
Copyright (C) 2001-2003 Fabrice Bellard
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product and its documentation
*is* required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

View File

6241
libacc/acc.cpp Normal file

File diff suppressed because it is too large Load Diff

2
libacc/tests/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
test-acc
*.out

66
libacc/tests/Android.mk Normal file
View File

@ -0,0 +1,66 @@
LOCAL_PATH:= $(call my-dir)
# Executable for host
# ========================================================
include $(CLEAR_VARS)
LOCAL_MODULE:= acc
LOCAL_SRC_FILES:= \
main.cpp
LOCAL_SHARED_LIBRARIES := \
libacc
LOCAL_MODULE_TAGS := tests
include $(BUILD_HOST_EXECUTABLE)
# Executable for target
# ========================================================
include $(CLEAR_VARS)
LOCAL_MODULE:= acc
LOCAL_SRC_FILES:= \
main.cpp \
disassem.cpp
LOCAL_SHARED_LIBRARIES := \
libacc
LOCAL_CFLAGS := -O0 -g
LOCAL_MODULE_TAGS := tests
include $(BUILD_EXECUTABLE)
# Runtime tests for host
# ========================================================
include $(CLEAR_VARS)
LOCAL_MODULE:= accRuntimeTest
LOCAL_SRC_FILES:= \
runtimeTest.cpp
LOCAL_SHARED_LIBRARIES := \
libacc
LOCAL_MODULE_TAGS := tests
include $(BUILD_HOST_EXECUTABLE)
# Runtime tests for target
# ========================================================
include $(CLEAR_VARS)
LOCAL_MODULE:= accRuntimeTest
LOCAL_SRC_FILES:= \
runtimeTest.cpp
LOCAL_SHARED_LIBRARIES := \
libacc
LOCAL_CFLAGS := -O0 -g
LOCAL_MODULE_TAGS := tests
include $(BUILD_EXECUTABLE)

69
libacc/tests/accarm Executable file
View File

@ -0,0 +1,69 @@
#!/usr/bin/python
#
# Run a test on the ARM version of acc.
import unittest
import subprocess
import os
import sys
def compile(args):
proc = subprocess.Popen(["acc"] + args, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
result = proc.communicate()
return result
def runCmd(args):
proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
result = proc.communicate()
return result[0].strip()
def uname():
return runCmd(["uname"])
def unameM():
return runCmd(["uname", "-m"])
def which(item):
return runCmd(["which", item])
def adb(args):
return runCmd(["adb"] + args)
def setupArm(file):
print "Setting up arm"
adb(["remount"])
adb(["shell", "rm", "/system/bin/acc"])
adb(["shell", "mkdir", "/system/bin/accdata"])
adb(["shell", "mkdir", "/system/bin/accdata/data"])
remoteFileName = os.path.join("/system/bin/accdata", file)
adb(["push", file, remoteFileName])
# Copy over compiler
adb(["sync"])
return remoteFileName
def compileArm(args):
remoteArgs = []
fileName = ""
for arg in sys.argv[1:]:
if arg.startswith('-'):
remoteArgs.append(arg)
else:
fileName = arg
remoteFileName = setupArm(fileName)
remoteArgs.append(remoteFileName)
remoteCmdLine = ["adb", "shell", "/system/bin/acc"] + remoteArgs
proc = subprocess.Popen(remoteCmdLine, stdout=subprocess.PIPE)
result = proc.communicate()
return result[0].replace("\r","")
def main():
print compileArm(sys.argv[1:])
if __name__ == '__main__':
main()

300
libacc/tests/armreg.h Normal file
View File

@ -0,0 +1,300 @@
/* $NetBSD: armreg.h,v 1.28 2003/10/31 16:30:15 scw Exp $ */
/*-
* Copyright (c) 1998, 2001 Ben Harris
* Copyright (c) 1994-1996 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* This code is derived from software written for Brini by Mark Brinicombe
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: /repoman/r/ncvs/src/sys/arm/include/armreg.h,v 1.3 2005/11/21 19:06:25 cognet Exp $
*/
#ifndef MACHINE_ARMREG_H
#define MACHINE_ARMREG_H
#define INSN_SIZE 4
#define INSN_COND_MASK 0xf0000000 /* Condition mask */
#define PSR_MODE 0x0000001f /* mode mask */
#define PSR_USR26_MODE 0x00000000
#define PSR_FIQ26_MODE 0x00000001
#define PSR_IRQ26_MODE 0x00000002
#define PSR_SVC26_MODE 0x00000003
#define PSR_USR32_MODE 0x00000010
#define PSR_FIQ32_MODE 0x00000011
#define PSR_IRQ32_MODE 0x00000012
#define PSR_SVC32_MODE 0x00000013
#define PSR_ABT32_MODE 0x00000017
#define PSR_UND32_MODE 0x0000001b
#define PSR_SYS32_MODE 0x0000001f
#define PSR_32_MODE 0x00000010
#define PSR_FLAGS 0xf0000000 /* flags */
#define PSR_C_bit (1 << 29) /* carry */
/* The high-order byte is always the implementor */
#define CPU_ID_IMPLEMENTOR_MASK 0xff000000
#define CPU_ID_ARM_LTD 0x41000000 /* 'A' */
#define CPU_ID_DEC 0x44000000 /* 'D' */
#define CPU_ID_INTEL 0x69000000 /* 'i' */
#define CPU_ID_TI 0x54000000 /* 'T' */
/* How to decide what format the CPUID is in. */
#define CPU_ID_ISOLD(x) (((x) & 0x0000f000) == 0x00000000)
#define CPU_ID_IS7(x) (((x) & 0x0000f000) == 0x00007000)
#define CPU_ID_ISNEW(x) (!CPU_ID_ISOLD(x) && !CPU_ID_IS7(x))
/* On ARM3 and ARM6, this byte holds the foundry ID. */
#define CPU_ID_FOUNDRY_MASK 0x00ff0000
#define CPU_ID_FOUNDRY_VLSI 0x00560000
/* On ARM7 it holds the architecture and variant (sub-model) */
#define CPU_ID_7ARCH_MASK 0x00800000
#define CPU_ID_7ARCH_V3 0x00000000
#define CPU_ID_7ARCH_V4T 0x00800000
#define CPU_ID_7VARIANT_MASK 0x007f0000
/* On more recent ARMs, it does the same, but in a different format */
#define CPU_ID_ARCH_MASK 0x000f0000
#define CPU_ID_ARCH_V3 0x00000000
#define CPU_ID_ARCH_V4 0x00010000
#define CPU_ID_ARCH_V4T 0x00020000
#define CPU_ID_ARCH_V5 0x00030000
#define CPU_ID_ARCH_V5T 0x00040000
#define CPU_ID_ARCH_V5TE 0x00050000
#define CPU_ID_VARIANT_MASK 0x00f00000
/* Next three nybbles are part number */
#define CPU_ID_PARTNO_MASK 0x0000fff0
/* Intel XScale has sub fields in part number */
#define CPU_ID_XSCALE_COREGEN_MASK 0x0000e000 /* core generation */
#define CPU_ID_XSCALE_COREREV_MASK 0x00001c00 /* core revision */
#define CPU_ID_XSCALE_PRODUCT_MASK 0x000003f0 /* product number */
/* And finally, the revision number. */
#define CPU_ID_REVISION_MASK 0x0000000f
/* Individual CPUs are probably best IDed by everything but the revision. */
#define CPU_ID_CPU_MASK 0xfffffff0
/* Fake CPU IDs for ARMs without CP15 */
#define CPU_ID_ARM2 0x41560200
#define CPU_ID_ARM250 0x41560250
/* Pre-ARM7 CPUs -- [15:12] == 0 */
#define CPU_ID_ARM3 0x41560300
#define CPU_ID_ARM600 0x41560600
#define CPU_ID_ARM610 0x41560610
#define CPU_ID_ARM620 0x41560620
/* ARM7 CPUs -- [15:12] == 7 */
#define CPU_ID_ARM700 0x41007000 /* XXX This is a guess. */
#define CPU_ID_ARM710 0x41007100
#define CPU_ID_ARM7500 0x41027100 /* XXX This is a guess. */
#define CPU_ID_ARM710A 0x41047100 /* inc ARM7100 */
#define CPU_ID_ARM7500FE 0x41077100
#define CPU_ID_ARM710T 0x41807100
#define CPU_ID_ARM720T 0x41807200
#define CPU_ID_ARM740T8K 0x41807400 /* XXX no MMU, 8KB cache */
#define CPU_ID_ARM740T4K 0x41817400 /* XXX no MMU, 4KB cache */
/* Post-ARM7 CPUs */
#define CPU_ID_ARM810 0x41018100
#define CPU_ID_ARM920T 0x41129200
#define CPU_ID_ARM920T_ALT 0x41009200
#define CPU_ID_ARM922T 0x41029220
#define CPU_ID_ARM940T 0x41029400 /* XXX no MMU */
#define CPU_ID_ARM946ES 0x41049460 /* XXX no MMU */
#define CPU_ID_ARM966ES 0x41049660 /* XXX no MMU */
#define CPU_ID_ARM966ESR1 0x41059660 /* XXX no MMU */
#define CPU_ID_ARM1020E 0x4115a200 /* (AKA arm10 rev 1) */
#define CPU_ID_ARM1022ES 0x4105a220
#define CPU_ID_SA110 0x4401a100
#define CPU_ID_SA1100 0x4401a110
#define CPU_ID_TI925T 0x54029250
#define CPU_ID_SA1110 0x6901b110
#define CPU_ID_IXP1200 0x6901c120
#define CPU_ID_80200 0x69052000
#define CPU_ID_PXA250 0x69052100 /* sans core revision */
#define CPU_ID_PXA210 0x69052120
#define CPU_ID_PXA250A 0x69052100 /* 1st version Core */
#define CPU_ID_PXA210A 0x69052120 /* 1st version Core */
#define CPU_ID_PXA250B 0x69052900 /* 3rd version Core */
#define CPU_ID_PXA210B 0x69052920 /* 3rd version Core */
#define CPU_ID_PXA250C 0x69052d00 /* 4th version Core */
#define CPU_ID_PXA210C 0x69052d20 /* 4th version Core */
#define CPU_ID_80321_400 0x69052420
#define CPU_ID_80321_600 0x69052430
#define CPU_ID_80321_400_B0 0x69052c20
#define CPU_ID_80321_600_B0 0x69052c30
#define CPU_ID_IXP425_533 0x690541c0
#define CPU_ID_IXP425_400 0x690541d0
#define CPU_ID_IXP425_266 0x690541f0
/* ARM3-specific coprocessor 15 registers */
#define ARM3_CP15_FLUSH 1
#define ARM3_CP15_CONTROL 2
#define ARM3_CP15_CACHEABLE 3
#define ARM3_CP15_UPDATEABLE 4
#define ARM3_CP15_DISRUPTIVE 5
/* ARM3 Control register bits */
#define ARM3_CTL_CACHE_ON 0x00000001
#define ARM3_CTL_SHARED 0x00000002
#define ARM3_CTL_MONITOR 0x00000004
/*
* Post-ARM3 CP15 registers:
*
* 1 Control register
*
* 2 Translation Table Base
*
* 3 Domain Access Control
*
* 4 Reserved
*
* 5 Fault Status
*
* 6 Fault Address
*
* 7 Cache/write-buffer Control
*
* 8 TLB Control
*
* 9 Cache Lockdown
*
* 10 TLB Lockdown
*
* 11 Reserved
*
* 12 Reserved
*
* 13 Process ID (for FCSE)
*
* 14 Reserved
*
* 15 Implementation Dependent
*/
/* Some of the definitions below need cleaning up for V3/V4 architectures */
/* CPU control register (CP15 register 1) */
#define CPU_CONTROL_MMU_ENABLE 0x00000001 /* M: MMU/Protection unit enable */
#define CPU_CONTROL_AFLT_ENABLE 0x00000002 /* A: Alignment fault enable */
#define CPU_CONTROL_DC_ENABLE 0x00000004 /* C: IDC/DC enable */
#define CPU_CONTROL_WBUF_ENABLE 0x00000008 /* W: Write buffer enable */
#define CPU_CONTROL_32BP_ENABLE 0x00000010 /* P: 32-bit exception handlers */
#define CPU_CONTROL_32BD_ENABLE 0x00000020 /* D: 32-bit addressing */
#define CPU_CONTROL_LABT_ENABLE 0x00000040 /* L: Late abort enable */
#define CPU_CONTROL_BEND_ENABLE 0x00000080 /* B: Big-endian mode */
#define CPU_CONTROL_SYST_ENABLE 0x00000100 /* S: System protection bit */
#define CPU_CONTROL_ROM_ENABLE 0x00000200 /* R: ROM protection bit */
#define CPU_CONTROL_CPCLK 0x00000400 /* F: Implementation defined */
#define CPU_CONTROL_BPRD_ENABLE 0x00000800 /* Z: Branch prediction enable */
#define CPU_CONTROL_IC_ENABLE 0x00001000 /* I: IC enable */
#define CPU_CONTROL_VECRELOC 0x00002000 /* V: Vector relocation */
#define CPU_CONTROL_ROUNDROBIN 0x00004000 /* RR: Predictable replacement */
#define CPU_CONTROL_V4COMPAT 0x00008000 /* L4: ARMv4 compat LDR R15 etc */
#define CPU_CONTROL_IDC_ENABLE CPU_CONTROL_DC_ENABLE
/* XScale Auxillary Control Register (CP15 register 1, opcode2 1) */
#define XSCALE_AUXCTL_K 0x00000001 /* dis. write buffer coalescing */
#define XSCALE_AUXCTL_P 0x00000002 /* ECC protect page table access */
#define XSCALE_AUXCTL_MD_WB_RA 0x00000000 /* mini-D$ wb, read-allocate */
#define XSCALE_AUXCTL_MD_WB_RWA 0x00000010 /* mini-D$ wb, read/write-allocate */
#define XSCALE_AUXCTL_MD_WT 0x00000020 /* mini-D$ wt, read-allocate */
#define XSCALE_AUXCTL_MD_MASK 0x00000030
/* Cache type register definitions */
#define CPU_CT_ISIZE(x) ((x) & 0xfff) /* I$ info */
#define CPU_CT_DSIZE(x) (((x) >> 12) & 0xfff) /* D$ info */
#define CPU_CT_S (1U << 24) /* split cache */
#define CPU_CT_CTYPE(x) (((x) >> 25) & 0xf) /* cache type */
#define CPU_CT_CTYPE_WT 0 /* write-through */
#define CPU_CT_CTYPE_WB1 1 /* write-back, clean w/ read */
#define CPU_CT_CTYPE_WB2 2 /* w/b, clean w/ cp15,7 */
#define CPU_CT_CTYPE_WB6 6 /* w/b, cp15,7, lockdown fmt A */
#define CPU_CT_CTYPE_WB7 7 /* w/b, cp15,7, lockdown fmt B */
#define CPU_CT_xSIZE_LEN(x) ((x) & 0x3) /* line size */
#define CPU_CT_xSIZE_M (1U << 2) /* multiplier */
#define CPU_CT_xSIZE_ASSOC(x) (((x) >> 3) & 0x7) /* associativity */
#define CPU_CT_xSIZE_SIZE(x) (((x) >> 6) & 0x7) /* size */
/* Fault status register definitions */
#define FAULT_TYPE_MASK 0x0f
#define FAULT_USER 0x10
#define FAULT_WRTBUF_0 0x00 /* Vector Exception */
#define FAULT_WRTBUF_1 0x02 /* Terminal Exception */
#define FAULT_BUSERR_0 0x04 /* External Abort on Linefetch -- Section */
#define FAULT_BUSERR_1 0x06 /* External Abort on Linefetch -- Page */
#define FAULT_BUSERR_2 0x08 /* External Abort on Non-linefetch -- Section */
#define FAULT_BUSERR_3 0x0a /* External Abort on Non-linefetch -- Page */
#define FAULT_BUSTRNL1 0x0c /* External abort on Translation -- Level 1 */
#define FAULT_BUSTRNL2 0x0e /* External abort on Translation -- Level 2 */
#define FAULT_ALIGN_0 0x01 /* Alignment */
#define FAULT_ALIGN_1 0x03 /* Alignment */
#define FAULT_TRANS_S 0x05 /* Translation -- Section */
#define FAULT_TRANS_P 0x07 /* Translation -- Page */
#define FAULT_DOMAIN_S 0x09 /* Domain -- Section */
#define FAULT_DOMAIN_P 0x0b /* Domain -- Page */
#define FAULT_PERM_S 0x0d /* Permission -- Section */
#define FAULT_PERM_P 0x0f /* Permission -- Page */
#define FAULT_IMPRECISE 0x400 /* Imprecise exception (XSCALE) */
/*
* Address of the vector page, low and high versions.
*/
#define ARM_VECTORS_LOW 0x00000000U
#define ARM_VECTORS_HIGH 0xffff0000U
/*
* ARM Instructions
*
* 3 3 2 2 2
* 1 0 9 8 7 0
* +-------+-------------------------------------------------------+
* | cond | instruction dependant |
* |c c c c| |
* +-------+-------------------------------------------------------+
*/
#define INSN_SIZE 4 /* Always 4 bytes */
#define INSN_COND_MASK 0xf0000000 /* Condition mask */
#define INSN_COND_AL 0xe0000000 /* Always condition */
#endif /* !MACHINE_ARMREG_H */

View File

@ -0,0 +1,31 @@
void testStruct() {
struct str {
float x;
float y;
};
struct str base;
int index = 0;
base.x = 10.0;
struct str *s = &base;
float *v = &(*s).x;
float *v2 = &s[index].x;
printf("testStruct: %g %g %g\n",base.x, *v, *v2);
}
void testArray() {
int a[2];
a[0] = 1;
a[1] = 2;
int* p = &a[0];
int* p2 = a;
printf("testArray: %d %d %d\n", a[0], *p, *p2);
}
int main() {
testStruct();
testArray();
return 0;
}

107
libacc/tests/data/array.c Normal file
View File

@ -0,0 +1,107 @@
// Array allocation tests
void testLocalInt()
{
int a[3];
a[0] = 1;
a[1] = 2;
a[2] = a[0] + a[1];
printf("localInt: %d\n", a[2]);
}
char a[3];
double d[3];
void testGlobalChar()
{
a[0] = 1;
a[1] = 2;
a[2] = a[0] + a[1];
printf("globalChar: %d\n", a[2]);
}
void testGlobalDouble()
{
d[0] = 1;
d[1] = 2;
d[2] = d[0] + d[1];
printf("globalDouble: %g\n", d[2]);
}
void testLocalDouble()
{
double d[3];
float m[12];
m[0] = 1.0f;
m[1] = 2.0f;
d[0] = 1.0;
d[1] = 2.0;
d[2] = d[0] + d[1];
m[2] = m[0] + m[1];
printf("localDouble: %g %g\n", d[2], m[2]);
}
void vectorAdd(int* a, int* b, float* c, int len) {
int i;
for(i = 0; i < len; i++) {
c[i] = a[i] + b[i];
}
}
void testArgs() {
int a[3], b[3];
float c[3];
int i;
int len = 3;
for(i = 0; i < len; i++) {
a[i] = i;
b[i] = i;
c[i] = 0;
}
vectorAdd(a,b,c, len);
printf("testArgs:");
for(i = 0; i < len; i++) {
printf(" %g", c[i]);
}
printf("\n");
}
void testDecay() {
char c[4];
c[0] = 'H';
c[1] = 'i';
c[2] = '!';
c[3] = 0;
printf("testDecay: %s\n", c);
}
void test2D() {
char c[10][20];
int x;
int y;
printf("test2D:\n");
for(y = 0; y < 10; y++) {
for(x = 0; x < 20; x++) {
c[y][x] = 'a' + (15 & (y * 19 + x));
}
}
for(y = 0; y < 10; y++) {
for(x = 0; x < 20; x++) {
printf("%c", c[y][x]);
}
printf("\n");
}
}
int main()
{
testLocalInt();
testLocalDouble();
testGlobalChar();
testGlobalDouble();
testArgs();
testDecay();
test2D();
return 0;
}

View File

@ -0,0 +1,9 @@
int main() {
int a = 0;
int b = 1;
a = b = 2; // Test that "b = 2" generates an rvalue.
if (a = 7) { // Test that a = 7 generates an rvalue.
b = 3;
}
return a;
}

View File

@ -0,0 +1,62 @@
// Test assignment operations
void testAssignment() {
int a = 2;
a *= 5;
printf("2 *= 5 %d\n", a);
a = 20;
a /= 5;
printf("20 /= 5 %d\n", a);
a = 17;
a %= 5;
printf("17 %%= 5 %d\n", a);
a = 17;
a += 5;
printf("17 += 5 %d\n", a);
a = 17;
a-=5;
printf("17 -= 5 %d\n", a);
a = 17;
a<<=1;
printf("17<<= 1 %d\n", a);
a = 17;
a>>=1;
printf("17>>= 1 %d\n", a);
a = 17;
a&=1;
printf("17&= 1 %d\n", a);
a = 17;
a^=1;
printf("17^= 1 %d\n", a);
a = 16;
a^=1;
printf("16|= 1 %d\n", a);
}
int a;
int* f() {
printf("f()\n");
return &a;
}
void testEval() {
a = 0;
printf("*f() = *f() + 10;\n");
*f() = *f() + 10;
printf("a = %d\n", a);
}
void testOpEval() {
a = 0;
printf("*f() += 10;\n");
*f() += 10;
printf("a = %d\n", a);
}
int main() {
testAssignment();
testEval();
testOpEval();
return 0;
}

View File

@ -0,0 +1,9 @@
// See http://b/2071670
int main() {
float f = 10.0f;
float* floatPointer = &f;
// The following line used to incorrectly error: "Incompatible pointer or array types"
int* buffer = (int*) floatPointer;
return *buffer;
}

View File

@ -0,0 +1,126 @@
/* #!/usr/local/bin/otcc */
/*
* Sample OTCC C example. You can uncomment the first line and install
* otcc in /usr/local/bin to make otcc scripts !
*/
/* Any preprocessor directive except #define are ignored. We put this
include so that a standard C compiler can compile this code too. */
#include <stdio.h>
/* defines are handled, but macro arguments cannot be given. No
recursive defines are tolerated */
#define DEFAULT_BASE 10
/*
* Only old style K&R prototypes are parsed. Only int arguments are
* allowed (implicit types).
*
* By benchmarking the execution time of this function (for example
* for fib(35)), you'll notice that OTCC is quite fast because it
* generates native i386 machine code.
*/
fib(n)
{
if (n <= 2)
return 1;
else
return fib(n-1) + fib(n-2);
}
/* Identifiers are parsed the same way as C: begins with letter or
'_', and then letters, '_' or digits */
fact(n)
{
/* local variables can be declared. Only 'int' type is supported */
int i, r;
r = 1;
/* 'while' and 'for' loops are supported */
for(i=2;i<=n;i++)
r = r * i;
return r;
}
/* Well, we could use printf, but it would be too easy */
print_num(n, b)
{
int tab, p, c;
/* Numbers can be entered in decimal, hexadecimal ('0x' prefix) and
octal ('0' prefix) */
/* more complex programs use malloc */
tab = malloc(0x100);
p = tab;
while (1) {
c = n % b;
/* Character constants can be used */
if (c >= 10)
c = c + 'a' - 10;
else
c = c + '0';
*(char *)p = c;
p++;
n = n / b;
/* 'break' is supported */
if (n == 0)
break;
}
while (p != tab) {
p--;
printf("%c", *(char *)p);
}
free(tab);
}
/* 'main' takes standard 'argc' and 'argv' parameters */
main(argc, argv)
{
/* no local name space is supported, but local variables ARE
supported. As long as you do not use a globally defined
variable name as local variable (which is a bad habbit), you
won't have any problem */
int s, n, f, base;
/* && and || operator have the same semantics as C (left to right
evaluation and early exit) */
if (argc != 2 && argc != 3) {
/* '*' operator is supported with explicit casting to 'int *',
'char *' or 'int (*)()' (function pointer). Of course, 'int'
are supposed to be used as pointers too. */
s = *(int *)argv;
help(s);
return 1;
}
/* Any libc function can be used because OTCC uses dynamic linking */
n = atoi(*(int *)(argv + 4));
base = DEFAULT_BASE;
if (argc >= 3) {
base = atoi(*(int *)(argv + 8));
if (base < 2 || base > 36) {
/* external variables can be used too (here: 'stderr') */
fprintf(stderr, "Invalid base\n");
return 1;
}
}
printf("fib(%d) = ", n);
print_num(fib(n), base);
printf("\n");
printf("fact(%d) = ", n);
if (n > 12) {
printf("Overflow");
} else {
/* why not using a function pointer ? */
f = &fact;
print_num((*(int (*)())f)(n), base);
}
printf("\n");
return 0;
}
/* functions can be used before being defined */
help(name)
{
printf("usage: %s n [base]\n", name);
printf("Compute fib(n) and fact(n) and output the result in base 'base'\n");
}

View File

@ -0,0 +1,61 @@
void testBrackets(int* ar, int len) {
int i;
int errors = 0;
for (i = 0; i < len; i++) {
ar[i] = i;
}
for (i = 0; i < len; i++) {
if (ar[i] != i) {
printf("error: [%d] %d != %d\n", i, ar[i], i);
errors++;
}
}
printf("Errors: %d\n", errors);
}
void testBrackets2D(int** ar2D, int lenX, int lenY) {
int x, y;
int errors = 0;
for (x = 0; x < lenX; x++) {
for (y = 0; y < lenY; y++) {
ar2D[x][y] = x * lenY + y;
}
}
for (x = 0; x < lenX; x++) {
for (y = 0; y < lenY; y++) {
int expected = x * lenY + y;
int val = ar2D[x][y];
if (val != expected) {
printf("error: [%d][%d] %d != %d\n", x, y, val, expected);
errors++;
}
}
}
printf("2D Errors: %d\n", errors);
}
void testHeap() {
int* ar = (int*) malloc(100);
testBrackets(ar, 25);
free(ar);
}
void testHeap2D() {
int lenX = 10;
int lenY = 5;
int* ar = (int*) malloc(lenX * lenY * 4);
int** ar2D = (int**) malloc(lenX * 4);
int i;
for(i = 0; i < lenX; i++) {
ar2D[i] = ar + lenY * i;
}
testBrackets2D(ar2D, lenX, lenY);
free(ar);
free(ar2D);
}
int main() {
testHeap();
testHeap2D();
return 0;
}

85
libacc/tests/data/casts.c Normal file
View File

@ -0,0 +1,85 @@
void test1() {
int a = 3;
int* pb = &a;
int c = *pb;
printf("Reading from a pointer: %d %d\n", a, c);
*pb = 4;
printf("Writing to a pointer: %d\n", a);
printf("Testing casts: %d %g %g %d\n", 3, (float) 3, 4.5, (int) 4.5);
}
void test2() {
int x = 4;
int px = &x;
// int z = * px; // An error, expected a pointer type
int y = * (int*) px;
printf("Testing reading (int*): %d\n", y);
}
void test3() {
int px = (int) malloc(120);
* (int*) px = 8;
* (int*) (px + 4) = 9;
printf("Testing writing (int*): %d %d\n", * (int*) px, * (int*) (px + 4));
free((void*) px);
}
void test4() {
int x = 0x12345678;
int px = &x;
int a = * (char*) px;
int b = * (char*) (px + 1);
int c = * (char*) (px + 2);
int d = * (char*) (px + 3);
printf("Testing reading (char*): 0x%02x 0x%02x 0x%02x 0x%02x\n", a, b, c, d);
}
void test5() {
int x = 0xFFFFFFFF;
int px = &x;
* (char*) px = 0x21;
* (char*) (px + 1) = 0x43;
* (char*) (px + 2) = 0x65;
* (char*) (px + 3) = 0x87;
printf("Testing writing (char*): 0x%08x\n", x);
}
int f(int b) {
printf("f(%d)\n", b);
return 7 * b;
}
void test6() {
int fp = &f;
int x = (*(int(*)()) fp)(10);
printf("Function pointer result: %d\n", x);
}
void test7() {
int px = (int) malloc(120);
* (float*) px = 8.8f;
* (float*) (px + 4) = 9.9f;
printf("Testing read/write (float*): %g %g\n", * (float*) px, * (float*) (px + 4));
free((void*) px);
}
void test8() {
int px = (int) malloc(120);
* (double*) px = 8.8;
* (double*) (px + 8) = 9.9;
printf("Testing read/write (double*): %g %g\n", * (double*) px, * (double*) (px + 8));
free((void*) px);
}
int main() {
test1();
test2();
test3();
test4();
test5();
test6();
test7();
test8();
return 0;
}

13
libacc/tests/data/char.c Normal file
View File

@ -0,0 +1,13 @@
char ga;
char gb;
int main() {
char a = 'c';
char b = a * 3;
printf("a = %d, b = %d\n", a, b);
ga = 'd';
gb = ga * 3;
printf("ga = %d, gb = %d\n", ga, gb);
return 0;
}

35
libacc/tests/data/comma.c Normal file
View File

@ -0,0 +1,35 @@
int testReturn() {
return 10, 20, 30;
}
int testArg(int a) {
return a;
}
void testComma() {
int a;
0, a = 10,20;
printf("statement: %d\n", a);
a = 1;
if (a = 0, 1) {
printf("if: a = %d\n", a);
}
int b = 0;
a = 10;
while(b++,a--) {}
printf("while: b = %d\n", b);
b = 0;
for(b++,a = 0;b++, a < 10; b++, a++) {}
printf("for: b = %d\n", b);
b = testReturn();
printf("return: %d\n", b);
b = testArg((a,12));
printf("arg: %d\n", b);
}
int main() {
testComma();
return 0;
}

View File

@ -0,0 +1,30 @@
#define FOO 0x10
int main() {
printf("0 = %d\n", 0);
printf("010 = %d\n", 010);
printf("0x10 = %d\n", FOO);
printf("'\\a' = %d\n", '\a');
printf("'\\b' = %d\n", '\b');
printf("'\\f' = %d\n", '\f');
printf("'\\n' = %d\n", '\n');
printf("'\\r' = %d\n", '\r');
printf("'\\t' = %d\n", '\t');
printf("'\\v' = %d\n", '\v');
// Undefined
// printf("'\\z' = %d\n", '\z');
printf("'\\\\' = %d\n", '\\');
printf("'\\'' = %d\n", '\'');
printf("'\\\"' = %d\n", '\"');
printf("'\\?' = %d\n", '\?');
printf("'\\0' = %d\n", '\0');
printf("'\\1' = %d\n", '\1');
printf("'\\12' = %d\n", '\12');
printf("'\\123' = %d\n", '\123');
printf("'\\x0' = %d\n", '\x0');
printf("'\\x1' = %d\n", '\x1');
printf("'\\x12' = %d\n", '\x12');
printf("'\\x123' = %d\n", '\x123');
printf("'\\x1f' = %d\n", '\x1f');
printf("'\\x1F' = %d\n", '\x1F');
}

View File

@ -0,0 +1,9 @@
// Simple tests of the C preprocessor
#define A 1
#define A (4 / 2)
#define B 1 // This is a comment. With a / in it.
int main() {
return A + B;
}

View File

@ -0,0 +1,7 @@
double atof(char *nptr);
int main() {
printf("Value = %g\n", atof("10.42"));
return 0;
}

View File

@ -0,0 +1,2 @@
void foo;

View File

@ -0,0 +1,60 @@
/* Test operators */
void testInc() { int a, b; a = 3; b = a++; printf("3++ = %d %d\n", b, a); }
void testDec() { int a, b; a = 3; b = a--; printf("3-- = %d %d\n", b, a); }
void testTimes(){ printf("%d * %d = %d\n", 10, 4, 10 * 4); }
void testDiv(){ printf("%d / %d = %d\n", 11, 4, 11 / 4); }
void testMod(){ printf("%d %% %d = %d\n", 11, 4, 11 % 4); }
void testPlus(){ printf("%d + %d = %d\n", 10, 4, 10 + 4); }
void testMinus(){ printf("%d - %d = %d\n", 10, 4, 10 - 4); }
void testShiftLeft(){ printf("%d << %d = %d\n", 10, 4, 10 << 4); }
void testShiftRight(){ printf("%d >> %d = %d\n", 100, 4, 100 >> 4); }
void testLess(){ printf("%d < %d = %d\n", 10, 4, 10 < 4); }
void testLesEqual(){ printf("%d <= %d = %d\n", 10, 4, 10 <= 4); }
void testGreater(){ printf("%d > %d = %d\n", 10, 4, 10 > 4); }
void testGreaterEqual(){ printf("%d >= %d = %d\n", 10, 4, 10 >= 4); }
void testEqualTo(){ printf("%d == %d = %d\n", 10, 4, 10 == 4); }
void testNotEqualTo(){ printf("%d != %d = %d\n", 10, 4, 10 != 4); }
void testBitAnd(){ printf("%d & %d = %d\n", 10, 7, 10 & 7); }
void testBitXor(){ printf("%d ^ %d = %d\n", 10, 7, 10 ^ 7); }
void testBitOr(){ printf("%d | %d = %d\n", 10, 4, 10 | 4); }
void testAssignment(){ int a, b; a = 3; b = a; printf("b == %d\n", b); }
void testLogicalAnd(){ printf("%d && %d = %d\n", 10, 4, 10 && 4); }
void testLogicalOr(){ printf("%d || %d = %d\n", 10, 4, 10 || 4); }
void testAddressOf(){ int a; printf("&a is %d\n", &a); }
void testPointerIndirection(){ int a, b; a = &b; b = 17; printf("*%d = %d =?= %d\n", a, * (int*) a, b); }
void testNegation(){ printf("-%d = %d\n", 10, -10); }
void testUnaryPlus(){ printf("+%d = %d\n", 10, +10); }
void testUnaryNot(){ printf("!%d = %d\n", 10, !10); }
void testBitNot(){ printf("~%d = %d\n", 10, ~10); }
int main(int a, char** b) {
testInc();
testDec();
testTimes();
testDiv();
testMod();
testPlus();
testMinus();
testShiftLeft();
testShiftRight();
testLess();
testLesEqual();
testGreater();
testGreaterEqual();
testEqualTo();
testNotEqualTo();
testBitAnd();
testBinXor();
testBitOr();
testAssignment();
testLogicalAnd();
testLogicalOr();
testAddressOf();
testPointerIndirection();
testNegation();
testUnaryPlus();
testUnaryNot();
testBitNot();
return 0;
}

60
libacc/tests/data/expr.c Normal file
View File

@ -0,0 +1,60 @@
/* Test operators */
testInc() { int a, b; a = 3; b = a++; printf("3++ = %d %d\n", b, a); }
testDec() { int a, b; a = 3; b = a--; printf("3-- = %d %d\n", b, a); }
testTimes(){ printf("%d * %d = %d\n", 10, 4, 10 * 4); }
testDiv(){ printf("%d / %d = %d\n", 11, 4, 11 / 4); }
testMod(){ printf("%d %% %d = %d\n", 11, 4, 11 % 4); }
testPlus(){ printf("%d + %d = %d\n", 10, 4, 10 + 4); }
testMinus(){ printf("%d - %d = %d\n", 10, 4, 10 - 4); }
testShiftLeft(){ printf("%d << %d = %d\n", 10, 4, 10 << 4); }
testShiftRight(){ printf("%d >> %d = %d\n", 100, 4, 100 >> 4); }
testLess(){ printf("%d < %d = %d\n", 10, 4, 10 < 4); }
testLesEqual(){ printf("%d <= %d = %d\n", 10, 4, 10 <= 4); }
testGreater(){ printf("%d > %d = %d\n", 10, 4, 10 > 4); }
testGreaterEqual(){ printf("%d >= %d = %d\n", 10, 4, 10 >= 4); }
testEqualTo(){ printf("%d == %d = %d\n", 10, 4, 10 == 4); }
testNotEqualTo(){ printf("%d != %d = %d\n", 10, 4, 10 != 4); }
testBitAnd(){ printf("%d & %d = %d\n", 10, 7, 10 & 7); }
testBitXor(){ printf("%d ^ %d = %d\n", 10, 7, 10 ^ 7); }
testBitOr(){ printf("%d | %d = %d\n", 10, 4, 10 | 4); }
testAssignment(){ int a, b; a = 3; b = a; printf("b == %d\n", b); }
testLogicalAnd(){ printf("%d && %d = %d\n", 10, 4, 10 && 4); }
testLogicalOr(){ printf("%d || %d = %d\n", 10, 4, 10 || 4); }
testAddressOf(){ int a; printf("&a is %d\n", &a); }
testPointerIndirection(){ int a, b; a = &b; b = 17; printf("*%d = %d =?= %d\n", a, * (int*) a, b); }
testNegation(){ printf("-%d = %d\n", 10, -10); }
testUnaryPlus(){ printf("+%d = %d\n", 10, +10); }
testUnaryNot(){ printf("!%d = %d\n", 10, !10); }
testBitNot(){ printf("~%d = %d\n", 10, ~10); }
main(a,b) {
testInc();
testDec();
testTimes();
testDiv();
testMod();
testPlus();
testMinus();
testShiftLeft();
testShiftRight();
testLess();
testLesEqual();
testGreater();
testGreaterEqual();
testEqualTo();
testNotEqualTo();
testBitAnd();
testBinXor();
testBitOr();
testAssignment();
testLogicalAnd();
testLogicalOr();
testAddressOf();
testPointerIndirection();
testNegation();
testUnaryPlus();
testUnaryNot();
testBitNot();
return 0;
}

View File

@ -0,0 +1,6 @@
/* Test operators */
main() {
int a;
a = a++;
}

53
libacc/tests/data/film.c Normal file
View File

@ -0,0 +1,53 @@
// Test logical and bitwise AND and OR
int test(int x, int y) {
int v = x || y;
return v;
}
int test2(int x, int y) {
if(x | y) {
return 1;
} else {
return 0;
}
}
int test3(int x, int y) {
int v = x && y;
return v;
}
int test4(int x, int y) {
if(x & y) {
return 1;
} else {
return 0;
}
}
int main(int index)
{
int x,y;
printf("testing...\n");
int totalBad = 0;
for(y = 0; y < 2; y++) {
for(x = 0; x < 2; x++) {
int a = test(x,y);
int b = test2(x,y);
if (a != b) {
printf("Results differ: OR x=%d y=%d a=%d b=%d\n", x, y, a, b);
totalBad++;
}
a = test3(x,y);
b = test4(x,y);
if (a != b) {
printf("Results differ: AND x=%d y=%d a=%d b=%d\n", x, y, a, b);
totalBad++;
}
}
}
printf("Total bad: %d\n", totalBad);
return 0;
}

57
libacc/tests/data/float.c Normal file
View File

@ -0,0 +1,57 @@
int ftoi(float f) {
return f;
}
int dtoi(double d) {
return d;
}
float itof(int i) {
return i;
}
double itod(int i) {
return i;
}
float f0, f1;
double d0, d1;
void testParseConsts() {
printf("Constants: %g %g %g %g %g %g %g %g %g\n", 0e1, 0E1, 0.f, .01f,
.01e0f, 1.0e-1, 1.0e1, 1.0e+1,
.1f);
}
void testVars(float arg0, float arg1, double arg2, double arg3) {
float local0, local1;
double local2, local3;
f0 = arg0;
f1 = arg1;
d0 = arg2;
d1 = arg3;
local0 = arg0;
local1 = arg1;
local2 = arg2;
local3 = arg3;
printf("globals: %g %g %g %g\n", f0, f1, d0, d1);
printf("args: %g %g %g %g\n", arg0, arg1, arg2, arg3);
printf("locals: %g %g %g %g\n", local0, local1, local2, local3);
printf("cast rval: %g %g\n", * (float*) & f1, * (double*) & d1);
* (float*) & f0 = 1.1f;
* (double*) & d0 = 3.3;
printf("cast lval: %g %g %g %g\n", f0, f1, d0, d1);
}
int main() {
testParseConsts();
printf("int: %d float: %g double: %g\n", 1, 2.2f, 3.3);
printf(" ftoi(1.4f)=%d\n", ftoi(1.4f));
printf(" dtoi(2.4)=%d\n", dtoi(2.4));
printf(" itof(3)=%g\n", itof(3));
printf(" itod(4)=%g\n", itod(4));
testVars(1.0f, 2.0f, 3.0, 4.0);
return 0;
}

View File

@ -0,0 +1,9 @@
int main()
{
// Test coercing values when storing.
float a = 0.002;
double b = 0.1f;
int c = 10.002;
printf("%g %g %d\n", a, b, c);
return 0;
}

158
libacc/tests/data/flops.c Normal file
View File

@ -0,0 +1,158 @@
// Test floating point operations.
void unaryOps() {
// Unary ops
printf("-%g = %g\n", 1.1, -1.1);
printf("!%g = %d\n", 1.2, !1.2);
printf("!%g = %d\n", 0.0, !0.0);
}
void binaryOps() {
printf("double op double:\n");
printf("%g + %g = %g\n", 1.0, 2.0, 1.0 + 2.0);
printf("%g - %g = %g\n", 1.0, 2.0, 1.0 - 2.0);
printf("%g * %g = %g\n", 1.0, 2.0, 1.0 * 2.0);
printf("%g / %g = %g\n", 1.0, 2.0, 1.0 / 2.0);
printf("float op float:\n");
printf("%g + %g = %g\n", 1.0f, 2.0f, 1.0f + 2.0f);
printf("%g - %g = %g\n", 1.0f, 2.0f, 1.0f - 2.0f);
printf("%g * %g = %g\n", 1.0f, 2.0f, 1.0f * 2.0f);
printf("%g / %g = %g\n", 1.0f, 2.0f, 1.0f / 2.0f);
printf("double op float:\n");
printf("%g + %g = %g\n", 1.0, 2.0f, 1.0 + 2.0f);
printf("%g - %g = %g\n", 1.0, 2.0f, 1.0 - 2.0f);
printf("%g * %g = %g\n", 1.0, 2.0f, 1.0 * 2.0f);
printf("%g / %g = %g\n", 1.0, 2.0f, 1.0 / 2.0f);
printf("double op int:\n");
printf("%g + %d = %g\n", 1.0, 2, 1.0 + 2);
printf("%g - %d = %g\n", 1.0, 2, 1.0 - 2);
printf("%g * %d = %g\n", 1.0, 2, 1.0 * 2);
printf("%g / %d = %g\n", 1.0, 2, 1.0 / 2);
printf("int op double:\n");
printf("%d + %g = %g\n", 1, 2.0, 1 + 2.0);
printf("%d - %g = %g\n", 1, 2.0, 1 - 2.0);
printf("%d * %g = %g\n", 1, 2.0, 1 * 2.0);
printf("%d / %g = %g\n", 1, 2.0, 1 / 2.0);
}
void comparisonTestdd(double a, double b) {
printf("%g op %g: < %d <= %d == %d >= %d > %d != %d\n",
a, b, a < b, a <= b, a == b, a >= b, a > b, a != b);
}
void comparisonOpsdd() {
printf("double op double:\n");
comparisonTestdd(1.0, 2.0);
comparisonTestdd(1.0, 1.0);
comparisonTestdd(2.0, 1.0);
}
void comparisonTestdf(double a, float b) {
printf("%g op %g: < %d <= %d == %d >= %d > %d != %d\n",
a, b, a < b, a <= b, a == b, a >= b, a > b, a != b);
}
void comparisonOpsdf() {
printf("double op float:\n");
comparisonTestdf(1.0, 2.0f);
comparisonTestdf(1.0, 1.0f);
comparisonTestdf(2.0, 1.0f);
}
void comparisonTestff(float a, float b) {
printf("%g op %g: < %d <= %d == %d >= %d > %d != %d\n",
a, b, a < b, a <= b, a == b, a >= b, a > b, a != b);
}
void comparisonOpsff() {
printf("float op float:\n");
comparisonTestff(1.0f, 2.0f);
comparisonTestff(1.0f, 1.0f);
comparisonTestff(2.0f, 1.0f);
}
void comparisonTestid(int a, double b) {
printf("%d op %g: < %d <= %d == %d >= %d > %d != %d\n",
a, b, a < b, a <= b, a == b, a >= b, a > b, a != b);
}
void comparisonOpsid() {
printf("int op double:\n");
comparisonTestid(1, 2.0);
comparisonTestid(1, 1.0);
comparisonTestid(2, 1.0);
}
void comparisonTestdi(double a, int b) {
printf("%g op %d: < %d <= %d == %d >= %d > %d != %d\n",
a, b, a < b, a <= b, a == b, a >= b, a > b, a != b);
}
void comparisonOpsdi() {
printf("double op int:\n");
comparisonTestdi(1.0f, 2);
comparisonTestdi(1.0f, 1);
comparisonTestdi(2.0f, 1);
}
void comparisonOps() {
comparisonOpsdd();
comparisonOpsdf();
comparisonOpsff();
comparisonOpsid();
comparisonOpsdi();
}
int branch(double d) {
if (d) {
return 1;
}
return 0;
}
void testBranching() {
printf("branching: %d %d %d\n", branch(-1.0), branch(0.0), branch(1.0));
}
void testpassi(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l) {
printf("testpassi: %d %d %d %d %d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h, i, j, k, l);
}
void testpassf(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l) {
printf("testpassf: %g %g %g %g %g %g %g %g %g %g %g %g\n", a, b, c, d, e, f, g, h, i, j, k, l);
}
void testpassd(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j, double k, double l) {
printf("testpassd: %g %g %g %g %g %g %g %g %g %g %g %g\n", a, b, c, d, e, f, g, h, i, j, k, l);
}
void testpassidf(int i, double d, float f) {
printf("testpassidf: %d %g %g\n", i, d, f);
}
void testParameterPassing() {
float x;
testpassi(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
testpassf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
testpassd(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
testpassi(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f);
testpassf(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f);
testpassd(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f);
testpassi(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0);
testpassf(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0);
testpassd(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0);
testpassidf(1, 2.0, 3.0f);
}
int main() {
unaryOps();
binaryOps();
comparisonOps();
testBranching();
testParameterPassing();
return 0;
}

View File

@ -0,0 +1,8 @@
int f(int a,int, int c) {
return a + c;
}
int main() {
return f(1,2,3);
}

View File

@ -0,0 +1,3 @@
main(a,b) {
printf("Hello, world\n");
}

14
libacc/tests/data/inc.c Normal file
View File

@ -0,0 +1,14 @@
// Check integer operations
int main() {
int a = 0;
printf("%d\n", a++);
printf("%d\n", a++);
printf("%d\n", a--);
printf("%d\n", a--);
printf("%d\n", ++a);
printf("%d\n", ++a);
printf("%d\n", --a);
printf("%d\n", --a);
return a;
}

23
libacc/tests/data/iops.c Normal file
View File

@ -0,0 +1,23 @@
// Check integer operations
void loops() {
int y;
printf("++\n");
for(y = 0; y < 10; y++) {
printf("%d\n", y);
}
printf("--\n");
for(y = 10; y >= 0; y--) {
printf("%d\n", y);
}
}
void checkLiterals() {
printf("Literals: %d %d\n", 1, -1);
}
int main() {
checkLiterals();
loops();
return 0;
}

View File

@ -0,0 +1,71 @@
int a;
int f() {
int a;
// Undefined variable b
// printf("f 0: a = %d b = %d\n", a, b);
printf("f 0: a = %d\n", a);
a = 2;
printf("f 1: a = %d\n", a);
}
int g(int a) {
printf("g 0: a = %d\n", a);
a = 3;
printf("g 1: a = %d\n", a);
}
int h(int a) {
// int a; // gcc 4.3 says error: 'a' redeclared as different kind of symbol
printf("h 0: a = %d\n", a);
a = 4;
printf("h 1: a = %d\n", a);
}
// Already defined global
// int h() {}
int globCheck() {
fprintf(stdout, "globCheck()\n");
}
int fwdCheck() {
b();
// Undefined forward reference
// c();
}
int b() {
printf("b()\n");
}
int nested() {
int a;
printf("nested 0: a = %d\n", a);
a = 50;
printf("nested 1: a = %d\n", a);
{
int a;
printf("nested 2: a = %d\n", a);
a = 51;
printf("nested 3: a = %d\n", a);
}
printf("nested 4: a = %d\n", a);
}
int main() {
globCheck();
fwdCheck();
printf("main 0: a = %d\n", a);
a = 5;
printf("main 1: a = %d\n", a);
f();
printf("main 2: a = %d\n", a);
g(77);
printf("main 3: a = %d\n", a);
h(30);
printf("main 4: a = %d\n", a);
nested();
printf("main 5: a = %d\n", a);
return 0;
}

View File

@ -0,0 +1,4 @@
/* No main. */
a() {
}

View File

@ -0,0 +1,466 @@
// #include <stdio.h>
int d, z, C, h, P, K, ac, q, G, v, Q, R, D, L, W, M;
void E(int e) {
*(char*) D++ = e;
}
void o() {
if (L) {
h = *(char*) L++;
if (h == 2) {
L = 0;
h = W;
}
} else
h = fgetc(Q);
}
int X() {
return isalnum(h) | h == 95;
}
void Y() {
if (h == 92) {
o();
if (h == 110)
h = 10;
}
}
void ad() {
int e, j, m;
while (isspace(h) | h == 35) {
if (h == 35) {
o();
ad();
if (d == 536) {
ad();
E(32);
*(int*) d = 1;
*(int*) (d + 4) = D;
}
while (h != 10) {
E(h);
o();
}
E(h);
E(2);
}
o();
}
C = 0;
d = h;
if (X()) {
E(32);
M = D;
while (X()) {
E(h);
o();
}
if (isdigit(d)) {
z = strtol(M, 0, 0);
d = 2;
} else {
*(char*) D = 32;
d = strstr(R, M - 1) - R;
*(char*) D = 0;
d = d * 8 + 256;
if (d > 536) {
d = P + d;
if (*(int*) d == 1) {
L = *(int*) (d + 4);
W = h;
o();
ad();
}
}
}
} else {
o();
if (d == 39) {
d = 2;
Y();
z = h;
o();
o();
} else if (d == 47 & h == 42) {
o();
while (h) {
while (h != 42)
o();
o();
if (h == 47)
h = 0;
}
o();
ad();
} else {
e
= "++#m--%am*@R<^1c/@%[_[H3c%@%[_[H3c+@.B#d-@%:_^BKd<<Z/03e>>`/03e<=0f>=/f<@.f>@1f==&g!='g&&k||#l&@.BCh^@.BSi|@.B+j~@/%Yd!@&d*@b";
while (j = *(char*) e++) {
m = *(char*) e++;
z = 0;
while ((C = *(char*) e++ - 98) < 0)
z = z * 64 + C + 64;
if (j == d & (m == h | m == 64)) {
if (m == h) {
o();
d = 1;
}
break;
}
}
}
}
}
void ae(int g) {
while( g&&g!=-1) {
*(char*) q++=g;
g=g>>8;
}
}
void A(int e) {
int g;
while( e) {
g=*(int*) e;
*(int*) e=q-e-4;
e=g;
}
}
int s(int g, int e) {
ae(g);
*(int*) q = e;
e = q;
q = q + 4;
return e;
}
void H(int e) {
s(184,e);
}
int B(int e) {
return s(233,e);
}
int S(int j, int e) {
ae(1032325);
return s(132 + j, e);
}
void Z(int e) {
ae( 49465);
H(0);
ae( 15);
ae( e+144);
ae( 192);
}
void N(int j, int e) {
ae(j + 131);
s((e > -512 && e < 512) << 7 | 5, e);
}
void T (int j) {
int g,e,m,aa;
g=1;
if( d == 34) {
H(v);
while( h!=34) {
Y ();
*(char*) v++=h;
o ();
}
*(char*) v=0;
v=v +4&-4;
o ();
ad();
}
else {
aa=C;
m= z;
e=d;
ad();
if( e == 2) {
H(m);
}
else if( aa == 2) {
T(0);
s(185,0);
if( e == 33)Z(m);
else ae( m);
}
else if( e == 40) {
w ();
ad();
}
else if( e == 42) {
ad();
e=d;
ad();
ad();
if( d == 42) {
ad();
ad();
ad();
ad();
e=0;
}
ad();
T(0);
if( d == 61) {
ad();
ae( 80);
w ();
ae( 89);
ae( 392+(e == 256));
}
else if( e) {
if( e == 256)ae( 139);
else ae( 48655);
q++;
}
}
else if( e == 38) {
N(10,*(int*) d);
ad();
}
else {
g=*(int*) e;
if(!g)g=dlsym(0,M);
if( d == 61&j) {
ad();
w ();
N(6,g);
}
else if( d!= 40) {
N(8,g);
if( C == 11) {
N(0,g);
ae( z);
ad();
}
}
}
}
if( d == 40) {
if( g == 1)ae( 80);
m= s(60545,0);
ad();
j=0;
while( d!= 41) {
w ();
s(2393225,j);
if( d == 44)ad();
j=j +4;
}
*(int*) m= j;
ad();
if(!g) {
e=e +4;
*(int*) e=s(232,*(int*) e);
}
else if( g == 1) {
s(2397439,j);
j=j +4;
}
else {
s(232,g-q-5);
}
if( j)s(50305,j);
}
}
void O (int j) {
int e,g,m;
if( j--== 1)T(1);
else {
O (j);
m= 0;
while( j == C) {
g=d;
e=z;
ad();
if( j>8) {
m= S(e,m);
O (j);
}
else {
ae( 80);
O (j);
ae( 89);
if( j == 4|j == 5) {
Z(e);
}
else {
ae( e);
if( g == 37)ae( 146);
}
}
}
if( m&&j>8) {
m= S(e,m);
H(e^1);
B(5);
A(m);
H(e);
}
}
}
void w() {
O(11);
}
int U() {
w();
return S(0, 0);
}
void I (int j) {
int m,g,e;
if( d == 288) {
ad();
ad();
m= U ();
ad();
I (j);
if( d == 312) {
ad();
g=B(0);
A(m);
I (j);
A(g);
}
else {
A(m);
}
}
else if( d == 352|d == 504) {
e=d;
ad();
ad();
if( e == 352) {
g=q;
m= U ();
}
else {
if( d!= 59)w ();
ad();
g=q;
m= 0;
if( d!= 59)m= U ();
ad();
if( d!= 41) {
e=B(0);
w ();
B(g-q-5);
A(e);
g=e +4;
}
}
ad();
I(&m);
B(g-q-5);
A(m);
}
else if( d == 123) {
ad();
ab(1);
while( d!= 125)I (j);
ad();
}
else {
if( d == 448) {
ad();
if( d!= 59)w ();
K=B(K);
}
else if( d == 400) {
ad();
*(int*) j=B(*(int*) j);
}
else if( d!= 59)w ();
ad();
}
}
void ab (int j) {
int m;
while( d == 256|d!=-1&!j) {
if( d == 256) {
ad();
while( d!= 59) {
if( j) {
G=G +4;
*(int*) d=-G;
}
else {
*(int*) d=v;
v=v +4;
}
ad();
if( d == 44)ad() ;
}
ad();
}
else {
A(*(int*)(d +4));
*(int*) d=q;
ad();
ad();
m= 8;
while( d!= 41) {
*(int*) d=m;
m= m +4;
ad();
if( d == 44)ad();
}
ad();
K=G=0;
ae( 15042901);
m= s(60545,0);
I(0);
A(K);
ae( 50121);
*(int*) m= G;
}
}
}
int run(int g, int e) {
return (*(int(*)()) *(int*) (P + 592))(g, e);
}
int main(int g, int e) {
int result;
Q = stdin;
if (g-- > 1) {
e = e + 4;
Q = fopen(*(int*) e, "r");
if (!Q) {
fprintf(stderr, "otcc-ansi.c: could not open file %s\n", *(int*) e);
return -2;
}
}
D = strcpy(R = calloc(1, 99999), " int if else while break return for define main ") + 48;
v = calloc(1, 99999);
q = ac = calloc(1, 99999);
P = calloc(1, 99999);
o();
ad();
ab(0);
if (mprotect(ac & (~ 4095), (99999 + 4095) & (~ 4095), 7)) {
printf("Mprotect failed. %d\n", errno);
return -1;
}
fprintf(stderr, "otcc-ansi.c: About to execute compiled code:\n");
result = run(g, e);
fprintf(stderr, "atcc-ansi.c: result: %d\n", result);
return result;
}

View File

@ -0,0 +1,446 @@
// #include <stdio.h>
#define k *(int*)
#define a if(
#define c ad()
#define i else
#define p while(
#define x *(char*)
#define b ==
#define V =calloc(1,99999)
#define f ()
#define J return
#define l ae(
#define n e)
#define u d!=
#define F int
#define y (j)
#define r m=
#define t +4
F d,z,C,h,P,K,ac,q,G,v,Q,R,D,L,W,M;
E(n{
x D++=e;
}
o f{
a L){
h=x L++;
a h b 2){
L=0;
h=W;
}
}
i h=fgetc(Q);
}
X f{
J isalnum(h)|h b 95;
}
Y f{
a h b 92){
o f;
a h b 110)h=10;
}
}
c{
F e,j,m;
p isspace(h)|h b 35){
a h b 35){
o f;
c;
a d b 536){
c;
E(32);
k d=1;
k(d t)=D;
}
p h!=10){
E(h);
o f;
}
E(h);
E(2);
}
o f;
}
C=0;
d=h;
a X f){
E(32);
M=D;
p X f){
E(h);
o f;
}
a isdigit(d)){
z=strtol(M,0,0);
d=2;
}
i{
x D=32;
d=strstr(R,M-1)-R;
x D=0;
d=d*8+256;
a d>536){
d=P+d;
a k d b 1){
L=k(d t);
W=h;
o f;
c;
}
}
}
}
i{
o f;
a d b 39){
d=2;
Y f;
z=h;
o f;
o f;
}
i a d b 47&h b 42){
o f;
p h){
p h!=42)o f;
o f;
a h b 47)h=0;
}
o f;
c;
}
i{
e="++#m--%am*@R<^1c/@%[_[H3c%@%[_[H3c+@.B#d-@%:_^BKd<<Z/03e>>`/03e<=0f>=/f<@.f>@1f==&g!='g&&k||#l&@.BCh^@.BSi|@.B+j~@/%Yd!@&d*@b";
p j=x e++){
r x e++;
z=0;
p(C=x e++-98)<0)z=z*64+C+64;
a j b d&(m b h|m b 64)){
a m b h){
o f;
d=1;
}
break;
}
}
}
}
}
l g){
p g&&g!=-1){
x q++=g;
g=g>>8;
}
}
A(n{
F g;
p n{
g=k e;
k e=q-e-4;
e=g;
}
}
s(g,n{
l g);
k q=e;
e=q;
q=q t;
J e;
}
H(n{
s(184,n;
}
B(n{
J s(233,n;
}
S(j,n{
l 1032325);
J s(132+j,n;
}
Z(n{
l 49465);
H(0);
l 15);
l e+144);
l 192);
}
N(j,n{
l j+131);
s((e<512)<<7|5,n;
}
T y{
F g,e,m,aa;
g=1;
a d b 34){
H(v);
p h!=34){
Y f;
x v++=h;
o f;
}
x v=0;
v=v t&-4;
o f;
c;
}
i{
aa=C;
r z;
e=d;
c;
a e b 2){
H(m);
}
i a aa b 2){
T(0);
s(185,0);
a e b 33)Z(m);
i l m);
}
i a e b 40){
w f;
c;
}
i a e b 42){
c;
e=d;
c;
c;
a d b 42){
c;
c;
c;
c;
e=0;
}
c;
T(0);
a d b 61){
c;
l 80);
w f;
l 89);
l 392+(e b 256));
}
i a n{
a e b 256)l 139);
i l 48655);
q++;
}
}
i a e b 38){
N(10,k d);
c;
}
i{
g=k e;
a!g)g=dlsym(0,M);
a d b 61&j){
c;
w f;
N(6,g);
}
i a u 40){
N(8,g);
a C b 11){
N(0,g);
l z);
c;
}
}
}
}
a d b 40){
a g b 1)l 80);
r s(60545,0);
c;
j=0;
p u 41){
w f;
s(2393225,j);
a d b 44)c;
j=j t;
}
k r j;
c;
a!g){
e=e t;
k e=s(232,k n;
}
i a g b 1){
s(2397439,j);
j=j t;
}
i{
s(232,g-q-5);
}
a j)s(50305,j);
}
}
O y{
F e,g,m;
a j--b 1)T(1);
i{
O y;
r 0;
p j b C){
g=d;
e=z;
c;
a j>8){
r S(e,m);
O y;
}
i{
l 80);
O y;
l 89);
a j b 4|j b 5){
Z(n;
}
i{
l n;
a g b 37)l 146);
}
}
}
a m&&j>8){
r S(e,m);
H(e^1);
B(5);
A(m);
H(n;
}
}
}
w f{
O(11);
}
U f{
w f;
J S(0,0);
}
I y{
F m,g,e;
a d b 288){
c;
c;
r U f;
c;
I y;
a d b 312){
c;
g=B(0);
A(m);
I y;
A(g);
}
i{
A(m);
}
}
i a d b 352|d b 504){
e=d;
c;
c;
a e b 352){
g=q;
r U f;
}
i{
a u 59)w f;
c;
g=q;
r 0;
a u 59)r U f;
c;
a u 41){
e=B(0);
w f;
B(g-q-5);
A(n;
g=e t;
}
}
c;
I(&m);
B(g-q-5);
A(m);
}
i a d b 123){
c;
ab(1);
p u 125)I y;
c;
}
i{
a d b 448){
c;
a u 59)w f;
K=B(K);
}
i a d b 400){
c;
k j=B(k j);
}
i a u 59)w f;
c;
}
}
ab y{
F m;
p d b 256|u-1&!j){
a d b 256){
c;
p u 59){
a j){
G=G t;
k d=-G;
}
i{
k d=v;
v=v t;
}
c;
a d b 44)c;
}
c;
}
i{
A(k(d t));
k d=q;
c;
c;
r 8;
p u 41){
k d=m;
r m t;
c;
a d b 44)c;
}
c;
K=G=0;
l 15042901);
r s(60545,0);
I(0);
A(K);
l 50121);
k r G;
}
}
}
main(g,n{
Q=stdin;
a g-->1){
e=e t;
Q=fopen(k e,"r");
}
D=strcpy(R V," int if else while break return for define main ")+48;
v V;
q=ac V;
P V;
o f;
c;
ab(0);
J(*(int(*)f)k(P+592))(g,n;
}

448
libacc/tests/data/otcc.c Normal file
View File

@ -0,0 +1,448 @@
#include <stdio.h>
#define k *(int*)
#define a if(
#define c ad()
#define i else
#define p while(
#define x *(char*)
#define b ==
#define V =calloc(1,99999)
#define f ()
#define J return
#define l ae(
#define n e)
#define u d!=
#define F int
#define y (j)
#define r m=
#define t +4
F d,z,C,h,P,K,ac,q,G,v,Q,R,D,L,W,M;
E(n{
x D++=e;
}
o f{
a L){
h=x L++;
a h b 2){
L=0;
h=W;
}
}
i h=fgetc(Q);
}
X f{
J isalnum(h)|h b 95;
}
Y f{
a h b 92){
o f;
a h b 110)h=10;
}
}
c{
F e,j,m;
p isspace(h)|h b 35){
a h b 35){
o f;
c;
a d b 536){
c;
E(32);
k d=1;
k(d t)=D;
}
p h!=10){
E(h);
o f;
}
E(h);
E(2);
}
o f;
}
C=0;
d=h;
a X f){
E(32);
M=D;
p X f){
E(h);
o f;
}
a isdigit(d)){
z=strtol(M,0,0);
d=2;
}
i{
x D=32;
d=strstr(R,M-1)-R;
x D=0;
d=d*8+256;
a d>536){
d=P+d;
a k d b 1){
L=k(d t);
W=h;
o f;
c;
}
}
}
}
i{
o f;
a d b 39){
d=2;
Y f;
z=h;
o f;
o f;
}
i a d b 47&h b 42){
o f;
p h){
p h!=42)o f;
o f;
a h b 47)h=0;
}
o f;
c;
}
i{
e="++#m--%am*@R<^1c/@%[_[H3c%@%[_[H3c+@.B#d-@%:_^BKd<<Z/03e>>`/03e<=0f>=/f<@.f>@1f==&g!='g&&k||#l&@.BCh^@.BSi|@.B+j~@/%Yd!@&d*@b";
p j=x e++){
r x e++;
z=0;
p(C=x e++-98)<0)z=z*64+C+64;
a j b d&(m b h|m b 64)){
a m b h){
o f;
d=1;
}
break;
}
}
}
}
}
l g){
p g&&g!=-1){
x q++=g;
g=g>>8;
}
}
A(n{
F g;
p n{
g=k e;
k e=q-e-4;
e=g;
}
}
s(g,n{
l g);
k q=e;
e=q;
q=q t;
J e;
}
H(n{
s(184,n;
}
B(n{
J s(233,n;
}
S(j,n{
l 1032325);
J s(132+j,n;
}
Z(n{
l 49465);
H(0);
l 15);
l e+144);
l 192);
}
N(j,n{
l j+131);
s((e<512)<<7|5,n;
}
T y{
F g,e,m,aa;
g=1;
a d b 34){
H(v);
p h!=34){
Y f;
x v++=h;
o f;
}
x v=0;
v=v t&-4;
o f;
c;
}
i{
aa=C;
r z;
e=d;
c;
a e b 2){
H(m);
}
i a aa b 2){
T(0);
s(185,0);
a e b 33)Z(m);
i l m);
}
i a e b 40){
w f;
c;
}
i a e b 42){
c;
e=d;
c;
c;
a d b 42){
c;
c;
c;
c;
e=0;
}
c;
T(0);
a d b 61){
c;
l 80);
w f;
l 89);
l 392+(e b 256));
}
i a n{
a e b 256)l 139);
i l 48655);
q++;
}
}
i a e b 38){
N(10,k d);
c;
}
i{
g=k e;
a!g)g=dlsym(0,M);
a d b 61&j){
c;
w f;
N(6,g);
}
i a u 40){
N(8,g);
a C b 11){
N(0,g);
l z);
c;
}
}
}
}
a d b 40){
a g b 1)l 80);
r s(60545,0);
c;
j=0;
p u 41){
w f;
s(2393225,j);
a d b 44)c;
j=j t;
}
k r j;
c;
a!g){
e=e t;
k e=s(232,k n;
}
i a g b 1){
s(2397439,j);
j=j t;
}
i{
s(232,g-q-5);
}
a j)s(50305,j);
}
}
O y{
F e,g,m;
a j--b 1)T(1);
i{
O y;
r 0;
p j b C){
g=d;
e=z;
c;
a j>8){
r S(e,m);
O y;
}
i{
l 80);
O y;
l 89);
a j b 4|j b 5){
Z(n;
}
i{
l n;
a g b 37)l 146);
}
}
}
a m&&j>8){
r S(e,m);
H(e^1);
B(5);
A(m);
H(n;
}
}
}
w f{
O(11);
}
U f{
w f;
J S(0,0);
}
I y{
F m,g,e;
a d b 288){
c;
c;
r U f;
c;
I y;
a d b 312){
c;
g=B(0);
A(m);
I y;
A(g);
}
i{
A(m);
}
}
i a d b 352|d b 504){
e=d;
c;
c;
a e b 352){
g=q;
r U f;
}
i{
a u 59)w f;
c;
g=q;
r 0;
a u 59)r U f;
c;
a u 41){
e=B(0);
w f;
B(g-q-5);
A(n;
g=e t;
}
}
c;
I(&m);
B(g-q-5);
A(m);
}
i a d b 123){
c;
ab(1);
p u 125)I y;
c;
}
i{
a d b 448){
c;
a u 59)w f;
K=B(K);
}
i a d b 400){
c;
k j=B(k j);
}
i a u 59)w f;
c;
}
}
ab y{
F m;
p d b 256|u-1&!j){
a d b 256){
c;
p u 59){
a j){
G=G t;
k d=-G;
}
i{
k d=v;
v=v t;
}
c;
a d b 44)c;
}
c;
}
i{
A(k(d t));
k d=q;
c;
c;
r 8;
p u 41){
k d=m;
r m t;
c;
a d b 44)c;
}
c;
K=G=0;
l 15042901);
r s(60545,0);
I(0);
A(K);
l 50121);
k r G;
}
}
}
main(g,n{
Q=stdin;
a g-->1){
e=e t;
Q=fopen(k e,"r");
}
D=strcpy(R V," int if else while break return for define main ")+48;
v V;
q=ac V;
P V;
o f;
c;
ab(0);
mprotect(ac & (~ 4095), (99999 + 4095) & (~ 4095), 7);
fprintf(stderr, "otcc.c: about to execute compiled code.\n");
J(*(int(*)f)k(P+592))(g,n;
}

View File

@ -0,0 +1,15 @@
int main() {
int* pa = (int*) malloc(100);
int* pb = pa + 1;
int* pc = (int*) 0;
*pa = 1;
*pb = 2;
printf("Pointer difference: %d %d\n", pb - pa, ((int) pb) - ((int) pa));
int c = * (pa + 1);
printf("Pointer addition: %d\n", c);
printf("Pointer comparison to zero: %d %d %d\n", pa == 0, pb == 0, pc == 0);
printf("Pointer comparison: %d %d %d %d %d\n", pa < pb, pa == pb, pa > pb, ! pb, ! pc);
free(pa);
return 0;
}

View File

@ -0,0 +1,35 @@
// Test multiple levels of indirection
void testsingle() {
int a = 0;
int* pa = &a;
printf("a = %d, *pa = %d\n", a, *pa);
*pa = 2;
printf("a = %d, *pa = %d\n", a, *pa);
}
void testdouble() {
int a = 0;
int* pa = &a;
int** ppa = &pa;
printf("a = %d, *pa = %d **ppa = %d\n", a, *pa, **ppa);
**ppa = 2;
printf("a = %d, *pa = %d **ppa = %d\n", a, *pa, **ppa);
}
void testtripple() {
int a = 0;
int* pa = &a;
int** ppa = &pa;
int*** pppa = &ppa;
printf("a = %d, *pa = %d **ppa = %d\n ***pppa = %d", a, *pa, **ppa, ***pppa);
***pppa = 2;
printf("a = %d, *pa = %d **ppa = %d\n ***pppa = %d", a, *pa, **ppa, ***pppa);
}
int main() {
testsingle();
testdouble();
testdouble();
return 0;
}

View File

@ -0,0 +1,8 @@
int main(int argc, char** argv) {
return f();
}
int f() {
return 42;
}

View File

@ -0,0 +1,4 @@
main() {
return 42;
}

View File

@ -0,0 +1,9 @@
float fabsf(float);
int main(void* con, int ft, int launchID)
{
float f = fabsf(-10.0f);
return f;
}

View File

@ -0,0 +1,6 @@
short a = 3;
int main() {
short* b = &a;
*b = *b - 5;
return a;
}

View File

@ -0,0 +1 @@
main() {}

View File

@ -0,0 +1,95 @@
// struct definition and declaration
struct a {
int a;
int b;
} c;
// Useless, but legal struct declaration
struct {
int x;
};
// Useful anonymous struct declaration
struct {
int y;
} anon1, anon2;
// forward declarations
struct a;
struct b;
struct c;
struct b {int a; int b; };
// struct c {b g; }; // syntax error.
// struct s {float c,a,b,c;} s; // duplicate struct member
struct c {struct b g; };
// struct a { int w; }; // error
void testCopying() {
struct a {int a[10]; char c;} a, b;
a.c = 37;
b.c = 38;
b = a;
printf("testCopying: %d == %d\n", a.c, b.c);
}
void testUnion() {
union u;
union u {float f;int i;} u;
u.f = 1.0f;
printf("testUnion: %g == 0x%08x\n", u.f, u.i);
}
struct v {float x, y, z, w; };
void add(struct v* result, struct v* a, struct v* b) {
result->x = a->x + b->x;
result->y = a->y + b->y;
result->z = a->z + b->z;
result->w = a->w + b->w;
}
void set(struct v* v, float x, float y, float z, float w) {
v->x = x;
v->y = y;
v->z = z;
v->w = w;
}
void print(struct v* v) {
printf("(%g, %g, %g, %g)\n", v->x, v->y, v->z, v->w);
}
void testArgs() {
struct v a, b, c;
set(&a, 1.0f, 2.0f, 3.0f, 4.0f);
set(&b, 5.0f, 6.0f, 7.0f, 8.0f);
add(&c, &a, &b);
printf("testArgs: ");
print(&c);
}
int main() {
anon1.y = 3;
anon2.y = anon1.y;
testCopying();
testUnion();
testArgs();
struct c cc;
cc.g.a = 3;
c.a = 1;
c.b = 3;
struct a {int x, y; } z;
// struct a {int x, y; } z2;
z.x = c.a;
struct a *pA;
pA = &z;
pA->x += 5;
return pA->x;
}

View File

@ -0,0 +1,4 @@
int main() {
return printf("Hello" "," " world\n");
}

711
libacc/tests/disassem.cpp Normal file
View File

@ -0,0 +1,711 @@
/* $NetBSD: disassem.c,v 1.14 2003/03/27 16:58:36 mycroft Exp $ */
/*-
* Copyright (c) 1996 Mark Brinicombe.
* Copyright (c) 1996 Brini.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
*
* db_disasm.c
*
* Kernel disassembler
*
* Created : 10/02/96
*
* Structured after the sparc/sparc/db_disasm.c by David S. Miller &
* Paul Kranenburg
*
* This code is not complete. Not all instructions are disassembled.
*/
#include <sys/cdefs.h>
//__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/arm/arm/disassem.c,v 1.2 2005/01/05 21:58:47 imp Exp $");
#include <sys/param.h>
#include <stdio.h>
#include <stdarg.h>
#include "disassem.h"
#include "armreg.h"
//#include <ddb/ddb.h>
/*
* General instruction format
*
* insn[cc][mod] [operands]
*
* Those fields with an uppercase format code indicate that the field
* follows directly after the instruction before the separator i.e.
* they modify the instruction rather than just being an operand to
* the instruction. The only exception is the writeback flag which
* follows a operand.
*
*
* 2 - print Operand 2 of a data processing instruction
* d - destination register (bits 12-15)
* n - n register (bits 16-19)
* s - s register (bits 8-11)
* o - indirect register rn (bits 16-19) (used by swap)
* m - m register (bits 0-3)
* a - address operand of ldr/str instruction
* e - address operand of ldrh/strh instruction
* l - register list for ldm/stm instruction
* f - 1st fp operand (register) (bits 12-14)
* g - 2nd fp operand (register) (bits 16-18)
* h - 3rd fp operand (register/immediate) (bits 0-4)
* b - branch address
* t - thumb branch address (bits 24, 0-23)
* k - breakpoint comment (bits 0-3, 8-19)
* X - block transfer type
* Y - block transfer type (r13 base)
* c - comment field bits(0-23)
* p - saved or current status register
* F - PSR transfer fields
* D - destination-is-r15 (P) flag on TST, TEQ, CMP, CMN
* L - co-processor transfer size
* S - set status flag
* P - fp precision
* Q - fp precision (for ldf/stf)
* R - fp rounding
* v - co-processor data transfer registers + addressing mode
* W - writeback flag
* x - instruction in hex
* # - co-processor number
* y - co-processor data processing registers
* z - co-processor register transfer registers
*/
struct arm32_insn {
u_int mask;
u_int pattern;
const char* name;
const char* format;
};
static const struct arm32_insn arm32_i[] = {
{ 0x0fffffff, 0x0ff00000, "imb", "c" }, /* Before swi */
{ 0x0fffffff, 0x0ff00001, "imbrange", "c" }, /* Before swi */
{ 0x0f000000, 0x0f000000, "swi", "c" },
{ 0xfe000000, 0xfa000000, "blx", "t" }, /* Before b and bl */
{ 0x0f000000, 0x0a000000, "b", "b" },
{ 0x0f000000, 0x0b000000, "bl", "b" },
{ 0x0fe000f0, 0x00000090, "mul", "Snms" },
{ 0x0fe000f0, 0x00200090, "mla", "Snmsd" },
{ 0x0fe000f0, 0x00800090, "umull", "Sdnms" },
{ 0x0fe000f0, 0x00c00090, "smull", "Sdnms" },
{ 0x0fe000f0, 0x00a00090, "umlal", "Sdnms" },
{ 0x0fe000f0, 0x00e00090, "smlal", "Sdnms" },
{ 0x0d700000, 0x04200000, "strt", "daW" },
{ 0x0d700000, 0x04300000, "ldrt", "daW" },
{ 0x0d700000, 0x04600000, "strbt", "daW" },
{ 0x0d700000, 0x04700000, "ldrbt", "daW" },
{ 0x0c500000, 0x04000000, "str", "daW" },
{ 0x0c500000, 0x04100000, "ldr", "daW" },
{ 0x0c500000, 0x04400000, "strb", "daW" },
{ 0x0c500000, 0x04500000, "ldrb", "daW" },
{ 0x0e1f0000, 0x080d0000, "stm", "YnWl" },/* separate out r13 base */
{ 0x0e1f0000, 0x081d0000, "ldm", "YnWl" },/* separate out r13 base */
{ 0x0e100000, 0x08000000, "stm", "XnWl" },
{ 0x0e100000, 0x08100000, "ldm", "XnWl" },
{ 0x0e1000f0, 0x00100090, "ldrb", "deW" },
{ 0x0e1000f0, 0x00000090, "strb", "deW" },
{ 0x0e1000f0, 0x001000d0, "ldrsb", "deW" },
{ 0x0e1000f0, 0x001000b0, "ldrh", "deW" },
{ 0x0e1000f0, 0x000000b0, "strh", "deW" },
{ 0x0e1000f0, 0x001000f0, "ldrsh", "deW" },
{ 0x0f200090, 0x00200090, "und", "x" }, /* Before data processing */
{ 0x0e1000d0, 0x000000d0, "und", "x" }, /* Before data processing */
{ 0x0ff00ff0, 0x01000090, "swp", "dmo" },
{ 0x0ff00ff0, 0x01400090, "swpb", "dmo" },
{ 0x0fbf0fff, 0x010f0000, "mrs", "dp" }, /* Before data processing */
{ 0x0fb0fff0, 0x0120f000, "msr", "pFm" },/* Before data processing */
{ 0x0fb0f000, 0x0320f000, "msr", "pF2" },/* Before data processing */
{ 0x0ffffff0, 0x012fff10, "bx", "m" },
{ 0x0fff0ff0, 0x016f0f10, "clz", "dm" },
{ 0x0ffffff0, 0x012fff30, "blx", "m" },
{ 0xfff000f0, 0xe1200070, "bkpt", "k" },
{ 0x0de00000, 0x00000000, "and", "Sdn2" },
{ 0x0de00000, 0x00200000, "eor", "Sdn2" },
{ 0x0de00000, 0x00400000, "sub", "Sdn2" },
{ 0x0de00000, 0x00600000, "rsb", "Sdn2" },
{ 0x0de00000, 0x00800000, "add", "Sdn2" },
{ 0x0de00000, 0x00a00000, "adc", "Sdn2" },
{ 0x0de00000, 0x00c00000, "sbc", "Sdn2" },
{ 0x0de00000, 0x00e00000, "rsc", "Sdn2" },
{ 0x0df00000, 0x01100000, "tst", "Dn2" },
{ 0x0df00000, 0x01300000, "teq", "Dn2" },
{ 0x0df00000, 0x01500000, "cmp", "Dn2" },
{ 0x0df00000, 0x01700000, "cmn", "Dn2" },
{ 0x0de00000, 0x01800000, "orr", "Sdn2" },
{ 0x0de00000, 0x01a00000, "mov", "Sd2" },
{ 0x0de00000, 0x01c00000, "bic", "Sdn2" },
{ 0x0de00000, 0x01e00000, "mvn", "Sd2" },
{ 0x0ff08f10, 0x0e000100, "adf", "PRfgh" },
{ 0x0ff08f10, 0x0e100100, "muf", "PRfgh" },
{ 0x0ff08f10, 0x0e200100, "suf", "PRfgh" },
{ 0x0ff08f10, 0x0e300100, "rsf", "PRfgh" },
{ 0x0ff08f10, 0x0e400100, "dvf", "PRfgh" },
{ 0x0ff08f10, 0x0e500100, "rdf", "PRfgh" },
{ 0x0ff08f10, 0x0e600100, "pow", "PRfgh" },
{ 0x0ff08f10, 0x0e700100, "rpw", "PRfgh" },
{ 0x0ff08f10, 0x0e800100, "rmf", "PRfgh" },
{ 0x0ff08f10, 0x0e900100, "fml", "PRfgh" },
{ 0x0ff08f10, 0x0ea00100, "fdv", "PRfgh" },
{ 0x0ff08f10, 0x0eb00100, "frd", "PRfgh" },
{ 0x0ff08f10, 0x0ec00100, "pol", "PRfgh" },
{ 0x0f008f10, 0x0e000100, "fpbop", "PRfgh" },
{ 0x0ff08f10, 0x0e008100, "mvf", "PRfh" },
{ 0x0ff08f10, 0x0e108100, "mnf", "PRfh" },
{ 0x0ff08f10, 0x0e208100, "abs", "PRfh" },
{ 0x0ff08f10, 0x0e308100, "rnd", "PRfh" },
{ 0x0ff08f10, 0x0e408100, "sqt", "PRfh" },
{ 0x0ff08f10, 0x0e508100, "log", "PRfh" },
{ 0x0ff08f10, 0x0e608100, "lgn", "PRfh" },
{ 0x0ff08f10, 0x0e708100, "exp", "PRfh" },
{ 0x0ff08f10, 0x0e808100, "sin", "PRfh" },
{ 0x0ff08f10, 0x0e908100, "cos", "PRfh" },
{ 0x0ff08f10, 0x0ea08100, "tan", "PRfh" },
{ 0x0ff08f10, 0x0eb08100, "asn", "PRfh" },
{ 0x0ff08f10, 0x0ec08100, "acs", "PRfh" },
{ 0x0ff08f10, 0x0ed08100, "atn", "PRfh" },
{ 0x0f008f10, 0x0e008100, "fpuop", "PRfh" },
{ 0x0e100f00, 0x0c000100, "stf", "QLv" },
{ 0x0e100f00, 0x0c100100, "ldf", "QLv" },
{ 0x0ff00f10, 0x0e000110, "flt", "PRgd" },
{ 0x0ff00f10, 0x0e100110, "fix", "PRdh" },
{ 0x0ff00f10, 0x0e200110, "wfs", "d" },
{ 0x0ff00f10, 0x0e300110, "rfs", "d" },
{ 0x0ff00f10, 0x0e400110, "wfc", "d" },
{ 0x0ff00f10, 0x0e500110, "rfc", "d" },
{ 0x0ff0ff10, 0x0e90f110, "cmf", "PRgh" },
{ 0x0ff0ff10, 0x0eb0f110, "cnf", "PRgh" },
{ 0x0ff0ff10, 0x0ed0f110, "cmfe", "PRgh" },
{ 0x0ff0ff10, 0x0ef0f110, "cnfe", "PRgh" },
{ 0xff100010, 0xfe000010, "mcr2", "#z" },
{ 0x0f100010, 0x0e000010, "mcr", "#z" },
{ 0xff100010, 0xfe100010, "mrc2", "#z" },
{ 0x0f100010, 0x0e100010, "mrc", "#z" },
{ 0xff000010, 0xfe000000, "cdp2", "#y" },
{ 0x0f000010, 0x0e000000, "cdp", "#y" },
{ 0xfe100090, 0xfc100000, "ldc2", "L#v" },
{ 0x0e100090, 0x0c100000, "ldc", "L#v" },
{ 0xfe100090, 0xfc000000, "stc2", "L#v" },
{ 0x0e100090, 0x0c000000, "stc", "L#v" },
{ 0xf550f000, 0xf550f000, "pld", "ne" },
{ 0x0ff00ff0, 0x01000050, "qaad", "dmn" },
{ 0x0ff00ff0, 0x01400050, "qdaad", "dmn" },
{ 0x0ff00ff0, 0x01600050, "qdsub", "dmn" },
{ 0x0ff00ff0, 0x01200050, "dsub", "dmn" },
{ 0x0ff000f0, 0x01000080, "smlabb", "nmsd" }, // d & n inverted!!
{ 0x0ff000f0, 0x010000a0, "smlatb", "nmsd" }, // d & n inverted!!
{ 0x0ff000f0, 0x010000c0, "smlabt", "nmsd" }, // d & n inverted!!
{ 0x0ff000f0, 0x010000e0, "smlatt", "nmsd" }, // d & n inverted!!
{ 0x0ff000f0, 0x01400080, "smlalbb","ndms" }, // d & n inverted!!
{ 0x0ff000f0, 0x014000a0, "smlaltb","ndms" }, // d & n inverted!!
{ 0x0ff000f0, 0x014000c0, "smlalbt","ndms" }, // d & n inverted!!
{ 0x0ff000f0, 0x014000e0, "smlaltt","ndms" }, // d & n inverted!!
{ 0x0ff000f0, 0x01200080, "smlawb", "nmsd" }, // d & n inverted!!
{ 0x0ff0f0f0, 0x012000a0, "smulwb","nms" }, // d & n inverted!!
{ 0x0ff000f0, 0x012000c0, "smlawt", "nmsd" }, // d & n inverted!!
{ 0x0ff0f0f0, 0x012000e0, "smulwt","nms" }, // d & n inverted!!
{ 0x0ff0f0f0, 0x01600080, "smulbb","nms" }, // d & n inverted!!
{ 0x0ff0f0f0, 0x016000a0, "smultb","nms" }, // d & n inverted!!
{ 0x0ff0f0f0, 0x016000c0, "smulbt","nms" }, // d & n inverted!!
{ 0x0ff0f0f0, 0x016000e0, "smultt","nms" }, // d & n inverted!!
{ 0x00000000, 0x00000000, NULL, NULL }
};
static char const arm32_insn_conditions[][4] = {
"eq", "ne", "cs", "cc",
"mi", "pl", "vs", "vc",
"hi", "ls", "ge", "lt",
"gt", "le", "", "nv"
};
static char const insn_block_transfers[][4] = {
"da", "ia", "db", "ib"
};
static char const insn_stack_block_transfers[][4] = {
"ed", "ea", "fd", "fa"
};
static char const op_shifts[][4] = {
"lsl", "lsr", "asr", "ror"
};
static char const insn_fpa_rounding[][2] = {
"", "p", "m", "z"
};
static char const insn_fpa_precision[][2] = {
"s", "d", "e", "p"
};
static char const insn_fpaconstants[][8] = {
"0.0", "1.0", "2.0", "3.0",
"4.0", "5.0", "0.5", "10.0"
};
#define insn_condition(x) arm32_insn_conditions[(x >> 28) & 0x0f]
#define insn_blktrans(x) insn_block_transfers[(x >> 23) & 3]
#define insn_stkblktrans(x) insn_stack_block_transfers[(x >> 23) & 3]
#define op2_shift(x) op_shifts[(x >> 5) & 3]
#define insn_fparnd(x) insn_fpa_rounding[(x >> 5) & 0x03]
#define insn_fpaprec(x) insn_fpa_precision[(((x >> 18) & 2)|(x >> 7)) & 1]
#define insn_fpaprect(x) insn_fpa_precision[(((x >> 21) & 2)|(x >> 15)) & 1]
#define insn_fpaimm(x) insn_fpaconstants[x & 0x07]
/* Local prototypes */
static void disasm_register_shift(const disasm_interface_t *di, u_int insn);
static void disasm_print_reglist(const disasm_interface_t *di, u_int insn);
static void disasm_insn_ldrstr(const disasm_interface_t *di, u_int insn,
u_int loc);
static void disasm_insn_ldrhstrh(const disasm_interface_t *di, u_int insn,
u_int loc);
static void disasm_insn_ldcstc(const disasm_interface_t *di, u_int insn,
u_int loc);
static u_int disassemble_readword(u_int address);
static void disassemble_printaddr(u_int address);
u_int
disasm(const disasm_interface_t *di, u_int loc, int altfmt)
{
const struct arm32_insn *i_ptr = &arm32_i[0];
u_int insn;
int matchp;
int branch;
const char* f_ptr;
int fmt;
fmt = 0;
matchp = 0;
insn = di->di_readword(loc);
/* di->di_printf("loc=%08x insn=%08x : ", loc, insn);*/
while (i_ptr->name) {
if ((insn & i_ptr->mask) == i_ptr->pattern) {
matchp = 1;
break;
}
i_ptr++;
}
if (!matchp) {
di->di_printf("und%s\t%08x\n", insn_condition(insn), insn);
return(loc + INSN_SIZE);
}
/* If instruction forces condition code, don't print it. */
if ((i_ptr->mask & 0xf0000000) == 0xf0000000)
di->di_printf("%s", i_ptr->name);
else
di->di_printf("%s%s", i_ptr->name, insn_condition(insn));
f_ptr = i_ptr->format;
/* Insert tab if there are no instruction modifiers */
if (*(f_ptr) < 'A' || *(f_ptr) > 'Z') {
++fmt;
di->di_printf("\t");
}
while (*f_ptr) {
switch (*f_ptr) {
/* 2 - print Operand 2 of a data processing instruction */
case '2':
if (insn & 0x02000000) {
int rotate= ((insn >> 7) & 0x1e);
di->di_printf("#0x%08x",
(insn & 0xff) << (32 - rotate) |
(insn & 0xff) >> rotate);
} else {
disasm_register_shift(di, insn);
}
break;
/* d - destination register (bits 12-15) */
case 'd':
di->di_printf("r%d", ((insn >> 12) & 0x0f));
break;
/* D - insert 'p' if Rd is R15 */
case 'D':
if (((insn >> 12) & 0x0f) == 15)
di->di_printf("p");
break;
/* n - n register (bits 16-19) */
case 'n':
di->di_printf("r%d", ((insn >> 16) & 0x0f));
break;
/* s - s register (bits 8-11) */
case 's':
di->di_printf("r%d", ((insn >> 8) & 0x0f));
break;
/* o - indirect register rn (bits 16-19) (used by swap) */
case 'o':
di->di_printf("[r%d]", ((insn >> 16) & 0x0f));
break;
/* m - m register (bits 0-4) */
case 'm':
di->di_printf("r%d", ((insn >> 0) & 0x0f));
break;
/* a - address operand of ldr/str instruction */
case 'a':
disasm_insn_ldrstr(di, insn, loc);
break;
/* e - address operand of ldrh/strh instruction */
case 'e':
disasm_insn_ldrhstrh(di, insn, loc);
break;
/* l - register list for ldm/stm instruction */
case 'l':
disasm_print_reglist(di, insn);
break;
/* f - 1st fp operand (register) (bits 12-14) */
case 'f':
di->di_printf("f%d", (insn >> 12) & 7);
break;
/* g - 2nd fp operand (register) (bits 16-18) */
case 'g':
di->di_printf("f%d", (insn >> 16) & 7);
break;
/* h - 3rd fp operand (register/immediate) (bits 0-4) */
case 'h':
if (insn & (1 << 3))
di->di_printf("#%s", insn_fpaimm(insn));
else
di->di_printf("f%d", insn & 7);
break;
/* b - branch address */
case 'b':
branch = ((insn << 2) & 0x03ffffff);
if (branch & 0x02000000)
branch |= 0xfc000000;
di->di_printaddr(loc + 8 + branch);
break;
/* t - blx address */
case 't':
branch = ((insn << 2) & 0x03ffffff) |
(insn >> 23 & 0x00000002);
if (branch & 0x02000000)
branch |= 0xfc000000;
di->di_printaddr(loc + 8 + branch);
break;
/* X - block transfer type */
case 'X':
di->di_printf("%s", insn_blktrans(insn));
break;
/* Y - block transfer type (r13 base) */
case 'Y':
di->di_printf("%s", insn_stkblktrans(insn));
break;
/* c - comment field bits(0-23) */
case 'c':
di->di_printf("0x%08x", (insn & 0x00ffffff));
break;
/* k - breakpoint comment (bits 0-3, 8-19) */
case 'k':
di->di_printf("0x%04x",
(insn & 0x000fff00) >> 4 | (insn & 0x0000000f));
break;
/* p - saved or current status register */
case 'p':
if (insn & 0x00400000)
di->di_printf("spsr");
else
di->di_printf("cpsr");
break;
/* F - PSR transfer fields */
case 'F':
di->di_printf("_");
if (insn & (1 << 16))
di->di_printf("c");
if (insn & (1 << 17))
di->di_printf("x");
if (insn & (1 << 18))
di->di_printf("s");
if (insn & (1 << 19))
di->di_printf("f");
break;
/* B - byte transfer flag */
case 'B':
if (insn & 0x00400000)
di->di_printf("b");
break;
/* L - co-processor transfer size */
case 'L':
if (insn & (1 << 22))
di->di_printf("l");
break;
/* S - set status flag */
case 'S':
if (insn & 0x00100000)
di->di_printf("s");
break;
/* P - fp precision */
case 'P':
di->di_printf("%s", insn_fpaprec(insn));
break;
/* Q - fp precision (for ldf/stf) */
case 'Q':
break;
/* R - fp rounding */
case 'R':
di->di_printf("%s", insn_fparnd(insn));
break;
/* W - writeback flag */
case 'W':
if (insn & (1 << 21))
di->di_printf("!");
break;
/* # - co-processor number */
case '#':
di->di_printf("p%d", (insn >> 8) & 0x0f);
break;
/* v - co-processor data transfer registers+addressing mode */
case 'v':
disasm_insn_ldcstc(di, insn, loc);
break;
/* x - instruction in hex */
case 'x':
di->di_printf("0x%08x", insn);
break;
/* y - co-processor data processing registers */
case 'y':
di->di_printf("%d, ", (insn >> 20) & 0x0f);
di->di_printf("c%d, c%d, c%d", (insn >> 12) & 0x0f,
(insn >> 16) & 0x0f, insn & 0x0f);
di->di_printf(", %d", (insn >> 5) & 0x07);
break;
/* z - co-processor register transfer registers */
case 'z':
di->di_printf("%d, ", (insn >> 21) & 0x07);
di->di_printf("r%d, c%d, c%d, %d",
(insn >> 12) & 0x0f, (insn >> 16) & 0x0f,
insn & 0x0f, (insn >> 5) & 0x07);
/* if (((insn >> 5) & 0x07) != 0)
di->di_printf(", %d", (insn >> 5) & 0x07);*/
break;
default:
di->di_printf("[%c - unknown]", *f_ptr);
break;
}
if (*(f_ptr+1) >= 'A' && *(f_ptr+1) <= 'Z')
++f_ptr;
else if (*(++f_ptr)) {
++fmt;
if (fmt == 1)
di->di_printf("\t");
else
di->di_printf(", ");
}
};
di->di_printf("\n");
return(loc + INSN_SIZE);
}
static void
disasm_register_shift(const disasm_interface_t *di, u_int insn)
{
di->di_printf("r%d", (insn & 0x0f));
if ((insn & 0x00000ff0) == 0)
;
else if ((insn & 0x00000ff0) == 0x00000060)
di->di_printf(", rrx");
else {
if (insn & 0x10)
di->di_printf(", %s r%d", op2_shift(insn),
(insn >> 8) & 0x0f);
else
di->di_printf(", %s #%d", op2_shift(insn),
(insn >> 7) & 0x1f);
}
}
static void
disasm_print_reglist(const disasm_interface_t *di, u_int insn)
{
int loop;
int start;
int comma;
di->di_printf("{");
start = -1;
comma = 0;
for (loop = 0; loop < 17; ++loop) {
if (start != -1) {
if (loop == 16 || !(insn & (1 << loop))) {
if (comma)
di->di_printf(", ");
else
comma = 1;
if (start == loop - 1)
di->di_printf("r%d", start);
else
di->di_printf("r%d-r%d", start, loop - 1);
start = -1;
}
} else {
if (insn & (1 << loop))
start = loop;
}
}
di->di_printf("}");
if (insn & (1 << 22))
di->di_printf("^");
}
static void
disasm_insn_ldrstr(const disasm_interface_t *di, u_int insn, u_int loc)
{
int offset;
offset = insn & 0xfff;
if ((insn & 0x032f0000) == 0x010f0000) {
/* rA = pc, immediate index */
if (insn & 0x00800000)
loc += offset;
else
loc -= offset;
di->di_printaddr(loc + 8);
} else {
di->di_printf("[r%d", (insn >> 16) & 0x0f);
if ((insn & 0x03000fff) != 0x01000000) {
di->di_printf("%s, ", (insn & (1 << 24)) ? "" : "]");
if (!(insn & 0x00800000))
di->di_printf("-");
if (insn & (1 << 25))
disasm_register_shift(di, insn);
else
di->di_printf("#0x%03x", offset);
}
if (insn & (1 << 24))
di->di_printf("]");
}
}
static void
disasm_insn_ldrhstrh(const disasm_interface_t *di, u_int insn, u_int loc)
{
int offset;
offset = ((insn & 0xf00) >> 4) | (insn & 0xf);
if ((insn & 0x004f0000) == 0x004f0000) {
/* rA = pc, immediate index */
if (insn & 0x00800000)
loc += offset;
else
loc -= offset;
di->di_printaddr(loc + 8);
} else {
di->di_printf("[r%d", (insn >> 16) & 0x0f);
if ((insn & 0x01400f0f) != 0x01400000) {
di->di_printf("%s, ", (insn & (1 << 24)) ? "" : "]");
if (!(insn & 0x00800000))
di->di_printf("-");
if (insn & (1 << 22))
di->di_printf("#0x%02x", offset);
else
di->di_printf("r%d", (insn & 0x0f));
}
if (insn & (1 << 24))
di->di_printf("]");
}
}
static void
disasm_insn_ldcstc(const disasm_interface_t *di, u_int insn, u_int loc)
{
if (((insn >> 8) & 0xf) == 1)
di->di_printf("f%d, ", (insn >> 12) & 0x07);
else
di->di_printf("c%d, ", (insn >> 12) & 0x0f);
di->di_printf("[r%d", (insn >> 16) & 0x0f);
di->di_printf("%s, ", (insn & (1 << 24)) ? "" : "]");
if (!(insn & (1 << 23)))
di->di_printf("-");
di->di_printf("#0x%03x", (insn & 0xff) << 2);
if (insn & (1 << 24))
di->di_printf("]");
if (insn & (1 << 21))
di->di_printf("!");
}
static u_int
disassemble_readword(u_int address)
{
return(*((u_int *)address));
}
static void
disassemble_printaddr(u_int address)
{
printf("0x%08x", address);
}
static void
disassemble_printf(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
static const disasm_interface_t disassemble_di = {
disassemble_readword, disassemble_printaddr, disassemble_printf
};
void
disassemble(u_int address)
{
(void)disasm(&disassemble_di, address, 0);
}
/* End of disassem.c */

65
libacc/tests/disassem.h Normal file
View File

@ -0,0 +1,65 @@
/* $NetBSD: disassem.h,v 1.4 2001/03/04 04:15:58 matt Exp $ */
/*-
* Copyright (c) 1997 Mark Brinicombe.
* Copyright (c) 1997 Causality Limited.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Mark Brinicombe.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Define the interface structure required by the disassembler.
*
* $FreeBSD: /repoman/r/ncvs/src/sys/arm/include/disassem.h,v 1.2 2005/01/05 21:58:48 imp Exp $
*/
#ifndef ANDROID_MACHINE_DISASSEM_H
#define ANDROID_MACHINE_DISASSEM_H
#include <sys/types.h>
#if __cplusplus
extern "C" {
#endif
typedef struct {
u_int (*di_readword)(u_int);
void (*di_printaddr)(u_int);
void (*di_printf)(const char *, ...);
} disasm_interface_t;
/* Prototypes for callable functions */
u_int disasm(const disasm_interface_t *, u_int, int);
void disassemble(u_int);
#if __cplusplus
}
#endif
#endif /* !ANDROID_MACHINE_DISASSEM_H */

207
libacc/tests/main.cpp Normal file
View File

@ -0,0 +1,207 @@
/*
* Android "Almost" C Compiler.
* This is a compiler for a small subset of the C language, intended for use
* in scripting environments where speed and memory footprint are important.
*
* This code is based upon the "unobfuscated" version of the
* Obfuscated Tiny C compiler, see the file LICENSE for details.
*
*/
#include <ctype.h>
#include <dlfcn.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(__arm__)
#include <unistd.h>
#endif
#if defined(__arm__)
#define PROVIDE_ARM_DISASSEMBLY
#endif
#ifdef PROVIDE_ARM_DISASSEMBLY
#include "disassem.h"
#endif
#include <acc/acc.h>
typedef int (*MainPtr)(int, char**);
// This is a separate function so it can easily be set by breakpoint in gdb.
int run(MainPtr mainFunc, int argc, char** argv) {
return mainFunc(argc, argv);
}
ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) {
return (ACCvoid*) dlsym(RTLD_DEFAULT, name);
}
#ifdef PROVIDE_ARM_DISASSEMBLY
static FILE* disasmOut;
static u_int
disassemble_readword(u_int address)
{
return(*((u_int *)address));
}
static void
disassemble_printaddr(u_int address)
{
fprintf(disasmOut, "0x%08x", address);
}
static void
disassemble_printf(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vfprintf(disasmOut, fmt, ap);
va_end(ap);
}
static int disassemble(ACCscript* script, FILE* out) {
disasmOut = out;
disasm_interface_t di;
di.di_readword = disassemble_readword;
di.di_printaddr = disassemble_printaddr;
di.di_printf = disassemble_printf;
ACCvoid* base;
ACCsizei length;
accGetProgramBinary(script, &base, &length);
unsigned long* pBase = (unsigned long*) base;
unsigned long* pEnd = (unsigned long*) (((unsigned char*) base) + length);
for(unsigned long* pInstruction = pBase; pInstruction < pEnd; pInstruction++) {
fprintf(out, "%08x: %08x ", (int) pInstruction, (int) *pInstruction);
::disasm(&di, (uint) pInstruction, 0);
}
return 0;
}
#endif // PROVIDE_ARM_DISASSEMBLY
int main(int argc, char** argv) {
const char* inFile = NULL;
bool printListing;
bool runResults = false;
FILE* in = stdin;
int i;
for (i = 1; i < argc; i++) {
char* arg = argv[i];
if (arg[0] == '-') {
switch (arg[1]) {
case 'S':
printListing = true;
break;
case 'R':
runResults = true;
break;
default:
fprintf(stderr, "Unrecognized flag %s\n", arg);
return 3;
}
} else if (inFile == NULL) {
inFile = arg;
} else {
break;
}
}
if (! inFile) {
fprintf(stderr, "input file required\n");
return 2;
}
if (inFile) {
in = fopen(inFile, "r");
if (!in) {
fprintf(stderr, "Could not open input file %s\n", inFile);
return 1;
}
}
fseek(in, 0, SEEK_END);
size_t fileSize = (size_t) ftell(in);
rewind(in);
ACCchar* text = new ACCchar[fileSize + 1];
size_t bytesRead = fread(text, 1, fileSize, in);
if (bytesRead != fileSize) {
fprintf(stderr, "Could not read all of file %s\n", inFile);
}
text[fileSize] = '\0';
ACCscript* script = accCreateScript();
const ACCchar* scriptSource[] = {text};
accScriptSource(script, 1, scriptSource, NULL);
delete[] text;
accRegisterSymbolCallback(script, symbolLookup, NULL);
accCompileScript(script);
int result = accGetError(script);
MainPtr mainPointer = 0;
if (result != 0) {
ACCsizei bufferLength;
accGetScriptInfoLog(script, 0, &bufferLength, NULL);
char* buf = (char*) malloc(bufferLength + 1);
if (buf != NULL) {
accGetScriptInfoLog(script, bufferLength + 1, NULL, buf);
fprintf(stderr, "%s", buf);
free(buf);
} else {
fprintf(stderr, "Out of memory.\n");
}
goto exit;
}
{
ACCsizei numPragmaStrings;
accGetPragmas(script, &numPragmaStrings, 0, NULL);
if (numPragmaStrings) {
char** strings = new char*[numPragmaStrings];
accGetPragmas(script, NULL, numPragmaStrings, strings);
for(ACCsizei i = 0; i < numPragmaStrings; i += 2) {
fprintf(stderr, "#pragma %s(%s)\n", strings[i], strings[i+1]);
}
delete[] strings;
}
}
if (printListing) {
#ifdef PROVIDE_ARM_DISASSEMBLY
disassemble(script, stderr);
#endif
}
if (runResults) {
accGetScriptLabel(script, "main", (ACCvoid**) & mainPointer);
result = accGetError(script);
if (result != ACC_NO_ERROR) {
fprintf(stderr, "Could not find main: %d\n", result);
} else {
fprintf(stderr, "Executing compiled code:\n");
int codeArgc = argc - i + 1;
char** codeArgv = argv + i - 1;
codeArgv[0] = (char*) (inFile ? inFile : "stdin");
result = run(mainPointer, codeArgc, codeArgv);
fprintf(stderr, "result: %d\n", result);
}
}
exit:
accDeleteScript(script);
return result;
}

View File

@ -0,0 +1,118 @@
/*
* RuntimeTest for ACC compiler.
*
*/
#include <ctype.h>
#include <dlfcn.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(__arm__)
#include <unistd.h>
#endif
#include <acc/acc.h>
typedef void (*ScriptPtr)();
// This is a separate function so it can easily be set by breakpoint in gdb.
void run(ScriptPtr scriptFn) {
scriptFn();
}
// Private API for development:
extern "C"
void accDisassemble(ACCscript* script);
int globalVar;
void op_int(int a) {
printf("op_int(%d)\n", a);
}
void op_float12(float a, float b, float c, float d,
float e, float f, float g, float h,
float i, float j, float k, float l) {
printf("op_float12(%g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g)\n",
a, b, c, d, e, f, g, h, i, j, k, l);
}
const char* text = "void op_int(int a);\n"
"void op_float12(float a, float b, float c, float d,\n"
" float e, float f, float g, float h,\n"
" float i, float j, float k, float l);\n"
"void script() {\n"
" globalVar += 3;\n"
" op_int(123);\n"
" op_float12(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0);\n"
"}\n";
ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) {
if (strcmp("op_int", name) == 0) {
return (ACCvoid*) op_int;
}
if (strcmp("op_float12", name) == 0) {
return (ACCvoid*) op_float12;
}
if (strcmp("globalVar", name) == 0) {
return (ACCvoid*) &globalVar;
}
return (ACCvoid*) dlsym(RTLD_DEFAULT, name);
}
int main(int argc, char** argv) {
ACCscript* script = accCreateScript();
accRegisterSymbolCallback(script, symbolLookup, NULL);
const ACCchar* scriptSource[] = {text};
accScriptSource(script, 1, scriptSource, NULL);
accCompileScript(script);
int result = accGetError(script);
ScriptPtr scriptPointer = 0;
if (result != 0) {
char buf[1024];
accGetScriptInfoLog(script, sizeof(buf), NULL, buf);
fprintf(stderr, "%s", buf);
goto exit;
}
{
ACCsizei numPragmaStrings;
accGetPragmas(script, &numPragmaStrings, 0, NULL);
if (numPragmaStrings) {
char** strings = new char*[numPragmaStrings];
accGetPragmas(script, NULL, numPragmaStrings, strings);
for(ACCsizei i = 0; i < numPragmaStrings; i += 2) {
fprintf(stderr, "#pragma %s(%s)\n", strings[i], strings[i+1]);
}
delete[] strings;
}
}
accGetScriptLabel(script, "script", (ACCvoid**) & scriptPointer);
result = accGetError(script);
if (result != ACC_NO_ERROR) {
fprintf(stderr, "Could not find script: %d\n", result);
} else {
fprintf(stderr, "Executing script:\n");
globalVar = 17;
run(scriptPointer);
fprintf(stderr, "After script globalVar = %d\n", globalVar);
}
exit:
accDeleteScript(script);
return result;
}

6
libacc/tests/test Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
SCRIPT_DIR=`dirname $BASH_SOURCE`
cd $SCRIPT_DIR
python test.py "$@"

493
libacc/tests/test.py Normal file
View File

@ -0,0 +1,493 @@
#
# Test the acc compiler
import unittest
import subprocess
import os
import sys
gArmInitialized = False
gUseArm = True
gUseX86 = True
gRunOTCCOutput = True
def parseArgv():
global gUseArm
global gUseX86
global gRunOTCCOutput
for arg in sys.argv[1:]:
if arg == "--noarm":
print "--noarm: not testing ARM"
gUseArm = False
elif arg == "--nox86":
print "--nox86: not testing x86"
gUseX86 = False
elif arg == "--norunotcc":
print "--norunotcc detected, not running OTCC output"
gRunOTCCOutput = False
else:
print "Unknown parameter: ", arg
raise "Unknown parameter"
sys.argv = sys.argv[0:1]
def compile(args):
proc = subprocess.Popen(["acc"] + args, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
result = proc.communicate()
return result
def runCmd(args):
proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
result = proc.communicate()
return result[0].strip()
def uname():
return runCmd(["uname"])
def unameM():
return runCmd(["uname", "-m"])
def which(item):
return runCmd(["which", item])
def fileType(item):
return runCmd(["file", item])
def outputCanRun():
ft = fileType(which("acc"))
return ft.find("ELF 32-bit LSB executable, Intel 80386") >= 0
def checkEnvironment():
global gRunOTCCOutput
gRunOTCCOutput = uname() == "Linux" and unameM() != "x86_64" and outputCanRun()
def adb(args):
return runCmd(["adb"] + args)
def setupArm():
global gArmInitialized
if gArmInitialized:
return
print "Setting up arm"
adb(["remount"])
adb(["shell", "rm", "/system/bin/acc"])
adb(["shell", "mkdir", "/system/bin/accdata"])
adb(["shell", "mkdir", "/system/bin/accdata/data"])
# Clear out old data TODO: handle recursion
adb(["shell", "rm", "/system/bin/accdata/data/*"])
# Copy over data
for root, dirs, files in os.walk("data"):
for d in dirs:
adb(["shell", "mkdir", os.path.join(root, d)])
for f in files:
adb(["push", os.path.join(root, f), os.path.join("/system/bin/accdata", root, f)])
# Copy over compiler
adb(["sync"])
gArmInitialized = True
def compileArm(args):
setupArm()
proc = subprocess.Popen(["adb", "shell", "/system/bin/acc"] + args, stdout=subprocess.PIPE)
result = proc.communicate()
return result[0].replace("\r","")
def compare(a, b):
if a != b:
firstDiff = firstDifference(a, b)
print "Strings differ at character %d. Common: %s. Difference '%s' != '%s'" % (
firstDiff, a[0:firstDiff], safeAccess(a, firstDiff), safeAccess(b, firstDiff))
def safeAccess(s, i):
if 0 <= i < len(s):
return s[i]
else:
return '?'
def firstDifference(a, b):
commonLen = min(len(a), len(b))
for i in xrange(0, commonLen):
if a[i] != b[i]:
return i
return commonLen
# a1 and a2 are the expected stdout and stderr.
# b1 and b2 are the actual stdout and stderr.
# Compare the two, sets. Allow any individual line
# to appear in either stdout or stderr. This is because
# the way we obtain output on the ARM combines both
# streams into one sequence.
def compareOuput(a1,a2,b1,b2):
while True:
totalLen = len(a1) + len(a2) + len(b1) + len(b2)
a1, b1 = matchCommon(a1, b1)
a1, b2 = matchCommon(a1, b2)
a2, b1 = matchCommon(a2, b1)
a2, b2 = matchCommon(a2, b2)
newTotalLen = len(a1) + len(a2) + len(b1) + len(b2)
if newTotalLen == 0:
return True
if newTotalLen == totalLen:
print "Failed at %d %d %d %d" % (len(a1), len(a2), len(b1), len(b2))
print "a1", a1
print "a2", a2
print "b1", b1
print "b2", b2
return False
def matchCommon(a, b):
"""Remove common items from the beginning of a and b,
return just the tails that are different."""
while len(a) > 0 and len(b) > 0 and a[0] == b[0]:
a = a[1:]
b = b[1:]
return a, b
def rewritePaths(args):
return [rewritePath(x) for x in args]
def rewritePath(p):
"""Take a path that's correct on the x86 and convert to a path
that's correct on ARM."""
if p.startswith("data/"):
p = "/system/bin/accdata/" + p
return p
class TestACC(unittest.TestCase):
def checkResult(self, out, err, stdErrResult, stdOutResult=""):
a1 = out.splitlines()
a2 = err.splitlines()
b2 = stdErrResult.splitlines()
b1 = stdOutResult.splitlines()
self.assertEqual(True, compareOuput(a1,a2,b1,b2))
def compileCheck(self, args, stdErrResult, stdOutResult="",
targets=['arm', 'x86']):
global gUseArm
global gUseX86
targetSet = frozenset(targets)
if gUseX86 and 'x86' in targetSet:
out, err = compile(args)
self.checkResult(out, err, stdErrResult, stdOutResult)
if gUseArm and 'arm' in targetSet:
out = compileArm(rewritePaths(args))
self.checkResult(out, "", stdErrResult, stdOutResult)
def compileCheckArm(self, args, result):
self.assertEqual(compileArm(args), result)
def testCompileReturnVal(self):
self.compileCheck(["data/returnval-ansi.c"], "")
def testCompileOTCCANSII(self):
self.compileCheck(["data/otcc-ansi.c"], "", "", ['x86'])
def testRunReturnVal(self):
self.compileCheck(["-R", "data/returnval-ansi.c"],
"Executing compiled code:\nresult: 42\n")
def testStringLiteralConcatenation(self):
self.compileCheck(["-R", "data/testStringConcat.c"],
"Executing compiled code:\nresult: 13\n", "Hello, world\n")
def testRunOTCCANSI(self):
global gRunOTCCOutput
if gRunOTCCOutput:
self.compileCheck(["-R", "data/otcc-ansi.c", "data/returnval.c"],
"Executing compiled code:\notcc-ansi.c: About to execute compiled code:\natcc-ansi.c: result: 42\nresult: 42\n", "",
['x86'])
def testRunOTCCANSI2(self):
global gRunOTCCOutput
if gRunOTCCOutput:
self.compileCheck(["-R", "data/otcc-ansi.c", "data/otcc.c", "data/returnval.c"],
"Executing compiled code:\notcc-ansi.c: About to execute compiled code:\notcc.c: about to execute compiled code.\natcc-ansi.c: result: 42\nresult: 42\n", "",['x86'])
def testRunConstants(self):
self.compileCheck(["-R", "data/constants.c"],
"Executing compiled code:\nresult: 12\n",
"0 = 0\n010 = 8\n0x10 = 16\n'\\a' = 7\n'\\b' = 8\n'\\f' = 12\n'\\n' = 10\n'\\r' = 13\n'\\t' = 9\n'\\v' = 11\n'\\\\' = 92\n'\\'' = 39\n" +
"'\\\"' = 34\n'\\?' = 63\n'\\0' = 0\n'\\1' = 1\n'\\12' = 10\n'\\123' = 83\n'\\x0' = 0\n'\\x1' = 1\n'\\x12' = 18\n'\\x123' = 291\n'\\x1f' = 31\n'\\x1F' = 31\n")
def testRunFloat(self):
self.compileCheck(["-R", "data/float.c"],
"Executing compiled code:\nresult: 0\n",
"""Constants: 0 0 0 0.01 0.01 0.1 10 10 0.1
int: 1 float: 2.2 double: 3.3
ftoi(1.4f)=1
dtoi(2.4)=2
itof(3)=3
itod(4)=4
globals: 1 2 3 4
args: 1 2 3 4
locals: 1 2 3 4
cast rval: 2 4
cast lval: 1.1 2 3.3 4
""")
def testRunFlops(self):
self.compileCheck(["-R", "data/flops.c"],
"""Executing compiled code:
result: 0""",
"""-1.1 = -1.1
!1.2 = 0
!0 = 1
double op double:
1 + 2 = 3
1 - 2 = -1
1 * 2 = 2
1 / 2 = 0.5
float op float:
1 + 2 = 3
1 - 2 = -1
1 * 2 = 2
1 / 2 = 0.5
double op float:
1 + 2 = 3
1 - 2 = -1
1 * 2 = 2
1 / 2 = 0.5
double op int:
1 + 2 = 3
1 - 2 = -1
1 * 2 = 2
1 / 2 = 0.5
int op double:
1 + 2 = 3
1 - 2 = -1
1 * 2 = 2
1 / 2 = 0.5
double op double:
1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
double op float:
1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
float op float:
1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
int op double:
1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
double op int:
1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
branching: 1 0 1
testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
testpassi: 1 2 3 4 5 6 7 8 9 10 11 12
testpassf: 1 2 3 4 5 6 7 8 9 10 11 12
testpassd: 1 2 3 4 5 6 7 8 9 10 11 12
testpassidf: 1 2 3
""")
def testCasts(self):
self.compileCheck(["-R", "data/casts.c"],
"""Executing compiled code:
result: 0""", """Reading from a pointer: 3 3
Writing to a pointer: 4
Testing casts: 3 3 4.5 4
Testing reading (int*): 4
Testing writing (int*): 8 9
Testing reading (char*): 0x78 0x56 0x34 0x12
Testing writing (char*): 0x87654321
f(10)
Function pointer result: 70
Testing read/write (float*): 8.8 9.9
Testing read/write (double*): 8.8 9.9
""")
def testChar(self):
self.compileCheck(["-R", "data/char.c"], """Executing compiled code:
result: 0""", """a = 99, b = 41
ga = 100, gb = 44""")
def testPointerArithmetic(self):
self.compileCheck(["-R", "data/pointers.c"], """Executing compiled code:
result: 0""", """Pointer difference: 1 4
Pointer addition: 2
Pointer comparison to zero: 0 0 1
Pointer comparison: 1 0 0 0 1
""")
def testRollo3(self):
self.compileCheck(["-R", "data/rollo3.c"], """Executing compiled code:
result: 10""", """""")
def testFloatDouble(self):
self.compileCheck(["-R", "data/floatdouble.c"], """Executing compiled code:
result: 0""", """0.002 0.1 10""")
def testIncDec(self):
self.compileCheck(["-R", "data/inc.c"], """Executing compiled code:
0
1
2
1
1
2
1
0
result: 0
""","""""")
def testIops(self):
self.compileCheck(["-R", "data/iops.c"], """Executing compiled code:
result: 0""", """Literals: 1 -1
++
0
1
2
3
4
5
6
7
8
9
--
10
9
8
7
6
5
4
3
2
1
0
""")
def testFilm(self):
self.compileCheck(["-R", "data/film.c"], """Executing compiled code:
result: 0""", """testing...
Total bad: 0
""")
def testpointers2(self):
self.compileCheck(["-R", "data/pointers2.c"], """Executing compiled code:
result: 0""", """a = 0, *pa = 0
a = 2, *pa = 2
a = 0, *pa = 0 **ppa = 0
a = 2, *pa = 2 **ppa = 2
a = 0, *pa = 0 **ppa = 0
a = 2, *pa = 2 **ppa = 2
""")
def testassignmentop(self):
self.compileCheck(["-R", "data/assignmentop.c"], """Executing compiled code:
result: 0""", """2 *= 5 10
20 /= 5 4
17 %= 5 2
17 += 5 22
17 -= 5 12
17<<= 1 34
17>>= 1 8
17&= 1 1
17^= 1 16
16|= 1 17
*f() = *f() + 10;
f()
f()
a = 10
*f() += 10;
f()
a = 10
""")
def testcomma(self):
self.compileCheck(["-R", "data/comma.c"], """Executing compiled code:
result: 0""", """statement: 10
if: a = 0
while: b = 11
for: b = 22
return: 30
arg: 12
""")
def testBrackets(self):
self.compileCheck(["-R", "data/brackets.c"], """Executing compiled code:
Errors: 0
2D Errors: 0
result: 0
""","""""")
def testShort(self):
self.compileCheck(["-R", "data/short.c"], """Executing compiled code:
result: -2
""","""""")
def testAssignment(self):
self.compileCheck(["-R", "data/assignment.c"], """Executing compiled code:
result: 7
""","""""")
def testArray(self):
self.compileCheck(["-R", "data/array.c"], """Executing compiled code:
localInt: 3
localDouble: 3 3
globalChar: 3
globalDouble: 3
testArgs: 0 2 4
testDecay: Hi!
test2D:
abcdefghijdefghijklm
defghijklmghijklmnop
ghijklmnopjklmnopabc
jklmnopabcmnopabcdef
mnopabcdefpabcdefghi
pabcdefghicdefghijkl
cdefghijklfghijklmno
fghijklmnoijklmnopab
ijklmnopablmnopabcde
lmnopabcdefghijklmno
result: 0
""","""""")
def testDefines(self):
self.compileCheck(["-R", "data/defines.c"], """Executing compiled code:
result: 3
""","""""")
def testFuncArgs(self):
self.compileCheck(["-R", "data/funcargs.c"], """Executing compiled code:
result: 4
""","""""")
def testB2071670(self):
self.compileCheck(["-R", "data/b2071670.c"], """Executing compiled code:
result: 1092616192
""","""""")
def testStructs(self):
self.compileCheck(["-R", "data/structs.c"], """Executing compiled code:
testCopying: 37 == 37
testUnion: 1 == 0x3f800000
testArgs: (6, 8, 10, 12)
result: 6
""","""""")
def testAddressOf(self):
self.compileCheck(["-R", "data/addressOf.c"], """Executing compiled code:
testStruct: 10 10 10
testArray: 1 1 1
result: 0
""","""""")
def main():
checkEnvironment()
parseArgv()
unittest.main()
if __name__ == '__main__':
main()

Some files were not shown because too many files have changed in this diff Show More