I use polybench kernels. In polybench.c, code has a line as follows:
int ret = posix_memalign (&new, 32, num);
This line makes problem with lli interpreter. I tries to use malloc instead, but I have the same error
LLVM ERROR: Tried to execute an unknown external function: posix_memalign
Is there any other function could be used without having this problem?
You will not be surprised to hear that posix_memalign() is standardized as part of POSIX, not part of standard C. As such, providing that function is not a requirement on conforming C implementations. On the other hand, as part of POSIX, it is widely available.
malloc() promises to return a pointer to memory aligned properly for an object of any type. I'm not sure why you want to ensure an even stronger alignment requirement, but your next best bet for doing so is the aligned_alloc() function, which is standard C since C2011. If your C library conforms to C2011, then you can replace your posix_memalign() call with
#include <stdlib.h>
#include <errno.h>
// ...
new = aligned_alloc(32, num);
int ret = (new ? 0 : errno);
If you don't have aligned_alloc(), either, then your implementation may provide other alternatives, but none of them are standard.
Related
I have been reading about the strict aliasing rule for a while, and I'm starting to get really confused. First of all, I have read these questions and some answers:
strict-aliasing-rule-and-char-pointers
when-is-char-safe-for-strict-pointer-aliasing
is-the-strict-aliasing-rule-really-a-two-way-street
According to them (as far as I understand), accessing a char buffer using a pointer to another type violates the strict aliasing rule. However, the glibc implementation of strlen() has such code (with comments and the 64-bit implementation removed):
size_t strlen(const char *str)
{
const char *char_ptr;
const unsigned long int *longword_ptr;
unsigned long int longword, magic_bits, himagic, lomagic;
for (char_ptr = str; ((unsigned long int) char_ptr
& (sizeof (longword) - 1)) != 0; ++char_ptr)
if (*char_ptr == '\0')
return char_ptr - str;
longword_ptr = (unsigned long int *) char_ptr;
himagic = 0x80808080L;
lomagic = 0x01010101L;
for (;;)
{
longword = *longword_ptr++;
if (((longword - lomagic) & himagic) != 0)
{
const char *cp = (const char *) (longword_ptr - 1);
if (cp[0] == 0)
return cp - str;
if (cp[1] == 0)
return cp - str + 1;
if (cp[2] == 0)
return cp - str + 2;
if (cp[3] == 0)
return cp - str + 3;
}
}
}
The longword_ptr = (unsigned long int *) char_ptr; line obviously aliases an unsigned long int to char. I fail to understand what makes this possible. I see that the code takes care of alignment problems, so no issues there, but I think this is not related with the strict aliasing rule.
The accepted answer for the third linked question says:
However, there is a very common compiler extension allowing you to cast properly aligned pointers from char to other types and access them, however this is non-standard.
Only thing comes to my mind is the -fno-strict-aliasing option, is this the case? I could not find it documented anywhere what glibc implementors depend on, and the comments somehow imply that this cast is done without any concerns like it is obvious that there will be no problems. That makes me think that it is indeed obvious and I am missing something silly, but my search failed me.
In ISO C this code would violate the strict aliasing rule. (And also violate the rule that you cannot define a function with the same name as a standard library function). However this code is not subject to the rules of ISO C. The standard library doesn't even have to be implemented in a C-like language. The standard only specifies that the implementation implements the behaviour of the standard functions.
In this case, we could say that the implementation is in a C-like GNU dialect, and if the code is compiled with the writer's intended compiler and settings then it would implement the standard library function successfully.
When writing the aliasing rules, the authors of the Standard only considered forms that would be useful, and should thus be mandated, on all implementations. C implementations are targeted toward a variety of purposes, and the authors of the Standard make no attempt to specify what a compiler must do to be suitable for any particular purpose (e.g. low-level programming) or, for that matter, any purpose whatsoever.
Code like the above which relies upon low-level constructs should not be expected to run on compilers that make no claim of being suitable for low-level programming. On the flip side, any compiler which can't support such code should be viewed as unsuitable for low-level programming. Note that compilers can employ type-based aliasing assumptions and still be suitable for low-level programming if they make a reasonable effort to recognize common aliasing patterns. Some compiler writers are very highly invested in a view of code which fits neither common low-level coding patterns, nor the C Standard, but
anyone writing low-level code should simply recognize that those compilers'
optimizers are unsuitable for use with low-level code.
The wording of the standard is actually a bit more weird than the actual compiler implementations: The C standard talks about declared object types, but the compilers only ever see pointers to these objects. As such, when a compiler sees a cast from a char* to an unsigned long*, it has to assume that the char* is actually aliasing an object with a declared type of unsigned long, making the cast correct.
A word of caution: I assume that strlen() is compiled into a library that is later only linked to the rest of the application. As such, the optimizer does not see the use of the function when compiling it, forcing it to assume that the cast to unsigned long* is indeed legit. If you called strlen() with
short myString[] = {0x666f, 0x6f00, 0};
size_t length = strlen((char*)myString); //implementation now invokes undefined behavior!
the cast within strlen() is undefined behavior, and your compiler would be allowed to strip pretty much the entire body of strlen() if it saw your use while compiling strlen() itself. The only thing that allows strlen() to behave as expected in this call is the fact, that strlen() is compiled separately as a library, hiding the undefined behavior from the optimizer, so the optimizer has to assume the cast to be legit when compiling strlen().
So, assuming that the optimizer cannot call "undefined behavior", the reason why casts from char* to anything else are dangerous, is not aliasing, but alignment. On some hardware, weird stuff starts happening if you try to access a misaligned pointer. The hardware might load data from the wrong address, raise an interrupt, or just process the requested memory load extremely slowly. That is why the C standard generally declares such casts undefined behavior.
Nevertheless, you see that the code in question actually handles the alignment issue explicitly (the first loop that contains the (unsigned long int) char_ptr & (sizeof (longword) - 1) subcondition). After that, the char* is properly aligned to be reinterpreted as unsigned long*.
Of course, all of this is not really compliant with the C standard, but it is compliant with the C implementation of the compiler that this code is meant to be compiled with. If the gcc people modified their compiler to act up on this bit of code, the glibc people would just complain about it loud enough so that the gcc will be changed back to handle this kind of cast correctly.
At the end of the day, standard C library implementations simply must violate strict aliasing rules to work properly and be efficient. strlen() just needs to violate those rules to be efficient, the malloc()/free() function pair must be able to take a memory region that had a declared type of Foo, and turn it into a memory region of declared type Bar. And there is no malloc() call inside the malloc() implementation that would give the object a declared type in the first place. The abstraction of the C language simply breaks down at this level.
The underlying assumption is probably that the function is separately compiled, and not available for inlining or other cross function optimizations. This means that no compile time information flows inside or outside the function.
The function doesn't try to modify anything through a pointer, so there is no conflict.
I am cleaning up warnings and found the following error:
warning: assignment makes pointer from integer without a cast buf = aligned_alloc(ALIGN_VALUE,BUF_SZ);
This call is at the very top of the function, essentially:
char* buf;
buf = aligned_alloc(ALIGN_VALUE,BUF_SZ);
It is my understanding that aligned_alloc returns a void *. If cast the return from aligned_alloc to a (char *) I get:
warning: cast to pointer from integer of different size [-Wint-to-pointer-ast] buf = (char*)aligned_alloc(ALIGN_VALUE,BUF_SZ);
The only thing that seems to fix it is
buf = (char*)(uintptr_t)aligned_alloc(ALIGN_VALUE,BUF_SZ);
I have made sure that I am including stdlib.h to avoid implicit declarations referred to in another post. I assumed the cast to char pointer should have resolved this. I am not understanding why the cast to uintptr_t resolves it when void* and uintptr_t are equivalent as far as I understand.
The following is an example of the structure of the file
#include <syslog.h>
#include <linux/fs.h>
#include <linux/hdreg.h>
#include <sys/ioctl.h>
#include <sys/mman.h> // mmap
#include <sys/time.h>
#include <unistd.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <stdio.h>
#include <pthread.h>
void* ax_read_thread(void* arg)
{
fprintf(stderr, "read thread started\n");
ax_priv* priv = (ax_priv*)arg;
char* buf;
uint32_t count = 0;
size_t len, transferred = 0;
buf = (char*)(uintptr_t)aligned_alloc(ALIGN_VALUE,BUF_SZ);
if (buf == NULL){
fprintf(stderr, "Aligned alloc failed\n");
pthread_exit(NULL);
}
while(1){
//do things
}
}
Thank you for all of the help. I see now that the warning is a result of not indicating the proper version when invoking the compiler.
This answer largely summarizes the observations and suggestions from the comments thread, including mine and many others', and wraps them in a bit of expository prose.
In the first place, the problem arises because when you build your program with your present toolchain, in its current form, the aligned_alloc() function is not explicitly declared. In the absence of a declaration, the compiler is inferring its signature: it guesses that the function returns int, and that its parameter types are those obtained via the default argument promotions applied to the types of the actual arguments. The compiler then warns you that those inferences -- especially the return type -- seem inconsistent with how you're actually using the function.
The solution, supposing that the function is available in your C library at all, is to ensure that a correct prototype is provided. You could insert the prototype manually, but you shouldn't. Since it's a standard library function, you should get its declaration from the appropriate header, which for this function is stdlib.h.
HOWEVER, this particular function is new in C11, and evidently you're using a version of GCC that defaults to compiling for an earlier standard. Glibc supports that in part by protecting functions that are new in C11 with a feature-test macro, _ISOC11_SOURCE. This is for your protection: in the event that you're building code written for an earlier standard, and that code happens to provide is own function with the same name as one of C11's new functions, the feature-test system prevents you from suffering a name collision.
If you are indeed writing for C11, as seems to be the case, and if your version of gcc has an option to support C11 (i.e. -std=c11 and/or -std=gnu11), then compiling with that option enabled is your best alternative. If you happen to have a version of Glibc that provides aligned_alloc() but not a version of the compiler that supports a C11 mode, then you have the alternative of manually ensuring that the needed feature test macro is defined to the compiler before any of the standard headers are included. You can do that via a #define at the top of your source file, or via a command-line option to the compiler (e.g. -D_ISOC11_SOURCE=1).
Glibc does have aligned_alloc() from at least version 2.17 (but I think from as early as 2.16). GCC does have a C11 mode since at least version 4.8. If your versions of these components are at least that recent, then it should be sufficient to add the option -std=c11 (to omit GNU extensions) or -std=gnu11 (to support GNU extensions) to your compilation command:
gcc -std=c11 my_program.c
I'm trying to fix an undefined reference to memcpy_s() error. I've included string.h in my file and the memcpy() function works okay, and I've also tried including memory.h. I'm on x64 Windows 7 and using gcc 4.8.1 to compile.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void doMemCopy(char* buf, size_t buf_size, char* in, int chr) {
memcpy_s(buf, buf_size, in, chr);
}
memory for buf has been allocated in the main function, which calls doMemCpy(buf, 64, in, bytes). in is a string read from standard input
Exact error from cmd terminal:
undefined reference to "memcpy_s" collect2.exe: error: ld returned 1 exit status
GCC 4.8 does not include the function memcpy_s, or any of the other _s bounds checking functions as far as I can tell. These functions are defined in ISO 9899:2011 Annex K and they are optional to implement. Before using them you must check if __STDC_LIB_EXT1__ is defined.
These functions were originally implemented by Microsoft and many parties objected to including them in the standard. I think the main objection is that the error handling that is done by the functions involves a global callback handle that is shared between threads, but they are also quite inefficient.
Further reading is available from Carlos O'Donell and Martin Sebor in Updated Field Experience With Annex K — Bounds Checking Interfaces.
I've never used this, but AFAIK, you need to add
#define __STDC_WANT_LIB_EXT1__ 1
before
#include <string.h>
to use memcpy_s().
Per the standard, is it legal to access data from a function pointer?
Something like:
#include <stdio.h>
int test(){
//
}
int main() {
int (*fp)(void) = &test;
int i=0;
for(i; i<10; ++i)
printf("%x", *(fp+i));
}
Running on ideone, it seems to work - but I'm wondering if it is expected to, or whether it is implementation-defined, and the page may be read-protected by OS?
From C standards perspective, no, it's not.
Annex J in N1570 has a chapter on common extensions:
J.5 Common extensions
The following extensions are widely used in many systems, but are not portable to all
implementations. The inclusion of any extension that may cause a strictly conforming
program to become invalid renders an implementation nonconforming. ...
And then mentions this extension later in J.5.7 Function pointer casts:
A pointer to a function may be cast to a pointer to an object or to void, allowing a
function to be inspected or modified (for example, by a debugger) (6.5.4).
Function pointers are legal by design.
Manipulating pointers yourself is also legal by design, BUT can cause undefined behaviour, including crashing your program.
I tried expanding the loop to 10000 and got a runtime error, propably because memory access was prohibited there.
Is there any reason to use the non-standard bzero() and bcopy() instead of memset() and memcpy() in a Linux environment? I've heard many say that they're better for Linux compilers, but haven't seen any advantages over the standard functions.
Are they more optimized than the standard ones, or do they have any behavioral particularity for which they're preferred?
While bzero and bcopy functions aren't ISO C (the actual standard that I assume you're talking about when referring to them as non-standard), they were a POSIX standard thing, although they pre-dated both ISO and POSIX.
And note that use of the word "were" - these functions were deprecated in POSIX.1-2001 and fianally removed in POSIX.1-2008, in deference to memset, memcpy and memmove. So you're better off using the standard C functions where possible.
If you have a lot of code that uses them and you don't want to have to go and change it all (though you probably should at some point), you can use the following quick substitutions:
// void bzero(void *s, size_t n);
#define bzero(s, n) memset((s), 0, (n))
// void bcopy(const void *s1, void *s2, size_t n);
#define bcopy(s1, s2, n) memmove((s2), (s1), (n))
#include <strings.h>
void bcopy(const void *src, void *dest, size_t n);
Description
The bcopy() function copies n bytes from src to dest. The result is correct, even when both areas overlap.
Conforming to:
4.3BSD, it seems b comes from BSD and it seems deprecated.
Which means bcopy is analogous to memmove() not memcpy() as R.. said at his comment.
Note: strings.h is also distinct from string.h.
Actually nowdays it could be the other way around. You see that because memcpy and memset is included in the standard the compiler will be allowed to assume that function called so does exactly what the standard prescribes. This means that the compiler can replace them with the most efficient way of performing the operation it can figure out. With bcopy and bzero on the other hand the standard does not prescribe any behavior on those so the compiler can't assume anything - which means that the compiler would need to issue an actual function call.
However GCC for example knows about bcopy and bzero if it's built for an OS that have them.