[uClibc]strange stack behavior

Mark and Janice Juszczec juszczec at hotmail.com
Tue Feb 11 23:09:49 UTC 2003


Hi folks

I threw all kinds of debugging info into my kernel and ldso/ldso/ldso.c

I think my kernel puts the stack together differently than uClibc expects.  
Here's my evidence; can folks who know about kernel and uClibc internals 
tell me if I'm way off base?

In kernel/fs/binfmt_elf.c create_elf_tables I added printk's that dump the 
parms to NEW_AUX_ENT as hex.

The original code:
/*
* Put the ELF interpreter info on the stack
*/
#define NEW_AUX_ENT(nr, id, val) \
  __put_user ((id), sp+(nr*2)); \
  __put_user ((val), sp+(nr*2+1)); \

  sp -= 2;
  NEW_AUX_ENT(0, AT_NULL, 0);
  if (k_platform) {
   sp -= 2;
   NEW_AUX_ENT(0, AT_PLATFORM,
               (elf_addr_t)(unsigned long) u_platform);
  }
  sp -= 2;
  NEW_AUX_ENT(0, AT_HWCAP, hwcap);

  if (exec) {
   sp -= 11*2;

   NEW_AUX_ENT(0, AT_PHDR, load_addr + exec->e_phoff);
   NEW_AUX_ENT(1, AT_PHENT, sizeof (struct elf_phdr));
   NEW_AUX_ENT(2, AT_PHNUM, exec->e_phnum);
   NEW_AUX_ENT(3, AT_PAGESZ, ELF_EXEC_PAGESIZE);
   NEW_AUX_ENT(4, AT_BASE, interp_load_addr);
   NEW_AUX_ENT(5, AT_FLAGS, 0);
   NEW_AUX_ENT(6, AT_ENTRY, load_bias + exec->e_entry);
   NEW_AUX_ENT(7, AT_UID, (elf_addr_t) current->uid);
   NEW_AUX_ENT(8, AT_EUID, (elf_addr_t) current->euid);
   NEW_AUX_ENT(9, AT_GID, (elf_addr_t) current->gid);
   NEW_AUX_ENT(10, AT_EGID, (elf_addr_t) current->egid);
  }
#undef NEW_AUX_ENT

I get the following messages at boot:

0a AT_NULL=0 0
0c AT_HWCAP=16 hwap=0
0d AT_PHDR=3 40000+34=400034
1 AT_PHENT=4 sizef (struct elf_phr)=20
2 AT_PHNUM=5 exec>e_phnum=6
3 AT_PAGESZ=6 ELFEXEC_PAGESIZE=100
4 AT_BASE=7 inter_load_addr=0
5 AT_FLAGS=8 0
6 AT_ENTRY=0 40300+4030e0=400034
7 AT_UID=11 (elf_ddr_t)current->ud=0
8 AT_EUID=12 (elfaddr_t)current->uid=0
9 AT_GID=13 (elf_ddr_t)current->gd=0
a AT_EGID=14 (elfaddr_t)current->gid=0

0a,0c & 0d refer to the 1st, 3rd and 4th NEW_AUX_ENT(0,

The remainder refer to NEW_AUX_ENT(1 thru NEW_AUX_ENT(10

I'm printing out the AT constants in decimal and the remaining NEW_AUX_ENT 
parms in hex.  In the places where the parm is a sum, I print out the values 
of the addends as well.

So stuff is getting on the stack.

In ldso/ldso/ldso.c LD_BOOT I knew at
header = (elfhdr *) auxvt[AT_BASE].a_un.a_ptr;
header was getting 0x00

I threw in a bunch of SEND_STDERR to see where things went bad:

SEND_STDERR("ldso.c LD_BOOT start\n");
if(args==0){
  SEND_STDERR("args == 0\n");
}
else{
  SEND_STDERR("args != 0\n");
}
GET_ARGV(aux_dat, args);
SEND_STDERR("after GET_ARGV\n");
if ((*aux_dat)){
  SEND_STDERR("aux_dat has value\n");
}
else{
  SEND_STDERR("aux_dat DOES NOT HAVE value\n");
}

#if defined (__arm__) || defined (__mips__)
aux_dat += 1;
if ((*aux_dat)){
  SEND_STDERR("at 1 aux_dat has value\n");
}
else{
  SEND_STDERR("at 1 aux_dat DOES NOT HAVE value\n");
}
#endif
argc = *(aux_dat - 1);
argv = (char **) aux_dat;
aux_dat += argc;	/* Skip over the argv pointers */
aux_dat++;		/* Skip over NULL at end of argv */
if ((*aux_dat)){
   SEND_STDERR("at 2 aux_dat has value\n");
}
else{
   SEND_STDERR("at 2 aux_dat DOES NOT HAVE value\n");
}

At boot time, I get:

ldso.c LD_BOOT start
args != 0
after GET_ARGV
aux_dat has value
at 1 aux_dat has value
at 2 aux_dat DOES NOT HAVE value

Based on the information, does my screwed up stack idea make sense?  Does 
anyone have any advice about where to look in the kernel code to figure out 
how it assembles a stack?

Sorry for the long post.

Mark

_________________________________________________________________
Add photos to your messages with MSN 8. Get 2 months FREE*.  
http://join.msn.com/?page=features/featuredemail




More information about the uClibc mailing list