Re: inline asm question(s)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>>>>> "Borislav" == Borislav Petkov <petkov@uni-muenster.de> writes:

Borislav> Hi there people,
Borislav> I'm trying to figure out for several days now how the following functions:

Borislav> <from include/asm-i386/thread_info.h>
Borislav>  86 /* how to get the thread information struct from C */
Borislav>  87 static inline struct thread_info *current_thread_info(void)
Borislav>  88 {
Borislav>  89         struct thread_info *ti;
Borislav>  90         __asm__("andl %%esp,%0; ":"=r" (ti) : "" (~(THREAD_SIZE - 1)));
Borislav>  91         return ti;
Borislav>  92 }

Borislav> I've read several tutorials on inline asm but what is peculiar here is, that 
Borislav> the input operand's constraint is "" (nothing) 

  What version of the kernel is that? There's no such thing in 2.6.6
and both gcc 3.3 and gcc 3.5 report an error compiling your example.
The constraint must be "0", so initially the constant is loaded into a
register and the result is obtained in the same register ("0" means
"the same constraint as the one of operand 0").

Borislav> I also have another question:

Borislav> <from include/linux/kernel.h>
Borislav> 203 /**
Borislav> 204  * container_of - cast a member of a structure out to the containing 
Borislav> structure
Borislav> 205  *
Borislav> 206  * @ptr:        the pointer to the member.
Borislav> 207  * @type:       the type of the container struct this is embedded in.
Borislav> 208  * @member:     the name of the member within the struct.
Borislav> 209  *
Borislav> 210  */
Borislav> 211 #define container_of(ptr, type, member) ({                      \
Borislav> 212         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
Borislav> 213         (type *)( (char *)__mptr - offsetof(type,member) );})

Borislav> I can't understand the ((type *)0) part - type is passed as an argument and it 
Borislav> is some struct pointer but the trailing 0 ... what does it actually do?

  No type is passed as an argument as this is a macro.  The syntactic
construct "typeof (expr)" is parsed as a type, the type of the
expression (surprise).  For example:

   "int a; typeof (a) b;" - "a" and "b" have the same type, "int"

   "struct S { int x, y; } a; typeof (a.x) b;" - "b" has type "int"

   "((struct S *)0)" is an expression of type "pointer to S", thus
   "((struct S *)0)->x" is an expression of type "int", thus
   "typeof (((struct S *)0)->x) b" declares an interer variable "b"

Borislav> offsetof is similar:

Borislav> <from include/linux/stddef.h>
Borislav>  12 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

  "(type *)0" is simply an idiom for obtaining a fictitious object out
of the thin air. Compare to

"struct S *a; ptrdiff_t off = (char *)&a->y - (char *)a"

  Obviously the value of "off" is the same no matter the value of "a",
so we can just as well use "0", thus obtaining

 "(char *) &((struct S *)0)->a - (char *)0".

  Next we remove the gratuitous subtraction of zero, not having
subtraction we don't need any more the cast to "char *", hence

"&((struct S *)0)->a"

and to make it reusable for any member of any structured type we make
it into a macro

#define offsetoff (S,a) (&((S *) 0)->a)

QED :)

~velco

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux