#include #include #include #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; ielf)->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(int verbose) { int i; Fhdr *hdr; u32int linkdebug, linkmap, name, addr; char buf[1024]; 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 == 0 || getstr(cormap, name, buf, sizeof buf) < 0 || buf[0] == 0) continue; if((hdr = crackhdr(buf, OREAD)) == nil){ fprint(2, "crackhdr %s: %r\n", buf); continue; } hdr->base = addr; if(verbose) fprint(2, "%s: %s %s %s\n", buf, hdr->aname, hdr->mname, hdr->fname); if(mapfile(hdr, addr, symmap, nil) < 0) fprint(2, "mapping %s: %r\n", buf); if(corhdr){ /* * Need to map the text file under the core file. */ unmapfile(corhdr, cormap); mapfile(hdr, addr, cormap, nil); mapfile(corhdr, 0, cormap, nil); } if(symopen(hdr) < 0) fprint(2, "syminit %s: %r\n", buf); } }