Compare commits
	
		
			17 Commits
		
	
	
		
			android-2.
			...
			eclair-sho
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					5f53a18204 | ||
| 
						 | 
					754c178ae5 | ||
| 
						 | 
					e1e684920f | ||
| 
						 | 
					fe62de1ad0 | ||
| 
						 | 
					7b12b4a349 | ||
| 
						 | 
					cd5df2d92c | ||
| 
						 | 
					7e61789985 | ||
| 
						 | 
					a6083b7768 | ||
| 
						 | 
					110044b131 | ||
| 
						 | 
					199f9d9238 | ||
| 
						 | 
					763ac28357 | ||
| 
						 | 
					96bbbe2177 | ||
| 
						 | 
					bb9eedeff4 | ||
| 
						 | 
					af7315acf6 | ||
| 
						 | 
					7e7d6c48a0 | ||
| 
						 | 
					ff7b46b87c | ||
| 
						 | 
					3c99876116 | 
@@ -37,8 +37,9 @@
 | 
			
		||||
        .type memcpy, %function
 | 
			
		||||
        .align 4
 | 
			
		||||
 | 
			
		||||
/* a prefetch distance of 32*4 works best experimentally */
 | 
			
		||||
#define PREFETCH_DISTANCE   (32*4)
 | 
			
		||||
/* a prefetch distance of 4 cache-lines works best experimentally */
 | 
			
		||||
#define CACHE_LINE_SIZE     64
 | 
			
		||||
#define PREFETCH_DISTANCE   (CACHE_LINE_SIZE*4)
 | 
			
		||||
 | 
			
		||||
memcpy:
 | 
			
		||||
        .fnstart
 | 
			
		||||
