@global elf_defined; if (elf_defined == nil) { /* apparently unused at time of librarization */ /* @local DT_VALTAGIDX,DT_ADDRTAGIDX,DT_VERSIONTAGIDX; @local EF_ARM_EABI_VERSION; @local ELF32_R_SYM,ELF32_R_TYPE,ELF32_R_INFO; @local ELF64_R_SYM,ELF64_R_TYPE,ELF64_R_INFO; @local ELF32_M_SYM,ELF32_M_SIZE,ELF32_M_INFO; @local ELF64_M_SYM,ELF64_M_SIZE,ELF64_M_INFO; @local elfsegtype,elfsegoffset,elfsegvaddr,elfsegpaddr,elfsegfilesz,elfsegmemsz,elfsegflags,elfsegalign; */ @global mkelfrec,showelfheader,showallelfsectionheaders,showsectionheader; @global showelfsym,getsyms,getelfsyms,dumpsym,showsym,getelfsection; @global getelfsecname,getelfsegmenthdr,getelfsegment,showsegmentheader; @global getcqctelfsym,show_elf_syms,show_elf_addrs; @global elfshndx,elfother,elfinfo,elfsize,elfvisibility,elftype,elfaddr,elfname; @global bd,isbd; @global iself; @global ELF32_ST_BIND,ELF32_ST_TYPE,ELF32_ST_INFO; @global ELF64_ST_BIND,ELF64_ST_TYPE,ELF64_ST_INFO; @global ELF32_ST_VISIBILITY; @global ELF64_ST_VISIBILITY; elf_defined = 1; @record bd {exec, elf, debug_aranges, debug_pubnames, debug_info, debug_abbrev, debug_line, debug_frame, debug_str, debug_ranges, debug_loc, frametable, linetable, addrsize, rootns, cuinfotab, nstab, fregtab, artab}; /** * Tests a string to see if it is ELF. * param: stroras - a string or an address space * returns: 1 -- the string may be valid ELF * 0 -- the string is certianly not ELF */ @define iself (stroras) { @local sig; sig = "\x7f""ELF"; if(isas(stroras)) { if ( getbytes({stroras}(void *)0, length(sig)) != sig) return 0; else return 1; } else if(isstring(stroras)) { if ( ( length(stroras) < 4 ) || ( substr(stroras,0,length(sig)) != sig ) ) return 0; else return 1; } else { error("operand 0 to iself must be a string or an address space"); } } /** * Makes and returns an elf record for the provided elf object. * param: binfile - a string or address space of the contents of an elf file * returns: a bd record containing the file's elf information */ @define mkelfrec (binfile) { @local elfas, elfheader, elfnames, hdom, hns, root, rv; if(isstring(binfile)) return mkelfrec(mksas(binfile)); rv = bd(); elfas = binfile; hns = @names c32le { enum x { EI_NIDENT =16, EI_MAG0 =0, ELFMAG0 =0x7f, EI_MAG1 =1, ELFMAG1 ='E', EI_MAG2 =2, ELFMAG2 ='L', EI_MAG3 =3, ELFMAG3 ='F', EI_CLASS =4, ELFCLASSNONE =0, ELFCLASS32 =1, ELFCLASS64 =2, ELFCLASSNUM =3, EI_DATA =5, ELFDATANONE =0, ELFDATA2LSB =1, ELFDATA2MSB =2, ELFDATANUM =3, }; }; hdom = mkdom (hns, elfas); elfheader = (unsigned char *) {hdom}0; if (getbytes(elfheader, 4) != "\x7f""ELF") error ("argument to mkelfrec must be a string containing an elf binary"); if (elfheader[hdom`EI_CLASS] == hdom`ELFCLASS32) { if (elfheader[hdom`EI_DATA] == hdom`ELFDATA2LSB) root = c32le; else if (elfheader[hdom`EI_DATA] == hdom`ELFDATA2MSB) root = c32be; else error ("unsupported ELF data encoding: %d", elfheader[hdom`EI_DATA]); } else if (elfheader[hdom`EI_CLASS] == hdom`ELFCLASS64) { if (elfheader[hdom`EI_DATA] == hdom`ELFDATA2LSB) root = clp64le; else if (elfheader[hdom`EI_DATA] == hdom`ELFDATA2MSB) root = clp64be; else error ("unsupported ELF data encoding: %d", elfheader[hdom`EI_DATA]); } else error ("unsupported ELF class: %d", elfheader[hdom`EI_CLASS]); rv.rootns = root; elfnames = @names root { @include "elf.names" }; rv.elf = mkdom (elfnames, elfas); return rv; } /* functions to perform some macros defined in /usr/include/elf.h */ /* unused at time of librarization */ /* @define DT_VALTAGIDX (edom, tag) { return (edom`DT_VALRNGHI - (tag)); } @define DT_ADDRTAGIDX (edom, tag) { return (edom`DT_ADDRRNGHI - (tag)); } @define DT_VERSIONTAGIDX (edom, tag) { return (edom`DT_VERNEEDNUM - (tag)); } @define EF_ARM_EABI_VERSION (edom, flags) { return ((flags) & edom`EF_ARM_EABIMASK); } @define ELF32_ST_BIND (val) { return (((unsigned char) (val)) >> 4); } @define ELF32_ST_TYPE (val) { return (val & 0xf); } @define ELF32_ST_INFO (bind, type) { return (((bind) << 4) + ( type & 0xf)); } @define ELF64_ST_BIND (val) { return (((unsigned char) val) >> 4); } @define ELF64_ST_TYPE (val) { return (val & 0xf); } @define ELF64_ST_INFO (bind, type) { return (((bind) << 4) + (type & 0xf)); } @define ELF32_ST_VISIBILITY (o) { return (o & 0x03); } @define ELF64_ST_VISIBILITY (o) { return (o & 0x03); } @define ELF32_R_SYM (val) { return ((val) >> 8); } @define ELF32_R_TYPE (val) { return (val & 0xff); } @define ELF32_R_INFO (sym, type) { return (((sym) << 8) + (type & 0xff)); } @define ELF64_R_SYM (val) { return ((val) >> 32); } @define ELF64_R_TYPE (val) { return (val & 0xffffffff); } @define ELF64_R_INFO (sym, type) { return ((((Elf64_Xword) (sym)) << 32) + (type)); } @define ELF32_M_SYM (info) { return ((info) >> 8); } @define ELF32_M_SIZE (info) { return ((unsigned char) (info)); } @define ELF32_M_INFO (sym, size) { return (((sym) << 8) + (unsigned char) (size)); } @define ELF64_M_SYM (info) { return ((info) >> 8); } @define ELF64_M_SIZE (info) { return ((unsigned char) (info)); } @define ELF64_M_INFO (sym, size) { return (((sym) << 8) + (unsigned char) (size)); } */ /** * prints the values of the elf header for the elf file represented by the * given domain. * param: elfdom - an elf domain (generally mkelfrec(...).elf) * returns: nil */ @define showelfheader (elfdom) { @local e; if (sizeof (nsptr (elfdom.ns)) == 4) e = (elfdom`Elf32_Ehdr *){elfdom} 0; else e = (elfdom`Elf64_Ehdr *){elfdom} 0; printf ("e_type = %d\te_machine = %d\te_version = %d\n", e->e_type, e->e_machine, e->e_version); printf ("e_entry = 0x%x\te_phoff = 0x%x\te_shoff = 0x%x\n", e->e_entry, e->e_phoff, e->e_shoff); printf ("e_flags = 0x%x\te_ehsize = %d\te_phentsize = 0x%x\n", e->e_flags, e->e_ehsize, e->e_phentsize); printf ("e_phnum = %d\te_shentsize = %d\te_shnum = %d\te_shstrndx = %d\n", e->e_phnum, e->e_shentsize, e->e_shnum, e->e_shstrndx); } /** * Print all elf section headers to stdout for the given domain. * param: elfdom - an elf domain (gerneally mkelfrec(...).elf) * returns: nil */ @define showallelfsectionheaders (elfdom) { @local e, sarray, i, shsize; if (sizeof (nsptr (elfdom.ns)) == 4){ e = (elfdom`Elf32_Ehdr *){elfdom} 0; sarray = (elfdom`Elf32_Shdr *) e->e_shoff; shsize = sizeof (elfdom`Elf32_Shdr); }else{ e = (elfdom`Elf64_Ehdr *){elfdom} 0; sarray = (elfdom`Elf64_Shdr *) e->e_shoff; shsize = sizeof (elfdom`Elf64_Shdr); } printf ("Size of section header is %d\n", shsize); for (i = 0; i < e->e_shnum; i++) { printf ("Section header %d begins at offset 0x%x\n", i, &sarray[i]); showsectionheader (elfdom, &sarray[0], i); } } /** * Prints a section header at index for the given elf domain. * param: elfdom - an elf domain (gerneally mkelfrec(...).elf) * param: sbase - appropriately set elfdom`Elf64_Shdr* or elfdom`Elf32_Shdr* * param: index - the index of the header to print * returns: nil */ @define showsectionheader (elfdom, sbase, index) { @local e, s, st; if (sizeof (nsptr (elfdom.ns)) == 4) { e = (elfdom`Elf32_Ehdr *){elfdom} 0; st = (unsigned char *) sbase[e->e_shstrndx].sh_offset; s = (elfdom`Elf32_Shdr *) &sbase[index]; } else { e = (elfdom`Elf64_Ehdr *){elfdom} 0; st = (unsigned char *) sbase[e->e_shstrndx].sh_offset; s = (elfdom`Elf64_Shdr *) &sbase[index]; } printf ("sh_name = %d(%s)\tsh_type = 0x%x\tsh_flags = 0x%x\n", s->sh_name, &st[s->sh_name], s->sh_type, s->sh_flags); printf ("sh_addr = 0x%x\tsh_offset = 0x%x\tsh_size = 0x%x\n", s->sh_addr, s->sh_offset, s->sh_size); printf ("sh_link = %d\tsh_info = 0x%x\tsh_addralign = 0x%x\n", s->sh_link, s->sh_info, s->sh_addralign); printf ("sh_entsize = 0x%x\n", s->sh_entsize); } /** * Prints a description of the elf symbol at the given addr with * the given offset into the e_shoff table. * param: elfdom - an elf domain (gerneally mkelfrec(...).elf) * param: addr - the symbol address * param: strind - the index into the e_shoff table */ @define showelfsym (elfdom, addr, strind) { @local e, sym, sind, sbase, st; if (sizeof (nsptr (elfdom.ns)) == 4) { e = (elfdom`Elf32_Ehdr *){elfdom} 0; sbase = (elfdom`Elf32_Shdr *) (e->e_shoff); sym = (elfdom`Elf32_Sym *)(addr); } else { e = (elfdom`Elf64_Ehdr *){elfdom} 0; sbase = (elfdom`Elf64_Shdr *) (e->e_shoff); sym = (elfdom`Elf64_Sym *)(addr); } /* Find the right string table for the name. It could be static or dynamic, but the link field of the containing symbol table tells us which to use. */ sind = sym->st_shndx; st = (unsigned char *) sbase[strind].sh_offset; printf ("%s : st_value = 0x%x\tst_size = 0x%x\n", &st[sym->st_name], sym->st_value, sym->st_size); printf ("st_info = 0x%x\tst_other = 0x%x\tst_shndx = %d\n", sym->st_info, sym->st_other, sind); } /** * prints the symbols in a given elf domain * param: elfdom - an elf domain (gerneally mkelfrec(...).elf) * returns: a table mapping symbol names to Sym* objects */ @define getsyms (elfdom) { @local e, shbase, strbase, symbase, sec, sym, ht, i; ht = [:]; if (sizeof (nsptr (elfdom.ns)) == 4) { e = (elfdom`Elf32_Ehdr *){elfdom} 0; shbase = (elfdom`Elf32_Shdr *) (e->e_shoff); } else { e = (elfdom`Elf64_Ehdr *){elfdom} 0; shbase = (elfdom`Elf64_Shdr *) (e->e_shoff); } for (i = 0; i < e->e_shnum; i++) { sec = &shbase[i]; if (sec->sh_type == 2 /* SHT_SYMTAB in elf.h */ || sec->sh_type == 11) { /* SHT_DYNSYMTAB in elf.h */ @local symcount, strind, j; if (sizeof (nsptr (elfdom.ns)) == 4) symbase = (elfdom`Elf32_Sym *)sec->sh_offset; else symbase = (elfdom`Elf64_Sym *)sec->sh_offset; strind = sec->sh_link; strbase = (unsigned char *) shbase[strind].sh_offset; if (sizeof (nsptr (elfdom.ns)) == 4) symcount = sec->sh_size / (sizeof (elfdom`Elf32_Sym)); else symcount = sec->sh_size / (sizeof (elfdom`Elf64_Sym)); //printf ("sec %d link %d count %d\n", i, strind, symcount); for (j = 1; j < symcount; j++) { @local name; if (sizeof (nsptr (elfdom.ns)) == 4) sym = (elfdom`Elf32_Sym *)(&symbase[j]); else sym = (elfdom`Elf64_Sym *)(&symbase[j]); name = sprintfa ("%s", &strbase[sym->st_name]); tabinsert (ht, name, sym); } } } return ht; } /** * Returns a list of symbols in a given elf domain * mapping strings to pointers to ElfXX_Sym objects. * param: edom - an elf domain (gerneally mkelfrec(...).elf) * returns: A vector of cqct symbols contained in the given elf domain */ @define getelfsyms (edom) { @local e, shbase, strbase, symbase, sec, sym, symtab, symsize, i, symcount; @local syml, sl, symind; syml = []; if (sizeof (nsptr (edom.ns)) == 4) { e = (edom`Elf32_Ehdr *){edom} 0; shbase = (edom`Elf32_Shdr *) (e->e_shoff); symbase = (edom`Elf32_Sym *) {edom} 0; symsize = sizeof (edom`Elf32_Sym); } else if (sizeof (nsptr (edom.ns)) == {edom} 8) { e = (edom`Elf64_Ehdr *){edom} 0; shbase = (edom`Elf64_Shdr *) (e->e_shoff); symbase = (edom`Elf64_Sym *) {edom} 0; symsize = sizeof (edom`Elf64_Sym); } else { printf ("Elf support available only for address sizes of 4 or 8 bytes.\n"); return []; /* so that the caller will get a type mismatch */ } symcount = {edom} 0; for (i = 0; i < e->e_shnum; i++) { sec = &shbase[i]; if (sec->sh_type == 2 /* SHT_SYMTAB in elf.h */ || sec->sh_type == 11) { /* SHT_DYNSYMTAB in elf.h */ @local shsymcount, strind, j; if (sizeof (nsptr (edom.ns)) == 4) symbase = (edom`Elf32_Sym *)sec->sh_offset; else symbase = (edom`Elf64_Sym *)sec->sh_offset; strind = sec->sh_link; strbase = (unsigned char *) shbase[strind].sh_offset; shsymcount = sec->sh_size / symsize; /* start at 1 because the ELF spec requires that the 0 element is 0 */ for (j = 1; j < shsymcount; j++) { @local name, csym; if (sizeof (nsptr (edom.ns)) == 4) sym = (edom`Elf32_Sym *)(&symbase[j]); else sym = (edom`Elf64_Sym *)(&symbase[j]); name = sprintfa ("%s", &strbase[sym->st_name]); csym = getcqctelfsym (edom, sym, name); if (length (csym) != 0) { append (syml, csym); symcount++; } } } } symtab = mkvec (symcount); for (symind = 0, sl = syml; symind < symcount && !isempty (sl); symind++, sl = tail (sl)) { vecset (symtab, symind, head (sl)); } if (symind < symcount || !isempty (sl)) printf ("Unexpected mismatch between symcount and syml\n"); sort (symtab, @lambda (a, b) { if (vecref (a, 1) < vecref (b, 1)) return -1; else if (vecref (a, 1) > vecref (b, 1)) return 1; else return 0;}); return symtab; } /** * For an ElfXX_Sym* object with name name, print its contents. * param: name - the name of the symbol * prarm: esym - the ElfXX_Sym* pointer * returns: nil */ @define dumpsym (name, esym) { printf ("0x%x\t%d\t0x%x\t0x%x\t%d\t%s\n", esym->st_value, esym->st_size, esym->st_info, esym->st_other, esym->st_shndx, name); } /** * Print some information about the given ElfXX_Sym* * param: esym - the elfsym vector * returns: nil */ @define showsym (esym) { @local bind, type, dom, visibility; dom = domof (vecref (esym, 1)); bind = ELF32_ST_BIND (elfinfo (esym)); type = ELF32_ST_TYPE (elfinfo (esym)); if (bind == dom`STB_GLOBAL) visibility = "global"; else visibility = "local "; if (type == dom`STT_FUNC) type = "FUNC"; else type = "OBJ"; printf ("0x%x\t%d\t%s\t%s\t%d\t%s\n", elfaddr (esym), elfsize (esym), type, visibility, elfshndx (esym), elfname (esym)); } /** * return a byte string containing the data of an ELF section * param: edom - the elf domain * name: the name of the section * returns: a byte string containing the data of an ELF section */ @define getelfsection (edom, name) { @local e, sarray, st, sname, i; if (sizeof (nsptr (edom.ns)) == 4) { //printf ("choosing 32 header\n"); e = (edom`Elf32_Ehdr *){edom} 0; /* get the base of the section header array */ sarray = (edom`Elf32_Shdr *) e->e_shoff; } else { //printf ("choosing 64 header\n"); e = (edom`Elf64_Ehdr *){edom} 0; /* get the base of the section header array */ sarray = (edom`Elf64_Shdr *) e->e_shoff; //printf ("sarray is 0x%x (%d)\n", sarray, sarray); } /* get the base address of the section header name table. sh_name values are byte offsets from this base address. */ st = (edom`unsigned char *) sarray[e->e_shstrndx].sh_offset; //printf ("st is 0x%x (%d)\n", st, st); for (i = 0; i < e->e_shnum; i++) { sname = stringof (st + sarray[i].sh_name); if (name == sname) { /* Should perhaps enter the [name, section] pair to global_dwarf_domain_list */ //printf ("returning string at 0x%x of size 0x%x\n", // sarray[i].sh_offset, sarray[i].sh_size); return getbytes ((edom`char *)sarray[i].sh_offset, sarray[i].sh_size); } } return ""; } /** * Get the name of an elf section. This function does not check that there * actually is a section at that index. * param: edom - an elf domain * param: ind - the number of the section * returns: the string name of the given section */ @define getelfsecname (edom, ind) { @local e, sarray, st; if (sizeof (nsptr (edom.ns)) == 4) { e = (edom`Elf32_Ehdr *){edom} 0; /* get the base of the section header array */ sarray = (edom`Elf32_Shdr *) e->e_shoff; } else { e = (edom`Elf64_Ehdr *){edom} 0; /* get the base of the section header array */ sarray = (edom`Elf64_Shdr *) e->e_shoff; } /* get the base address of the section header name table. sh_name values are byte offsets from this base address. */ st = (unsigned char *) sarray[e->e_shstrndx].sh_offset; return stringof (st + sarray[ind].sh_name); } /** return the header for an ELF segment * param: edom - an elf domain * param: n - an index for the given header. * returns: an ElfXX_Phdr* pointer */ @define getelfsegmenthdr (edom, n) { @local e, pharray, cnt; if (sizeof (nsptr (edom.ns)) == 4) { e = (edom`Elf32_Ehdr *){edom} 0; cnt = {edom} n; if (e->e_phnum < cnt) { printf ("Elf domain has only %d segment headers.\n", e->e_phnum); return (edom`Elf32_Phdr *) {edom} 0; } /* get the base of the segment header table */ pharray = (edom`Elf32_Phdr *) e->e_phoff; return (edom`Elf32_Phdr *) (&pharray [cnt]); } else { e = (edom`Elf64_Ehdr *){edom} 0; cnt = {edom} n; if (e->e_phnum < cnt) { printf ("Elf domain has only %d segment headers.\n", e->e_phnum); return (edom`Elf64_Phdr *) {edom} 0; } /* get the base of the segment header table */ pharray = (edom`Elf64_Phdr *) e->e_phoff; return (edom`Elf64_Phdr *) (&pharray [cnt]); } } /** * return a byte string containing the data of an ELF section * param: edom - an elf domain * param: n - the index of the elf section * returns: a string containing the data in that section */ @define getelfsegment (edom, n) { @local e, pharray, ph, cnt; if (sizeof (nsptr (edom.ns)) == 4) { e = (edom`Elf32_Ehdr *){edom} 0; cnt = {edom} n; if (e->e_phnum < cnt) { printf ("Elf domain has only %d segments.\n", e->e_phnum); return ""; } /* get the base of the segment header table */ pharray = (edom`Elf32_Phdr *) e->e_phoff; ph = (edom`Elf32_Phdr *) (&pharray [cnt]); return getbytes ((char *)ph->p_paddr, ph->p_filesz); } else { e = (edom`Elf64_Ehdr *){edom} 0; cnt = {edom} n; if (e->e_phnum < cnt) { printf ("Elf domain has only %d segments.\n", e->e_phnum); return ""; } /* get the base of the segment header table */ pharray = (edom`Elf64_Phdr *) e->e_phoff; ph = (edom`Elf64_Phdr *) (&pharray [cnt]); return getbytes ((char *)ph->p_paddr, ph->p_filesz); } } /** * Print the information in an ElfXX_Phdr* object. * param: eseg - an ElfXX_Phdr* object * returns: nil */ @define showsegmentheader (eseg) { printf ("p_type = 0x%x\tp_flags = 0x%x\tp_offset = 0x%x\n", eseg->p_type, eseg->p_flags, eseg->p_offset); printf ("p_vaddr = 0x%x\tp_paddr = 0x%x\n", eseg->p_vaddr, eseg->p_paddr); printf ("p_filesz = 0x%x\tp_memsz = 0x%x\n", eseg->p_filesz, eseg->p_memsz); printf ("p_align = 0x%x\n", eseg->p_align); } /** Convert a raw ELF symbol from the binary into a Cinquecento list of * the processed field values. * param: edom - an elf domain * param: esym - an ElfXX_Sym* * param: name - the symbol's name * returns: a cqct list of processed field values. */ @define getcqctelfsym (edom, esym, name) { @local result, typec, sarray, st, e, visibility; if (sizeof (nsptr (edom.ns)) == 4) { e = (edom`Elf32_Ehdr *){edom} 0; sarray = (edom`Elf32_Shdr *) e->e_shoff; } else { e = (edom`Elf64_Ehdr *){edom} 0; sarray = (edom`Elf64_Shdr *) e->e_shoff; } /* get the base address of the section header name table. sh_name values are byte offsets from this base address. */ st = (unsigned char *) sarray[e->e_shstrndx].sh_offset; typec = ' '; if (ELF32_ST_BIND (esym->st_info) == edom`STB_WEAK) { if (esym->st_shndx == edom`SHN_UNDEF) typec = 'w'; else typec = 'W'; } else if (esym->st_shndx == edom`SHN_UNDEF) return mkvec (0); else if (ELF64_ST_TYPE (esym->st_info) == edom`STT_SECTION || ELF64_ST_TYPE (esym->st_info) == edom`STT_FILE) /* ELF64_ST_TYPE and ELF32_ST_TYPE are equivalent, so we can use either one */ return mkvec (0); else if (esym->st_shndx >= ((edom`Elf32_Ehdr *) {edom} 0)->e_shnum) { if (esym->st_shndx == edom`SHN_ABS) typec = 'a'; } else if (ELF32_ST_TYPE (esym->st_info) == edom`STT_FUNC) typec = 't'; else if ( stringof (st + sarray[esym->st_shndx].sh_name) == ".bss") typec = 'b'; else if ( stringof (st + sarray[esym->st_shndx].sh_name) == ".data") typec = 'd'; else if ( stringof (st + sarray[esym->st_shndx].sh_name) == ".rodata") typec = 'r'; else if ( stringof (st + sarray[esym->st_shndx].sh_name) == ".rdata") typec = 'r'; /* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ if (ELF32_ST_BIND (esym->st_info) == edom`STB_GLOBAL) typec = typec - 32; /*toupper (typec) */ if (typec >= 'A' && typec <= 'Z') /* isupper (typec) */ visibility = "global"; else visibility = "local"; result = mkvec (8); vecset (result, 0, name); vecset (result, 1, esym->st_value); vecset (result, 2, typec); vecset (result, 3, visibility); vecset (result, 4, esym->st_size); vecset (result, 5, esym->st_info); vecset (result, 6, esym->st_other); vecset (result, 7, esym->st_shndx); return result; } /** * Prints information in the table tab. * param: tab - a vector of symbols * returns: nil */ @define show_elf_syms (syms) { @local i, len; len = length (syms); for (i = 0; i < len; i++) //printf ("%a\n", vecref (syms, i)); showsym (vecref (syms, i)); } /** * print the addresses in the given vector of symbols. * param: syms - a vector of symbols * returns: nil */ @define show_elf_addrs (syms) { @local i, len; len = length (syms); for (i = 0; i < len; i++) printf ("0x%x\n", listref (vecref (syms, i), 1)); } /* Accessor functions for ELF symbols */ @define elfname (esym) { return vecref (esym, 0); } @define elfaddr (esym) { return vecref (esym, 1); } @define elftype (esym) { return vecref (esym, 2); } @define elfvisibility (esym) { return vecref (esym, 3); } @define elfsize (esym) { return vecref (esym, 4); } @define elfinfo (esym) { return vecref (esym, 5); } @define elfother (esym) { return vecref (esym, 6); } @define elfshndx (esym) { return vecref (esym, 7); } /* Accessor functions for ELF segments */ /* unused at time of librarization */ /* @define elfsegtype (eseg) { return head (eseg); } @define elfsegoffset (eseg) { return head (tail (eseg)); } @define elfsegvaddr (eseg) { return head (tail (tail (eseg))); } @define elfsegpaddr (eseg) { return head (tail (tail (tail (eseg)))); } @define elfsegfilesz (eseg) { return head (tail (tail (tail (tail (eseg))))); } @define elfsegmemsz (eseg) { return head (tail (tail (tail (tail (tail (eseg)))))); } @define elfsegflags (eseg) { return head (tail (tail (tail (tail (tail (tail (eseg))))))); } @define elfsegalign (eseg) { return head (tail (tail (tail (tail (tail (tail (tail (eseg)))))))); } */ nil; }