github.com/afumu/libc@v0.0.6/musl/src/ldso/dl_iterate_phdr.c (about)

     1  #include <elf.h>
     2  #include <link.h>
     3  #include "libc.h"
     4  
     5  #define AUX_CNT 38
     6  
     7  extern weak hidden const size_t _DYNAMIC[];
     8  
     9  static int static_dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
    10  {
    11  	unsigned char *p;
    12  	ElfW(Phdr) *phdr, *tls_phdr=0;
    13  	size_t base = 0;
    14  	size_t n;
    15  	struct dl_phdr_info info;
    16  	size_t i, aux[AUX_CNT] = {0};
    17  
    18  	for (i=0; libc.auxv[i]; i+=2)
    19  		if (libc.auxv[i]<AUX_CNT) aux[libc.auxv[i]] = libc.auxv[i+1];
    20  
    21  	for (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) {
    22  		phdr = (void *)p;
    23  		if (phdr->p_type == PT_PHDR)
    24  			base = aux[AT_PHDR] - phdr->p_vaddr;
    25  		if (phdr->p_type == PT_DYNAMIC && _DYNAMIC)
    26  			base = (size_t)_DYNAMIC - phdr->p_vaddr;
    27  		if (phdr->p_type == PT_TLS)
    28  			tls_phdr = phdr;
    29  	}
    30  	info.dlpi_addr  = base;
    31  	info.dlpi_name  = "/proc/self/exe";
    32  	info.dlpi_phdr  = (void *)aux[AT_PHDR];
    33  	info.dlpi_phnum = aux[AT_PHNUM];
    34  	info.dlpi_adds  = 0;
    35  	info.dlpi_subs  = 0;
    36  	if (tls_phdr) {
    37  		info.dlpi_tls_modid = 1;
    38  		info.dlpi_tls_data = (void *)(base + tls_phdr->p_vaddr);
    39  	} else {
    40  		info.dlpi_tls_modid = 0;
    41  		info.dlpi_tls_data = 0;
    42  	}
    43  	return (callback)(&info, sizeof (info), data);
    44  }
    45  
    46  weak_alias(static_dl_iterate_phdr, dl_iterate_phdr);