@@ -46,8 +47,8 @@ memcpy:
 | 
			
		||||
        stmfd       sp!, {r0, lr}
 | 
			
		||||
 | 
			
		||||
        /* start preloading as early as possible */
 | 
			
		||||
        pld         [r1, #0]
 | 
			
		||||
        pld         [r1, #32]
 | 
			
		||||
        pld         [r1, #(CACHE_LINE_SIZE*0)]
 | 
			
		||||
        pld         [r1, #(CACHE_LINE_SIZE*1)]
 | 
			
		||||
 | 
			
		||||
        /* do we have at least 16-bytes to copy (needed for alignment below) */
 | 
			
		||||
        cmp         r2, #16
 | 
			
		||||
@@ -79,13 +80,11 @@ memcpy:
 | 
			
		||||
2:
 | 
			
		||||
 | 
			
		||||
0:      /* preload immediately the next cache line, which we may need */
 | 
			
		||||
        pld         [r1, #(32*0)]
 | 
			
		||||
        pld         [r1, #(32*1)]
 | 
			
		||||
        pld         [r1, #(32*2)]
 | 
			
		||||
        pld         [r1, #(32*3)]
 | 
			
		||||
        pld         [r1, #(CACHE_LINE_SIZE*0)]
 | 
			
		||||
        pld         [r1, #(CACHE_LINE_SIZE*1)]
 | 
			
		||||
 | 
			
		||||
        /* make sure we have at least 128 bytes to copy */
 | 
			
		||||
        subs        r2, r2, #128
 | 
			
		||||
        /* make sure we have at least 64 bytes to copy */
 | 
			
		||||
        subs        r2, r2, #64
 | 
			
		||||
        blo         2f
 | 
			
		||||
 | 
			
		||||
        /* preload all the cache lines we need.
 | 
			
		||||
@@ -94,29 +93,21 @@ memcpy:
 | 
			
		||||
         * avoid the goofy code below. In practice this doesn't seem to make
 | 
			
		||||
         * a big difference.
 | 
			
		||||
         */
 | 
			
		||||
        pld         [r1, #(PREFETCH_DISTANCE + 32*0)]
 | 
			
		||||
        pld         [r1, #(PREFETCH_DISTANCE + 32*1)]
 | 
			
		||||
        pld         [r1, #(PREFETCH_DISTANCE + 32*2)]
 | 
			
		||||
        pld         [r1, #(PREFETCH_DISTANCE + 32*3)]
 | 
			
		||||
        pld         [r1, #(CACHE_LINE_SIZE*2)]
 | 
			
		||||
        pld         [r1, #(CACHE_LINE_SIZE*3)]
 | 
			
		||||
        pld         [r1, #(PREFETCH_DISTANCE)]
 | 
			
		||||
 | 
			
		||||
1:      /* The main loop copies 128 bytes at a time */
 | 
			
		||||
1:      /* The main loop copies 64 bytes at a time */
 | 
			
		||||
        vld1.8      {d0  - d3},   [r1]!
 | 
			
		||||
        vld1.8      {d4  - d7},   [r1]!
 | 
			
		||||
        vld1.8      {d16 - d19},  [r1]!
 | 
			
		||||
        vld1.8      {d20 - d23},  [r1]!
 | 
			
		||||
        pld         [r1, #(PREFETCH_DISTANCE + 32*0)]
 | 
			
		||||
        pld         [r1, #(PREFETCH_DISTANCE + 32*1)]
 | 
			
		||||
        pld         [r1, #(PREFETCH_DISTANCE + 32*2)]
 | 
			
		||||
        pld         [r1, #(PREFETCH_DISTANCE + 32*3)]
 | 
			
		||||
        subs        r2, r2, #128
 | 
			
		||||
        pld         [r1, #(PREFETCH_DISTANCE)]
 | 
			
		||||
        subs        r2, r2, #64
 | 
			
		||||
        vst1.8      {d0  - d3},   [r0, :128]!
 | 
			
		||||
        vst1.8      {d4  - d7},   [r0, :128]!
 | 
			
		||||
        vst1.8      {d16 - d19},  [r0, :128]!
 | 
			
		||||
        vst1.8      {d20 - d23},  [r0, :128]!
 | 
			
		||||
        bhs         1b
 | 
			
		||||
 | 
			
		||||
2:      /* fix-up the remaining count and make sure we have >= 32 bytes left */
 | 
			
		||||
        add         r2, r2, #128
 | 
			
		||||
        add         r2, r2, #64
 | 
			
		||||
        subs        r2, r2, #32
 | 
			
		||||
        blo         4f
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -80,7 +80,7 @@ memset:
 | 
			
		||||
        
 | 
			
		||||
		rsb         r3, r0, #0
 | 
			
		||||
		ands		r3, r3, #0x1C
 | 
			
		||||
		beq         aligned32
 | 
			
		||||
		beq         3f
 | 
			
		||||
		cmp         r3, r2
 | 
			
		||||
		andhi		r3, r2, #0x1C
 | 
			
		||||
		sub         r2, r2, r3
 | 
			
		||||
@@ -93,7 +93,7 @@ memset:
 | 
			
		||||
		movs		r3, r3, lsl #2
 | 
			
		||||
        strcs       r1, [r0], #4
 | 
			
		||||
 | 
			
		||||
aligned32:
 | 
			
		||||
3:
 | 
			
		||||
        subs        r2, r2, #32
 | 
			
		||||
        mov         r3, r1
 | 
			
		||||
        bmi         2f
 | 
			
		||||
 
 | 
			
		||||
@@ -139,6 +139,8 @@ struct kgsl_drawctxt_destroy {
 | 
			
		||||
struct kgsl_sharedmem_from_pmem {
 | 
			
		||||
 int pmem_fd;
 | 
			
		||||
 unsigned int gpuaddr;
 | 
			
		||||
 unsigned int len;
 | 
			
		||||
 unsigned int offset;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define IOCTL_KGSL_SHAREDMEM_FROM_PMEM   _IOWR(KGSL_IOC_TYPE, 0x20, struct kgsl_sharedmem_from_pmem)
 | 
			
		||||
@@ -188,5 +190,12 @@ struct kgsl_sharedmem_from_vmalloc {
 | 
			
		||||
 | 
			
		||||
#define IOCTL_KGSL_SHAREDMEM_FLUSH_CACHE   _IOW(KGSL_IOC_TYPE, 0x24, struct kgsl_sharedmem_free)
 | 
			
		||||
 | 
			
		||||
struct kgsl_drawctxt_set_bin_base_offset {
 | 
			
		||||
 unsigned int drawctxt_id;
 | 
			
		||||
 unsigned int offset;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define IOCTL_KGSL_DRAWCTXT_SET_BIN_BASE_OFFSET   _IOW(KGSL_IOC_TYPE, 0x25, struct kgsl_drawctxt_set_bin_base_offset)
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -39,8 +39,13 @@
 | 
			
		||||
#define debug_log(format, ...)  \
 | 
			
		||||
    __libc_android_log_print(ANDROID_LOG_DEBUG, "libc-abort", (format), ##__VA_ARGS__ )
 | 
			
		||||
 | 
			
		||||
#ifdef __arm__
 | 
			
		||||
void
 | 
			
		||||
__libc_android_abort(void)
 | 
			
		||||
#else
 | 
			
		||||
void
 | 
			
		||||
abort(void)
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	struct atexit *p = __atexit;
 | 
			
		||||
	static int cleanup_called = 0;
 | 
			
		||||
@@ -97,3 +102,29 @@ abort(void)
 | 
			
		||||
	(void)kill(getpid(), SIGABRT);
 | 
			
		||||
	_exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef __arm__
 | 
			
		||||
/*
 | 
			
		||||
 * abort() does not return, which gcc interprets to mean that it doesn't
 | 
			
		||||
 * need to preserve any of the callee-save registers.  Unfortunately this
 | 
			
		||||
 * includes the link register, so if LR is used there is no way to determine
 | 
			
		||||
 * which function called abort().
 | 
			
		||||
 *
 | 
			
		||||
 * We work around this by inserting a trivial stub that doesn't alter
 | 
			
		||||
 * any of the "interesting" registers and thus doesn't need to save them.
 | 
			
		||||
 * We can't just call __libc_android_abort from C because gcc uses "bl"
 | 
			
		||||
 * without first saving LR, so we use an asm statement.  This also has
 | 
			
		||||
 * the side-effect of replacing abort() with __libc_android_abort() in
 | 
			
		||||
 * the stack trace.
 | 
			
		||||
 *
 | 
			
		||||
 * Ideally __libc_android_abort would be static, but I haven't figured out
 | 
			
		||||
 * how to tell gcc to call a static function from an asm statement.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
abort(void)
 | 
			
		||||
{
 | 
			
		||||
    asm ("b __libc_android_abort");
 | 
			
		||||
    _exit(1);       /* suppress gcc noreturn warnings */
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -1 +1 @@
 | 
			
		||||
2007h
 | 
			
		||||
2009s
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										76
									
								
								linker/ba.c
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								linker/ba.c
									
									
									
									
									
								
							@@ -30,65 +30,41 @@
 | 
			
		||||
#include "linker_debug.h"
 | 
			
		||||
#include "ba.h"
 | 
			
		||||
 | 
			
		||||
struct ba_bits {
 | 
			
		||||
    unsigned allocated:1;           /* 1 if allocated, 0 if free */
 | 
			
		||||
    unsigned order:7;               /* size of the region in ba space */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ba_info {
 | 
			
		||||
    /* start address of the ba space */
 | 
			
		||||
    unsigned long base;
 | 
			
		||||
    /* total size of the ba space */
 | 
			
		||||
    unsigned long size;
 | 
			
		||||
    /* number of entries in the ba space */
 | 
			
		||||
    int num_entries;
 | 
			
		||||
    /* the bitmap for the region indicating which entries are allocated
 | 
			
		||||
     * and which are free */
 | 
			
		||||
    struct ba_bits *bitmap;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#undef min
 | 
			
		||||
#define min(a,b) ((a)<(b)?(a):(b))
 | 
			
		||||
 | 
			
		||||
#define BA_MIN_ALLOC LIBINC
 | 
			
		||||
#define BA_MAX_ORDER 128
 | 
			
		||||
#define BA_START LIBBASE
 | 
			
		||||
#define BA_SIZE (LIBLAST - LIBBASE)
 | 
			
		||||
 | 
			
		||||
#define BA_IS_FREE(index) (!(ba.bitmap[index].allocated))
 | 
			
		||||
#define BA_ORDER(index) ba.bitmap[index].order
 | 
			
		||||
#define BA_IS_FREE(index) (!(ba->bitmap[index].allocated))
 | 
			
		||||
#define BA_ORDER(index) ba->bitmap[index].order
 | 
			
		||||
#define BA_BUDDY_INDEX(index) ((index) ^ (1 << BA_ORDER(index)))
 | 
			
		||||
#define BA_NEXT_INDEX(index) ((index) + (1 << BA_ORDER(index)))
 | 
			
		||||
#define BA_OFFSET(index) ((index) * BA_MIN_ALLOC)
 | 
			
		||||
#define BA_START_ADDR(index) (BA_OFFSET(index) + ba.base)
 | 
			
		||||
#define BA_LEN(index) ((1 << BA_ORDER(index)) * BA_MIN_ALLOC)
 | 
			
		||||
#define BA_OFFSET(index) ((index) * ba->min_alloc)
 | 
			
		||||
#define BA_START_ADDR(index) (BA_OFFSET(index) + ba->base)
 | 
			
		||||
#define BA_LEN(index) ((1 << BA_ORDER(index)) * ba->min_alloc)
 | 
			
		||||
 | 
			
		||||
static struct ba_bits ba_bitmap[BA_SIZE / BA_MIN_ALLOC];
 | 
			
		||||
static unsigned long ba_order(struct ba *ba, unsigned long len);
 | 
			
		||||
 | 
			
		||||
static struct ba_info ba = {
 | 
			
		||||
    .base = BA_START,
 | 
			
		||||
    .size = BA_SIZE,
 | 
			
		||||
    .bitmap = ba_bitmap,
 | 
			
		||||
    .num_entries = sizeof(ba_bitmap)/sizeof(ba_bitmap[0]),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void ba_init(void)
 | 
			
		||||
void ba_init(struct ba *ba)
 | 
			
		||||
{
 | 
			
		||||
    int i, index = 0;
 | 
			
		||||
    for (i = sizeof(ba.num_entries) * 8 - 1; i >= 0; i--) {
 | 
			
		||||
        if (ba.num_entries &  1<<i) {
 | 
			
		||||
 | 
			
		||||
    unsigned long max_order = ba_order(ba, ba->size);
 | 
			
		||||
    if (ba->max_order == 0 || ba->max_order > max_order)
 | 
			
		||||
        ba->max_order = max_order;
 | 
			
		||||
 | 
			
		||||
    for (i = sizeof(ba->num_entries) * 8 - 1; i >= 0; i--) {
 | 
			
		||||
        if (ba->num_entries &  1<<i) {
 | 
			
		||||
            BA_ORDER(index) = i;
 | 
			
		||||
            index = BA_NEXT_INDEX(index);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ba_free(int index)
 | 
			
		||||
int ba_free(struct ba *ba, int index)
 | 
			
		||||
{
 | 
			
		||||
    int buddy, curr = index;
 | 
			
		||||
 | 
			
		||||
    /* clean up the bitmap, merging any buddies */
 | 
			
		||||
    ba.bitmap[curr].allocated = 0;
 | 
			
		||||
    ba->bitmap[curr].allocated = 0;
 | 
			
		||||
    /* find a slots buddy Buddy# = Slot# ^ (1 << order)
 | 
			
		||||
     * if the buddy is also free merge them
 | 
			
		||||
     * repeat until the buddy is not free or end of the bitmap is reached
 | 
			
		||||
@@ -103,16 +79,16 @@ int ba_free(int index)
 | 
			
		||||
        } else {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    } while (curr < ba.num_entries);
 | 
			
		||||
    } while (curr < ba->num_entries);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned long ba_order(unsigned long len)
 | 
			
		||||
static unsigned long ba_order(struct ba *ba, unsigned long len)
 | 
			
		||||
{
 | 
			
		||||
    unsigned long i;
 | 
			
		||||
 | 
			
		||||
    len = (len + BA_MIN_ALLOC - 1) / BA_MIN_ALLOC;
 | 
			
		||||
    len = (len + ba->min_alloc - 1) / ba->min_alloc;
 | 
			
		||||
    len--;
 | 
			
		||||
    for (i = 0; i < sizeof(len)*8; i++)
 | 
			
		||||
        if (len >> i == 0)
 | 
			
		||||
@@ -120,14 +96,14 @@ static unsigned long ba_order(unsigned long len)
 | 
			
		||||
    return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ba_allocate(unsigned long len)
 | 
			
		||||
int ba_allocate(struct ba *ba, unsigned long len)
 | 
			
		||||
{
 | 
			
		||||
    int curr = 0;
 | 
			
		||||
    int end = ba.num_entries;
 | 
			
		||||
    int end = ba->num_entries;
 | 
			
		||||
    int best_fit = -1;
 | 
			
		||||
    unsigned long order = ba_order(len);
 | 
			
		||||
    unsigned long order = ba_order(ba, len);
 | 
			
		||||
 | 
			
		||||
    if (order > BA_MAX_ORDER)
 | 
			
		||||
    if (order > ba->max_order)
 | 
			
		||||
        return -1;
 | 
			
		||||
 | 
			
		||||
    /* look through the bitmap:
 | 
			
		||||
@@ -165,16 +141,16 @@ int ba_allocate(unsigned long len)
 | 
			
		||||
        buddy = BA_BUDDY_INDEX(best_fit);
 | 
			
		||||
        BA_ORDER(buddy) = BA_ORDER(best_fit);
 | 
			
		||||
    }
 | 
			
		||||
    ba.bitmap[best_fit].allocated = 1;
 | 
			
		||||
    ba->bitmap[best_fit].allocated = 1;
 | 
			
		||||
    return best_fit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned long ba_start_addr(int index)
 | 
			
		||||
unsigned long ba_start_addr(struct ba *ba, int index)
 | 
			
		||||
{
 | 
			
		||||
    return BA_START_ADDR(index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned long ba_len(int index)
 | 
			
		||||
unsigned long ba_len(struct ba *ba, int index)
 | 
			
		||||
{
 | 
			
		||||
    return BA_LEN(index);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								linker/ba.h
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								linker/ba.h
									
									
									
									
									
								
							@@ -29,10 +29,31 @@
 | 
			
		||||
#ifndef __LINKER_BA_H
 | 
			
		||||
#define __LINKER_BA_H
 | 
			
		||||
 | 
			
		||||
extern void ba_init(void);
 | 
			
		||||
extern int ba_allocate(unsigned long len);
 | 
			
		||||
extern int ba_free(int index);
 | 
			
		||||
extern unsigned long ba_start_addr(int index);
 | 
			
		||||
extern unsigned long ba_len(int index);
 | 
			
		||||
struct ba_bits {
 | 
			
		||||
    unsigned allocated:1;           /* 1 if allocated, 0 if free */
 | 
			
		||||
    unsigned order:7;               /* size of the region in ba space */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ba {
 | 
			
		||||
    /* start address of the ba space */
 | 
			
		||||
    unsigned long base;
 | 
			
		||||
    /* total size of the ba space */
 | 
			
		||||
    unsigned long size;
 | 
			
		||||
    /* the smaller allocation that can be made */
 | 
			
		||||
    unsigned long min_alloc;
 | 
			
		||||
    /* the order of the largest allocation that can be made */
 | 
			
		||||
    unsigned long max_order;
 | 
			
		||||
    /* number of entries in the ba space */
 | 
			
		||||
    int num_entries;
 | 
			
		||||
    /* the bitmap for the region indicating which entries are allocated
 | 
			
		||||
     * and which are free */
 | 
			
		||||
    struct ba_bits *bitmap;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern void ba_init(struct ba *ba);
 | 
			
		||||
extern int ba_allocate(struct ba *ba, unsigned long len);
 | 
			
		||||
extern int ba_free(struct ba *ba, int index);
 | 
			
		||||
extern unsigned long ba_start_addr(struct ba *ba, int index);
 | 
			
		||||
extern unsigned long ba_len(struct ba *ba, int index);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -91,6 +91,18 @@ static soinfo *sonext = &libdl_info;
 | 
			
		||||
static soinfo *somain; /* main process, always the one after libdl_info */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Set up for the buddy allocator managing the prelinked libraries. */
 | 
			
		||||
static struct ba_bits ba_prelink_bitmap[(LIBLAST - LIBBASE) / LIBINC];
 | 
			
		||||
static struct ba ba_prelink = {
 | 
			
		||||
    .base = LIBBASE,
 | 
			
		||||
    .size = LIBLAST - LIBBASE,
 | 
			
		||||
    .min_alloc = LIBINC,
 | 
			
		||||
    /* max_order will be determined automatically */
 | 
			
		||||
    .bitmap = ba_prelink_bitmap,
 | 
			
		||||
    .num_entries = sizeof(ba_prelink_bitmap)/sizeof(ba_prelink_bitmap[0]),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static inline int validate_soinfo(soinfo *si)
 | 
			
		||||
{
 | 
			
		||||
    return (si >= sopool && si < sopool + SO_MAX) ||
 | 
			
		||||
@@ -783,14 +795,14 @@ alloc_mem_region(soinfo *si)
 | 
			
		||||
       for it from the buddy allocator, which manages the area between
 | 
			
		||||
       LIBBASE and LIBLAST.
 | 
			
		||||
    */
 | 
			
		||||
    si->ba_index = ba_allocate(si->size);
 | 
			
		||||
    si->ba_index = ba_allocate(&ba_prelink, si->size);
 | 
			
		||||
    if(si->ba_index >= 0) {
 | 
			
		||||
        si->base = ba_start_addr(si->ba_index);
 | 
			
		||||
        si->base = ba_start_addr(&ba_prelink, si->ba_index);
 | 
			
		||||
        PRINT("%5d mapping library '%s' at %08x (index %d) " \
 | 
			
		||||
              "through buddy allocator.\n",
 | 
			
		||||
              pid, si->name, si->base, si->ba_index);
 | 
			
		||||
        if (reserve_mem_region(si) < 0) {
 | 
			
		||||
            ba_free(si->ba_index);
 | 
			
		||||
            ba_free(&ba_prelink, si->ba_index);
 | 
			
		||||
            si->ba_index = -1;
 | 
			
		||||
            si->base = 0;
 | 
			
		||||
            goto err;
 | 
			
		||||
@@ -1086,7 +1098,7 @@ load_library(const char *name)
 | 
			
		||||
    /* Now actually load the library's segments into right places in memory */
 | 
			
		||||
    if (load_segments(fd, &__header[0], si) < 0) {
 | 
			
		||||
        if (si->ba_index >= 0) {
 | 
			
		||||
            ba_free(si->ba_index);
 | 
			
		||||
            ba_free(&ba_prelink, si->ba_index);
 | 
			
		||||
            si->ba_index = -1;
 | 
			
		||||
        }
 | 
			
		||||
        goto fail;
 | 
			
		||||
@@ -1189,7 +1201,7 @@ unsigned unload_library(soinfo *si)
 | 
			
		||||
            PRINT("%5d releasing library '%s' address space at %08x "\
 | 
			
		||||
                  "through buddy allocator.\n",
 | 
			
		||||
                  pid, si->name, si->base);
 | 
			
		||||
            ba_free(si->ba_index);
 | 
			
		||||
            ba_free(&ba_prelink, si->ba_index);
 | 
			
		||||
        }
 | 
			
		||||
        notify_gdb_of_unload(si);
 | 
			
		||||
        free_info(si);
 | 
			
		||||
@@ -1240,9 +1252,13 @@ static int reloc_library(soinfo *si, Elf32_Rel *rel, unsigned count)
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
            if ((s->st_shndx == SHN_UNDEF) && (s->st_value != 0)) {
 | 
			
		||||
                DL_ERR("%5d In '%s', shndx=%d && value=0x%08x. We do not "
 | 
			
		||||
                      "handle this yet", pid, si->name, s->st_shndx,
 | 
			
		||||
            // st_shndx==SHN_UNDEF means an undefined symbol.
 | 
			
		||||
            // st_value should be 0 then, except that the low bit of st_value is
 | 
			
		||||
            // used to indicate whether the symbol points to an ARM or thumb function,
 | 
			
		||||
            // and should be ignored in the following check.
 | 
			
		||||
            if ((s->st_shndx == SHN_UNDEF) && ((s->st_value & ~1) != 0)) {
 | 
			
		||||
                DL_ERR("%5d In '%s', symbol=%s shndx=%d && value=0x%08x. We do not "
 | 
			
		||||
                      "handle this yet", pid, si->name, sym_name, s->st_shndx,
 | 
			
		||||
                      s->st_value);
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
@@ -1278,6 +1294,13 @@ static int reloc_library(soinfo *si, Elf32_Rel *rel, unsigned count)
 | 
			
		||||
                       reloc, sym_addr, sym_name);
 | 
			
		||||
            *((unsigned*)reloc) += sym_addr;
 | 
			
		||||
            break;
 | 
			
		||||
        case R_ARM_REL32:
 | 
			
		||||
            COUNT_RELOC(RELOC_RELATIVE);
 | 
			
		||||
            MARK(rel->r_offset);
 | 
			
		||||
            TRACE_TYPE(RELO, "%5d RELO REL32 %08x <- %08x - %08x %s\n", pid,
 | 
			
		||||
                       reloc, sym_addr, rel->r_offset, sym_name);
 | 
			
		||||
            *((unsigned*)reloc) += sym_addr - rel->r_offset;
 | 
			
		||||
            break;
 | 
			
		||||
#elif defined(ANDROID_X86_LINKER)
 | 
			
		||||
        case R_386_JUMP_SLOT:
 | 
			
		||||
            COUNT_RELOC(RELOC_ABSOLUTE);
 | 
			
		||||
@@ -1893,7 +1916,7 @@ unsigned __linker_init(unsigned **elfdata)
 | 
			
		||||
        vecs += 2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ba_init();
 | 
			
		||||
    ba_init(&ba_prelink);
 | 
			
		||||
 | 
			
		||||
    si->base = 0;
 | 
			
		||||
    si->dynamic = (unsigned *)-1;
 | 
			
		||||
 
 | 
			
		||||
@@ -159,6 +159,13 @@ extern soinfo libdl_info;
 | 
			
		||||
#define R_ARM_JUMP_SLOT  22
 | 
			
		||||
#define R_ARM_RELATIVE   23
 | 
			
		||||
 | 
			
		||||
/* According to the AAPCS specification, we only
 | 
			
		||||
 * need the above relocations. However, in practice,
 | 
			
		||||
 * the following ones turn up from time to time.
 | 
			
		||||
 */
 | 
			
		||||
#define R_ARM_ABS32      2
 | 
			
		||||
#define R_ARM_REL32      3
 | 
			
		||||
 | 
			
		||||
#elif defined(ANDROID_X86_LINKER)
 | 
			
		||||
 | 
			
		||||
#define R_386_32         1
 | 
			
		||||
@@ -194,12 +201,6 @@ extern soinfo libdl_info;
 | 
			
		||||
#define DT_PREINIT_ARRAYSZ 33
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* in theory we only need the above relative relocations,
 | 
			
		||||
   but in practice the following one turns up from time
 | 
			
		||||
   to time.  fushigi na.
 | 
			
		||||
*/
 | 
			
		||||
#define R_ARM_ABS32      2
 | 
			
		||||
 | 
			
		||||
soinfo *find_library(const char *name);
 | 
			
		||||
unsigned unload_library(soinfo *si);
 | 
			
		||||
Elf32_Sym *lookup_in_library(soinfo *si, const char *name);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user