uint32_t definition issues??

Kevin Day thekevinday at gmail.com
Fri Sep 26 22:59:59 UTC 2008


On Fri, Sep 26, 2008 at 5:09 PM, Rob Landley <rob at landley.net> wrote:
> On Friday 26 September 2008 14:37:14 Kevin Day wrote:
>> While looking into the dlclose issue, I ran into this problem that I
>> never noticed before.
>>
>> I got this warning:
>> ../ldso/dl-hash.c:142: warning: pointer targets in passing argument 1
>> of '_dl_elf_hash' differ in signedness
>>
>> My Research (uClibc 0.9.28.3):
>> include/bits/elfclass.h:14:typedef uint32_t Elf_Symndx;
>> ldso/ldso/dl-hash.c:60:static inline Elf_Symndx _dl_elf_hash(const
>> unsigned char *name)
>> ldso/ldso/dl-hash.c:142:        elf_hash_number = _dl_elf_hash(name);
>> ldso/ldso/dl-hash.c:138:        unsigned long elf_hash_number, hn;
>>
>> Here, _dl_elf_hash returns a "uint32_t" and elf_hash_number, is an
>> "unsigned long".
>>
>> Looking up uint32_t on the web, i get:
>> typedef unsigned long int uint32_t
>> from: http://linux.die.net/man/3/uint32_t
>>
>> Which means that the usage of unsigned long in replacement of uint32_t
>> "should" work.
>>
>> However, looking on my /usr/include/stdint.h, i see:
>> #ifndef __uint32_t_defined
>> typedef unsigned int            uint32_t;
>> # define __uint32_t_defined
>> #endif
>>
>> This means that uint32_t can at any point be defined as an "unsigned
>> int" and an "unsigned long" depending on whether __uint32_t_defined
>> was defined before the stdint.h is included.
>
> uint32_t should alwasy be an unsigned int on Linux, due to the LP64 standard.
>
> In fact, on Linux with gcc, int is always 32 bits, long long is always 64
> bits, and long is the same size as a pointer (32 bits on x86, 64 bits on
> x86_64).
>
> Int is always 32 bits, long long is always 64 bits.
>
>
> The LP64 standard (which Linux and MacOS X both implement):
>  http://www.unix.org/whitepapers/64bit.html
> Rationale for said standard:
>  http://www.unix.org/version2/whatsnew/lp64_wp.html
>
> And for your entertainment, the insane legacy reasons windows is broken:
>  http://blogs.msdn.com/oldnewthing/archive/2005/01/31/363790.aspx
Whats a windows?

>
>> Furthermore, the fact that "unsigned long" is being used in place of
>> "uint32_t" is dangerous if some header defines uint32_t as something
>> other than "unsigned long" (which is what happened here).
>
> No, copying uint32_t is into an unsigned long isn't dangerous.  This should
> never change the value, because it can always fit.  Wasteful perhaps, but not
> dangerous.

My mind was on the inconsistency portion.

In the case of  _dl_elf_hash, there seems to be the following:
"static inline Elf_Symndx _dl_elf_hash(const char *name)"
So it returns Elf_Symndx which is uint32_t which is unsigned int

Inside the function hash is defined as unsigned long and is then returned.

The problem is I do not know how the function is supposed to work to
know whether or not using an unsigned long and then truncating it to
an unsigned int is necessary.
What I do know is based on different parts of the code I was looking
at and that website I was using, there is enough inconsistency for me
to question what is going on with that data type.

_dl_elf_hash gets a hash, stores it in an unsigned long, returns an
unsigned int to a function that will then store this unsigned int into
an unsigned long.

Thus, the question marks in the e-mail title.



>
> What, exactly, is the issue?  The warning you gave was about a _sign_
> mismatch, not about a size mismatch.  (You only get a warning about a size
> mismatch if you try to typecast between point and int on a 64 bit platform,
> which doesn't work.)
>
> Rob
>

Sorry, the warning was what made me look at the function and notice
the inconsistency with the data types.
The problem that triggered the warning was that the _dl_elf_hash(const
unsigned char *) is being passed a signed char *.

-- 
Kevin Day



More information about the uClibc mailing list