From c87cb75a66135759330236e6b4a1a5dad55d849c Mon Sep 17 00:00:00 2001 From: Iliyan Malchev <> Date: Wed, 25 Mar 2009 18:09:52 -0700 Subject: [PATCH] Automated import from //branches/master/...@142824,142824 --- tools/apriori/prelinkmap.c | 111 ++++++++++++++++++++++++------------- 1 file changed, 71 insertions(+), 40 deletions(-) diff --git a/tools/apriori/prelinkmap.c b/tools/apriori/prelinkmap.c index 739c181767..9fb00e4ad0 100644 --- a/tools/apriori/prelinkmap.c +++ b/tools/apriori/prelinkmap.c @@ -7,11 +7,14 @@ typedef struct mapentry mapentry; +#define MAX_ALIASES 10 + struct mapentry { mapentry *next; unsigned base; - char name[0]; + char *names[MAX_ALIASES]; + int num_names; }; static mapentry *maplist = 0; @@ -22,14 +25,13 @@ static mapentry *maplist = 0; */ #define PRELINK_MIN 0x90000000 -#define PRELINK_MAX 0xB0000000 +#define PRELINK_MAX 0xBFFFFFFF void pm_init(const char *file) { unsigned line = 0; char buf[256]; char *x; - unsigned n; FILE *fp; mapentry *me; unsigned last = -1UL; @@ -65,26 +67,52 @@ void pm_init(const char *file) continue; } - 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); - - me = malloc(sizeof(mapentry) + strlen(buf) + 1); - FAILIF(me == NULL, "Out of memory parsing %s\n", file); + if (isalpha(*x)) { + /* Assume that this is an alias, and look through the list of + already-installed libraries. + */ + me = maplist; + while(me) { + /* The strlen() call ignores the newline at the end of x */ + if (!strncmp(me->names[0], x, strlen(me->names[0]))) { + PRINT("Aliasing library %s to %s at %08x\n", + buf, x, me->base); + 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 " - "at entry %s (%08x)!\n", buf, n); - last = n; - - me->base = n; - strcpy(me->name, buf); - me->next = maplist; - maplist = me; + me = malloc(sizeof(mapentry)); + FAILIF(me == NULL, "Out of memory parsing %s\n", file); + + FAILIF(last <= n, "The prelink map is not in descending order " + "at entry %s (%08x)!\n", buf, n); + last = n; + + 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); @@ -99,41 +127,44 @@ void pm_report_library_size_in_memory(const char *name, { char *x; mapentry *me; + int n; x = strrchr(name,'/'); if(x) name = x+1; for(me = maplist; me; me = me->next){ - if(!strcmp(name, me->name)) { - off_t slot = me->next ? me->next->base : PRELINK_MAX; - slot -= me->base; - FAILIF(fsize > slot, - "prelink map error: library %s@0x%08x is too big " - "at %lld bytes, it runs %lld bytes into " - "library %s@0x%08x!\n", - me->name, me->base, fsize, fsize - slot, - me->next->name, me->next->base); - break; + for (n = 0; n < me->num_names; n++) { + if(!strcmp(name, me->names[n])) { + off_t slot = me->next ? me->next->base : PRELINK_MAX; + slot -= me->base; + FAILIF(fsize > slot, + "prelink map error: library %s@0x%08x is too big " + "at %lld bytes, it runs %lld bytes into " + "library %s@0x%08x!\n", + me->names[0], me->base, fsize, fsize - slot, + 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) { char *x; mapentry *me; + int n; x = strrchr(lookup_name,'/'); if(x) lookup_name = x+1; - for(me = maplist; me; me = me->next){ - if(!strcmp(lookup_name, me->name)) { - return me->base; - } - } - - FAILIF(1==1,"library '%s' not in prelink map\n", lookup_name); + for(me = maplist; me; me = me->next) + for (n = 0; n < me->num_names; n++) + if(!strcmp(lookup_name, me->names[n])) + return me->base; + + FAILIF(1, "library '%s' not in prelink map\n", lookup_name); return 0; }