blob: 104e5a95c36d4464e940ad2ae56cfd03f7ff47f5 [file] [log] [blame]
#include <u.h>
#include <libc.h>
#include <mach.h>
#include "elf.h"
/*
aggr Linkdebug
{
'X' 0 version;
'X' 4 map;
};
aggr Linkmap
{
'X' 0 addr;
'X' 4 name;
'X' 8 dynsect;
'X' 12 next;
'X' 16 prev;
};
*/
enum
{
DT_NULL = 0,
DT_NEEDED,
DT_PLTRRELSZ,
DT_PLTGOT,
DT_HASH,
DT_STRTAB,
DT_SYMTAB,
DT_RELA,
DT_RELASZ = 8,
DT_RELAENT,
DT_STSZ,
DT_SYMENT,
DT_INIT,
DT_FINI,
DT_SONAME,
DT_RPATH,
DT_SYMBOLIC = 16,
DT_REL,
DT_RELSZ,
DT_RELENT,
DT_PLTREL,
DT_DEBUG,
DT_TEXTREL,
DT_JMPREL,
};
static int
getstr(Map *map, ulong addr, char *buf, uint nbuf)
{
int i;
for(i=0; i<nbuf; i++){
if(get1(map, addr+i, buf+i, 1) < 0)
return -1;
if(buf[i] == 0)
return 0;
}
return -1; /* no nul */
}
static ulong
dyninfo(Fhdr *hdr, int x)
{
u32int addr, u;
if(hdr == nil || (addr = ((Elf*)hdr->elf)->dynamic) == 0){
fprint(2, "no hdr/dynamic %p\n", hdr);
return 0;
}
addr += hdr->base;
while(addr != 0){
if(get4(cormap, addr, &u) < 0)
return 0;
if(u == x){
if(get4(cormap, addr+4, &u) < 0)
return 0;
return u;
}
addr += 8;
}
return 0;
}
void
elfdl386mapdl(void)
{
int i;
Fhdr *hdr;
u32int linkdebug, linkmap, name, addr;
char buf[1024];
print("elfdl386mapdl\n");
if((linkdebug = dyninfo(symhdr, DT_DEBUG)) == 0){
fprint(2, "no dt_debug section\n");
return;
}
if(get4(cormap, linkdebug+4, &linkmap) < 0){
fprint(2, "get4 linkdebug+4 (0x%lux) failed\n", linkdebug);
return;
}
for(i=0; i<100 && linkmap != 0; i++){
if(get4(cormap, linkmap, &addr) < 0
|| get4(cormap, linkmap+4, &name) < 0
|| get4(cormap, linkmap+12, &linkmap) < 0)
break;
if(name
&& getstr(cormap, name, buf, sizeof buf) >= 0
&& buf[0]
&& access(buf, AEXIST) >= 0){
if((hdr = crackhdr(buf, OREAD)) == nil)
fprint(2, "crackhdr %s: %r\n", buf);
else{
fprint(2, "%s: %s %s %s\n", buf, hdr->aname, hdr->mname, hdr->fname);
hdr->base = addr;
if(mapfile(hdr, addr, symmap, nil) < 0)
fprint(2, "mapfile %s: %r\n", buf);
if(corhdr){
unmapfile(corhdr, cormap);
mapfile(hdr, addr, cormap, nil);
}
if(syminit(hdr) < 0)
fprint(2, "syminit %s: %\r", buf);
}
}
}
}