Automated import from //branches/master/...@142824,142824
This commit is contained in:

committed by
The Android Open Source Project
parent
7bbec3ab97
commit
c87cb75a66
@@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user