plan9port

[fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port # fast
git clone https://src.adamsgaard.dk/plan9port.git # slow
Log | Files | Refs | README | LICENSE Back to index

elfdl386.c (2242B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <mach.h>
      4 #include "elf.h"
      5 
      6 /*
      7 aggr Linkdebug
      8 {
      9 	'X' 0 version;
     10 	'X' 4 map;
     11 };
     12 
     13 aggr Linkmap
     14 {
     15 	'X' 0 addr;
     16 	'X' 4 name;
     17 	'X' 8 dynsect;
     18 	'X' 12 next;
     19 	'X' 16 prev;
     20 };
     21 */
     22 enum
     23 {
     24 	DT_NULL = 0,
     25 	DT_NEEDED,
     26 	DT_PLTRRELSZ,
     27 	DT_PLTGOT,
     28 	DT_HASH,
     29 	DT_STRTAB,
     30 	DT_SYMTAB,
     31 	DT_RELA,
     32 	DT_RELASZ = 8,
     33 	DT_RELAENT,
     34 	DT_STSZ,
     35 	DT_SYMENT,
     36 	DT_INIT,
     37 	DT_FINI,
     38 	DT_SONAME,
     39 	DT_RPATH,
     40 	DT_SYMBOLIC = 16,
     41 	DT_REL,
     42 	DT_RELSZ,
     43 	DT_RELENT,
     44 	DT_PLTREL,
     45 	DT_DEBUG,
     46 	DT_TEXTREL,
     47 	DT_JMPREL
     48 };
     49 
     50 static int
     51 getstr(Map *map, ulong addr, char *buf, uint nbuf)
     52 {
     53 	int i;
     54 
     55 	for(i=0; i<nbuf; i++){
     56 		if(get1(map, addr+i, (uchar*)buf+i, 1) < 0)
     57 			return -1;
     58 		if(buf[i] == 0)
     59 			return 0;
     60 	}
     61 	return -1;	/* no nul */
     62 }
     63 
     64 static ulong
     65 dyninfo(Fhdr *hdr, int x)
     66 {
     67 	u32int addr, u;
     68 
     69 	if(hdr == nil || (addr = ((Elf*)hdr->elf)->dynamic) == 0){
     70 		fprint(2, "no hdr/dynamic %p\n", hdr);
     71 		return 0;
     72 	}
     73 	addr += hdr->base;
     74 
     75 	while(addr != 0){
     76 		if(get4(cormap, addr, &u) < 0)
     77 			return 0;
     78 		if(u == x){
     79 			if(get4(cormap, addr+4, &u) < 0)
     80 				return 0;
     81 			return u;
     82 		}
     83 		addr += 8;
     84 	}
     85 	return 0;
     86 }
     87 
     88 void
     89 elfdl386mapdl(int verbose)
     90 {
     91 	int i;
     92 	Fhdr *hdr;
     93 	u32int linkdebug, linkmap, name, addr;
     94 	char buf[1024];
     95 
     96 	if((linkdebug = dyninfo(symhdr, DT_DEBUG)) == 0){
     97 		fprint(2, "no dt_debug section\n");
     98 		return;
     99 	}
    100 	if(get4(cormap, linkdebug+4, &linkmap) < 0){
    101 		fprint(2, "get4 linkdebug+4 (0x%lux) failed\n", linkdebug);
    102 		return;
    103 	}
    104 
    105 	for(i=0; i<100 && linkmap != 0; i++){
    106 		if(get4(cormap, linkmap, &addr) < 0
    107 		|| get4(cormap, linkmap+4, &name) < 0
    108 		|| get4(cormap, linkmap+12, &linkmap) < 0)
    109 			break;
    110 
    111 		if(name == 0 || getstr(cormap, name, buf, sizeof buf) < 0 || buf[0] == 0)
    112 			continue;
    113 		if((hdr = crackhdr(buf, OREAD)) == nil){
    114 			fprint(2, "crackhdr %s: %r\n", buf);
    115 			continue;
    116 		}
    117 		hdr->base = addr;
    118 		if(verbose)
    119 			fprint(2, "%s: %s %s %s\n", buf, hdr->aname, hdr->mname, hdr->fname);
    120 		if(mapfile(hdr, addr, symmap, nil) < 0)
    121 			fprint(2, "mapping %s: %r\n", buf);
    122 		if(corhdr){
    123 			/*
    124 			 * Need to map the text file under the core file.
    125 			 */
    126 			unmapfile(corhdr, cormap);
    127 			mapfile(hdr, addr, cormap, nil);
    128 			mapfile(corhdr, 0, cormap, nil);
    129 		}
    130 		if(symopen(hdr) < 0)
    131 			fprint(2, "syminit %s: %r\n", buf);
    132 	}
    133 }