Hi all,
I want to open an old issue with the bitfields used in some struct which
is shared between the core and the modules. It causes strange problems
if using different compilers for NetWare target builds, e.g. when
compiling some own or 3rd party modules designed for Apache. I still
hope that other compilers than CodeWarrior from Metrowerks will be
supported to build the Apache webserver for NetWare. I've succeeded with
build of Apache 2.0 using the GNU utilities (binutils, gcc) already, and
Watcom (now OpenWatcom) is also an alternative, I think.
Problem: There is a significant difference in implementation of the
bitfields - gcc uses the smallest amount of bytes to store whole
bitfield (three bits used here, so one byte allocated - i386, Linux,
NetWare, ...); size of the bitfield with CW and Watcom is dependent on
base type (e.g. char bf:1, small bf:1, ...; gcc is ignoring the base type).
A structure affected is defined in srclib/apr-util/include/apr_uri.h:
...
/**
* A structure to encompass all of the fields in a uri
*/
struct apr_uri_t {
...
/** has the structure been initialized */
unsigned is_initialized:1;
/** has the DNS been looked up yet */
unsigned dns_looked_up:1;
/** has the dns been resolved yet */
unsigned dns_resolved:1;
};
...
This struct is used within a request_rec struct defined in include/httpd.h:
...
/** A structure that represents the current request */
struct request_rec {
...
apr_uri_t parsed_uri;
/* Various other config info which may change with .htaccess files
* These are config vectors, with one void* pointer for each module
* (the thing pointed to being the module's business).
*/
/** Options set in config files, etc. */
struct ap_conf_vector_t *per_dir_config;
/** Notes on *this* request */
struct ap_conf_vector_t *request_config;
/**
* a linked list of the configuration directives in the .htaccess files
* accessed by this request.
* N.B. always add to the head of the list, _never_ to the end.
* that way, a sub request's list can (temporarily) point to a parent's
list
*/
const struct htaccess_result *htaccess;
/** A list of output filters to be used for this request */
struct ap_filter_t *output_filters;
/** A list of input filters to be used for this request */
struct ap_filter_t *input_filters;
/** A flag to determine if the eos bucket has been sent yet */
int eos_sent;
/* Things placed at the end of the record to avoid breaking binary
* compatibility. It would be nice to remember to reorder the entire
* record to improve 64bit alignment the next time we need to break
* binary compatibility for some other reason.
*/
};
...
So, any accesses below "parsed_uri" are affected by the issue, if
running mixed core/modules compiled with gcc/Watcom/CW (CW is
additionaly affected by some weird alignment issue, so also incompatible
with Watcom and gcc, but it is another problem). There is no problem, if
the core and all modules are compiled with only one compiler, of course.
I suggest to not use the bitfields in this struct anymore, but use some
single element (char type) instead and use some constantants defined in
apr_uri.h file (or elsewhere) to access individual bits. It is still
extendable, but not sure for alignment on all platforms and targets (it
must be tested here, of course). The second way is to change the base
type for "bits" from "unsigned" to "unsigned char", but it was rejected
for Apache 1.3 when I proposed this, so I don't expect that it will be
commited in version 2.0...
I found that the bitfield used in affected structure is not practically
used in the sources, so I think that it could be easily rearranged here
- only one reference from srclib/apr-util/uri/apr_uri.c found:
...
APU_DECLARE(int) apr_uri_parse(apr_pool_t *p, const char *uri,
apr_uri_t *uptr)
{
...
memset (uptr, '\0', sizeof(*uptr));
uptr->is_initialized = 1;
...
}
...
Thanks,
Pavel Novy