Note that there are some explanatory texts on larger screens.

plurals
  1. POInteger overflow not consistent
    primarykey
    data
    text
    <p>Pardon me if this question has been posed before. I looked for answers to similar questions, but I'm still puzzled with my problem. So I will shoot the question anyway. I'm using a C library called <a href="http://libexif.sourceforge.net/" rel="nofollow">libexif</a> for image data. I run my application (which uses this library) both on my Linux desktop and my MIPS board. For a particular image file when I try to fetch the created time, I was getting an error/invalid value. On debugging further I saw that for this particular image file, I was not getting the tag (EXIF_TAG_DATE_TIME) as expected. </p> <p>This library has several utility functions. Most functions are structured like below </p> <pre><code>int16_t exif_get_sshort (const unsigned char *buf, ExifByteOrder order) { if (!buf) return 0; switch (order) { case EXIF_BYTE_ORDER_MOTOROLA: return ((buf[0] &lt;&lt; 8) | buf[1]); case EXIF_BYTE_ORDER_INTEL: return ((buf[1] &lt;&lt; 8) | buf[0]); } /* Won't be reached */ return (0); } uint16_t exif_get_short (const unsigned char *buf, ExifByteOrder order) { return (exif_get_sshort (buf, order) &amp; 0xffff); } </code></pre> <p>When the library tries to investigate the presence of tags in raw data, it calls <code>exif_get_short()</code> and assigns the value returned to a variable which is of type enum (int). </p> <p>In the error case, <code>exif_get_short()</code> which is supposed to return unsigned value (34687) returns a negative number (-30871) which messes up the whole tag extraction from the image data. </p> <p>34687 is outside the range of maximum representable int16_t value. And therefore leads to an overflow. When I make this slight modification in code, everything seems to work fine </p> <pre><code>uint16_t exif_get_short (const unsigned char *buf, ExifByteOrder order) { int temp = (exif_get_sshort (buf, order) &amp; 0xffff); return temp; } </code></pre> <p>But since this is a pretty stable library and in use for quite some time, it led me to believe that I may be missing something here. Moreover this is the general way the code is structured for other utility functions as well. Ex: <code>exif_get_long()</code> calls <code>exif_get_slong()</code>. I would then have to change all utility functions. </p> <p>What is confusing me is that when I run this piece of code on my linux desktop for the error file, I see no problems and things work fine with the original library code. Which led to me believe that perhaps UINT16_MAX and INT16_MAX macros have different values on my desktop and MIPS board. But unfortunately, thats not the case. Both print identical values on the board and desktop. If this piece of code fails, it should fail also on my desktop. </p> <p>What am I missing here? Any hints would be much appreciated. </p> <p>EDIT: The code which calls exif_get_short() goes something like this:</p> <pre><code>ExifTag tag; ... tag = exif_get_short (d + offset + 12 * i, data-&gt;priv-&gt;order); switch (tag) { ... ... </code></pre> <p>The type ExifTag is as follows:</p> <pre><code>typedef enum { EXIF_TAG_GPS_VERSION_ID = 0x0000, EXIF_TAG_INTEROPERABILITY_INDEX = 0x0001, ... ... }ExifTag ; </code></pre> <p>The cross compiler being used is mipsisa32r2el-timesys-linux-gnu-gcc</p> <pre><code>CFLAGS = -pipe -mips32r2 -mtune=74kc -mdspr2 -Werror -O3 -Wall -W -D_REENTRANT -fPIC $(DEFINES) </code></pre> <p>I'm using libexif within Qt - Qt Media hub (actually libexif comes along with Qt Media hub)</p> <p>EDIT2: Some additional observations: I'm observing something bizarre. I have put print statements in exif_get_short(). Just before return</p> <pre><code>printf("return_value %d\n %u\n",exif_get_sshort (buf, order) &amp; 0xffff, exif_get_sshort (buf, order) &amp; 0xffff); return (exif_get_sshort (buf, order) &amp; 0xffff); </code></pre> <p>I see the following o/p: return_value 34665 34665</p> <p>I then also inserted print statements in the code which calls exif_get_short() </p> <pre><code>.... tag = exif_get_short (d + offset + 12 * i, data-&gt;priv-&gt;order); printf("TAG %d %u\n",tag,tag); </code></pre> <p>I see the following o/p: TAG -30871 4294936425</p> <p>EDIT3 : Posting assembly code for exif_get_short() and exif_get_sshort() taken on MIPS board</p> <pre><code> .file 1 "exif-utils.c" .section .mdebug.abi32 .previous .gnu_attribute 4, 1 .abicalls .text .align 2 .globl exif_get_sshort .ent exif_get_sshort .type exif_get_sshort, @function exif_get_sshort: .set nomips16 .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0 .mask 0x00000000,0 .fmask 0x00000000,0 .set noreorder .set nomacro beq $4,$0,$L2 nop beq $5,$0,$L3 nop li $2,1 # 0x1 beq $5,$2,$L8 nop $L2: j $31 move $2,$0 $L3: lbu $2,0($4) lbu $3,1($4) sll $2,$2,8 or $2,$2,$3 j $31 seh $2,$2 $L8: lbu $2,1($4) lbu $3,0($4) sll $2,$2,8 or $2,$2,$3 j $31 seh $2,$2 .set macro .set reorder .end exif_get_sshort .align 2 .globl exif_get_short .ent exif_get_short .type exif_get_short, @function exif_get_short: .set nomips16 .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0 .mask 0x00000000,0 .fmask 0x00000000,0 .set noreorder .cpload $25 .set nomacro lw $25,%call16(exif_get_sshort)($28) jr $25 nop .set macro .set reorder .end exif_get_short </code></pre> <p>Just for completeness, the ASM code taken from my linux machine</p> <pre><code> .file "exif-utils.c" .text .p2align 4,,15 .globl exif_get_sshort .type exif_get_sshort, @function exif_get_sshort: .LFB1: .cfi_startproc xorl %eax, %eax testq %rdi, %rdi je .L2 testl %esi, %esi jne .L8 movzbl (%rdi), %edx movzbl 1(%rdi), %eax sall $8, %edx orl %edx, %eax ret .p2align 4,,10 .p2align 3 .L8: cmpl $1, %esi jne .L2 movzbl 1(%rdi), %edx movzbl (%rdi), %eax sall $8, %edx orl %edx, %eax .L2: rep ret .cfi_endproc .LFE1: .size exif_get_sshort, .-exif_get_sshort .p2align 4,,15 .globl exif_get_short .type exif_get_short, @function exif_get_short: .LFB2: .cfi_startproc jmp exif_get_sshort@PLT .cfi_endproc .LFE2: .size exif_get_short, .-exif_get_short </code></pre> <p>EDIT4: Hopefully my last update :-) ASM code with compiler option set to -O1</p> <p>exif_get_short:</p> <pre><code>.set nomips16 .frame $sp,32,$31 # vars= 0, regs= 1/0, args= 16, gp= 8 .mask 0x80000000,-4 .fmask 0x00000000,0 .set noreorder .cpload $25 .set nomacro addiu $sp,$sp,-32 sw $31,28($sp) .cprestore 16 lw $25,%call16(exif_get_sshort)($28) jalr $25 nop lw $28,16($sp) andi $2,$2,0xffff lw $31,28($sp) j $31 addiu $sp,$sp,32 .set macro .set reorder .end exif_get_short </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload