Skip to content

argv alignment

1、argv不保证alignment

2、必要的时候,需要使用memcpy来将它load到一个aligned variable中

stackoverflow C - memory align argv?

I am on Linux, coding in C and tried to play with the align attribute for argv variables, but with no luck :

How could we cause the argv arguments (each of it) to be aligned to a defined boundary, say 16 bits, without copying it first to an aligned variable, via memcpy or alternatives ?

Is it even possible ?

A

It is not possible. The align attribute tells the compiler how to align structures for which it generates code and data. It also tells the compiler about the actual alignment of extern structures and data generated by other code.

The argv arguments are supplied by the C startup code or the OS directly. No assumptions should be made about their alignment beyond the implicit self alignment of the pointer array. You cannot change that with compiler attributes, not is it advisable to force the compiler to make other assumptions.

uwaterloo passing arguments

To pass arguments (argv) to a user program, you will have to load the arguments into the program's address space. In addition to the argument strings themselves, you have to create the argv array in the user program's address space - argv is an array of pointers to the actual argument strings.

Whenever you are loading data into an address space, you must ensure that it is properly aligned. Otherwise, the application will cause addressing exceptions when it tries to access the data. 4-byte items, like character pointers, must start at an address that is divisible by 4. So, it would be OK to start your argv array at an address like 0x7fffff08, but your application will run in to alignment problems if argv starts at an address like 0x7fffff09 or 0x7fffff0a, since those addresses are not divisible by 4. Characters are only 1 byte long, so there are no alignment issues. Your argument strings, which are character arrays, can start at any address.

A related constraint is that the stack pointer should always start at an address that is 8-byte aligned (evenly divisible by 8). This is because the largest data types that require alignment (and which might be pushed onto a stack) are 8 bytes long, e.g., a double-precision floating point value.

Make sure that you understand how argv and argc are supposed to work before you try implementing argument passing. As an example, consider the testbin/tail application, which expects two arguments. The main() function of tail looks like this:

int
main(int argc, char **argv)
{
    int file;

    if (argc < 3) {
        errx(1, "Usage: tail  ");
    }
    file = open(argv[1], O_RDONLY);
    if (file < 0) {
        err(1, "%s", argv[1]);
    }
    tail(file, atoi(argv[2]), argv[1]);
    close(file);
    return 0;
}

argv is a character pointer pointer - it points to an array of character pointers, each of which points to one of the arguments. For example, if the tail program is invoked from the kernel command line like this:

OS/161 kernel [? for menu]: p testbin/sort foo 100

Then the argv and argc variables should be set up as illustrated in the following illustration:

img A detailed description of the expected set up of argv and argc can be found in the man page for the execv system call.