Merge "- creates proper ifc.h and dhcp.h headers for libnetutils - adds ifc_set_hwaddr - adds hwaddr command to netcfg - code reuse: dhcp_configure calls ifc_configure; inet_ntoa is used for printing - consistency: use net.XXX.dnsX properties in favor of dhcp.XXX.dnsX properties (see related change to WifiStateTracker) - updated system/core/nexus to use new headers, although not sure if anybody still uses nexus"
diff --git a/adb/sockets.c b/adb/sockets.c
index 9f1b598..43925e4 100644
--- a/adb/sockets.c
+++ b/adb/sockets.c
@@ -65,8 +65,11 @@
asocket *result = NULL;
adb_mutex_lock(&socket_list_lock);
- for(s = local_socket_list.next; s != &local_socket_list && !result; s = s->next) {
- if(s->id == id) result = s;
+ for (s = local_socket_list.next; s != &local_socket_list; s = s->next) {
+ if (s->id == id) {
+ result = s;
+ break;
+ }
}
adb_mutex_unlock(&socket_list_lock);
@@ -366,7 +369,7 @@
asocket *create_local_socket(int fd)
{
asocket *s = calloc(1, sizeof(asocket));
- if(s == 0) fatal("cannot allocate socket");
+ if (s == NULL) fatal("cannot allocate socket");
install_local_socket(s);
s->fd = fd;
s->enqueue = local_socket_enqueue;
@@ -482,7 +485,7 @@
asocket *s = calloc(1, sizeof(aremotesocket));
adisconnect* dis = &((aremotesocket*)s)->disconnect;
- if(s == 0) fatal("cannot allocate socket");
+ if (s == NULL) fatal("cannot allocate socket");
s->id = id;
s->enqueue = remote_socket_enqueue;
s->ready = remote_socket_ready;
@@ -761,8 +764,7 @@
{
D("Creating smart socket \n");
asocket *s = calloc(1, sizeof(asocket));
- if(s == 0) fatal("cannot allocate socket");
- s->id = 0;
+ if (s == NULL) fatal("cannot allocate socket");
s->enqueue = smart_socket_enqueue;
s->ready = smart_socket_ready;
s->close = smart_socket_close;
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index 6d85fb1..db8b018 100644
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -69,6 +69,8 @@
#define VENDOR_ID_PANTECH 0x10A9
// Qualcomm's USB Vendor ID
#define VENDOR_ID_QUALCOMM 0x05c6
+// On-The-Go-Video's USB Vendor ID
+#define VENDOR_ID_OTGV 0x2257
/** built-in vendor list */
@@ -90,6 +92,7 @@
VENDOR_ID_KYOCERA,
VENDOR_ID_PANTECH,
VENDOR_ID_QUALCOMM,
+ VENDOR_ID_OTGV,
};
#define BUILT_IN_VENDOR_COUNT (sizeof(builtInVendorIds)/sizeof(builtInVendorIds[0]))
@@ -151,7 +154,7 @@
/* builds the path to the adb vendor id file. returns 0 if success */
int build_path(char* buff, size_t len, const char* format, const char* home)
{
- if (snprintf(buff, len, format, home, ANDROID_PATH, ANDROID_ADB_INI) >= len) {
+ if (snprintf(buff, len, format, home, ANDROID_PATH, ANDROID_ADB_INI) >= (signed)len) {
return 1;
}
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index b22e1a8..1dc8426 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -5,7 +5,7 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= debuggerd.c getevent.c unwind-arm.c pr-support.c utility.c
+LOCAL_SRC_FILES:= debuggerd.c getevent.c unwind-arm.c pr-support.c utility.c symbol_table.c
LOCAL_CFLAGS := -Wall
LOCAL_MODULE := debuggerd
diff --git a/debuggerd/debuggerd.c b/debuggerd/debuggerd.c
index 996e6c2..02bab2c 100644
--- a/debuggerd/debuggerd.c
+++ b/debuggerd/debuggerd.c
@@ -55,7 +55,7 @@
/* Log information onto the tombstone */
void _LOG(int tfd, bool in_tombstone_only, const char *fmt, ...)
{
- char buf[128];
+ char buf[512];
va_list ap;
va_start(ap, fmt);
@@ -98,10 +98,11 @@
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_elf_info if the mapped section starts with
* elf_header
*/
mi->exidx_start = mi->exidx_end = 0;
+ mi->symbols = 0;
mi->next = 0;
strcpy(mi->name, line + 49);
@@ -335,7 +336,7 @@
if(sig) dump_fault_addr(tfd, tid, sig);
}
-static void parse_exidx_info(mapinfo *milist, pid_t pid)
+static void parse_elf_info(mapinfo *milist, pid_t pid)
{
mapinfo *mi;
for (mi = milist; mi != NULL; mi = mi->next) {
@@ -365,6 +366,9 @@
break;
}
}
+
+ /* Try to load symbols from this file */
+ mi->symbols = symbol_table_create(mi->name);
}
}
}
@@ -402,7 +406,7 @@
fclose(fp);
}
- parse_exidx_info(milist, tid);
+ parse_elf_info(milist, tid);
/* If stack unwinder fails, use the default solution to dump the stack
* content.
@@ -422,6 +426,7 @@
while(milist) {
mapinfo *next = milist->next;
+ symbol_table_free(milist->symbols);
free(milist);
milist = next;
}
diff --git a/debuggerd/symbol_table.c b/debuggerd/symbol_table.c
new file mode 100644
index 0000000..150c058
--- /dev/null
+++ b/debuggerd/symbol_table.c
@@ -0,0 +1,178 @@
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "symbol_table.h"
+
+#include <linux/elf.h>
+
+// Compare func for qsort
+static int qcompar(const void *a, const void *b)
+{
+ return ((struct symbol*)a)->addr - ((struct symbol*)b)->addr;
+}
+
+// Compare func for bsearch
+static int bcompar(const void *addr, const void *element)
+{
+ struct symbol *symbol = (struct symbol*)element;
+
+ if((unsigned int)addr < symbol->addr) {
+ return -1;
+ }
+
+ if((unsigned int)addr - symbol->addr >= symbol->size) {
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * Create a symbol table from a given file
+ *
+ * Parameters:
+ * filename - Filename to process
+ *
+ * Returns:
+ * A newly-allocated SymbolTable structure, or NULL if error.
+ * Free symbol table with symbol_table_free()
+ */
+struct symbol_table *symbol_table_create(const char *filename)
+{
+ struct symbol_table *table = NULL;
+
+ // Open the file, and map it into memory
+ struct stat sb;
+ int length;
+ char *base;
+
+ int fd = open(filename, O_RDONLY);
+
+ if(fd < 0) {
+ goto out;
+ }
+
+ fstat(fd, &sb);
+ length = sb.st_size;
+
+ base = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);
+
+ if(!base) {
+ goto out_close;
+ }
+
+ // Parse the file header
+ Elf32_Ehdr *hdr = (Elf32_Ehdr*)base;
+ Elf32_Shdr *shdr = (Elf32_Shdr*)(base + hdr->e_shoff);
+
+ // Search for the dynamic symbols section
+ int dynsym_idx = -1;
+ int i;
+
+ for(i = 0; i < hdr->e_shnum; i++) {
+ if(shdr[i].sh_type == SHT_DYNSYM ) {
+ dynsym_idx = i;
+ }
+ }
+
+ if(dynsym_idx == -1) {
+ goto out_unmap;
+ }
+
+ Elf32_Sym *dynsyms = (Elf32_Sym*)(base + shdr[dynsym_idx].sh_offset);
+ int numsyms = shdr[dynsym_idx].sh_size / shdr[dynsym_idx].sh_entsize;
+
+ table = malloc(sizeof(struct symbol_table));
+ if(!table) {
+ goto out_unmap;
+ }
+ table->num_symbols = 0;
+
+ // Iterate through the dynamic symbol table, and count how many symbols
+ // are actually defined
+ for(i = 0; i < numsyms; i++) {
+ if(dynsyms[i].st_shndx != SHN_UNDEF) {
+ table->num_symbols++;
+ }
+ }
+
+ int dynstr_idx = shdr[dynsym_idx].sh_link;
+ char *dynstr = base + shdr[dynstr_idx].sh_offset;
+
+ // Now, create an entry in our symbol table structure for each symbol...
+ table->symbols = malloc(table->num_symbols * sizeof(struct symbol));
+ if(!table->symbols) {
+ free(table);
+ table = NULL;
+ goto out_unmap;
+ }
+
+ // ...and populate them
+ int j = 0;
+ for(i = 0; i < numsyms; i++) {
+ if(dynsyms[i].st_shndx != SHN_UNDEF) {
+ table->symbols[j].name = strdup(dynstr + dynsyms[i].st_name);
+ table->symbols[j].addr = dynsyms[i].st_value;
+ table->symbols[j].size = dynsyms[i].st_size;
+ j++;
+ }
+ }
+
+ // Sort the symbol table entries, so they can be bsearched later
+ qsort(table->symbols, table->num_symbols, sizeof(struct symbol), qcompar);
+
+out_unmap:
+ munmap(base, length);
+
+out_close:
+ close(fd);
+
+out:
+ return table;
+}
+
+/*
+ * Free a symbol table
+ *
+ * Parameters:
+ * table - Table to free
+ */
+void symbol_table_free(struct symbol_table *table)
+{
+ int i;
+
+ if(!table) {
+ return;
+ }
+
+ for(i=0; i<table->num_symbols; i++) {
+ free(table->symbols[i].name);
+ }
+
+ free(table->symbols);
+ free(table);
+}
+
+/*
+ * Search for an address in the symbol table
+ *
+ * Parameters:
+ * table - Table to search in
+ * addr - Address to search for.
+ *
+ * Returns:
+ * A pointer to the Symbol structure corresponding to the
+ * symbol which contains this address, or NULL if no symbol
+ * contains it.
+ */
+const struct symbol *symbol_table_lookup(struct symbol_table *table, unsigned int addr)
+{
+ if(!table) {
+ return NULL;
+ }
+
+ return bsearch((void*)addr, table->symbols, table->num_symbols, sizeof(struct symbol), bcompar);
+}
diff --git a/debuggerd/symbol_table.h b/debuggerd/symbol_table.h
new file mode 100644
index 0000000..d9d2520
--- /dev/null
+++ b/debuggerd/symbol_table.h
@@ -0,0 +1,19 @@
+#ifndef SYMBOL_TABLE_H
+#define SYMBOL_TABLE_H
+
+struct symbol {
+ unsigned int addr;
+ unsigned int size;
+ char *name;
+};
+
+struct symbol_table {
+ struct symbol *symbols;
+ int num_symbols;
+};
+
+struct symbol_table *symbol_table_create(const char *filename);
+void symbol_table_free(struct symbol_table *table);
+const struct symbol *symbol_table_lookup(struct symbol_table *table, unsigned int addr);
+
+#endif
diff --git a/debuggerd/unwind-arm.c b/debuggerd/unwind-arm.c
index 9642d2e..b081161 100644
--- a/debuggerd/unwind-arm.c
+++ b/debuggerd/unwind-arm.c
@@ -37,6 +37,8 @@
#include <unwind.h>
#include "utility.h"
+#include "symbol_table.h"
+
typedef struct _ZSt9type_info type_info; /* This names C++ type_info type */
void __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp);
@@ -393,6 +395,7 @@
phase2_vrs *vrs = (phase2_vrs*) context;
const mapinfo *mi;
bool only_in_tombstone = !at_fault;
+ const struct symbol* sym = 0;
if (stack_level < STACK_CONTENT_DEPTH) {
sp_list[stack_level] = vrs->core.r[R_SP];
@@ -451,9 +454,20 @@
rel_pc = pc;
mi = pc_to_mapinfo(map, pc, &rel_pc);
- _LOG(tfd, only_in_tombstone,
- " #%02d pc %08x %s\n", stack_level, rel_pc,
- mi ? mi->name : "");
+ /* See if we can determine what symbol this stack frame resides in */
+ if (mi != 0 && mi->symbols != 0) {
+ sym = symbol_table_lookup(mi->symbols, rel_pc);
+ }
+
+ if (sym) {
+ _LOG(tfd, only_in_tombstone,
+ " #%02d pc %08x %s (%s)\n", stack_level, rel_pc,
+ mi ? mi->name : "", sym->name);
+ } else {
+ _LOG(tfd, only_in_tombstone,
+ " #%02d pc %08x %s\n", stack_level, rel_pc,
+ mi ? mi->name : "");
+ }
return _URC_NO_REASON;
}
diff --git a/debuggerd/utility.h b/debuggerd/utility.h
index 49f5951..2ffdf56 100644
--- a/debuggerd/utility.h
+++ b/debuggerd/utility.h
@@ -21,6 +21,8 @@
#include <stddef.h>
#include <stdbool.h>
+#include "symbol_table.h"
+
#ifndef PT_ARM_EXIDX
#define PT_ARM_EXIDX 0x70000001 /* .ARM.exidx segment */
#endif
@@ -33,6 +35,7 @@
unsigned end;
unsigned exidx_start;
unsigned exidx_end;
+ struct symbol_table *symbols;
char name[];
} mapinfo;
diff --git a/libpixelflinger/codeflinger/ARMAssembler.cpp b/libpixelflinger/codeflinger/ARMAssembler.cpp
index d3720c3..fa9f1ad 100644
--- a/libpixelflinger/codeflinger/ARMAssembler.cpp
+++ b/libpixelflinger/codeflinger/ARMAssembler.cpp
@@ -433,6 +433,16 @@
{
*mPC++ = (cc<<28) | 0x6CF0070 | (Rd<<12) | ((rotate >> 3) << 10) | Rm;
}
+#if 0
+#pragma mark -
+#pragma mark Bit manipulation (ARMv7+ only)...
+#endif
+
+// Bit manipulation (ARMv7+ only)...
+void ARMAssembler::UBFX(int cc, int Rd, int Rn, int lsb, int width)
+{
+ *mPC++ = (cc<<28) | 0x7E00000 | ((width-1)<<16) | (Rd<<12) | (lsb<<7) | 0x50 | Rn;
+}
}; // namespace android
diff --git a/libpixelflinger/codeflinger/ARMAssembler.h b/libpixelflinger/codeflinger/ARMAssembler.h
index a667cb5..e7f038a 100644
--- a/libpixelflinger/codeflinger/ARMAssembler.h
+++ b/libpixelflinger/codeflinger/ARMAssembler.h
@@ -124,6 +124,7 @@
virtual void SMLAW(int cc, int y,
int Rd, int Rm, int Rs, int Rn);
virtual void UXTB16(int cc, int Rd, int Rm, int rotate);
+ virtual void UBFX(int cc, int Rd, int Rn, int lsb, int width);
private:
ARMAssembler(const ARMAssembler& rhs);
diff --git a/libpixelflinger/codeflinger/ARMAssemblerInterface.h b/libpixelflinger/codeflinger/ARMAssemblerInterface.h
index ff6af2a..796342a 100644
--- a/libpixelflinger/codeflinger/ARMAssemblerInterface.h
+++ b/libpixelflinger/codeflinger/ARMAssemblerInterface.h
@@ -206,6 +206,9 @@
// byte/half word extract...
virtual void UXTB16(int cc, int Rd, int Rm, int rotate) = 0;
+ // bit manipulation...
+ virtual void UBFX(int cc, int Rd, int Rn, int lsb, int width) = 0;
+
// -----------------------------------------------------------------------
// convenience...
// -----------------------------------------------------------------------
diff --git a/libpixelflinger/codeflinger/ARMAssemblerProxy.cpp b/libpixelflinger/codeflinger/ARMAssemblerProxy.cpp
index 7c422db..c57d7da 100644
--- a/libpixelflinger/codeflinger/ARMAssemblerProxy.cpp
+++ b/libpixelflinger/codeflinger/ARMAssemblerProxy.cpp
@@ -199,5 +199,9 @@
mTarget->UXTB16(cc, Rd, Rm, rotate);
}
+void ARMAssemblerProxy::UBFX(int cc, int Rd, int Rn, int lsb, int width) {
+ mTarget->UBFX(cc, Rd, Rn, lsb, width);
+}
+
}; // namespace android
diff --git a/libpixelflinger/codeflinger/ARMAssemblerProxy.h b/libpixelflinger/codeflinger/ARMAssemblerProxy.h
index 9134cce..8c7f270 100644
--- a/libpixelflinger/codeflinger/ARMAssemblerProxy.h
+++ b/libpixelflinger/codeflinger/ARMAssemblerProxy.h
@@ -115,6 +115,7 @@
int Rd, int Rm, int Rs, int Rn);
virtual void UXTB16(int cc, int Rd, int Rm, int rotate);
+ virtual void UBFX(int cc, int Rd, int Rn, int lsb, int width);
private:
ARMAssemblerInterface* mTarget;
diff --git a/libpixelflinger/codeflinger/disassem.c b/libpixelflinger/codeflinger/disassem.c
index c17f3ec..aeb8034 100644
--- a/libpixelflinger/codeflinger/disassem.c
+++ b/libpixelflinger/codeflinger/disassem.c
@@ -81,6 +81,8 @@
* g - 2nd fp operand (register) (bits 16-18)
* h - 3rd fp operand (register/immediate) (bits 0-4)
* j - xtb rotate literal (bits 10-11)
+ * i - bfx lsb literal (bits 7-11)
+ * w - bfx width literal (bits 16-20)
* b - branch address
* t - thumb branch address (bits 24, 0-23)
* k - breakpoint comment (bits 0-3, 8-19)
@@ -124,6 +126,7 @@
{ 0x0fe000f0, 0x00a00090, "umlal", "Sdnms" },
{ 0x0fe000f0, 0x00e00090, "smlal", "Sdnms" },
{ 0x0fff03f0, 0x06cf0070, "uxtb16", "dmj" },
+ { 0x0fe00070, 0x07e00050, "ubfx", "dmiw" },
{ 0x0d700000, 0x04200000, "strt", "daW" },
{ 0x0d700000, 0x04300000, "ldrt", "daW" },
{ 0x0d700000, 0x04600000, "strbt", "daW" },
@@ -412,6 +415,14 @@
case 'j':
di->di_printf("ror #%d", ((insn >> 10) & 3) << 3);
break;
+ /* i - bfx lsb literal (bits 7-11) */
+ case 'i':
+ di->di_printf("#%d", (insn >> 7) & 31);
+ break;
+ /* w - bfx width literal (bits 16-20) */
+ case 'w':
+ di->di_printf("#%d", 1 + ((insn >> 16) & 31));
+ break;
/* b - branch address */
case 'b':
branch = ((insn << 2) & 0x03ffffff);
diff --git a/libpixelflinger/codeflinger/load_store.cpp b/libpixelflinger/codeflinger/load_store.cpp
index 93c5825..ed20a00 100644
--- a/libpixelflinger/codeflinger/load_store.cpp
+++ b/libpixelflinger/codeflinger/load_store.cpp
@@ -18,9 +18,12 @@
#include <assert.h>
#include <stdio.h>
#include <cutils/log.h>
-
#include "codeflinger/GGLAssembler.h"
+#ifdef __ARM_ARCH__
+#include <machine/cpu-features.h>
+#endif
+
namespace android {
// ----------------------------------------------------------------------------
@@ -110,6 +113,20 @@
assert(maskLen<=8);
assert(h);
+#if __ARM_ARCH__ >= 7
+ const int mask = (1<<maskLen)-1;
+ if ((h == bits) && !l && (s != d.reg)) {
+ MOV(AL, 0, d.reg, s); // component = packed;
+ } else if ((h == bits) && l) {
+ MOV(AL, 0, d.reg, reg_imm(s, LSR, l)); // component = packed >> l;
+ } else if (!l && isValidImmediate(mask)) {
+ AND(AL, 0, d.reg, s, imm(mask)); // component = packed & mask;
+ } else if (!l && isValidImmediate(~mask)) {
+ BIC(AL, 0, d.reg, s, imm(~mask)); // component = packed & mask;
+ } else {
+ UBFX(AL, d.reg, s, l, maskLen); // component = (packed & mask) >> l;
+ }
+#else
if (h != bits) {
const int mask = ((1<<maskLen)-1) << l;
if (isValidImmediate(mask)) {
@@ -132,6 +149,7 @@
if (s != d.reg) {
MOV(AL, 0, d.reg, s);
}
+#endif
d.s = maskLen;
}