lwip-users
[Top][All Lists]
Advanced

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

RE: [lwip-users] Problem With dns.c Using 32-Bit Compilers


From: Tamas Somogyi
Subject: RE: [lwip-users] Problem With dns.c Using 32-Bit Compilers
Date: Fri, 29 Aug 2008 10:18:49 +0100

Hi,

Reading this topic, it seems that the problem is the direct byte-stream
access through typed (struct) pointers. However it is based on two
independent issues:
1. Pointer conversion
2. Struct member alignment

We use TI's Code Composer Studio. Even if it is a scrappy compiler, it
is C++ conformant, because the C++ standard says:
"[...] A pointer to an object can be explicitly converted to a pointer
to an object of different type.65) Except that converting an rvalue of
type "pointer to T1" to the type "pointer to T2" (where T1 and T2 are
object types and where the alignment requirements of T2 are no stricter
than those of T1) and back to its original type yields the original
pointer value, the result of such a pointer conversion is unspecified.
[...]"
C (C99) standard mentions alignment requirement for types as well.
It means, that if we'd like to write "portable" code, we can forget
{char* pch=...; u16_t* p16 = (u16_t*)pch;} conversions, because we don't
know the alignment requirement for u16_t (which is at least 2 on our
platform, so greater than the alignment of char=1).

And there's no universal way to control the struct member alignment
either (like specifying /Zp1 in MSVC).

My conclusion is that there's no standard way to directly access typed
values in byte-stream.

So the solution is writing get/set code for byte-copying data from/to
the stream to the variable. It can be done either on (A) member-level or
(B) on struct-level, like this (using Alain's sample):

(A)
#define OFS_DNS_ANSWER_TTL 4
#define get_dns_answer_ttl(p,a) memcpy(&a,
((char*)p)+OFS_DNS_ANSWER_TTL, sizeof(a));
#define set_dns_answer_ttl(p,a) memcpy(((char*)p)+OFS_DNS_ANSWER_TTL,
&a, sizeof(a));
- where 'a' is an aligned (local) variable of the corresponding type.
- supposing that alignment req for char is 1 on all supported platform
according to Jifl [1].

(B)
void dns_answer_load_from_stream(char* p, struct dns_answer* s)
{
  memcpy(&(s->type), p, sizeof(s->type));
  p+=sizeof(s->type);
  memcpy(&(s->class), p, sizeof(s->class));
  p+=sizeof(s->class);
  ...
}
- and similar for dns_answer_save_to_stream(...) in the opposite
direction.
- where 's' is aligned variable.

These routines can also be enriched with endian conversion.
My preference is (B) as it is more encapsulated and no need to define
offsets which looks not so nice having #define-dependent optional
members.

Best Regards, 
Tamas

 

-----Original Message-----
From: address@hidden
[mailto:address@hidden On
Behalf Of Alain M.
Sent: 29 August 2008 01:15
To: Mailing list for lwIP users
Subject: Re: [lwip-users] Problem With dns.c Using 32-Bit Compilers -
Email found in subject


Jonathan Larmour escreveu:
> 
> They are only aligned according to their type. For char, that means 
> 8-bit alignment[1].

hum, bad... and I remember of a few parameters in headers that are in 
the middle 2 bytes :(

A geneal purpose copy-one-byte-at-a-time to and from a buffer would then

be the only quasi-portable implementation. If, as I understood, you 
implemented something like that for 16bits, it could be available in 
some fashion... I see a lot of waste of time in lwip on small thinks 
like that :(

If it got implemented in some modular way, then users could implemnt 
optimizations for each architecture, and that be shared again :)

Alain



_______________________________________________
lwip-users mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/lwip-users




reply via email to

[Prev in Thread] Current Thread [Next in Thread]