I was using perf top to profile a process which running on arm-linux, and the result shown like below:
4.27% [vectors] [.] 0x00000fc4
3.84% [kernel] [k] _raw_spin_unlock_irqrestore
2.30% [kernel] [k] _raw_spin_unlock_irq
1.94% libc-2.20.so [.] 0x0007c35c
1.91% [vectors] [.] 0x00000fd8
1.56% libGLESv2.so.1.9.6.0 [.] 0x0003a5e0
1.34% libGLESv2.so.1.9.6.0 [.] 0x0003a5cc
0.91% [omapdrm_pvr] [k] _SegmentListInsert
0.87% libpthread-2.20.so [.] 0x0000aee4
0.82% libc-2.20.so [.] 0x00075464
0.76% libc-2.20.so [.] 0x0007767c
0.48% libpthread-2.20.so [.] 0x000094dc
0.46% libv8.so.4 [.] 0x0017a058
0.46% libGLESv2.so.1.9.6.0 [.] 0x0003a420
0.43% [kernel] [k] do_nanosleep
0.41% [kernel] [k] __copy_from_user
0.40% libc-2.20.so [.] 0x0007d8a4
0.40% libpthread-2.20.so [.] 0x00009480
0.39% [kernel] [k] do_vfp
0.39% librender_engine.so [.] 0x004d3ff8
I am wondering what [vectros] may stand for? as I know, it's not a kernel module, however, 0x00000fc4 is a low-end address which should never be used, besides that, 0x00000fc4 seems like the address of arm exception vectors.
any comment is welcomed.
This [vectors] is for arm memory range of vectors page, the name is defined in aarch32_setup_vectors_page function of arch/arm64/kernel/vdso.c
#define AARCH32_VECTORS_BASE 0xffff0000
....
int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
{
...
unsigned long addr = AARCH32_VECTORS_BASE;
static const struct vm_special_mapping spec = {
.name = "[vectors]",
.pages = vectors_page,
};
...
current->mm->context.vdso = (void *)addr;
/* Map vectors page at the high address. */
ret = _install_special_mapping(mm, addr, PAGE_SIZE,
VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC,
&spec);
...
}
and in arch_vma_name of arch/arm/kernel/process.c
/*
* The vectors page is always readable from user space for the
* atomic helpers. Insert it into the gate_vma so that it is visible
* through ptrace and /proc/<pid>/mem.
*/
static struct vm_area_struct gate_vma = {
.vm_start = 0xffff0000,
.vm_end = 0xffff0000 + PAGE_SIZE,
.vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC,
};
...
const char *arch_vma_name(struct vm_area_struct *vma)
{
return is_gate_vma(vma) ? "[vectors]" : NULL;
}
I'm not sure that perf will show correct address for profiling samples in this area, it may be offset inside the section...
Another question about arm's vector page: Vectors page mapping in linux for ARM
"The Exception Vector Table" on arm32 is mapped to 0xffff0000, according to https://doar-e.github.io/blog/2014/04/30/corrupting-arm-evt/
You may check output of cat /proc/self/maps on the platform and dump the page from 0xffff0000 offset with gdb x/1024wx 0xffff0000.
Presentation about newer vdso on arm64 https://blog.linuxplumbersconf.org/2016/ocw/system/presentations/3711/original/LPC_vDSO.pdf
Related
I am trying to create a slice for variable addr from this sample program:
#include <stdio.h>
#include <stdlib.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#define PKT_LEN 8192
int main (int argc, char *argv[]) {
char *pkt = (char *)malloc(PKT_LEN);
uint32_t addr;
int unrelated_var;
struct ethhdr *ehdr = (struct ethhdr *)pkt;
struct iphdr *ihdr = (struct iphdr *)(pkt + sizeof(struct ethhdr));
addr = ihdr->saddr;
return 0;
}
Here is the command I have used to print the slice in the terminal:
frama-c iphdr_issue.c -cpp-extra-args="-I/usr/include, -I/usr/include/x86_64-linux-gnu/" -kernel-msg-key pp -slice-value addr -then-on 'Slicing export' -print
It is generating following output with the mentioned error:
[kernel:pp]
preprocessing with "gcc -E -C -I. -I/users/ashfaqur/.opam/system/share/frama-c/libc -D__FRAMAC__ -D__FC_MACHDEP_X86_32 -I/usr/include -I/usr/include/x86_64-linux-gnu/ -dD -nostdinc -m32 iphdr_issue.c"
[kernel] Parsing iphdr_issue.c (with preprocessing)
[kernel] iphdr_issue.c:16: User Error:
Cannot find field saddr in type struct iphdr
14 struct iphdr *ihdr = (struct iphdr *)(pkt + sizeof(struct ethhdr));
15
16 addr = ihdr->saddr;
^^^^^^^^^^^^^^^^^^^^^^^
17
18 return 0;
[kernel] User Error: stopping on file "iphdr_issue.c" that has errors.
[kernel] Frama-C aborted: invalid user input.
How can I solve this issue?
If you want to use your system's standard headers instead of Frama-C's ones (beware however that there's absolutely no guarantee that Frama-C will be able to parse them, especially the ones that are heavily architecture-dependent), the solution is not to use -cpp-extra-args, but -no-frama-c-stdlib, as in:
frama-c iphdr_issue.c -no-frama-c-stdlib -slice-value addr test.c -then-on "Slicing export" -print
Incidentally, the example you provided gives an empty slice:
/* Generated by Frama-C */
void main(void)
{
return;
}
because Eva complains that you are trying from the uninitialized location ihdr->saddr (presumably because the example is correctly reduced to highlight the parsing error, but a bit too small for slicing to be meaningful).
I've a Cypress BLE module and have compilation problem with IAR.
In "ezsapi.h" are defined this macros:
#ifdef __GNUC__
/* standard GNU C */
#ifdef _WIN32
/* MinGW, Cygwin, TDM-GCC, etc. */
#define __PACKDEF(STRUCTNAME, STRUCTDEF) typedef struct STRUCTDEF __attribute__((__packed__,gcc_struct)) STRUCTNAME
#else
/* generic gcc */
#define __PACKDEF(STRUCTNAME, STRUCTDEF) typedef struct STRUCTDEF __attribute__((__packed__)) STRUCTNAME
#endif
#define ALIGNED __attribute__((aligned(0x4)))
#else
/* Microsoft Visual C++ */
#define __PACKDEF(STRUCTNAME, STRUCTDEF) __pragma(pack(push, 1)) STRUCTDEF __pragma(pack(pop)) STRUCTNAME
#define ALIGNED
#endif
IAR usually use #pragma pack(push,1) and #pragma pack(pop) and I tryed to modify the macro in:
#define __PACKDEF(STRUCTNAME, STRUCTDEF) #pragma(pack(push, 1)) STRUCTDEF #pragma(pack(pop)) STRUCTNAME
With original macros the errors reported is:
ezsapi.h(694) : Error[Pe020]: identifier "pack" is undefined
ezsapi.h(694) : Error[Pe018]: expected a ")" ezsapi.h(694) :
Error[Pe079]: expected a type specifier ezsapi.h(694) : Error[Pe260]:
explicit type is missing ("int" assumed) ezsapi.h(694) : Error[Pe141]:
unnamed prototyped parameters not allowed when body is present
ezsapi.h(694) : Error[Pe130]: expected a "{"
and with my macro the errors reported is:
(69 is the line where the macro is located)
ezsapi.h(69) : Error[Pe052]: expected a macro parameter name
ezsapi.h(69) : Error[Pe052]: expected a macro parameter name
ezsapi.h(694) : Error[Pe020]: identifier "pack" is undefined
ezsapi.h(694) : Error[Pe018]: expected a ")" ezsapi.h(694) :
Error[Pe079]: expected a type specifier ezsapi.h(694) : Error[Pe260]:
explicit type is missing ("int" assumed) ezsapi.h(694) : Error[Pe141]:
unnamed prototyped parameters not allowed when body is present
ezsapi.h(694) : Error[Pe130]: expected a "{"
What's the correct formula for IAR?
What's escaping me?
Thanks.
There are two ways of solving this problem. My suggestion is that you use the __packed type attibute instead of #pragma pack() as this has a more well defined meaning. This, however, needs IAR language extensions to be switched on. If you can't enable language extensions or for some other reason need to use pack-pragma you have to use an alternative pragma syntax to be able to include it in a preprocessor macro. If you use _Pragma("pack(push,1)") and _Pragma("pack(pop)") you macro should work as expected. Definitions of PACKDEF for both alternatives are shown below:
#define PACKDEF(STRUCTNAME, STRUCTDEF) typedef __packed struct STRUCTDEF STRUCTNAME
#define PACKDEF(STRUCTNAME, STRUCTDEF) _Pragma("pack(push,1)") typedef struct STRUCTDEF STRUCTNAME _Pragma("pack(pop)")
I have a deployed kiosk system which mounts an encrypted partition at boot time using crytpsetup and a key file on disk as such:
cryptsetup open --type plain --key-file /root/key.bin /dev/sda3 sda3
This yields a /dev/mapper/sda3 device which I can then mount for data access.
I am moving the key to a smart card and want to open the partition using libcryptsetup so the key is not exposed on the command line. Unfortunately, the only example given in the cryptsetup source is for LUKS.
I have tried to reverse engineer the cryptsetup source to get the correct library calls but have been frustrated by the complexity of the options.
Are there examples of other projects which use the library for plain encryption or perhaps a skeleton of the library calls required to duplicate the actions of the command line invocation?
The basic sequence of the library calls required for duplicating the actions on command line to open an encrypted partition using cryptsetup library will be as follows
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/types.h>
#include <libcryptsetup.h>
int activate_and_check_status(const char *path, const char *device_name)
{
struct crypt_device *cd;
struct crypt_active_device cad;
int r;
/*
* LUKS device activation example.
* It's sequence of sub-steps: device initialization, LUKS header load
* and the device activation itself.
*/
r = crypt_init(&cd, path);
if (r < 0 ) {
printf("crypt_init() failed for %s.\n", path);
return r;
}
/*
* crypt_load() is used to load the LUKS header from block device
* into crypt_device context.
*/
r = crypt_load(cd, /* crypt context */
CRYPT_LUKS1, /* requested type */
NULL); /* additional parameters (not used) */
if (r < 0) {
printf("crypt_load() failed on device %s.\n", crypt_get_device_name(cd));
crypt_free(cd);
return r;
}
/*
* Device activation creates device-mapper devie mapping with name device_name.
*/
r = crypt_activate_by_passphrase(cd, /* crypt context */
device_name, /* device name to activate */
CRYPT_ANY_SLOT,/* which slot use (ANY - try all) */
"foo", 3, /* passphrase */
CRYPT_ACTIVATE_READONLY); /* flags */
if (r < 0) {
printf("Device %s activation failed.\n", device_name);
crypt_free(cd);
return r;
}
printf("LUKS device %s/%s is active.\n", crypt_get_dir(), device_name);
printf("\tcipher used: %s\n", crypt_get_cipher(cd));
printf("\tcipher mode: %s\n", crypt_get_cipher_mode(cd));
printf("\tdevice UUID: %s\n", crypt_get_uuid(cd));
/*
* Get info about active device (query DM backend)
*/
r = crypt_get_active_device(cd, device_name, &cad);
if (r < 0) {
printf("Get info about active device %s failed.\n", device_name);
crypt_deactivate(cd, device_name);
crypt_free(cd);
return r;
}
printf("Active device parameters for %s:\n"
"\tDevice offset (in sectors): %" PRIu64 "\n"
"\tIV offset (in sectors) : %" PRIu64 "\n"
"\tdevice size (in sectors) : %" PRIu64 "\n"
"\tread-only flag : %s\n",
device_name, cad.offset, cad.iv_offset, cad.size,
cad.flags & CRYPT_ACTIVATE_READONLY ? "1" : "0");
crypt_free(cd);
return 0;
}
The API references for luks format, open, activate and deactivate with examples for cryptsetup is available at this link:
cryptsetup API
Can someone explain why the following code yields different results on the second printf if I comment the first printf line or not, in 64 bits?
/* gcc -O0 -o test test.c */
#include <stdio.h>
#include <stdlib.h>
int main() {
char a[20] = {0};
char b = 'a';
int count=-1;
// printf("%.16llx %.16llx\n", a, &b);
printf("%x\n", *(a+count));
return 0;
}
I get the following results for the second printf:
commented: 0
uncommented: 61
Thanks in advance!
iansus
Can someone explain why the following code yields different results on the second printf if I comment the first printf line or not
Your program uses a[-1], and thus exhibits undefined behavior. Anything can happen, and figuring out exactly why one or the other thing happenes is pointless.
The precise reason is that you are reading memory that gets written to by the first printf (when commented in).
I get a different result (which is expected with undefined behavior):
// with first `printf` commented out:
ffffffff
// with it commented in:
00007fffffffdd20 00007fffffffdd1b
ffffffff
You could see where that memory is written to by setting a GDB watchpoint on it:
(gdb) p a[-1]
$1 = 0 '\000'
(gdb) p &a[-1]
$2 = 0x7fffffffdd1f ""
(gdb) watch *(int*)0x7fffffffdd1f
Hardware watchpoint 4: *(int*)0x7fffffffdd1f
(gdb) c
Continuing.
Hardware watchpoint 4: *(int*)0x7fffffffdd1f
Old value = 0
New value = 255
main () at t.c:12
12 printf("%.16llx %.16llx\n", a, &b);
It my case above, the value is written as part of initializing count=-1. That is, with my version of gcc, count is located just before a[0]. But this may depend on compiler version, exactly how this compiler was built, etc. etc.
This might be my misunderstanding of how parsers reduce rather than a potential bug in SQLite's lemon parser. I have been experimenting with simple grammars for a database input file. The database consists of a list of at least one entry sets, things like "commands", or "maps" or...
Here's a grammar that does not work - I have started creating the entry sets and so far all I have is a "command":
database ::= entrylist.
entrylist ::= entrylist entryset.
entrylist ::= entryset.
entryset ::= command.
/* Commands are in the form %command [arguments] \n */
command ::= CMDNAME cmdargs EOL.
cmdargs ::= cmdargs cmdarg.
cmdargs ::= .
cmdarg ::= INTEGER.
cmdarg ::= TEXT.
If I run this with a test program that just feeds in tokens I get:
$ test
Debug: Input 'CMDNAME'
Debug: Shift 'CMDNAME', go to state 3
Debug: Return. Stack=[CMDNAME]
Debug: Input 'INTEGER'
Assertion failed: stateno <= YY_SHIFT_COUNT, file testpar.c, line 513
If I give the entryset an additional alternative:
entryset ::= command.
entryset ::= map.
...
map ::= MAPNAME EOL.
then the whole thing works as expected. I think perhaps you aren't allowed create a situation where a::=b and b::=c. You must have b ::= c | d at the very least. I'd like to understand if this is my mistake in understanding.
Lemon compresses the shift table to remove default actions from the end of the table. Presumably, default actions should be handled elsewhere but they aren't. Your example happens to have default actions so the table is compressed, YY_MAX_SHIFT and YY_SHIFT_COUNT are out of sync, and the assert is triggered.
In lemon.c, around line 4235, you can comment out this line:
while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--;
to prevent compression and to prevent the bug.
Generated code with compression:
#define YY_MAX_SHIFT 3
#define YY_SHIFT_COUNT (2)
#define YY_SHIFT_USE_DFLT (13)
static const unsigned char yy_shift_ofst[] = {
/* 0 */ 7, 1, 6,
};
Generated code without compression:
#define YY_MAX_SHIFT 3
#define YY_SHIFT_COUNT (3)
#define YY_SHIFT_USE_DFLT (13)
static const unsigned char yy_shift_ofst[] = {
/* 0 */ 7, 1, 6, 13,
};
I submitted the details to the SQLite mailing list earlier this year but nothing has happened yet. The correct solution is probably to continue compressing but handle default actions in the template.
Bug logged to SQLite mailing list:
http://www.mail-archive.com/sqlite-users#mailinglists.sqlite.org/msg99712.html
http://www.mail-archive.com/sqlite-users#mailinglists.sqlite.org/msg99716.html