blob: 07bde8731250d6bc8b20230a9474a2062f7fca00 [file] [log] [blame]
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Charmonizer/Probe/Memory.h"
#include "Charmonizer/Core/Compiler.h"
#include "Charmonizer/Core/HeaderChecker.h"
#include "Charmonizer/Core/ConfWriter.h"
#include "Charmonizer/Core/Util.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* Probe for alloca() or equivalent. */
static void
chaz_Memory_probe_alloca(void);
void
chaz_Memory_run(void) {
chaz_ConfWriter_start_module("Memory");
chaz_Memory_probe_alloca();
chaz_ConfWriter_end_module();
}
static void
chaz_Memory_probe_alloca(void) {
static const char alloca_code[] =
"#include <%s>\n"
CHAZ_QUOTE( int main() { )
CHAZ_QUOTE( void *foo = %s(1); )
CHAZ_QUOTE( return 0; )
CHAZ_QUOTE( } );
chaz_CFlags *temp_cflags = chaz_CC_get_temp_cflags();
int has_alloca = false;
char code_buf[sizeof(alloca_code) + 100];
{
/* OpenBSD needs sys/types.h for sys/mman.h to work and mmap() to be
* available. Everybody else that has sys/mman.h should have
* sys/types.h as well. */
const char *mman_headers[] = {
"sys/types.h",
"sys/mman.h",
NULL
};
if (chaz_HeadCheck_check_many_headers((const char**)mman_headers)) {
chaz_ConfWriter_add_def("HAS_SYS_MMAN_H", NULL);
}
}
/* Under GCC, alloca is a builtin that works without including the
* correct header, generating only a warning. To avoid misdetection,
* disable the alloca builtin temporarily. */
if (chaz_CC_gcc_version_num()) {
chaz_CFlags_append(temp_cflags, "-fno-builtin-alloca");
}
/* Unixen. */
sprintf(code_buf, alloca_code, "alloca.h", "alloca");
if (chaz_CC_test_link(code_buf)) {
has_alloca = true;
chaz_ConfWriter_add_def("HAS_ALLOCA_H", NULL);
chaz_ConfWriter_add_def("alloca", "alloca");
}
if (!has_alloca) {
sprintf(code_buf, alloca_code, "stdlib.h", "alloca");
if (chaz_CC_test_link(code_buf)) {
has_alloca = true;
chaz_ConfWriter_add_def("ALLOCA_IN_STDLIB_H", NULL);
chaz_ConfWriter_add_def("alloca", "alloca");
}
}
/* Windows. */
if (!has_alloca) {
sprintf(code_buf, alloca_code, "malloc.h", "alloca");
if (chaz_CC_test_link(code_buf)) {
has_alloca = true;
chaz_ConfWriter_add_def("HAS_MALLOC_H", NULL);
chaz_ConfWriter_add_def("alloca", "alloca");
}
}
if (!has_alloca) {
sprintf(code_buf, alloca_code, "malloc.h", "_alloca");
if (chaz_CC_test_link(code_buf)) {
chaz_ConfWriter_add_def("HAS_MALLOC_H", NULL);
chaz_ConfWriter_add_def("alloca", "_alloca");
}
}
chaz_CFlags_clear(temp_cflags);
}