Automated import from //branches/master/...@142824,142824

This commit is contained in:
Iliyan Malchev
2009-03-25 18:09:52 -07:00
committed by The Android Open Source Project
parent 7bbec3ab97
commit c87cb75a66

View File

@@ -7,11 +7,14 @@
typedef struct mapentry mapentry; typedef struct mapentry mapentry;
#define MAX_ALIASES 10
struct mapentry struct mapentry
{ {
mapentry *next; mapentry *next;
unsigned base; unsigned base;
char name[0]; char *names[MAX_ALIASES];
int num_names;
}; };
static mapentry *maplist = 0; static mapentry *maplist = 0;
@@ -22,14 +25,13 @@ static mapentry *maplist = 0;
*/ */
#define PRELINK_MIN 0x90000000 #define PRELINK_MIN 0x90000000
#define PRELINK_MAX 0xB0000000 #define PRELINK_MAX 0xBFFFFFFF
void pm_init(const char *file) void pm_init(const char *file)
{ {
unsigned line = 0; unsigned line = 0;
char buf[256]; char buf[256];
char *x; char *x;
unsigned n;
FILE *fp; FILE *fp;
mapentry *me; mapentry *me;
unsigned last = -1UL; unsigned last = -1UL;
@@ -65,26 +67,52 @@ void pm_init(const char *file)
continue; continue;
} }
n = strtoul(x, 0, 16); if (isalpha(*x)) {
/* Note that this is not the only bounds check. If a library's size /* Assume that this is an alias, and look through the list of
exceeds its slot as defined in the prelink map, the prelinker will already-installed libraries.
exit with an error. See pm_report_library_size_in_memory(). */
*/ me = maplist;
FAILIF((n < PRELINK_MIN) || (n > PRELINK_MAX), while(me) {
"%s:%d base 0x%08x out of range.\n", /* The strlen() call ignores the newline at the end of x */
file, line, n); if (!strncmp(me->names[0], x, strlen(me->names[0]))) {
PRINT("Aliasing library %s to %s at %08x\n",
me = malloc(sizeof(mapentry) + strlen(buf) + 1); buf, x, me->base);
FAILIF(me == NULL, "Out of memory parsing %s\n", file); break;
}
me = me->next;
}
FAILIF(!me, "Nonexistent alias %s -> %s\n", buf, x);
}
else {
unsigned n = strtoul(x, 0, 16);
/* Note that this is not the only bounds check. If a library's
size exceeds its slot as defined in the prelink map, the
prelinker will exit with an error. See
pm_report_library_size_in_memory().
*/
FAILIF((n < PRELINK_MIN) || (n > PRELINK_MAX),
"%s:%d base 0x%08x out of range.\n",
file, line, n);
FAILIF(last <= n, "The prelink map is not in descending order " me = malloc(sizeof(mapentry));
"at entry %s (%08x)!\n", buf, n); FAILIF(me == NULL, "Out of memory parsing %s\n", file);
last = n;
FAILIF(last <= n, "The prelink map is not in descending order "
me->base = n; "at entry %s (%08x)!\n", buf, n);
strcpy(me->name, buf); last = n;
me->next = maplist;
maplist = me; me->base = n;
me->next = maplist;
me->num_names = 0;
maplist = me;
}
FAILIF(me->num_names >= MAX_ALIASES,
"Too many aliases for library %s, maximum is %d.\n",
me->names[0],
MAX_ALIASES);
me->names[me->num_names] = strdup(buf);
me->num_names++;
} }
fclose(fp); fclose(fp);
@@ -99,41 +127,44 @@ void pm_report_library_size_in_memory(const char *name,
{ {
char *x; char *x;
mapentry *me; mapentry *me;
int n;
x = strrchr(name,'/'); x = strrchr(name,'/');
if(x) name = x+1; if(x) name = x+1;
for(me = maplist; me; me = me->next){ for(me = maplist; me; me = me->next){
if(!strcmp(name, me->name)) { for (n = 0; n < me->num_names; n++) {
off_t slot = me->next ? me->next->base : PRELINK_MAX; if(!strcmp(name, me->names[n])) {
slot -= me->base; off_t slot = me->next ? me->next->base : PRELINK_MAX;
FAILIF(fsize > slot, slot -= me->base;
"prelink map error: library %s@0x%08x is too big " FAILIF(fsize > slot,
"at %lld bytes, it runs %lld bytes into " "prelink map error: library %s@0x%08x is too big "
"library %s@0x%08x!\n", "at %lld bytes, it runs %lld bytes into "
me->name, me->base, fsize, fsize - slot, "library %s@0x%08x!\n",
me->next->name, me->next->base); me->names[0], me->base, fsize, fsize - slot,
break; me->next->names[0], me->next->base);
return;
}
} }
} }
FAILIF(!me,"library '%s' not in prelink map\n", name); FAILIF(1, "library '%s' not in prelink map\n", name);
} }
unsigned pm_get_next_link_address(const char *lookup_name) unsigned pm_get_next_link_address(const char *lookup_name)
{ {
char *x; char *x;
mapentry *me; mapentry *me;
int n;
x = strrchr(lookup_name,'/'); x = strrchr(lookup_name,'/');
if(x) lookup_name = x+1; if(x) lookup_name = x+1;
for(me = maplist; me; me = me->next){ for(me = maplist; me; me = me->next)
if(!strcmp(lookup_name, me->name)) { for (n = 0; n < me->num_names; n++)
return me->base; if(!strcmp(lookup_name, me->names[n]))
} return me->base;
}
FAILIF(1, "library '%s' not in prelink map\n", lookup_name);
FAILIF(1==1,"library '%s' not in prelink map\n", lookup_name);
return 0; return 0;
} }